@redocly/cli 1.7.0 → 1.8.1

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 (118) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/lib/__tests__/commands/build-docs.test.js +3 -3
  3. package/lib/__tests__/commands/bundle.test.js +5 -5
  4. package/lib/__tests__/commands/join.test.js +11 -11
  5. package/lib/__tests__/commands/lint.test.js +14 -14
  6. package/lib/__tests__/commands/push-region.test.js +1 -1
  7. package/lib/__tests__/commands/push.test.js +11 -11
  8. package/lib/__tests__/fetch-with-timeout.test.js +4 -13
  9. package/lib/__tests__/spinner.test.js +43 -0
  10. package/lib/__tests__/utils.test.js +36 -36
  11. package/lib/__tests__/wrapper.test.js +8 -8
  12. package/lib/cms/api/__tests__/api-keys.test.d.ts +1 -0
  13. package/lib/cms/api/__tests__/api-keys.test.js +26 -0
  14. package/lib/cms/api/__tests__/api.client.test.d.ts +1 -0
  15. package/lib/cms/api/__tests__/api.client.test.js +217 -0
  16. package/lib/cms/api/__tests__/domains.test.d.ts +1 -0
  17. package/lib/cms/api/__tests__/domains.test.js +13 -0
  18. package/lib/cms/api/api-client.d.ts +50 -0
  19. package/lib/cms/api/api-client.js +148 -0
  20. package/lib/cms/api/api-keys.d.ts +1 -0
  21. package/lib/cms/api/api-keys.js +24 -0
  22. package/lib/cms/api/domains.d.ts +1 -0
  23. package/lib/cms/api/domains.js +12 -0
  24. package/lib/cms/api/index.d.ts +3 -0
  25. package/lib/cms/api/index.js +19 -0
  26. package/lib/cms/api/types.d.ts +91 -0
  27. package/lib/cms/api/types.js +2 -0
  28. package/lib/cms/commands/__tests__/push-status.test.d.ts +1 -0
  29. package/lib/cms/commands/__tests__/push-status.test.js +164 -0
  30. package/lib/cms/commands/__tests__/push.test.d.ts +1 -0
  31. package/lib/cms/commands/__tests__/push.test.js +226 -0
  32. package/lib/cms/commands/push-status.d.ts +12 -0
  33. package/lib/cms/commands/push-status.js +150 -0
  34. package/lib/cms/commands/push.d.ts +23 -0
  35. package/lib/cms/commands/push.js +142 -0
  36. package/lib/cms/utils.d.ts +2 -0
  37. package/lib/cms/utils.js +6 -0
  38. package/lib/commands/build-docs/index.js +4 -4
  39. package/lib/commands/build-docs/utils.js +2 -2
  40. package/lib/commands/bundle.js +13 -13
  41. package/lib/commands/join.js +25 -25
  42. package/lib/commands/lint.js +10 -10
  43. package/lib/commands/login.js +2 -2
  44. package/lib/commands/preview-docs/index.js +4 -4
  45. package/lib/commands/preview-docs/preview-server/preview-server.js +2 -2
  46. package/lib/commands/preview-project/types.d.ts +1 -1
  47. package/lib/commands/push.d.ts +5 -0
  48. package/lib/commands/push.js +25 -17
  49. package/lib/commands/split/__tests__/index.test.js +2 -2
  50. package/lib/commands/split/index.js +17 -17
  51. package/lib/commands/stats.js +4 -4
  52. package/lib/index.d.ts +1 -1
  53. package/lib/index.js +130 -17
  54. package/lib/types.d.ts +8 -1
  55. package/lib/{__mocks__/utils.js → utils/__mocks__/miscellaneous.js} +1 -1
  56. package/lib/utils/assert-node-version.d.ts +1 -0
  57. package/lib/{fetch-with-timeout.js → utils/fetch-with-timeout.js} +2 -7
  58. package/lib/{utils.d.ts → utils/miscellaneous.d.ts} +1 -1
  59. package/lib/{utils.js → utils/miscellaneous.js} +2 -2
  60. package/lib/utils/spinner.d.ts +10 -0
  61. package/lib/utils/spinner.js +42 -0
  62. package/lib/{update-version-notifier.js → utils/update-version-notifier.js} +4 -4
  63. package/lib/wrapper.js +5 -5
  64. package/package.json +5 -3
  65. package/src/__tests__/commands/build-docs.test.ts +2 -2
  66. package/src/__tests__/commands/bundle.test.ts +2 -2
  67. package/src/__tests__/commands/join.test.ts +2 -2
  68. package/src/__tests__/commands/lint.test.ts +3 -3
  69. package/src/__tests__/commands/push-region.test.ts +1 -1
  70. package/src/__tests__/commands/push.test.ts +2 -2
  71. package/src/__tests__/fetch-with-timeout.test.ts +4 -16
  72. package/src/__tests__/spinner.test.ts +51 -0
  73. package/src/__tests__/utils.test.ts +2 -5
  74. package/src/__tests__/wrapper.test.ts +2 -2
  75. package/src/cms/api/__tests__/api-keys.test.ts +37 -0
  76. package/src/cms/api/__tests__/api.client.test.ts +275 -0
  77. package/src/cms/api/__tests__/domains.test.ts +15 -0
  78. package/src/cms/api/api-client.ts +199 -0
  79. package/src/cms/api/api-keys.ts +26 -0
  80. package/src/cms/api/domains.ts +11 -0
  81. package/src/cms/api/index.ts +3 -0
  82. package/src/cms/api/types.ts +101 -0
  83. package/src/cms/commands/__tests__/push-status.test.ts +212 -0
  84. package/src/cms/commands/__tests__/push.test.ts +293 -0
  85. package/src/cms/commands/push-status.ts +203 -0
  86. package/src/cms/commands/push.ts +215 -0
  87. package/src/cms/utils.ts +1 -0
  88. package/src/commands/build-docs/index.ts +1 -1
  89. package/src/commands/build-docs/utils.ts +1 -1
  90. package/src/commands/bundle.ts +2 -2
  91. package/src/commands/join.ts +2 -2
  92. package/src/commands/lint.ts +1 -1
  93. package/src/commands/login.ts +1 -1
  94. package/src/commands/preview-docs/index.ts +5 -1
  95. package/src/commands/preview-docs/preview-server/preview-server.ts +1 -1
  96. package/src/commands/preview-project/types.ts +1 -1
  97. package/src/commands/push.ts +15 -1
  98. package/src/commands/split/__tests__/index.test.ts +3 -4
  99. package/src/commands/split/index.ts +2 -2
  100. package/src/commands/stats.ts +2 -2
  101. package/src/index.ts +138 -20
  102. package/src/types.ts +8 -0
  103. package/src/{__mocks__/utils.ts → utils/__mocks__/miscellaneous.ts} +1 -1
  104. package/src/{fetch-with-timeout.ts → utils/fetch-with-timeout.ts} +1 -6
  105. package/src/{utils.ts → utils/miscellaneous.ts} +2 -2
  106. package/src/utils/spinner.ts +50 -0
  107. package/src/{update-version-notifier.ts → utils/update-version-notifier.ts} +2 -2
  108. package/src/wrapper.ts +7 -2
  109. package/tsconfig.tsbuildinfo +1 -1
  110. /package/lib/{assert-node-version.d.ts → __tests__/spinner.test.d.ts} +0 -0
  111. /package/lib/{__mocks__/utils.d.ts → utils/__mocks__/miscellaneous.d.ts} +0 -0
  112. /package/lib/{assert-node-version.js → utils/assert-node-version.js} +0 -0
  113. /package/lib/{fetch-with-timeout.d.ts → utils/fetch-with-timeout.d.ts} +0 -0
  114. /package/lib/{js-utils.d.ts → utils/js-utils.d.ts} +0 -0
  115. /package/lib/{js-utils.js → utils/js-utils.js} +0 -0
  116. /package/lib/{update-version-notifier.d.ts → utils/update-version-notifier.d.ts} +0 -0
  117. /package/src/{assert-node-version.ts → utils/assert-node-version.ts} +0 -0
  118. /package/src/{js-utils.ts → utils/js-utils.ts} +0 -0
@@ -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,7 +42,7 @@ 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);
@@ -55,17 +55,17 @@ function loadFile(fileName) {
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) {
@@ -85,9 +85,9 @@ function traverseDirectoryDeep(directory, callback, componentsFiles) {
85
85
  function traverseDirectoryDeepCallback(filename, directory, componentsFiles) {
86
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,16 +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
29
  const preview_project_1 = require("./commands/preview-project");
30
30
  const constants_1 = require("./commands/preview-project/constants");
31
+ const push_1 = require("./commands/push");
31
32
  if (!('replaceAll' in String.prototype)) {
32
33
  require('core-js/actual/string/replace-all');
33
34
  }
@@ -132,18 +133,65 @@ yargs
132
133
  process.env.REDOCLY_CLI_COMMAND = 'join';
133
134
  (0, wrapper_1.commandWrapper)(join_1.handleJoin)(argv);
134
135
  })
135
- .command('push [api] [maybeDestination] [maybeBranchName]', 'Push an API description to the Redocly API registry.', (yargs) => yargs
136
- .usage('push [api]')
137
- .positional('api', { type: 'string' })
138
- .positional('maybeDestination', { type: 'string' })
139
- .hide('maybeDestination')
140
- .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')
141
143
  .option({
142
144
  organization: {
143
145
  description: 'Name of the organization to push to.',
144
146
  type: 'string',
145
147
  alias: 'o',
146
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({
147
195
  destination: {
148
196
  description: 'API name and version in the format `name@version`.',
149
197
  type: 'string',
@@ -196,14 +244,79 @@ yargs
196
244
  choices: ['warn', 'error', 'off'],
197
245
  default: 'warn',
198
246
  },
199
- })
200
- .deprecateOption('batch-id', 'use --job-id')
201
- .deprecateOption('maybeDestination')
202
- .implies('job-id', 'batch-size')
203
- .implies('batch-id', 'batch-size')
204
- .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) => {
205
318
  process.env.REDOCLY_CLI_COMMAND = 'push';
206
- (0, wrapper_1.commandWrapper)((0, push_1.transformPush)(push_1.handlePush))(argv);
319
+ (0, wrapper_1.commandWrapper)((0, push_1.commonPushHandler)(argv))(argv);
207
320
  })
208
321
  .command('lint [apis...]', 'Lint an API description.', (yargs) => yargs.positional('apis', { array: true, type: 'string', demandOption: true }).option({
209
322
  format: {
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,9 @@ 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';
11
15
  import type { PreviewProjectOptions } from './commands/preview-project/types';
12
16
  export type Totals = {
13
17
  errors: number;
@@ -21,10 +25,13 @@ export type Entrypoint = {
21
25
  export declare const outputExtensions: readonly BundleOutputFormat[];
22
26
  export type OutputExtensions = 'json' | 'yaml' | 'yml' | undefined;
23
27
  export declare const regionChoices: readonly Region[];
24
- export type CommandOptions = StatsOptions | SplitOptions | JoinOptions | PushOptions | LintOptions | BundleOptions | LoginOptions | PreviewDocsOptions | BuildDocsArgv | PreviewProjectOptions;
28
+ export type CommandOptions = StatsOptions | SplitOptions | JoinOptions | PushOptions | PushBhOptions | LintOptions | BundleOptions | LoginOptions | PreviewDocsOptions | BuildDocsArgv | PushStatusOptions | PreviewProjectOptions;
25
29
  export type Skips = {
26
30
  'skip-rule'?: string[];
27
31
  'skip-decorator'?: string[];
28
32
  'skip-preprocessor'?: string[];
29
33
  };
30
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* () {
@@ -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
  };
package/lib/wrapper.js CHANGED
@@ -11,8 +11,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.commandWrapper = void 0;
13
13
  const openapi_core_1 = require("@redocly/openapi-core");
14
- const update_version_notifier_1 = require("./update-version-notifier");
15
- const utils_1 = require("./utils");
14
+ const update_version_notifier_1 = require("./utils/update-version-notifier");
15
+ const miscellaneous_1 = require("./utils/miscellaneous");
16
16
  const lint_1 = require("./commands/lint");
17
17
  function commandWrapper(commandHandler) {
18
18
  return (argv) => __awaiter(this, void 0, void 0, function* () {
@@ -21,9 +21,9 @@ function commandWrapper(commandHandler) {
21
21
  let telemetry;
22
22
  try {
23
23
  if (argv.config && !(0, openapi_core_1.doesYamlFileExist)(argv.config)) {
24
- (0, utils_1.exitWithError)('Please, provide valid path to the configuration file');
24
+ (0, miscellaneous_1.exitWithError)('Please, provide valid path to the configuration file');
25
25
  }
26
- const config = (yield (0, utils_1.loadConfigAndHandleErrors)({
26
+ const config = (yield (0, miscellaneous_1.loadConfigAndHandleErrors)({
27
27
  configPath: argv.config,
28
28
  customExtends: argv.extends,
29
29
  region: argv.region,
@@ -41,7 +41,7 @@ function commandWrapper(commandHandler) {
41
41
  }
42
42
  finally {
43
43
  if (process.env.REDOCLY_TELEMETRY !== 'off' && telemetry !== 'off') {
44
- yield (0, utils_1.sendTelemetry)(argv, code, hasConfig);
44
+ yield (0, miscellaneous_1.sendTelemetry)(argv, code, hasConfig);
45
45
  }
46
46
  process.once('beforeExit', () => {
47
47
  process.exit(code);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/cli",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -36,10 +36,12 @@
36
36
  "Roman Hotsiy <roman@redoc.ly> (https://redoc.ly/)"
37
37
  ],
38
38
  "dependencies": {
39
- "@redocly/openapi-core": "1.7.0",
39
+ "@redocly/openapi-core": "1.8.1",
40
+ "abort-controller": "^3.0.0",
40
41
  "chokidar": "^3.5.1",
41
42
  "colorette": "^1.2.0",
42
43
  "core-js": "^3.32.1",
44
+ "form-data": "^4.0.0",
43
45
  "get-port-please": "^3.0.1",
44
46
  "glob": "^7.1.6",
45
47
  "handlebars": "^4.7.6",
@@ -59,7 +61,7 @@
59
61
  "@types/react": "^17.0.0 || ^18.2.21",
60
62
  "@types/react-dom": "^17.0.0 || ^18.2.7",
61
63
  "@types/semver": "^7.5.0",
62
- "@types/yargs": "17.0.5",
64
+ "@types/yargs": "17.0.32",
63
65
  "typescript": "^5.2.2"
64
66
  }
65
67
  }
@@ -3,11 +3,11 @@ import { renderToString } from 'react-dom/server';
3
3
  import { handlerBuildCommand } from '../../commands/build-docs';
4
4
  import { BuildDocsArgv } from '../../commands/build-docs/types';
5
5
  import { getPageHTML } from '../../commands/build-docs/utils';
6
- import { getFallbackApisOrExit } from '../../utils';
6
+ import { getFallbackApisOrExit } from '../../utils/miscellaneous';
7
7
 
8
8
  jest.mock('redoc');
9
9
  jest.mock('fs');
10
- jest.mock('../../utils');
10
+ jest.mock('../../utils/miscellaneous');
11
11
 
12
12
  const config = {
13
13
  output: '',
@@ -1,13 +1,13 @@
1
1
  import { lint, bundle, getTotals, getMergedConfig } from '@redocly/openapi-core';
2
2
 
3
3
  import { BundleOptions, handleBundle } from '../../commands/bundle';
4
- import { handleError } from '../../utils';
4
+ import { handleError } from '../../utils/miscellaneous';
5
5
  import { commandWrapper } from '../../wrapper';
6
6
  import SpyInstance = jest.SpyInstance;
7
7
  import { Arguments } from 'yargs';
8
8
 
9
9
  jest.mock('@redocly/openapi-core');
10
- jest.mock('../../utils');
10
+ jest.mock('../../utils/miscellaneous');
11
11
 
12
12
  (getMergedConfig as jest.Mock).mockImplementation((config) => config);
13
13
 
@@ -1,11 +1,11 @@
1
1
  import { handleJoin } from '../../commands/join';
2
- import { exitWithError, writeToFileByExtension, writeYaml } from '../../utils';
2
+ import { exitWithError, writeToFileByExtension, writeYaml } from '../../utils/miscellaneous';
3
3
  import { yellow } from 'colorette';
4
4
  import { detectSpec } from '@redocly/openapi-core';
5
5
  import { loadConfig } from '../../__mocks__/@redocly/openapi-core';
6
6
  import { ConfigFixture } from '../fixtures/config';
7
7
 
8
- jest.mock('../../utils');
8
+ jest.mock('../../utils/miscellaneous');
9
9
 
10
10
  jest.mock('colorette');
11
11
 
@@ -14,7 +14,7 @@ import {
14
14
  exitWithError,
15
15
  loadConfigAndHandleErrors,
16
16
  checkIfRulesetExist,
17
- } from '../../utils';
17
+ } from '../../utils/miscellaneous';
18
18
  import { ConfigFixture } from '../fixtures/config';
19
19
  import { performance } from 'perf_hooks';
20
20
  import { commandWrapper } from '../../wrapper';
@@ -22,10 +22,10 @@ import { Arguments } from 'yargs';
22
22
  import { blue } from 'colorette';
23
23
 
24
24
  jest.mock('@redocly/openapi-core');
25
- jest.mock('../../utils');
25
+ jest.mock('../../utils/miscellaneous');
26
26
  jest.mock('perf_hooks');
27
27
 
28
- jest.mock('../../update-version-notifier', () => ({
28
+ jest.mock('../../utils/update-version-notifier', () => ({
29
29
  version: '1.0.0',
30
30
  }));
31
31