@redocly/cli 1.0.0-beta.99 → 1.0.0-rc.2

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 (103) hide show
  1. package/README.md +83 -22
  2. package/bin/cli.js +1 -1
  3. package/lib/__mocks__/@redocly/openapi-core.d.ts +53 -1
  4. package/lib/__mocks__/@redocly/openapi-core.js +56 -5
  5. package/lib/__mocks__/documents.d.ts +92 -0
  6. package/lib/__mocks__/documents.js +63 -0
  7. package/lib/__mocks__/fs.d.ts +2 -0
  8. package/lib/__mocks__/fs.js +3 -1
  9. package/lib/__mocks__/perf_hooks.d.ts +4 -0
  10. package/lib/__mocks__/perf_hooks.js +6 -0
  11. package/lib/__mocks__/redoc.d.ts +7 -0
  12. package/lib/__mocks__/redoc.js +5 -0
  13. package/lib/__mocks__/utils.d.ts +26 -4
  14. package/lib/__mocks__/utils.js +8 -3
  15. package/lib/__tests__/commands/build-docs.test.d.ts +1 -0
  16. package/lib/__tests__/commands/build-docs.test.js +59 -0
  17. package/lib/__tests__/commands/bundle.test.js +66 -30
  18. package/lib/__tests__/commands/join.test.d.ts +1 -0
  19. package/lib/__tests__/commands/join.test.js +85 -0
  20. package/lib/__tests__/commands/lint.test.d.ts +1 -0
  21. package/lib/__tests__/commands/lint.test.js +149 -0
  22. package/lib/__tests__/commands/push-region.test.js +5 -4
  23. package/lib/__tests__/commands/push.test.js +254 -39
  24. package/lib/__tests__/fetch-with-timeout.test.d.ts +1 -0
  25. package/lib/__tests__/fetch-with-timeout.test.js +38 -0
  26. package/lib/__tests__/fixtures/config.d.ts +22 -0
  27. package/lib/__tests__/fixtures/config.js +24 -0
  28. package/lib/__tests__/utils.test.js +429 -1
  29. package/lib/__tests__/wrapper.test.d.ts +1 -0
  30. package/lib/__tests__/wrapper.test.js +57 -0
  31. package/lib/commands/build-docs/index.d.ts +3 -0
  32. package/lib/commands/build-docs/index.js +50 -0
  33. package/{src/commands/preview-docs/preview-server/default.hbs → lib/commands/build-docs/template.hbs} +2 -3
  34. package/lib/commands/build-docs/types.d.ts +23 -0
  35. package/lib/commands/build-docs/types.js +2 -0
  36. package/lib/commands/build-docs/utils.d.ts +7 -0
  37. package/lib/commands/build-docs/utils.js +99 -0
  38. package/lib/commands/bundle.d.ts +10 -12
  39. package/lib/commands/bundle.js +25 -24
  40. package/lib/commands/join.d.ts +12 -3
  41. package/lib/commands/join.js +295 -109
  42. package/lib/commands/lint.d.ts +11 -8
  43. package/lib/commands/lint.js +49 -19
  44. package/lib/commands/login.d.ts +5 -3
  45. package/lib/commands/login.js +2 -2
  46. package/lib/commands/preview-docs/index.d.ts +6 -6
  47. package/lib/commands/preview-docs/index.js +30 -20
  48. package/lib/commands/preview-docs/preview-server/oauth2-redirect.html +1 -1
  49. package/lib/commands/preview-docs/preview-server/preview-server.js +5 -4
  50. package/lib/commands/preview-docs/preview-server/server.d.ts +1 -1
  51. package/lib/commands/push.d.ts +21 -10
  52. package/lib/commands/push.js +110 -63
  53. package/lib/commands/split/__tests__/index.test.js +10 -8
  54. package/lib/commands/split/index.d.ts +5 -3
  55. package/lib/commands/split/index.js +15 -24
  56. package/lib/commands/split/types.d.ts +11 -11
  57. package/lib/commands/split/types.js +19 -19
  58. package/lib/commands/stats.d.ts +7 -4
  59. package/lib/commands/stats.js +13 -12
  60. package/lib/fetch-with-timeout.d.ts +2 -0
  61. package/lib/fetch-with-timeout.js +30 -0
  62. package/lib/index.js +194 -40
  63. package/lib/js-utils.d.ts +1 -0
  64. package/lib/js-utils.js +9 -3
  65. package/lib/types.d.ts +17 -1
  66. package/lib/update-version-notifier.d.ts +3 -0
  67. package/lib/update-version-notifier.js +105 -0
  68. package/lib/utils.d.ts +38 -5
  69. package/lib/utils.js +270 -41
  70. package/lib/wrapper.d.ts +4 -0
  71. package/lib/wrapper.js +52 -0
  72. package/package.json +18 -8
  73. package/src/__mocks__/@redocly/openapi-core.ts +0 -26
  74. package/src/__mocks__/fs.ts +0 -4
  75. package/src/__mocks__/utils.ts +0 -11
  76. package/src/__tests__/commands/bundle.test.ts +0 -120
  77. package/src/__tests__/commands/push-region.test.ts +0 -51
  78. package/src/__tests__/commands/push.test.ts +0 -158
  79. package/src/__tests__/utils.test.ts +0 -50
  80. package/src/assert-node-version.ts +0 -8
  81. package/src/commands/bundle.ts +0 -180
  82. package/src/commands/join.ts +0 -488
  83. package/src/commands/lint.ts +0 -110
  84. package/src/commands/login.ts +0 -21
  85. package/src/commands/preview-docs/index.ts +0 -188
  86. package/src/commands/preview-docs/preview-server/hot.js +0 -42
  87. package/src/commands/preview-docs/preview-server/oauth2-redirect.html +0 -21
  88. package/src/commands/preview-docs/preview-server/preview-server.ts +0 -155
  89. package/src/commands/preview-docs/preview-server/server.ts +0 -91
  90. package/src/commands/push.ts +0 -357
  91. package/src/commands/split/__tests__/fixtures/samples.json +0 -61
  92. package/src/commands/split/__tests__/fixtures/spec.json +0 -70
  93. package/src/commands/split/__tests__/fixtures/webhooks.json +0 -88
  94. package/src/commands/split/__tests__/index.test.ts +0 -117
  95. package/src/commands/split/index.ts +0 -349
  96. package/src/commands/split/types.ts +0 -73
  97. package/src/commands/stats.ts +0 -115
  98. package/src/index.ts +0 -316
  99. package/src/js-utils.ts +0 -12
  100. package/src/types.ts +0 -13
  101. package/src/utils.ts +0 -307
  102. package/tsconfig.json +0 -9
  103. package/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const node_fetch_1 = require("node-fetch");
13
+ const TIMEOUT = 3000;
14
+ exports.default = (url, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
15
+ try {
16
+ if (!global.AbortController) {
17
+ return node_fetch_1.default(url, options);
18
+ }
19
+ const controller = new AbortController();
20
+ const timeout = setTimeout(() => {
21
+ controller.abort();
22
+ }, TIMEOUT);
23
+ const res = yield node_fetch_1.default(url, Object.assign({ signal: controller.signal }, options));
24
+ clearTimeout(timeout);
25
+ return res;
26
+ }
27
+ catch (e) {
28
+ return;
29
+ }
30
+ });
package/lib/index.js CHANGED
@@ -22,20 +22,28 @@ const push_1 = require("./commands/push");
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
- const version = require('../package.json').version;
25
+ const build_docs_1 = require("./commands/build-docs");
26
+ const update_version_notifier_1 = require("./update-version-notifier");
27
+ const wrapper_1 = require("./wrapper");
28
+ const update_version_notifier_2 = require("./update-version-notifier");
29
+ update_version_notifier_1.cacheLatestVersion();
26
30
  yargs
27
- .version('version', 'Show version number.', version)
31
+ .version('version', 'Show version number.', update_version_notifier_2.version)
28
32
  .help('help', 'Show help.')
29
- .command('stats [entrypoint]', 'Gathering statistics for a document.', (yargs) => yargs.positional('entrypoint', { type: 'string' }).option({
30
- config: { description: 'Specify path to the config file.', type: 'string' },
33
+ .parserConfiguration({ 'greedy-arrays': false, 'camel-case-expansion': false })
34
+ .command('stats [api]', 'Show statistics for an API description.', (yargs) => yargs.positional('api', { type: 'string' }).option({
35
+ config: { description: 'Path to the config file.', type: 'string' },
31
36
  format: {
32
37
  description: 'Use a specific output format.',
33
38
  choices: ['stylish', 'json'],
34
39
  default: 'stylish',
35
40
  },
36
- }), stats_1.handleStats)
37
- .command('split [entrypoint]', 'Split definition into a multi-file structure.', (yargs) => yargs
38
- .positional('entrypoint', {
41
+ }), (argv) => {
42
+ process.env.REDOCLY_CLI_COMMAND = 'stats';
43
+ wrapper_1.commandWrapper(stats_1.handleStats)(argv);
44
+ })
45
+ .command('split [api]', 'Split an API definition into a multi-file structure.', (yargs) => yargs
46
+ .positional('api', {
39
47
  description: 'API definition file that you want to split',
40
48
  type: 'string',
41
49
  })
@@ -51,16 +59,26 @@ yargs
51
59
  type: 'string',
52
60
  default: '_',
53
61
  },
62
+ config: {
63
+ description: 'Path to the config file.',
64
+ requiresArg: true,
65
+ type: 'string',
66
+ },
54
67
  })
55
- .demandOption('entrypoint'), split_1.handleSplit)
56
- .command('join [entrypoints...]', 'Join definitions [experimental].', (yargs) => yargs
57
- .positional('entrypoints', {
68
+ .demandOption('api'), (argv) => {
69
+ process.env.REDOCLY_CLI_COMMAND = 'split';
70
+ wrapper_1.commandWrapper(split_1.handleSplit)(argv);
71
+ })
72
+ .command('join [apis...]', 'Join definitions [experimental].', (yargs) => yargs
73
+ .positional('apis', {
58
74
  array: true,
59
75
  type: 'string',
60
76
  demandOption: true,
61
77
  })
62
78
  .option({
63
79
  lint: { description: 'Lint definitions', type: 'boolean', default: false },
80
+ decorate: { description: 'Run decorators', type: 'boolean', default: false },
81
+ preprocess: { description: 'Run preprocessors', type: 'boolean', default: false },
64
82
  'prefix-tags-with-info-prop': {
65
83
  description: 'Prefix tags with property value from info object.',
66
84
  requiresArg: true,
@@ -76,29 +94,94 @@ yargs
76
94
  requiresArg: true,
77
95
  type: 'string',
78
96
  },
97
+ 'without-x-tag-groups': {
98
+ description: 'Skip automated x-tagGroups creation',
99
+ type: 'boolean',
100
+ },
101
+ output: {
102
+ describe: 'Output file',
103
+ alias: 'o',
104
+ type: 'string',
105
+ default: 'openapi.yaml',
106
+ },
107
+ config: {
108
+ description: 'Path to the config file.',
109
+ requiresArg: true,
110
+ type: 'string',
111
+ },
79
112
  }), (argv) => {
80
- join_1.handleJoin(argv, version);
113
+ process.env.REDOCLY_CLI_COMMAND = 'join';
114
+ wrapper_1.commandWrapper(join_1.handleJoin)(argv);
81
115
  })
82
- .command('push [maybeEntrypointOrAliasOrDestination] [maybeDestination] [maybeBranchName]', 'Push an API definition to the Redocly API registry.', (yargs) => yargs
83
- .positional('maybeEntrypointOrAliasOrDestination', { type: 'string' })
116
+ .command('push [api] [maybeDestination] [maybeBranchName]', 'Push an API definition to the Redocly API registry.', (yargs) => yargs
117
+ .usage('push [api]')
118
+ .positional('api', { type: 'string' })
84
119
  .positional('maybeDestination', { type: 'string' })
85
- .positional('maybeBranchName', { type: 'string' })
120
+ .hide('maybeDestination')
121
+ .hide('maybeBranchName')
86
122
  .option({
87
- branch: { type: 'string', alias: 'b' },
88
- upsert: { type: 'boolean', alias: 'u' },
89
- 'run-id': { type: 'string', requiresArg: true },
123
+ organization: {
124
+ description: 'Name of the organization to push to.',
125
+ type: 'string',
126
+ alias: 'o',
127
+ },
128
+ destination: {
129
+ description: 'API name and version in the format `name@version`.',
130
+ type: 'string',
131
+ alias: 'd',
132
+ },
133
+ branch: {
134
+ description: 'Branch name to push to.',
135
+ type: 'string',
136
+ alias: 'b',
137
+ },
138
+ upsert: {
139
+ description: "Create the specified API version if it doesn't exist, update if it does exist.",
140
+ type: 'boolean',
141
+ alias: 'u',
142
+ },
143
+ 'batch-id': {
144
+ description: 'Specifies the ID of the CI job that the current push will be associated with.',
145
+ type: 'string',
146
+ requiresArg: true,
147
+ deprecated: true,
148
+ hidden: true,
149
+ },
150
+ 'job-id': {
151
+ description: 'ID of the CI job that the current push will be associated with.',
152
+ type: 'string',
153
+ requiresArg: true,
154
+ },
155
+ 'batch-size': {
156
+ description: 'Number of CI pushes to expect in a batch.',
157
+ type: 'number',
158
+ requiresArg: true,
159
+ },
90
160
  region: { description: 'Specify a region.', alias: 'r', choices: types_1.regionChoices },
91
161
  'skip-decorator': {
92
162
  description: 'Ignore certain decorators.',
93
163
  array: true,
94
164
  type: 'string',
95
165
  },
96
- 'public': {
97
- description: 'Make API registry available to the public',
166
+ public: {
167
+ description: 'Make the API definition available to the public',
98
168
  type: 'boolean',
99
169
  },
100
- }), push_1.transformPush(push_1.handlePush))
101
- .command('lint [entrypoints...]', 'Lint definition.', (yargs) => yargs.positional('entrypoints', { array: true, type: 'string', demandOption: true }).option({
170
+ files: {
171
+ description: 'List of other folders and files to upload',
172
+ array: true,
173
+ type: 'string',
174
+ },
175
+ })
176
+ .deprecateOption('batch-id', 'use --job-id')
177
+ .deprecateOption('maybeDestination')
178
+ .implies('job-id', 'batch-size')
179
+ .implies('batch-id', 'batch-size')
180
+ .implies('batch-size', 'job-id'), (argv) => {
181
+ process.env.REDOCLY_CLI_COMMAND = 'push';
182
+ wrapper_1.commandWrapper(push_1.transformPush(push_1.handlePush))(argv);
183
+ })
184
+ .command('lint [apis...]', 'Lint definition.', (yargs) => yargs.positional('apis', { array: true, type: 'string', demandOption: true }).option({
102
185
  format: {
103
186
  description: 'Use a specific output format.',
104
187
  choices: [
@@ -107,17 +190,18 @@ yargs
107
190
  'json',
108
191
  'checkstyle',
109
192
  'codeclimate',
193
+ 'summary',
110
194
  ],
111
195
  default: 'codeframe',
112
196
  },
113
197
  'max-problems': {
114
198
  requiresArg: true,
115
- description: 'Reduce output to max N problems.',
199
+ description: 'Reduce output to a maximum of N problems.',
116
200
  type: 'number',
117
201
  default: 100,
118
202
  },
119
203
  'generate-ignore-file': {
120
- description: 'Generate ignore file.',
204
+ description: 'Generate an ignore file.',
121
205
  type: 'boolean',
122
206
  },
123
207
  'skip-rule': {
@@ -130,8 +214,13 @@ yargs
130
214
  array: true,
131
215
  type: 'string',
132
216
  },
217
+ 'lint-config': {
218
+ description: 'Severity level for config file linting.',
219
+ choices: ['warn', 'error', 'off'],
220
+ default: 'warn',
221
+ },
133
222
  config: {
134
- description: 'Specify path to the config file.',
223
+ description: 'Path to the config file.',
135
224
  requiresArg: true,
136
225
  type: 'string',
137
226
  },
@@ -142,9 +231,10 @@ yargs
142
231
  type: 'string',
143
232
  },
144
233
  }), (argv) => {
145
- lint_1.handleLint(argv, version);
234
+ process.env.REDOCLY_CLI_COMMAND = 'lint';
235
+ wrapper_1.commandWrapper(lint_1.handleLint)(argv);
146
236
  })
147
- .command('bundle [entrypoints...]', 'Bundle definition.', (yargs) => yargs.positional('entrypoints', { array: true, type: 'string', demandOption: true }).options({
237
+ .command('bundle [apis...]', 'Bundle definition.', (yargs) => yargs.positional('apis', { array: true, type: 'string', demandOption: true }).options({
148
238
  output: { type: 'string', alias: 'o' },
149
239
  format: {
150
240
  description: 'Use a specific output format.',
@@ -153,7 +243,7 @@ yargs
153
243
  },
154
244
  'max-problems': {
155
245
  requiresArg: true,
156
- description: 'Reduce output to max N problems.',
246
+ description: 'Reduce output to a maximum of N problems.',
157
247
  type: 'number',
158
248
  default: 100,
159
249
  },
@@ -180,7 +270,7 @@ yargs
180
270
  dereferenced: {
181
271
  alias: 'd',
182
272
  type: 'boolean',
183
- description: 'Produce fully dereferenced bundle.',
273
+ description: 'Produce a fully dereferenced bundle.',
184
274
  },
185
275
  force: {
186
276
  alias: 'f',
@@ -188,11 +278,11 @@ yargs
188
278
  description: 'Produce bundle output even when errors occur.',
189
279
  },
190
280
  config: {
191
- description: 'Specify path to the config file.',
281
+ description: 'Path to the config file.',
192
282
  type: 'string',
193
283
  },
194
284
  lint: {
195
- description: 'Lint definitions',
285
+ description: 'Lint API definitions',
196
286
  type: 'boolean',
197
287
  default: false,
198
288
  },
@@ -211,8 +301,14 @@ yargs
211
301
  type: 'boolean',
212
302
  default: false,
213
303
  },
304
+ 'keep-url-references': {
305
+ description: 'Keep absolute url references.',
306
+ type: 'boolean',
307
+ alias: 'k',
308
+ },
214
309
  }), (argv) => {
215
- bundle_1.handleBundle(argv, version);
310
+ process.env.REDOCLY_CLI_COMMAND = 'bundle';
311
+ wrapper_1.commandWrapper(bundle_1.handleBundle)(argv);
216
312
  })
217
313
  .command('login', 'Login to the Redocly API registry with an access token.', (yargs) => __awaiter(void 0, void 0, void 0, function* () {
218
314
  return yargs.options({
@@ -225,14 +321,25 @@ yargs
225
321
  alias: 'r',
226
322
  choices: types_1.regionChoices,
227
323
  },
324
+ config: {
325
+ description: 'Path to the config file.',
326
+ requiresArg: true,
327
+ type: 'string',
328
+ },
228
329
  });
229
- }), login_1.handleLogin)
230
- .command('logout', 'Clear your stored credentials for the Redocly API registry.', (yargs) => yargs, () => __awaiter(void 0, void 0, void 0, function* () {
231
- const client = new openapi_core_1.RedoclyClient();
232
- client.logout();
233
- process.stdout.write('Logged out from the Redocly account. ✋\n');
330
+ }), (argv) => {
331
+ process.env.REDOCLY_CLI_COMMAND = 'login';
332
+ wrapper_1.commandWrapper(login_1.handleLogin)(argv);
333
+ })
334
+ .command('logout', 'Clear your stored credentials for the Redocly API registry.', (yargs) => yargs, (argv) => __awaiter(void 0, void 0, void 0, function* () {
335
+ process.env.REDOCLY_CLI_COMMAND = 'logout';
336
+ yield wrapper_1.commandWrapper(() => __awaiter(void 0, void 0, void 0, function* () {
337
+ const client = new openapi_core_1.RedoclyClient();
338
+ client.logout();
339
+ process.stdout.write('Logged out from the Redocly account. ✋\n');
340
+ }))(argv);
234
341
  }))
235
- .command('preview-docs [entrypoint]', 'Preview API reference docs for the specified definition.', (yargs) => yargs.positional('entrypoint', { type: 'string' }).options({
342
+ .command('preview-docs [api]', 'Preview API reference docs for the specified definition.', (yargs) => yargs.positional('api', { type: 'string' }).options({
236
343
  port: {
237
344
  alias: 'p',
238
345
  type: 'number',
@@ -256,7 +363,7 @@ yargs
256
363
  type: 'string',
257
364
  },
258
365
  'use-community-edition': {
259
- description: 'Force using Redoc CE for docs preview.',
366
+ description: 'Use Redoc CE for documentation preview.',
260
367
  type: 'boolean',
261
368
  },
262
369
  force: {
@@ -265,10 +372,57 @@ yargs
265
372
  description: 'Produce bundle output even when errors occur.',
266
373
  },
267
374
  config: {
268
- description: 'Specify path to the config file.',
375
+ description: 'Path to the config file.',
269
376
  type: 'string',
270
377
  },
271
- }), preview_docs_1.previewDocs)
378
+ }), (argv) => {
379
+ process.env.REDOCLY_CLI_COMMAND = 'preview-docs';
380
+ wrapper_1.commandWrapper(preview_docs_1.previewDocs)(argv);
381
+ })
382
+ .command('build-docs [api]', 'Produce API documentation as an HTML file', (yargs) => yargs
383
+ .positional('api', { type: 'string' })
384
+ .options({
385
+ o: {
386
+ describe: 'Output destination file.',
387
+ alias: 'output',
388
+ type: 'string',
389
+ default: 'redoc-static.html',
390
+ },
391
+ title: {
392
+ describe: 'Page title.',
393
+ type: 'string',
394
+ },
395
+ disableGoogleFont: {
396
+ describe: 'Disable Google fonts.',
397
+ type: 'boolean',
398
+ default: false,
399
+ },
400
+ t: {
401
+ alias: 'template',
402
+ describe: 'Path to handlebars page template, see https://git.io/vh8fP for the example.',
403
+ type: 'string',
404
+ },
405
+ templateOptions: {
406
+ describe: 'Additional options to pass to the template. Use dot notation, e.g. templateOptions.metaDescription',
407
+ },
408
+ theme: {
409
+ describe: 'Redoc theme.openapi configuration. Use dot notation, e.g. theme.openapi.nativeScrollbars',
410
+ },
411
+ config: {
412
+ describe: 'Path to the config file.',
413
+ type: 'string',
414
+ },
415
+ })
416
+ .check((argv) => {
417
+ var _a;
418
+ if (argv.theme && !((_a = argv.theme) === null || _a === void 0 ? void 0 : _a.openapi))
419
+ throw Error('Invalid option: theme.openapi not set');
420
+ return true;
421
+ }), (argv) => __awaiter(void 0, void 0, void 0, function* () {
422
+ process.env.REDOCLY_CLI_COMMAND = 'build-docs';
423
+ wrapper_1.commandWrapper(build_docs_1.handlerBuildCommand)(argv);
424
+ }))
272
425
  .completion('completion', 'Generate completion script.')
273
426
  .demandCommand(1)
427
+ .middleware([update_version_notifier_1.notifyUpdateCliVersion])
274
428
  .strict().argv;
package/lib/js-utils.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export declare function isObject(obj: any): boolean;
2
2
  export declare function isEmptyObject(obj: any): boolean;
3
3
  export declare function isString(str: string): boolean;
4
+ export declare function keysOf<T>(obj: T): (keyof T)[];
package/lib/js-utils.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isString = exports.isEmptyObject = exports.isObject = void 0;
3
+ exports.keysOf = exports.isString = exports.isEmptyObject = exports.isObject = void 0;
4
4
  function isObject(obj) {
5
5
  const type = typeof obj;
6
- return type === 'function' || type === 'object' && !!obj;
6
+ return type === 'function' || (type === 'object' && !!obj);
7
7
  }
8
8
  exports.isObject = isObject;
9
9
  function isEmptyObject(obj) {
@@ -11,6 +11,12 @@ function isEmptyObject(obj) {
11
11
  }
12
12
  exports.isEmptyObject = isEmptyObject;
13
13
  function isString(str) {
14
- return Object.prototype.toString.call(str) === "[object String]";
14
+ return Object.prototype.toString.call(str) === '[object String]';
15
15
  }
16
16
  exports.isString = isString;
17
+ function keysOf(obj) {
18
+ if (!obj)
19
+ return [];
20
+ return Object.keys(obj);
21
+ }
22
+ exports.keysOf = keysOf;
package/lib/types.d.ts CHANGED
@@ -1,4 +1,13 @@
1
- import { BundleOutputFormat, Region } from '@redocly/openapi-core';
1
+ import type { BundleOutputFormat, Region, Config } from '@redocly/openapi-core';
2
+ import type { LintOptions } from './commands/lint';
3
+ import type { BundleOptions } from './commands/bundle';
4
+ import type { JoinOptions } from './commands/join';
5
+ import type { LoginOptions } from './commands/login';
6
+ import type { PushOptions } from './commands/push';
7
+ import type { StatsOptions } from './commands/stats';
8
+ import type { SplitOptions } from './commands/split';
9
+ import type { PreviewDocsOptions } from './commands/preview-docs';
10
+ import type { BuildDocsArgv } from './commands/build-docs/types';
2
11
  export declare type Totals = {
3
12
  errors: number;
4
13
  warnings: number;
@@ -11,3 +20,10 @@ export declare type Entrypoint = {
11
20
  export declare const outputExtensions: readonly BundleOutputFormat[];
12
21
  export declare type OutputExtensions = 'json' | 'yaml' | 'yml' | undefined;
13
22
  export declare const regionChoices: readonly Region[];
23
+ export declare type CommandOptions = StatsOptions | SplitOptions | JoinOptions | PushOptions | LintOptions | BundleOptions | LoginOptions | PreviewDocsOptions | BuildDocsArgv;
24
+ export declare type Skips = {
25
+ 'skip-rule'?: string[];
26
+ 'skip-decorator'?: string[];
27
+ 'skip-preprocessor'?: string[];
28
+ };
29
+ export declare type ConfigApis = Pick<Config, 'apis' | 'configFile'>;
@@ -0,0 +1,3 @@
1
+ export declare const version: any, name: any;
2
+ export declare const notifyUpdateCliVersion: () => void;
3
+ export declare const cacheLatestVersion: () => void;
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var _a;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.cacheLatestVersion = exports.notifyUpdateCliVersion = exports.name = exports.version = void 0;
14
+ const os_1 = require("os");
15
+ const path_1 = require("path");
16
+ const fs_1 = require("fs");
17
+ const semver_1 = require("semver");
18
+ const fetch_with_timeout_1 = require("./fetch-with-timeout");
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;
22
+ const VERSION_CACHE_FILE = 'redocly-cli-version';
23
+ const SPACE_TO_BORDER = 4;
24
+ const INTERVAL_TO_CHECK = 1000 * 60 * 60 * 12;
25
+ const SHOULD_NOT_NOTIFY = process.env.NODE_ENV === 'test' || process.env.CI || !!process.env.LAMBDA_TASK_ROOT;
26
+ const notifyUpdateCliVersion = () => {
27
+ if (SHOULD_NOT_NOTIFY) {
28
+ return;
29
+ }
30
+ try {
31
+ const latestVersion = fs_1.readFileSync(path_1.join(os_1.tmpdir(), VERSION_CACHE_FILE)).toString();
32
+ if (isNewVersionAvailable(exports.version, latestVersion)) {
33
+ renderUpdateBanner(exports.version, latestVersion);
34
+ }
35
+ }
36
+ catch (e) {
37
+ return;
38
+ }
39
+ };
40
+ exports.notifyUpdateCliVersion = notifyUpdateCliVersion;
41
+ const isNewVersionAvailable = (current, latest) => semver_1.compare(current, latest) < 0;
42
+ const getLatestVersion = (packageName) => __awaiter(void 0, void 0, void 0, function* () {
43
+ const latestUrl = `http://registry.npmjs.org/${packageName}/latest`;
44
+ const response = yield fetch_with_timeout_1.default(latestUrl);
45
+ if (!response)
46
+ return;
47
+ const info = yield response.json();
48
+ return info.version;
49
+ });
50
+ const cacheLatestVersion = () => {
51
+ if (!isNeedToBeCached() || SHOULD_NOT_NOTIFY) {
52
+ return;
53
+ }
54
+ getLatestVersion(exports.name)
55
+ .then((version) => {
56
+ if (version) {
57
+ const lastCheckFile = path_1.join(os_1.tmpdir(), VERSION_CACHE_FILE);
58
+ fs_1.writeFileSync(lastCheckFile, version);
59
+ }
60
+ })
61
+ .catch(() => { });
62
+ };
63
+ exports.cacheLatestVersion = cacheLatestVersion;
64
+ const renderUpdateBanner = (current, latest) => {
65
+ const messageLines = [
66
+ `A new version of ${colorette_1.cyan('Redocly CLI')} (${colorette_1.green(latest)}) is available.`,
67
+ `Update now: \`${colorette_1.cyan('npm i -g @redocly/cli@latest')}\`.`,
68
+ `Changelog: https://redocly.com/docs/cli/changelog/`,
69
+ ];
70
+ const maxLength = Math.max(...messageLines.map((line) => utils_1.cleanColors(line).length));
71
+ const border = colorette_1.yellow('═'.repeat(maxLength + SPACE_TO_BORDER));
72
+ const banner = `
73
+ ${colorette_1.yellow('╔' + border + '╗')}
74
+ ${colorette_1.yellow('║' + ' '.repeat(maxLength + SPACE_TO_BORDER) + '║')}
75
+ ${messageLines
76
+ .map((line, index) => {
77
+ return getLineWithPadding(maxLength, line, index);
78
+ })
79
+ .join('\n')}
80
+ ${colorette_1.yellow('║' + ' '.repeat(maxLength + SPACE_TO_BORDER) + '║')}
81
+ ${colorette_1.yellow('╚' + border + '╝')}
82
+ `;
83
+ process.stderr.write(banner);
84
+ };
85
+ const getLineWithPadding = (maxLength, line, index) => {
86
+ const padding = ' '.repeat(maxLength - utils_1.cleanColors(line).length);
87
+ const extraSpaces = index !== 0 ? ' '.repeat(SPACE_TO_BORDER) : '';
88
+ return `${extraSpaces}${colorette_1.yellow('║')} ${line}${padding} ${colorette_1.yellow('║')}`;
89
+ };
90
+ const isNeedToBeCached = () => {
91
+ try {
92
+ // Last version from npm is stored in a file in the OS temp folder
93
+ const versionFile = path_1.join(os_1.tmpdir(), VERSION_CACHE_FILE);
94
+ if (!fs_1.existsSync(versionFile)) {
95
+ return true;
96
+ }
97
+ const now = new Date().getTime();
98
+ const stats = fs_1.statSync(versionFile);
99
+ const lastCheck = stats.mtime.getTime();
100
+ return now - lastCheck >= INTERVAL_TO_CHECK;
101
+ }
102
+ catch (e) {
103
+ return false;
104
+ }
105
+ };
package/lib/utils.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- import { BundleOutputFormat, Config, LintConfig } from '@redocly/openapi-core';
2
- import { Totals, Entrypoint } from './types';
3
- export declare function getFallbackEntryPointsOrExit(argsEntrypoints: string[] | undefined, config: Config): Promise<Entrypoint[]>;
1
+ import { BundleOutputFormat, StyleguideConfig, RawConfig, Region, Config, Oas3Definition, Oas2Definition } from '@redocly/openapi-core';
2
+ import { Totals, Entrypoint, ConfigApis, CommandOptions } from './types';
3
+ import { Arguments } from 'yargs';
4
+ export declare function getFallbackApisOrExit(argsApis: string[] | undefined, config: ConfigApis): Promise<Entrypoint[]>;
4
5
  export declare function getExecutionTime(startedAt: number): string;
5
- export declare function printExecutionTime(commandName: string, startedAt: number, entrypoint: string): void;
6
+ export declare function printExecutionTime(commandName: string, startedAt: number, api: string): void;
6
7
  export declare function pathToFilename(path: string, pathSeparator: string): string;
7
8
  export declare function escapeLanguageName(lang: string): string;
9
+ export declare function langToExt(lang: string): any;
8
10
  export declare class CircularJSONNotSupportedError extends Error {
9
11
  originalError: Error;
10
12
  constructor(originalError: Error);
@@ -16,14 +18,45 @@ export declare function readYaml(filename: string): unknown;
16
18
  export declare function writeYaml(data: any, filename: string, noRefs?: boolean): void;
17
19
  export declare function pluralize(label: string, num: number): string;
18
20
  export declare function handleError(e: Error, ref: string): void;
21
+ export declare class HandledError extends Error {
22
+ }
19
23
  export declare function printLintTotals(totals: Totals, definitionsCount: number): void;
24
+ export declare function printConfigLintTotals(totals: Totals): void;
20
25
  export declare function getOutputFileName(entrypoint: string, entries: number, output?: string, ext?: BundleOutputFormat): {
21
26
  outputFile: string;
22
27
  ext: BundleOutputFormat;
23
28
  };
24
- export declare function printUnusedWarnings(config: LintConfig): void;
29
+ export declare function printUnusedWarnings(config: StyleguideConfig): void;
25
30
  export declare function exitWithError(message: string): void;
26
31
  /**
27
32
  * Checks if dir is subdir of parent
28
33
  */
29
34
  export declare function isSubdir(parent: string, dir: string): boolean;
35
+ export declare function loadConfigAndHandleErrors(options?: {
36
+ configPath?: string;
37
+ customExtends?: string[];
38
+ processRawConfig?: (rawConfig: RawConfig) => void | Promise<void>;
39
+ files?: string[];
40
+ region?: Region;
41
+ }): Promise<Config | void>;
42
+ export declare function sortTopLevelKeysForOas(document: Oas3Definition | Oas2Definition): Oas3Definition | Oas2Definition;
43
+ export declare function checkIfRulesetExist(rules: typeof StyleguideConfig.prototype.rules): void;
44
+ export declare function cleanColors(input: string): string;
45
+ export declare function sendTelemetry(argv: Arguments | undefined, exit_code: ExitCode, has_config: boolean | undefined): Promise<void>;
46
+ export declare type ExitCode = 0 | 1 | 2;
47
+ export declare type Analytics = {
48
+ event: string;
49
+ event_time: string;
50
+ logged_in: boolean;
51
+ command: string | number;
52
+ arguments: Record<string, unknown>;
53
+ node_version: string;
54
+ version: string;
55
+ exit_code: ExitCode;
56
+ environment?: string;
57
+ environment_ci?: string;
58
+ raw_input: string;
59
+ has_config?: boolean;
60
+ };
61
+ export declare function cleanArgs(args: CommandOptions): Record<string, unknown>;
62
+ export declare function cleanRawInput(argv: string[]): string;