index.ts 2.6 KB

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