index.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /* global process */
  2. /* eslint import/no-nodejs-modules:0 */
  3. const fs = require('fs');
  4. const path = require('path');
  5. const JsonRefs = require('json-refs');
  6. const yaml = require('js-yaml');
  7. function dictToString(dict) {
  8. const res = [];
  9. for (const [k, v] of Object.entries(dict)) {
  10. res.push(`${k}: ${v}`);
  11. }
  12. return res.join('\n');
  13. }
  14. function bundle(originalFile) {
  15. const root = yaml.safeLoad(fs.readFileSync(originalFile, 'utf8'));
  16. const options = {
  17. filter: ['relative', 'remote'],
  18. resolveCirculars: true,
  19. location: originalFile,
  20. loaderOptions: {
  21. processContent: function(res, callback) {
  22. callback(undefined, yaml.safeLoad(res.text));
  23. },
  24. },
  25. };
  26. JsonRefs.clearCache();
  27. return JsonRefs.resolveRefs(root, options).then(
  28. function(results) {
  29. const resErrors = {};
  30. for (const [k, v] of Object.entries(results.refs)) {
  31. if (
  32. 'missing' in v &&
  33. v.missing === true &&
  34. (v.type === 'relative' || v.type === 'remote')
  35. )
  36. resErrors[k] = v.error;
  37. }
  38. if (Object.keys(resErrors).length > 0) {
  39. return Promise.reject(new Error(dictToString(resErrors)));
  40. }
  41. return results.resolved;
  42. },
  43. function(e) {
  44. const error = {};
  45. Object.getOwnPropertyNames(e).forEach(function(key) {
  46. error[key] = e[key];
  47. });
  48. return Promise.reject(new Error(dictToString(error)));
  49. }
  50. );
  51. }
  52. function build(originalFile, _, bundleTo) {
  53. bundle(originalFile).then(
  54. function(bundled) {
  55. const bundleString = JSON.stringify(bundled, null, 2);
  56. if (typeof bundleTo === 'string') {
  57. fs.writeFile(bundleTo, bundleString, function(err) {
  58. if (err) {
  59. // eslint-disable-next-line no-console
  60. console.log(err);
  61. return;
  62. }
  63. // eslint-disable-next-line no-console
  64. console.log('Saved bundle file at ' + bundleTo);
  65. });
  66. }
  67. },
  68. function(err) {
  69. // eslint-disable-next-line no-console
  70. console.log(err);
  71. }
  72. );
  73. }
  74. let originalFile;
  75. let targetDirValue;
  76. const argv = process.argv.slice(2);
  77. originalFile = argv[0];
  78. const derefedFile = argv[1] || 'tests/apidocs/openapi-derefed.json';
  79. try {
  80. if (!path.isAbsolute(originalFile)) {
  81. originalFile = path.resolve(process.cwd(), originalFile);
  82. }
  83. targetDirValue = path.dirname(originalFile);
  84. } catch (err) {
  85. // eslint-disable-next-line no-console
  86. console.error(`Failed to resolve path to [targetDir].`);
  87. process.exit(1);
  88. }
  89. build(originalFile, targetDirValue, derefedFile);