index.ts 2.6 KB

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