@redocly/cli 1.6.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +5 -5
  3. package/lib/__tests__/commands/build-docs.test.js +3 -3
  4. package/lib/__tests__/commands/bundle.test.js +5 -5
  5. package/lib/__tests__/commands/join.test.js +11 -11
  6. package/lib/__tests__/commands/lint.test.js +14 -14
  7. package/lib/__tests__/commands/push-region.test.js +1 -1
  8. package/lib/__tests__/commands/push.test.js +11 -11
  9. package/lib/__tests__/fetch-with-timeout.test.js +4 -13
  10. package/lib/__tests__/spinner.test.js +43 -0
  11. package/lib/__tests__/utils.test.js +54 -36
  12. package/lib/__tests__/wrapper.test.js +8 -8
  13. package/lib/cms/api/__tests__/api-keys.test.d.ts +1 -0
  14. package/lib/cms/api/__tests__/api-keys.test.js +26 -0
  15. package/lib/cms/api/__tests__/api.client.test.d.ts +1 -0
  16. package/lib/cms/api/__tests__/api.client.test.js +217 -0
  17. package/lib/cms/api/__tests__/domains.test.d.ts +1 -0
  18. package/lib/cms/api/__tests__/domains.test.js +13 -0
  19. package/lib/cms/api/api-client.d.ts +50 -0
  20. package/lib/cms/api/api-client.js +148 -0
  21. package/lib/cms/api/api-keys.d.ts +1 -0
  22. package/lib/cms/api/api-keys.js +24 -0
  23. package/lib/cms/api/domains.d.ts +1 -0
  24. package/lib/cms/api/domains.js +12 -0
  25. package/lib/cms/api/index.d.ts +3 -0
  26. package/lib/cms/api/index.js +19 -0
  27. package/lib/cms/api/types.d.ts +91 -0
  28. package/lib/cms/api/types.js +2 -0
  29. package/lib/cms/commands/__tests__/push-status.test.d.ts +1 -0
  30. package/lib/cms/commands/__tests__/push-status.test.js +164 -0
  31. package/lib/cms/commands/__tests__/push.test.d.ts +1 -0
  32. package/lib/cms/commands/__tests__/push.test.js +226 -0
  33. package/lib/cms/commands/push-status.d.ts +12 -0
  34. package/lib/cms/commands/push-status.js +150 -0
  35. package/lib/cms/commands/push.d.ts +23 -0
  36. package/lib/cms/commands/push.js +142 -0
  37. package/lib/cms/utils.d.ts +2 -0
  38. package/lib/cms/utils.js +6 -0
  39. package/lib/commands/build-docs/index.js +4 -4
  40. package/lib/commands/build-docs/utils.js +2 -2
  41. package/lib/commands/bundle.js +13 -13
  42. package/lib/commands/join.js +25 -25
  43. package/lib/commands/lint.js +10 -10
  44. package/lib/commands/login.js +2 -2
  45. package/lib/commands/preview-docs/index.js +4 -4
  46. package/lib/commands/preview-docs/preview-server/preview-server.js +2 -2
  47. package/lib/commands/preview-project/constants.d.ts +14 -0
  48. package/lib/commands/preview-project/constants.js +22 -0
  49. package/lib/commands/preview-project/index.d.ts +2 -0
  50. package/lib/commands/preview-project/index.js +58 -0
  51. package/lib/commands/preview-project/types.d.ts +10 -0
  52. package/lib/commands/preview-project/types.js +2 -0
  53. package/lib/commands/push.d.ts +5 -0
  54. package/lib/commands/push.js +25 -17
  55. package/lib/commands/split/__tests__/index.test.js +2 -2
  56. package/lib/commands/split/index.js +20 -20
  57. package/lib/commands/stats.js +4 -4
  58. package/lib/index.d.ts +1 -1
  59. package/lib/index.js +169 -25
  60. package/lib/types.d.ts +9 -1
  61. package/lib/{__mocks__/utils.js → utils/__mocks__/miscellaneous.js} +1 -1
  62. package/lib/utils/assert-node-version.d.ts +1 -0
  63. package/lib/{fetch-with-timeout.js → utils/fetch-with-timeout.js} +2 -7
  64. package/lib/{utils.d.ts → utils/miscellaneous.d.ts} +1 -1
  65. package/lib/{utils.js → utils/miscellaneous.js} +20 -2
  66. package/lib/utils/spinner.d.ts +10 -0
  67. package/lib/utils/spinner.js +42 -0
  68. package/lib/{update-version-notifier.js → utils/update-version-notifier.js} +4 -4
  69. package/lib/wrapper.js +5 -5
  70. package/package.json +5 -3
  71. package/src/__tests__/commands/build-docs.test.ts +2 -2
  72. package/src/__tests__/commands/bundle.test.ts +2 -2
  73. package/src/__tests__/commands/join.test.ts +2 -2
  74. package/src/__tests__/commands/lint.test.ts +3 -3
  75. package/src/__tests__/commands/push-region.test.ts +1 -1
  76. package/src/__tests__/commands/push.test.ts +2 -2
  77. package/src/__tests__/fetch-with-timeout.test.ts +4 -16
  78. package/src/__tests__/spinner.test.ts +51 -0
  79. package/src/__tests__/utils.test.ts +20 -5
  80. package/src/__tests__/wrapper.test.ts +2 -2
  81. package/src/cms/api/__tests__/api-keys.test.ts +37 -0
  82. package/src/cms/api/__tests__/api.client.test.ts +275 -0
  83. package/src/cms/api/__tests__/domains.test.ts +15 -0
  84. package/src/cms/api/api-client.ts +199 -0
  85. package/src/cms/api/api-keys.ts +26 -0
  86. package/src/cms/api/domains.ts +11 -0
  87. package/src/cms/api/index.ts +3 -0
  88. package/src/cms/api/types.ts +101 -0
  89. package/src/cms/commands/__tests__/push-status.test.ts +212 -0
  90. package/src/cms/commands/__tests__/push.test.ts +293 -0
  91. package/src/cms/commands/push-status.ts +203 -0
  92. package/src/cms/commands/push.ts +215 -0
  93. package/src/cms/utils.ts +1 -0
  94. package/src/commands/build-docs/index.ts +1 -1
  95. package/src/commands/build-docs/utils.ts +1 -1
  96. package/src/commands/bundle.ts +2 -2
  97. package/src/commands/join.ts +2 -2
  98. package/src/commands/lint.ts +1 -1
  99. package/src/commands/login.ts +1 -1
  100. package/src/commands/preview-docs/index.ts +5 -1
  101. package/src/commands/preview-docs/preview-server/preview-server.ts +1 -1
  102. package/src/commands/preview-project/constants.ts +23 -0
  103. package/src/commands/preview-project/index.ts +58 -0
  104. package/src/commands/preview-project/types.ts +12 -0
  105. package/src/commands/push.ts +15 -1
  106. package/src/commands/split/__tests__/index.test.ts +3 -4
  107. package/src/commands/split/index.ts +5 -5
  108. package/src/commands/stats.ts +2 -2
  109. package/src/index.ts +184 -28
  110. package/src/types.ts +12 -1
  111. package/src/{__mocks__/utils.ts → utils/__mocks__/miscellaneous.ts} +1 -1
  112. package/src/{fetch-with-timeout.ts → utils/fetch-with-timeout.ts} +1 -6
  113. package/src/{utils.ts → utils/miscellaneous.ts} +20 -2
  114. package/src/utils/spinner.ts +50 -0
  115. package/src/{update-version-notifier.ts → utils/update-version-notifier.ts} +2 -2
  116. package/src/wrapper.ts +7 -2
  117. package/tsconfig.tsbuildinfo +1 -1
  118. /package/lib/{assert-node-version.d.ts → __tests__/spinner.test.d.ts} +0 -0
  119. /package/lib/{__mocks__/utils.d.ts → utils/__mocks__/miscellaneous.d.ts} +0 -0
  120. /package/lib/{assert-node-version.js → utils/assert-node-version.js} +0 -0
  121. /package/lib/{fetch-with-timeout.d.ts → utils/fetch-with-timeout.d.ts} +0 -0
  122. /package/lib/{js-utils.d.ts → utils/js-utils.d.ts} +0 -0
  123. /package/lib/{js-utils.js → utils/js-utils.js} +0 -0
  124. /package/lib/{update-version-notifier.d.ts → utils/update-version-notifier.d.ts} +0 -0
  125. /package/src/{assert-node-version.ts → utils/assert-node-version.ts} +0 -0
  126. /package/src/{js-utils.ts → utils/js-utils.ts} +0 -0
@@ -13,8 +13,8 @@ const index_1 = require("../index");
13
13
  const path = require("path");
14
14
  const openapiCore = require("@redocly/openapi-core");
15
15
  const colorette_1 = require("colorette");
16
- const utils = require('../../../utils');
17
- jest.mock('../../../utils', () => (Object.assign(Object.assign({}, jest.requireActual('../../../utils')), { writeToFileByExtension: jest.fn() })));
16
+ const utils = require('../../../utils/miscellaneous');
17
+ jest.mock('../../../utils/miscellaneous', () => (Object.assign(Object.assign({}, jest.requireActual('../../../utils/miscellaneous')), { writeToFileByExtension: jest.fn() })));
18
18
  jest.mock('@redocly/openapi-core', () => (Object.assign(Object.assign({}, jest.requireActual('@redocly/openapi-core')), { isRef: jest.fn() })));
19
19
  describe('#split', () => {
20
20
  const openapiDir = 'test';
@@ -16,20 +16,20 @@ const openapi_core_1 = require("@redocly/openapi-core");
16
16
  const path = require("path");
17
17
  const perf_hooks_1 = require("perf_hooks");
18
18
  const isEqual = require('lodash.isequal');
19
- const utils_1 = require("../../utils");
20
- const js_utils_1 = require("../../js-utils");
19
+ const miscellaneous_1 = require("../../utils/miscellaneous");
20
+ const js_utils_1 = require("../../utils/js-utils");
21
21
  const types_1 = require("./types");
22
22
  function handleSplit(argv) {
23
23
  return __awaiter(this, void 0, void 0, function* () {
24
24
  const startedAt = perf_hooks_1.performance.now();
25
25
  const { api, outDir, separator } = argv;
26
26
  validateDefinitionFileName(api);
27
- const ext = (0, utils_1.getAndValidateFileExtension)(api);
28
- const openapi = (0, utils_1.readYaml)(api);
27
+ const ext = (0, miscellaneous_1.getAndValidateFileExtension)(api);
28
+ const openapi = (0, miscellaneous_1.readYaml)(api);
29
29
  splitDefinition(openapi, outDir, separator, ext);
30
30
  process.stderr.write(`🪓 Document: ${(0, colorette_1.blue)(api)} ${(0, colorette_1.green)('is successfully split')}
31
31
  and all related files are saved to the directory: ${(0, colorette_1.blue)(outDir)} \n`);
32
- (0, utils_1.printExecutionTime)('split', startedAt, api);
32
+ (0, miscellaneous_1.printExecutionTime)('split', startedAt, api);
33
33
  });
34
34
  }
35
35
  exports.handleSplit = handleSplit;
@@ -42,30 +42,30 @@ function splitDefinition(openapi, openapiDir, pathSeparator, ext) {
42
42
  // use webhook_ prefix for code samples to prevent potential name-clashes with paths samples
43
43
  iteratePathItems(webhooks, openapiDir, path.join(openapiDir, 'webhooks'), componentsFiles, pathSeparator, 'webhook_', ext);
44
44
  replace$Refs(openapi, openapiDir, componentsFiles);
45
- (0, utils_1.writeToFileByExtension)(openapi, path.join(openapiDir, `openapi.${ext}`));
45
+ (0, miscellaneous_1.writeToFileByExtension)(openapi, path.join(openapiDir, `openapi.${ext}`));
46
46
  }
47
47
  function isStartsWithComponents(node) {
48
48
  return node.startsWith(types_1.componentsPath);
49
49
  }
50
- function isNotYaml(filename) {
51
- return !(filename.endsWith('.yaml') || filename.endsWith('.yml'));
50
+ function isSupportedExtension(filename) {
51
+ return filename.endsWith('.yaml') || filename.endsWith('.yml') || filename.endsWith('.json');
52
52
  }
53
53
  function loadFile(fileName) {
54
54
  try {
55
55
  return (0, openapi_core_1.parseYaml)(fs.readFileSync(fileName, 'utf8'));
56
56
  }
57
57
  catch (e) {
58
- return (0, utils_1.exitWithError)(e.message);
58
+ return (0, miscellaneous_1.exitWithError)(e.message);
59
59
  }
60
60
  }
61
61
  function validateDefinitionFileName(fileName) {
62
62
  if (!fs.existsSync(fileName))
63
- (0, utils_1.exitWithError)(`File ${(0, colorette_1.blue)(fileName)} does not exist \n`);
63
+ (0, miscellaneous_1.exitWithError)(`File ${(0, colorette_1.blue)(fileName)} does not exist \n`);
64
64
  const file = loadFile(fileName);
65
65
  if (file.swagger)
66
- (0, utils_1.exitWithError)('OpenAPI 2 is not supported by this command');
66
+ (0, miscellaneous_1.exitWithError)('OpenAPI 2 is not supported by this command');
67
67
  if (!file.openapi)
68
- (0, utils_1.exitWithError)('File does not conform to the OpenAPI Specification. OpenAPI version is not specified');
68
+ (0, miscellaneous_1.exitWithError)('File does not conform to the OpenAPI Specification. OpenAPI version is not specified');
69
69
  return true;
70
70
  }
71
71
  function traverseDirectoryDeep(directory, callback, componentsFiles) {
@@ -83,11 +83,11 @@ function traverseDirectoryDeep(directory, callback, componentsFiles) {
83
83
  }
84
84
  }
85
85
  function traverseDirectoryDeepCallback(filename, directory, componentsFiles) {
86
- if (isNotYaml(filename))
86
+ if (!isSupportedExtension(filename))
87
87
  return;
88
- const pathData = (0, utils_1.readYaml)(filename);
88
+ const pathData = (0, miscellaneous_1.readYaml)(filename);
89
89
  replace$Refs(pathData, directory, componentsFiles);
90
- (0, utils_1.writeToFileByExtension)(pathData, filename);
90
+ (0, miscellaneous_1.writeToFileByExtension)(pathData, filename);
91
91
  }
92
92
  function crawl(object, visitor) {
93
93
  if (!(0, js_utils_1.isObject)(object))
@@ -160,7 +160,7 @@ function findComponentTypes(components) {
160
160
  return types_1.OPENAPI3_COMPONENT_NAMES.filter((item) => isNotSecurityComponentType(item) && Object.keys(components).includes(item));
161
161
  }
162
162
  function doesFileDiffer(filename, componentData) {
163
- return fs.existsSync(filename) && !isEqual((0, utils_1.readYaml)(filename), componentData);
163
+ return fs.existsSync(filename) && !isEqual((0, miscellaneous_1.readYaml)(filename), componentData);
164
164
  }
165
165
  function removeEmptyComponents(openapi, componentType) {
166
166
  if (openapi.components && (0, js_utils_1.isEmptyObject)(openapi.components[componentType])) {
@@ -197,7 +197,7 @@ function iteratePathItems(pathItems, openapiDir, outDir, componentsFiles, pathSe
197
197
  return;
198
198
  fs.mkdirSync(outDir, { recursive: true });
199
199
  for (const pathName of Object.keys(pathItems)) {
200
- const pathFile = `${path.join(outDir, (0, utils_1.pathToFilename)(pathName, pathSeparator))}.${ext}`;
200
+ const pathFile = `${path.join(outDir, (0, miscellaneous_1.pathToFilename)(pathName, pathSeparator))}.${ext}`;
201
201
  const pathData = pathItems[pathName];
202
202
  if ((0, openapi_core_1.isRef)(pathData))
203
203
  continue;
@@ -210,7 +210,7 @@ function iteratePathItems(pathItems, openapiDir, outDir, componentsFiles, pathSe
210
210
  for (const sample of methodDataXCode) {
211
211
  if (sample.source && sample.source.$ref)
212
212
  continue;
213
- const sampleFileName = path.join(openapiDir, 'code_samples', (0, utils_1.escapeLanguageName)(sample.lang), codeSamplesPathPrefix + (0, utils_1.pathToFilename)(pathName, pathSeparator), method + (0, utils_1.langToExt)(sample.lang));
213
+ const sampleFileName = path.join(openapiDir, 'code_samples', (0, miscellaneous_1.escapeLanguageName)(sample.lang), codeSamplesPathPrefix + (0, miscellaneous_1.pathToFilename)(pathName, pathSeparator), method + (0, miscellaneous_1.langToExt)(sample.lang));
214
214
  fs.mkdirSync(path.dirname(sampleFileName), { recursive: true });
215
215
  fs.writeFileSync(sampleFileName, sample.source);
216
216
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -220,7 +220,7 @@ function iteratePathItems(pathItems, openapiDir, outDir, componentsFiles, pathSe
220
220
  };
221
221
  }
222
222
  }
223
- (0, utils_1.writeToFileByExtension)(pathData, pathFile);
223
+ (0, miscellaneous_1.writeToFileByExtension)(pathData, pathFile);
224
224
  pathItems[pathName] = {
225
225
  $ref: (0, openapi_core_1.slash)(path.relative(openapiDir, pathFile)),
226
226
  };
@@ -258,7 +258,7 @@ function iterateComponents(openapi, openapiDir, componentsFiles, ext) {
258
258
  process.stderr.write((0, colorette_1.yellow)(`warning: conflict for ${componentName} - file already exists with different content: ${(0, colorette_1.blue)(filename)} ... Skip.\n`));
259
259
  }
260
260
  else {
261
- (0, utils_1.writeToFileByExtension)(componentData, filename);
261
+ (0, miscellaneous_1.writeToFileByExtension)(componentData, filename);
262
262
  }
263
263
  if (isNotSecurityComponentType(componentType)) {
264
264
  // security schemas must referenced from components
@@ -13,8 +13,8 @@ exports.handleStats = void 0;
13
13
  const perf_hooks_1 = require("perf_hooks");
14
14
  const colors = require("colorette");
15
15
  const openapi_core_1 = require("@redocly/openapi-core");
16
- const utils_1 = require("../utils");
17
- const utils_2 = require("../utils");
16
+ const miscellaneous_1 = require("../utils/miscellaneous");
17
+ const miscellaneous_2 = require("../utils/miscellaneous");
18
18
  const statsAccumulator = {
19
19
  refs: { metric: '🚗 References', total: 0, color: 'red', items: new Set() },
20
20
  externalDocs: { metric: '📦 External Documents', total: 0, color: 'magenta' },
@@ -54,7 +54,7 @@ function printStats(statsAccumulator, api, format) {
54
54
  }
55
55
  function handleStats(argv, config) {
56
56
  return __awaiter(this, void 0, void 0, function* () {
57
- const [{ path }] = yield (0, utils_1.getFallbackApisOrExit)(argv.api ? [argv.api] : [], config);
57
+ const [{ path }] = yield (0, miscellaneous_1.getFallbackApisOrExit)(argv.api ? [argv.api] : [], config);
58
58
  const externalRefResolver = new openapi_core_1.BaseResolver(config.resolve);
59
59
  const { bundle: document } = yield (0, openapi_core_1.bundle)({ config, ref: path });
60
60
  const lintConfig = config.styleguide;
@@ -86,7 +86,7 @@ function handleStats(argv, config) {
86
86
  ctx,
87
87
  });
88
88
  printStats(statsAccumulator, path, argv.format);
89
- (0, utils_2.printExecutionTime)('stats', startedAt, path);
89
+ (0, miscellaneous_2.printExecutionTime)('stats', startedAt, path);
90
90
  });
91
91
  }
92
92
  exports.handleStats = handleStats;
package/lib/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import './assert-node-version';
2
+ import './utils/assert-node-version';
package/lib/index.js CHANGED
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  });
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- require("./assert-node-version");
13
+ require("./utils/assert-node-version");
14
14
  const yargs = require("yargs");
15
15
  const types_1 = require("./types");
16
16
  const openapi_core_1 = require("@redocly/openapi-core");
@@ -18,14 +18,17 @@ const preview_docs_1 = require("./commands/preview-docs");
18
18
  const stats_1 = require("./commands/stats");
19
19
  const split_1 = require("./commands/split");
20
20
  const join_1 = require("./commands/join");
21
- const push_1 = require("./commands/push");
21
+ const push_status_1 = require("./cms/commands/push-status");
22
22
  const lint_1 = require("./commands/lint");
23
23
  const bundle_1 = require("./commands/bundle");
24
24
  const login_1 = require("./commands/login");
25
25
  const build_docs_1 = require("./commands/build-docs");
26
- const update_version_notifier_1 = require("./update-version-notifier");
26
+ const update_version_notifier_1 = require("./utils/update-version-notifier");
27
27
  const wrapper_1 = require("./wrapper");
28
- const update_version_notifier_2 = require("./update-version-notifier");
28
+ const update_version_notifier_2 = require("./utils/update-version-notifier");
29
+ const preview_project_1 = require("./commands/preview-project");
30
+ const constants_1 = require("./commands/preview-project/constants");
31
+ const push_1 = require("./commands/push");
29
32
  if (!('replaceAll' in String.prototype)) {
30
33
  require('core-js/actual/string/replace-all');
31
34
  }
@@ -82,14 +85,14 @@ yargs
82
85
  process.env.REDOCLY_CLI_COMMAND = 'split';
83
86
  (0, wrapper_1.commandWrapper)(split_1.handleSplit)(argv);
84
87
  })
85
- .command('join [apis...]', 'Join definitions [experimental].', (yargs) => yargs
88
+ .command('join [apis...]', 'Join multiple API descriptions into one [experimental].', (yargs) => yargs
86
89
  .positional('apis', {
87
90
  array: true,
88
91
  type: 'string',
89
92
  demandOption: true,
90
93
  })
91
94
  .option({
92
- lint: { description: 'Lint definitions', type: 'boolean', default: false, hidden: true },
95
+ lint: { description: 'Lint descriptions', type: 'boolean', default: false, hidden: true },
93
96
  decorate: { description: 'Run decorators', type: 'boolean', default: false },
94
97
  preprocess: { description: 'Run preprocessors', type: 'boolean', default: false },
95
98
  'prefix-tags-with-info-prop': {
@@ -112,7 +115,7 @@ yargs
112
115
  type: 'boolean',
113
116
  },
114
117
  output: {
115
- describe: 'Output file',
118
+ description: 'Output file.',
116
119
  alias: 'o',
117
120
  type: 'string',
118
121
  },
@@ -130,18 +133,65 @@ yargs
130
133
  process.env.REDOCLY_CLI_COMMAND = 'join';
131
134
  (0, wrapper_1.commandWrapper)(join_1.handleJoin)(argv);
132
135
  })
133
- .command('push [api] [maybeDestination] [maybeBranchName]', 'Push an API description to the Redocly API registry.', (yargs) => yargs
134
- .usage('push [api]')
135
- .positional('api', { type: 'string' })
136
- .positional('maybeDestination', { type: 'string' })
137
- .hide('maybeDestination')
138
- .hide('maybeBranchName')
136
+ .command('push-status [pushId]', false, (yargs) => yargs
137
+ .positional('pushId', {
138
+ description: 'Push id.',
139
+ type: 'string',
140
+ required: true,
141
+ })
142
+ .implies('max-execution-time', 'wait')
139
143
  .option({
140
144
  organization: {
141
145
  description: 'Name of the organization to push to.',
142
146
  type: 'string',
143
147
  alias: 'o',
144
148
  },
149
+ project: {
150
+ description: 'Name of the project to push to.',
151
+ type: 'string',
152
+ alias: 'p',
153
+ },
154
+ domain: { description: 'Specify a domain.', alias: 'd', type: 'string' },
155
+ wait: {
156
+ description: 'Wait for build to finish.',
157
+ type: 'boolean',
158
+ default: false,
159
+ },
160
+ 'max-execution-time': {
161
+ description: 'Maximum execution time in seconds.',
162
+ type: 'number',
163
+ },
164
+ }), (argv) => {
165
+ process.env.REDOCLY_CLI_COMMAND = 'push-status';
166
+ (0, wrapper_1.commandWrapper)(push_status_1.handlePushStatus)(argv);
167
+ })
168
+ .command('push [apis...]', 'Push an API description to the Redocly API registry.', (yargs) => yargs
169
+ .positional('apis', {
170
+ type: 'string',
171
+ array: true,
172
+ required: true,
173
+ default: [],
174
+ })
175
+ .hide('project')
176
+ .hide('domain')
177
+ .hide('mount-path')
178
+ .hide('author')
179
+ .hide('message')
180
+ .hide('default-branch')
181
+ .hide('verbose')
182
+ .hide('commit-sha')
183
+ .hide('commit-url')
184
+ .hide('namespace')
185
+ .hide('repository')
186
+ .hide('wait-for-deployment')
187
+ .hide('created-at')
188
+ .hide('max-execution-time')
189
+ .deprecateOption('batch-id', 'use --job-id')
190
+ .implies('job-id', 'batch-size')
191
+ .implies('batch-id', 'batch-size')
192
+ .implies('batch-size', 'job-id')
193
+ .implies('max-execution-time', 'wait-for-deployment')
194
+ .option({
145
195
  destination: {
146
196
  description: 'API name and version in the format `name@version`.',
147
197
  type: 'string',
@@ -194,16 +244,81 @@ yargs
194
244
  choices: ['warn', 'error', 'off'],
195
245
  default: 'warn',
196
246
  },
197
- })
198
- .deprecateOption('batch-id', 'use --job-id')
199
- .deprecateOption('maybeDestination')
200
- .implies('job-id', 'batch-size')
201
- .implies('batch-id', 'batch-size')
202
- .implies('batch-size', 'job-id'), (argv) => {
247
+ organization: {
248
+ description: 'Name of the organization to push to.',
249
+ type: 'string',
250
+ alias: 'o',
251
+ },
252
+ project: {
253
+ description: 'Name of the project to push to.',
254
+ type: 'string',
255
+ alias: 'p',
256
+ },
257
+ 'mount-path': {
258
+ description: 'The path files should be pushed to.',
259
+ type: 'string',
260
+ alias: 'mp',
261
+ },
262
+ author: {
263
+ description: 'Author of the commit.',
264
+ type: 'string',
265
+ alias: 'a',
266
+ },
267
+ message: {
268
+ description: 'Commit message.',
269
+ type: 'string',
270
+ alias: 'm',
271
+ },
272
+ 'commit-sha': {
273
+ description: 'Commit SHA.',
274
+ type: 'string',
275
+ alias: 'sha',
276
+ },
277
+ 'commit-url': {
278
+ description: 'Commit URL.',
279
+ type: 'string',
280
+ alias: 'url',
281
+ },
282
+ namespace: {
283
+ description: 'Repository namespace.',
284
+ type: 'string',
285
+ },
286
+ repository: {
287
+ description: 'Repository name.',
288
+ type: 'string',
289
+ },
290
+ 'created-at': {
291
+ description: 'Commit creation date.',
292
+ type: 'string',
293
+ },
294
+ domain: { description: 'Specify a domain.', alias: 'd', type: 'string' },
295
+ config: {
296
+ description: 'Path to the config file.',
297
+ requiresArg: true,
298
+ type: 'string',
299
+ },
300
+ 'default-branch': {
301
+ type: 'string',
302
+ default: 'main',
303
+ },
304
+ 'max-execution-time': {
305
+ description: 'Maximum execution time in seconds.',
306
+ type: 'number',
307
+ },
308
+ 'wait-for-deployment': {
309
+ description: 'Wait for build to finish.',
310
+ type: 'boolean',
311
+ default: false,
312
+ },
313
+ verbose: {
314
+ type: 'boolean',
315
+ default: false,
316
+ },
317
+ }), (argv) => {
203
318
  process.env.REDOCLY_CLI_COMMAND = 'push';
204
- (0, wrapper_1.commandWrapper)((0, push_1.transformPush)(push_1.handlePush))(argv);
319
+ (0, wrapper_1.commandWrapper)((0, push_1.commonPushHandler)(argv))(argv);
205
320
  })
206
- .command('lint [apis...]', 'Lint definition.', (yargs) => yargs.positional('apis', { array: true, type: 'string', demandOption: true }).option({
321
+ .command('lint [apis...]', 'Lint an API description.', (yargs) => yargs.positional('apis', { array: true, type: 'string', demandOption: true }).option({
207
322
  format: {
208
323
  description: 'Use a specific output format.',
209
324
  choices: [
@@ -256,8 +371,12 @@ yargs
256
371
  process.env.REDOCLY_CLI_COMMAND = 'lint';
257
372
  (0, wrapper_1.commandWrapper)(lint_1.handleLint)(argv);
258
373
  })
259
- .command('bundle [apis...]', 'Bundle definition.', (yargs) => yargs.positional('apis', { array: true, type: 'string', demandOption: true }).options({
260
- output: { type: 'string', alias: 'o' },
374
+ .command('bundle [apis...]', 'Bundle a multi-file API description to a single file.', (yargs) => yargs.positional('apis', { array: true, type: 'string', demandOption: true }).options({
375
+ output: {
376
+ type: 'string',
377
+ description: 'Output file.',
378
+ alias: 'o',
379
+ },
261
380
  format: {
262
381
  description: 'Use a specific output format.',
263
382
  choices: ['stylish', 'codeframe', 'json', 'checkstyle'],
@@ -369,7 +488,32 @@ yargs
369
488
  process.stdout.write('Logged out from the Redocly account. ✋\n');
370
489
  }))(argv);
371
490
  }))
372
- .command('preview-docs [api]', 'Preview API reference docs for the specified definition.', (yargs) => yargs.positional('api', { type: 'string' }).options({
491
+ .command('preview', 'Preview Redocly project using one of the product NPM packages.', (yargs) => yargs.options({
492
+ product: {
493
+ type: 'string',
494
+ choices: ['redoc', 'revel', 'reef', 'realm', 'redoc-revel', 'redoc-reef', 'revel-reef'],
495
+ description: "Product used to launch preview. Default is inferred from project's package.json or 'realm' is used.",
496
+ },
497
+ plan: {
498
+ type: 'string',
499
+ choices: constants_1.PRODUCT_PLANS,
500
+ default: 'enterprise',
501
+ },
502
+ port: {
503
+ type: 'number',
504
+ description: 'Preview port.',
505
+ default: 4000,
506
+ },
507
+ 'source-dir': {
508
+ alias: 'd',
509
+ type: 'string',
510
+ description: 'Project directory.',
511
+ default: '.',
512
+ },
513
+ }), (argv) => {
514
+ (0, wrapper_1.commandWrapper)(preview_project_1.previewProject)(argv);
515
+ })
516
+ .command('preview-docs [api]', 'Preview API reference docs for an API description.', (yargs) => yargs.positional('api', { type: 'string' }).options({
373
517
  port: {
374
518
  alias: 'p',
375
519
  type: 'number',
@@ -462,7 +606,7 @@ yargs
462
606
  process.env.REDOCLY_CLI_COMMAND = 'build-docs';
463
607
  (0, wrapper_1.commandWrapper)(build_docs_1.handlerBuildCommand)(argv);
464
608
  }))
465
- .completion('completion', 'Generate completion script.')
609
+ .completion('completion', 'Generate autocomplete script for `redocly` command.')
466
610
  .demandCommand(1)
467
611
  .middleware([update_version_notifier_1.notifyUpdateCliVersion])
468
612
  .strict().argv;
package/lib/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { BundleOutputFormat, Region, Config } from '@redocly/openapi-core';
2
+ import type { ArgumentsCamelCase } from 'yargs';
2
3
  import type { LintOptions } from './commands/lint';
3
4
  import type { BundleOptions } from './commands/bundle';
4
5
  import type { JoinOptions } from './commands/join';
@@ -8,6 +9,10 @@ import type { StatsOptions } from './commands/stats';
8
9
  import type { SplitOptions } from './commands/split';
9
10
  import type { PreviewDocsOptions } from './commands/preview-docs';
10
11
  import type { BuildDocsArgv } from './commands/build-docs/types';
12
+ import type { PushOptions as PushBhOptions } from './cms/commands/push';
13
+ import type { PushStatusOptions } from './cms/commands/push-status';
14
+ import type { PushOptions as CMSPushOptions } from './cms/commands/push';
15
+ import type { PreviewProjectOptions } from './commands/preview-project/types';
11
16
  export type Totals = {
12
17
  errors: number;
13
18
  warnings: number;
@@ -20,10 +25,13 @@ export type Entrypoint = {
20
25
  export declare const outputExtensions: readonly BundleOutputFormat[];
21
26
  export type OutputExtensions = 'json' | 'yaml' | 'yml' | undefined;
22
27
  export declare const regionChoices: readonly Region[];
23
- export type CommandOptions = StatsOptions | SplitOptions | JoinOptions | PushOptions | LintOptions | BundleOptions | LoginOptions | PreviewDocsOptions | BuildDocsArgv;
28
+ export type CommandOptions = StatsOptions | SplitOptions | JoinOptions | PushOptions | PushBhOptions | LintOptions | BundleOptions | LoginOptions | PreviewDocsOptions | BuildDocsArgv | PushStatusOptions | PreviewProjectOptions;
24
29
  export type Skips = {
25
30
  'skip-rule'?: string[];
26
31
  'skip-decorator'?: string[];
27
32
  'skip-preprocessor'?: string[];
28
33
  };
29
34
  export type ConfigApis = Pick<Config, 'apis' | 'configFile'>;
35
+ export type PushArguments = ArgumentsCamelCase<PushOptions & CMSPushOptions & {
36
+ apis: string[];
37
+ }>;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkForDeprecatedOptions = exports.writeToFileByExtension = exports.getAndValidateFileExtension = exports.sortTopLevelKeysForOas = exports.checkIfRulesetExist = exports.loadConfigAndHandleErrors = exports.writeYaml = exports.exitWithError = exports.handleError = exports.getOutputFileName = exports.printLintTotals = exports.printUnusedWarnings = exports.printExecutionTime = exports.getExecutionTime = exports.pluralize = exports.slash = exports.dumpBundle = exports.getFallbackApisOrExit = void 0;
4
- const config_1 = require("../__tests__/fixtures/config");
4
+ const config_1 = require("../../__tests__/fixtures/config");
5
5
  exports.getFallbackApisOrExit = jest.fn((entrypoints) => entrypoints.map((path) => ({ path })));
6
6
  exports.dumpBundle = jest.fn(() => '');
7
7
  exports.slash = jest.fn();
@@ -0,0 +1 @@
1
+ export {};
@@ -10,19 +10,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const node_fetch_1 = require("node-fetch");
13
+ const abort_controller_1 = require("abort-controller");
13
14
  const TIMEOUT = 3000;
14
15
  exports.default = (url, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
15
16
  try {
16
- if (!global.AbortController) {
17
- return (0, node_fetch_1.default)(url, options);
18
- }
19
- const controller = new AbortController();
17
+ const controller = new abort_controller_1.default();
20
18
  const timeout = setTimeout(() => {
21
19
  controller.abort();
22
20
  }, TIMEOUT);
23
- // FIXME: fix this (possibly along with this issue: https://github.com/Redocly/redocly-cli/issues/1260)
24
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
25
- // @ts-ignore
26
21
  const res = yield (0, node_fetch_1.default)(url, Object.assign({ signal: controller.signal }, options));
27
22
  clearTimeout(timeout);
28
23
  return res;
@@ -1,5 +1,5 @@
1
1
  import { BundleOutputFormat, StyleguideConfig, Region, Config, Oas3Definition, Oas2Definition } from '@redocly/openapi-core';
2
- import { Totals, Entrypoint, ConfigApis, CommandOptions, OutputExtensions } from './types';
2
+ import { Totals, Entrypoint, ConfigApis, CommandOptions, OutputExtensions } from '../types';
3
3
  import { Arguments } from 'yargs';
4
4
  import type { RawConfigProcessor } from '@redocly/openapi-core/lib/config';
5
5
  export declare function getFallbackApisOrExit(argsApis: string[] | undefined, config: ConfigApis): Promise<Entrypoint[]>;
@@ -31,10 +31,10 @@ const readline = require("readline");
31
31
  const stream_1 = require("stream");
32
32
  const child_process_1 = require("child_process");
33
33
  const openapi_core_1 = require("@redocly/openapi-core");
34
- const types_1 = require("./types");
34
+ const types_1 = require("../types");
35
35
  const utils_1 = require("@redocly/openapi-core/lib/utils");
36
36
  const update_version_notifier_1 = require("./update-version-notifier");
37
- const push_1 = require("./commands/push");
37
+ const push_1 = require("../commands/push");
38
38
  const config_1 = require("@redocly/openapi-core/lib/config");
39
39
  function getFallbackApisOrExit(argsApis, config) {
40
40
  return __awaiter(this, void 0, void 0, function* () {
@@ -127,6 +127,24 @@ function langToExt(lang) {
127
127
  javascript: '.js',
128
128
  js: '.js',
129
129
  python: '.py',
130
+ c: '.c',
131
+ 'c++': '.cpp',
132
+ coffeescript: '.litcoffee',
133
+ dart: '.dart',
134
+ elixir: '.ex',
135
+ go: '.go',
136
+ groovy: '.groovy',
137
+ java: '.java',
138
+ kotlin: '.kt',
139
+ 'objective-c': '.m',
140
+ perl: '.pl',
141
+ powershell: '.ps1',
142
+ ruby: '.rb',
143
+ rust: '.rs',
144
+ scala: '.sc',
145
+ swift: '.swift',
146
+ typescript: '.ts',
147
+ tsx: '.tsx',
130
148
  };
131
149
  return langObj[lang.toLowerCase()];
132
150
  }
@@ -0,0 +1,10 @@
1
+ export declare class Spinner {
2
+ private readonly frames;
3
+ private currentFrame;
4
+ private intervalId;
5
+ private message;
6
+ constructor();
7
+ private showFrame;
8
+ start(message: string): void;
9
+ stop(): void;
10
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Spinner = void 0;
4
+ const process = require("process");
5
+ const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
6
+ class Spinner {
7
+ constructor() {
8
+ this.frames = SPINNER_FRAMES;
9
+ this.currentFrame = 0;
10
+ this.intervalId = null;
11
+ this.message = '';
12
+ }
13
+ showFrame() {
14
+ process.stdout.write('\r' + this.frames[this.currentFrame] + ' ' + this.message);
15
+ this.currentFrame = (this.currentFrame + 1) % this.frames.length;
16
+ }
17
+ start(message) {
18
+ if (this.message === message) {
19
+ return;
20
+ }
21
+ this.message = message;
22
+ // If we're not in a TTY, don't display the spinner.
23
+ if (!process.stdout.isTTY) {
24
+ process.stdout.write(`${message}...\n`);
25
+ return;
26
+ }
27
+ if (this.intervalId === null) {
28
+ this.intervalId = setInterval(() => {
29
+ this.showFrame();
30
+ }, 100);
31
+ }
32
+ }
33
+ stop() {
34
+ if (this.intervalId !== null) {
35
+ clearInterval(this.intervalId);
36
+ this.intervalId = null;
37
+ process.stdout.write('\r');
38
+ }
39
+ this.message = '';
40
+ }
41
+ }
42
+ exports.Spinner = Spinner;
@@ -17,8 +17,8 @@ const fs_1 = require("fs");
17
17
  const semver_1 = require("semver");
18
18
  const fetch_with_timeout_1 = require("./fetch-with-timeout");
19
19
  const colorette_1 = require("colorette");
20
- const utils_1 = require("./utils");
21
- _a = require('../package.json'), exports.version = _a.version, exports.name = _a.name;
20
+ const miscellaneous_1 = require("./miscellaneous");
21
+ _a = require('../../package.json'), exports.version = _a.version, exports.name = _a.name;
22
22
  const VERSION_CACHE_FILE = 'redocly-cli-version';
23
23
  const SPACE_TO_BORDER = 4;
24
24
  const INTERVAL_TO_CHECK = 1000 * 60 * 60 * 12;
@@ -67,7 +67,7 @@ const renderUpdateBanner = (current, latest) => {
67
67
  `Update now: \`${(0, colorette_1.cyan)('npm i -g @redocly/cli@latest')}\`.`,
68
68
  `Changelog: https://redocly.com/docs/cli/changelog/`,
69
69
  ];
70
- const maxLength = Math.max(...messageLines.map((line) => (0, utils_1.cleanColors)(line).length));
70
+ const maxLength = Math.max(...messageLines.map((line) => (0, miscellaneous_1.cleanColors)(line).length));
71
71
  const border = (0, colorette_1.yellow)('═'.repeat(maxLength + SPACE_TO_BORDER));
72
72
  const banner = `
73
73
  ${(0, colorette_1.yellow)('╔' + border + '╗')}
@@ -83,7 +83,7 @@ const renderUpdateBanner = (current, latest) => {
83
83
  process.stderr.write(banner);
84
84
  };
85
85
  const getLineWithPadding = (maxLength, line, index) => {
86
- const padding = ' '.repeat(maxLength - (0, utils_1.cleanColors)(line).length);
86
+ const padding = ' '.repeat(maxLength - (0, miscellaneous_1.cleanColors)(line).length);
87
87
  const extraSpaces = index !== 0 ? ' '.repeat(SPACE_TO_BORDER) : '';
88
88
  return `${extraSpaces}${(0, colorette_1.yellow)('║')} ${line}${padding} ${(0, colorette_1.yellow)('║')}`;
89
89
  };