@redocly/cli 1.8.1 → 1.9.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @redocly/cli
2
2
 
3
+ ## 1.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - - Removed descriptions adding for x-tagGroups for the `join` command. Descriptions in x-tagGroups are not supported and cause errors on linting.
8
+ - Updated `info.title` to be used as a name in x-tagGroups instead of a file name for the `join` command, so you can now join files with the same names.
9
+ - Added new `no-required-schema-properties-undefined` rule to check if each required schema property is defined.
10
+
11
+ ### Patch Changes
12
+
13
+ - Fixed an issue where using the `--prefix-components-with-info-prop` option with the `join` command caused `$refs` to include duplicated prefixes.
14
+ - Fixed an issue where `$ref`s ending in `#` (instead of `#/`) would break the application.
15
+ - Updated @redocly/openapi-core to v1.9.0.
16
+
17
+ ## 1.8.2
18
+
19
+ ### Patch Changes
20
+
21
+ - Added markdown format option to stats command for use with GitHub job summaries.
22
+ - Fixed an issue with the `push` command, when `destination` option does not work without specifying it in `redocly.yaml`.
23
+ - Updated @redocly/openapi-core to v1.8.2.
24
+
3
25
  ## 1.8.1
4
26
 
5
27
  ### Patch Changes
@@ -207,8 +207,7 @@ describe('transformPush', () => {
207
207
  it('should adapt the existing syntax', () => {
208
208
  const cb = jest.fn();
209
209
  (0, push_1.transformPush)(cb)({
210
- api: 'openapi.yaml',
211
- maybeDestination: '@testing_org/main@v1',
210
+ apis: ['openapi.yaml', '@testing_org/main@v1'],
212
211
  }, {});
213
212
  expect(cb).toBeCalledWith({
214
213
  api: 'openapi.yaml',
@@ -218,9 +217,7 @@ describe('transformPush', () => {
218
217
  it('should adapt the existing syntax (including branchName)', () => {
219
218
  const cb = jest.fn();
220
219
  (0, push_1.transformPush)(cb)({
221
- api: 'openapi.yaml',
222
- maybeDestination: '@testing_org/main@v1',
223
- maybeBranchName: 'other',
220
+ apis: ['openapi.yaml', '@testing_org/main@v1', 'other'],
224
221
  }, {});
225
222
  expect(cb).toBeCalledWith({
226
223
  api: 'openapi.yaml',
@@ -231,9 +228,7 @@ describe('transformPush', () => {
231
228
  it('should use --branch option firstly', () => {
232
229
  const cb = jest.fn();
233
230
  (0, push_1.transformPush)(cb)({
234
- api: 'openapi.yaml',
235
- maybeDestination: '@testing_org/main@v1',
236
- maybeBranchName: 'other',
231
+ apis: ['openapi.yaml', '@testing_org/main@v1', 'other'],
237
232
  branch: 'priority-branch',
238
233
  }, {});
239
234
  expect(cb).toBeCalledWith({
@@ -245,30 +240,30 @@ describe('transformPush', () => {
245
240
  it('should work for a destination only', () => {
246
241
  const cb = jest.fn();
247
242
  (0, push_1.transformPush)(cb)({
248
- api: '@testing_org/main@v1',
243
+ apis: ['main@v1'],
249
244
  }, {});
250
245
  expect(cb).toBeCalledWith({
251
- destination: '@testing_org/main@v1',
246
+ destination: 'main@v1',
252
247
  }, {});
253
248
  });
254
249
  it('should work for a api only', () => {
255
250
  const cb = jest.fn();
256
251
  (0, push_1.transformPush)(cb)({
257
- api: 'test.yaml',
252
+ apis: ['test.yaml'],
258
253
  }, {});
259
254
  expect(cb).toBeCalledWith({
260
255
  api: 'test.yaml',
261
256
  }, {});
262
257
  });
263
- it('should accept aliases for the old syntax', () => {
258
+ it('should use destination from option', () => {
264
259
  const cb = jest.fn();
265
260
  (0, push_1.transformPush)(cb)({
266
- api: 'alias',
267
- maybeDestination: '@testing_org/main@v1',
261
+ apis: ['test.yaml', 'test@v1'],
262
+ destination: 'main@v1',
268
263
  }, {});
269
264
  expect(cb).toBeCalledWith({
270
- destination: '@testing_org/main@v1',
271
- api: 'alias',
265
+ destination: 'main@v1',
266
+ api: 'test.yaml',
272
267
  }, {});
273
268
  });
274
269
  it('should use --job-id option firstly', () => {
@@ -276,8 +271,7 @@ describe('transformPush', () => {
276
271
  (0, push_1.transformPush)(cb)({
277
272
  'batch-id': 'b-123',
278
273
  'job-id': 'j-123',
279
- api: 'test',
280
- maybeDestination: 'main@v1',
274
+ apis: ['test'],
281
275
  branch: 'test',
282
276
  destination: 'main@v1',
283
277
  }, {});
@@ -76,7 +76,7 @@ describe('handlePushStatus()', () => {
76
76
  'max-execution-time': 1000,
77
77
  }, mockConfig);
78
78
  expect(process.stdout.write).toHaveBeenCalledTimes(1);
79
- expect(process.stdout.write).toHaveBeenCalledWith('🚀 PREVIEW deployment succeeded.\nPreview URL: https://test-url\n');
79
+ expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://test-url\n');
80
80
  }));
81
81
  it('should return success push status for preview and production builds', () => __awaiter(void 0, void 0, void 0, function* () {
82
82
  process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
@@ -89,8 +89,8 @@ describe('handlePushStatus()', () => {
89
89
  'max-execution-time': 1000,
90
90
  }, mockConfig);
91
91
  expect(process.stdout.write).toHaveBeenCalledTimes(2);
92
- expect(process.stdout.write).toHaveBeenCalledWith('🚀 PREVIEW deployment succeeded.\nPreview URL: https://test-url\n');
93
- expect(process.stdout.write).toHaveBeenCalledWith('🚀 PRODUCTION deployment succeeded.\nPreview URL: https://test-url\n');
92
+ expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://test-url\n');
93
+ expect(process.stdout.write).toHaveBeenCalledWith('🚀 Production deploy success.\nProduction URL: https://test-url\n');
94
94
  }));
95
95
  it('should return failed push status for preview build', () => __awaiter(void 0, void 0, void 0, function* () {
96
96
  process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
@@ -108,7 +108,7 @@ describe('handlePushStatus()', () => {
108
108
  pushId: 'test-push-id',
109
109
  'max-execution-time': 1000,
110
110
  }, mockConfig);
111
- expect(miscellaneous_1.exitWithError).toHaveBeenCalledWith('❌ PREVIEW deployment failed.\nPreview URL: https://test-url');
111
+ expect(miscellaneous_1.exitWithError).toHaveBeenCalledWith('❌ Preview deploy fail.\nPreview URL: https://test-url');
112
112
  }));
113
113
  it('should return success push status for preview build and print scorecards', () => __awaiter(void 0, void 0, void 0, function* () {
114
114
  process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
@@ -137,7 +137,7 @@ describe('handlePushStatus()', () => {
137
137
  'max-execution-time': 1000,
138
138
  }, mockConfig);
139
139
  expect(process.stdout.write).toHaveBeenCalledTimes(4);
140
- expect(process.stdout.write).toHaveBeenCalledWith('🚀 PREVIEW deployment succeeded.\nPreview URL: https://test-url\n');
140
+ expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://test-url\n');
141
141
  expect(process.stdout.write).toHaveBeenCalledWith('\nScorecard:');
142
142
  expect(process.stdout.write).toHaveBeenCalledWith('\n Name: test-name\n Status: success\n URL: test-url\n Description: test-description\n');
143
143
  expect(process.stdout.write).toHaveBeenCalledWith('\n');
@@ -16,6 +16,7 @@ const spinner_1 = require("../../utils/spinner");
16
16
  const utils_1 = require("../utils");
17
17
  const colorette_1 = require("colorette");
18
18
  const api_1 = require("../api");
19
+ const js_utils_1 = require("../../utils/js-utils");
19
20
  const INTERVAL = 5000;
20
21
  function handlePushStatus(argv, config) {
21
22
  return __awaiter(this, void 0, void 0, function* () {
@@ -131,10 +132,10 @@ function displayDeploymentAndBuildStatus({ status, previewUrl, spinner, buildTyp
131
132
  switch (status) {
132
133
  case 'success':
133
134
  spinner.stop();
134
- return process.stdout.write(`${colors.green(`🚀 ${buildType.toLocaleUpperCase()} deployment succeeded.`)}\n${colors.magenta('Preview URL')}: ${colors.cyan(previewUrl)}\n`);
135
+ return process.stdout.write(`${colors.green(`🚀 ${(0, js_utils_1.capitalize)(buildType)} deploy success.`)}\n${colors.magenta(`${(0, js_utils_1.capitalize)(buildType)} URL`)}: ${colors.cyan(previewUrl)}\n`);
135
136
  case 'failed':
136
137
  spinner.stop();
137
- throw new utils_1.DeploymentError(`${colors.red(`❌ ${buildType.toLocaleUpperCase()} deployment failed.`)}\n${colors.magenta('Preview URL')}: ${colors.cyan(previewUrl)}`);
138
+ throw new utils_1.DeploymentError(`${colors.red(`❌ ${(0, js_utils_1.capitalize)(buildType)} deploy fail.`)}\n${colors.magenta(`${(0, js_utils_1.capitalize)(buildType)} URL`)}: ${colors.cyan(previewUrl)}`);
138
139
  case 'pending':
139
140
  return wait
140
141
  ? spinner.start(`${colors.yellow(`Pending ${buildType}`)}`)
@@ -119,6 +119,7 @@ function handleJoin(argv, config, packageVersion) {
119
119
  const context = {
120
120
  api,
121
121
  apiFilename,
122
+ apiTitle: info === null || info === void 0 ? void 0 : info.title,
122
123
  tags,
123
124
  potentialConflicts,
124
125
  tagsPrefix,
@@ -128,7 +129,6 @@ function handleJoin(argv, config, packageVersion) {
128
129
  populateTags(context);
129
130
  }
130
131
  collectServers(openapi);
131
- collectInfoDescriptions(openapi, context);
132
132
  collectExternalDocs(openapi, context);
133
133
  collectPaths(openapi, context);
134
134
  collectComponents(openapi, context);
@@ -144,7 +144,7 @@ function handleJoin(argv, config, packageVersion) {
144
144
  }
145
145
  (0, miscellaneous_1.writeToFileByExtension)((0, miscellaneous_1.sortTopLevelKeysForOas)(joinedDef), specFilename, noRefs);
146
146
  (0, miscellaneous_1.printExecutionTime)('join', startedAt, specFilename);
147
- function populateTags({ api, apiFilename, tags, potentialConflicts, tagsPrefix, componentsPrefix, }) {
147
+ function populateTags({ api, apiFilename, apiTitle, tags, potentialConflicts, tagsPrefix, componentsPrefix, }) {
148
148
  if (!joinedDef.hasOwnProperty(Tags)) {
149
149
  joinedDef[Tags] = [];
150
150
  }
@@ -176,9 +176,10 @@ function handleJoin(argv, config, packageVersion) {
176
176
  }
177
177
  }
178
178
  if (!withoutXTagGroups) {
179
- createXTagGroups(apiFilename);
179
+ const groupName = apiTitle || apiFilename;
180
+ createXTagGroups(groupName);
180
181
  if (!tagDuplicate) {
181
- populateXTagGroups(entrypointTagName, getIndexGroup(apiFilename));
182
+ populateXTagGroups(entrypointTagName, getIndexGroup(groupName));
182
183
  }
183
184
  }
184
185
  const doesEntrypointExist = !potentialConflicts.tags.all[entrypointTagName] ||
@@ -190,17 +191,17 @@ function handleJoin(argv, config, packageVersion) {
190
191
  ];
191
192
  }
192
193
  }
193
- function getIndexGroup(apiFilename) {
194
- return joinedDef[xTagGroups].findIndex((item) => item.name === apiFilename);
194
+ function getIndexGroup(name) {
195
+ return joinedDef[xTagGroups].findIndex((item) => item.name === name);
195
196
  }
196
- function createXTagGroups(apiFilename) {
197
+ function createXTagGroups(name) {
197
198
  if (!joinedDef.hasOwnProperty(xTagGroups)) {
198
199
  joinedDef[xTagGroups] = [];
199
200
  }
200
- if (!joinedDef[xTagGroups].some((g) => g.name === apiFilename)) {
201
- joinedDef[xTagGroups].push({ name: apiFilename, tags: [] });
201
+ if (!joinedDef[xTagGroups].some((g) => g.name === name)) {
202
+ joinedDef[xTagGroups].push({ name, tags: [] });
202
203
  }
203
- const indexGroup = getIndexGroup(apiFilename);
204
+ const indexGroup = getIndexGroup(name);
204
205
  if (!joinedDef[xTagGroups][indexGroup].hasOwnProperty(Tags)) {
205
206
  joinedDef[xTagGroups][indexGroup][Tags] = [];
206
207
  }
@@ -223,18 +224,6 @@ function handleJoin(argv, config, packageVersion) {
223
224
  }
224
225
  }
225
226
  }
226
- function collectInfoDescriptions(openapi, { apiFilename, componentsPrefix }) {
227
- const { info } = openapi;
228
- if (info === null || info === void 0 ? void 0 : info.description) {
229
- const groupIndex = joinedDef[xTagGroups] ? getIndexGroup(apiFilename) : -1;
230
- if (joinedDef.hasOwnProperty(xTagGroups) &&
231
- groupIndex !== -1 &&
232
- joinedDef[xTagGroups][groupIndex]['tags'] &&
233
- joinedDef[xTagGroups][groupIndex]['tags'].length) {
234
- joinedDef[xTagGroups][groupIndex]['description'] = addComponentsPrefix(info.description, componentsPrefix);
235
- }
236
- }
237
- }
238
227
  function collectExternalDocs(openapi, { api }) {
239
228
  const { externalDocs } = openapi;
240
229
  if (externalDocs) {
@@ -245,7 +234,7 @@ function handleJoin(argv, config, packageVersion) {
245
234
  joinedDef['externalDocs'] = externalDocs;
246
235
  }
247
236
  }
248
- function collectPaths(openapi, { apiFilename, api, potentialConflicts, tagsPrefix, componentsPrefix }) {
237
+ function collectPaths(openapi, { apiFilename, apiTitle, api, potentialConflicts, tagsPrefix, componentsPrefix, }) {
249
238
  const { paths } = openapi;
250
239
  const operationsSet = new Set((0, js_utils_1.keysOf)(types_1.OPENAPI3_METHOD));
251
240
  if (paths) {
@@ -365,6 +354,7 @@ function handleJoin(argv, config, packageVersion) {
365
354
  populateTags({
366
355
  api,
367
356
  apiFilename,
357
+ apiTitle,
368
358
  tags: formatTags(tags),
369
359
  potentialConflicts,
370
360
  tagsPrefix,
@@ -376,6 +366,7 @@ function handleJoin(argv, config, packageVersion) {
376
366
  populateTags({
377
367
  api,
378
368
  apiFilename,
369
+ apiTitle,
379
370
  tags: formatTags(['other']),
380
371
  potentialConflicts,
381
372
  tagsPrefix: tagsPrefix || apiFilename,
@@ -418,7 +409,7 @@ function handleJoin(argv, config, packageVersion) {
418
409
  }
419
410
  }
420
411
  }
421
- function collectWebhooks(oasVersion, openapi, { apiFilename, api, potentialConflicts, tagsPrefix, componentsPrefix }) {
412
+ function collectWebhooks(oasVersion, openapi, { apiFilename, apiTitle, api, potentialConflicts, tagsPrefix, componentsPrefix, }) {
422
413
  const webhooks = oasVersion === openapi_core_1.SpecVersion.OAS3_1 ? 'webhooks' : 'x-webhooks';
423
414
  const openapiWebhooks = openapi[webhooks];
424
415
  if (openapiWebhooks) {
@@ -443,6 +434,7 @@ function handleJoin(argv, config, packageVersion) {
443
434
  populateTags({
444
435
  api,
445
436
  apiFilename,
437
+ apiTitle,
446
438
  tags: formatTags(tags),
447
439
  potentialConflicts,
448
440
  tagsPrefix,
@@ -583,7 +575,7 @@ function crawl(object, visitor) {
583
575
  if (!(0, js_utils_1.isObject)(object))
584
576
  return;
585
577
  for (const key of Object.keys(object)) {
586
- visitor(object, key);
578
+ visitor(object[key], key);
587
579
  crawl(object[key], visitor);
588
580
  }
589
581
  }
@@ -18,7 +18,13 @@ export type PushOptions = {
18
18
  export declare function commonPushHandler({ project, 'mount-path': mountPath, }: {
19
19
  project?: string;
20
20
  'mount-path'?: string;
21
- }): typeof handleCMSPush | typeof handlePush;
21
+ }): typeof handleCMSPush | (({ apis, branch, "batch-id": batchId, "job-id": jobId, ...rest }: Omit<PushOptions, "destination" | "branchName"> & {
22
+ apis?: string[] | undefined;
23
+ branch?: string | undefined;
24
+ destination?: string | undefined;
25
+ } & {
26
+ 'batch-id'?: string | undefined;
27
+ }, config: Config) => Promise<void>);
22
28
  export declare function handlePush(argv: PushOptions, config: Config): Promise<void>;
23
29
  export declare function getDestinationProps(destination: string | undefined, organization: string | undefined): {
24
30
  organizationId: string | undefined;
@@ -26,12 +32,11 @@ export declare function getDestinationProps(destination: string | undefined, org
26
32
  version: string | undefined;
27
33
  };
28
34
  type BarePushArgs = Omit<PushOptions, 'destination' | 'branchName'> & {
29
- maybeDestination?: string;
30
- maybeBranchName?: string;
35
+ apis?: string[];
31
36
  branch?: string;
32
37
  destination?: string;
33
38
  };
34
- export declare const transformPush: (callback: typeof handlePush) => ({ api: maybeApiOrDestination, maybeDestination, maybeBranchName, branch, "batch-id": batchId, "job-id": jobId, ...rest }: BarePushArgs & {
39
+ export declare const transformPush: (callback: typeof handlePush) => ({ apis, branch, "batch-id": batchId, "job-id": jobId, ...rest }: BarePushArgs & {
35
40
  'batch-id'?: string;
36
41
  }, config: Config) => Promise<void>;
37
42
  export declare function getApiRoot({ name, version, config: { apis }, }: {
@@ -37,7 +37,7 @@ function commonPushHandler({ project, 'mount-path': mountPath, }) {
37
37
  if (project && mountPath) {
38
38
  return push_1.handlePush;
39
39
  }
40
- return handlePush;
40
+ return (0, exports.transformPush)(handlePush);
41
41
  }
42
42
  exports.commonPushHandler = commonPushHandler;
43
43
  function handlePush(argv, config) {
@@ -259,7 +259,9 @@ function getDestinationProps(destination, organization) {
259
259
  }
260
260
  exports.getDestinationProps = getDestinationProps;
261
261
  const transformPush = (callback) => (_a, config) => {
262
- var { api: maybeApiOrDestination, maybeDestination, maybeBranchName, branch, 'batch-id': batchId, 'job-id': jobId } = _a, rest = __rest(_a, ["api", "maybeDestination", "maybeBranchName", "branch", 'batch-id', 'job-id']);
262
+ var _b;
263
+ var { apis, branch, 'batch-id': batchId, 'job-id': jobId } = _a, rest = __rest(_a, ["apis", "branch", 'batch-id', 'job-id']);
264
+ const [maybeApiOrDestination, maybeDestination, maybeBranchName] = apis || [];
263
265
  if (batchId) {
264
266
  process.stderr.write((0, colorette_1.yellow)(`The ${(0, colorette_1.red)('batch-id')} option is deprecated. Please use ${(0, colorette_1.green)('job-id')} instead.\n\n`));
265
267
  }
@@ -279,8 +281,7 @@ const transformPush = (callback) => (_a, config) => {
279
281
  else if (maybeApiOrDestination && !exports.DESTINATION_REGEX.test(maybeApiOrDestination)) {
280
282
  apiFile = maybeApiOrDestination;
281
283
  }
282
- destination = rest.destination || destination;
283
- return callback(Object.assign(Object.assign({}, rest), { destination, api: apiFile, branchName: branch !== null && branch !== void 0 ? branch : maybeBranchName, 'job-id': jobId || batchId }), config);
284
+ return callback(Object.assign(Object.assign({}, rest), { destination: (_b = rest.destination) !== null && _b !== void 0 ? _b : destination, api: apiFile, branchName: branch !== null && branch !== void 0 ? branch : maybeBranchName, 'job-id': jobId || batchId }), config);
284
285
  };
285
286
  exports.transformPush = transformPush;
286
287
  function getApiRoot({ name, version, config: { apis }, }) {
@@ -41,15 +41,31 @@ function printStatsJson(statsAccumulator) {
41
41
  }
42
42
  process.stdout.write(JSON.stringify(json, null, 2));
43
43
  }
44
- function printStats(statsAccumulator, api, format) {
45
- process.stderr.write(`Document: ${colors.magenta(api)} stats:\n\n`);
44
+ function printStatsMarkdown(statsAccumulator) {
45
+ let output = '| Feature | Count |\n| --- | --- |\n';
46
+ for (const key of Object.keys(statsAccumulator)) {
47
+ output +=
48
+ '| ' +
49
+ statsAccumulator[key].metric +
50
+ ' | ' +
51
+ statsAccumulator[key].total +
52
+ ' |\n';
53
+ }
54
+ process.stdout.write(output);
55
+ }
56
+ function printStats(statsAccumulator, api, startedAt, format) {
46
57
  switch (format) {
47
58
  case 'stylish':
59
+ process.stderr.write(`Document: ${colors.magenta(api)} stats:\n\n`);
48
60
  printStatsStylish(statsAccumulator);
61
+ (0, miscellaneous_2.printExecutionTime)('stats', startedAt, api);
49
62
  break;
50
63
  case 'json':
51
64
  printStatsJson(statsAccumulator);
52
65
  break;
66
+ case 'markdown':
67
+ printStatsMarkdown(statsAccumulator);
68
+ break;
53
69
  }
54
70
  }
55
71
  function handleStats(argv, config) {
@@ -85,8 +101,7 @@ function handleStats(argv, config) {
85
101
  resolvedRefMap,
86
102
  ctx,
87
103
  });
88
- printStats(statsAccumulator, path, argv.format);
89
- (0, miscellaneous_2.printExecutionTime)('stats', startedAt, path);
104
+ printStats(statsAccumulator, path, startedAt, argv.format);
90
105
  });
91
106
  }
92
107
  exports.handleStats = handleStats;
package/lib/index.js CHANGED
@@ -46,7 +46,7 @@ yargs
46
46
  },
47
47
  format: {
48
48
  description: 'Use a specific output format.',
49
- choices: ['stylish', 'json'],
49
+ choices: ['stylish', 'json', 'markdown'],
50
50
  default: 'stylish',
51
51
  },
52
52
  }), (argv) => {
@@ -2,3 +2,4 @@ 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
4
  export declare function keysOf<T>(obj: T): (keyof T)[];
5
+ export declare function capitalize(s: string): string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.keysOf = exports.isString = exports.isEmptyObject = exports.isObject = void 0;
3
+ exports.capitalize = exports.keysOf = exports.isString = exports.isEmptyObject = exports.isObject = void 0;
4
4
  function isObject(obj) {
5
5
  const type = typeof obj;
6
6
  return type === 'function' || (type === 'object' && !!obj);
@@ -20,3 +20,10 @@ function keysOf(obj) {
20
20
  return Object.keys(obj);
21
21
  }
22
22
  exports.keysOf = keysOf;
23
+ function capitalize(s) {
24
+ if ((s === null || s === void 0 ? void 0 : s.length) > 0) {
25
+ return s[0].toUpperCase() + s.slice(1);
26
+ }
27
+ return s;
28
+ }
29
+ exports.capitalize = capitalize;
@@ -69,22 +69,21 @@ const renderUpdateBanner = (current, latest) => {
69
69
  ];
70
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
- const banner = `
73
- ${(0, colorette_1.yellow)('╔' + border + '╗')}
74
- ${(0, 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
- ${(0, colorette_1.yellow)('' + ' '.repeat(maxLength + SPACE_TO_BORDER) + '║')}
81
- ${(0, colorette_1.yellow)('' + border + '╝')}
82
- `;
72
+ const extraSpaces = ' '.repeat(SPACE_TO_BORDER);
73
+ const banner = [
74
+ '',
75
+ extraSpaces + (0, colorette_1.yellow)('╔' + border + '╗'),
76
+ extraSpaces + (0, colorette_1.yellow)('║' + ' '.repeat(maxLength + SPACE_TO_BORDER) + '║'),
77
+ messageLines.map(getLineWithPadding(maxLength, extraSpaces)).join('\n'),
78
+ extraSpaces + (0, colorette_1.yellow)('║' + ' '.repeat(maxLength + SPACE_TO_BORDER) + '║'),
79
+ extraSpaces + (0, colorette_1.yellow)('' + border + '╝'),
80
+ '',
81
+ '',
82
+ ].join('\n');
83
83
  process.stderr.write(banner);
84
84
  };
85
- const getLineWithPadding = (maxLength, line, index) => {
85
+ const getLineWithPadding = (maxLength, extraSpaces) => (line) => {
86
86
  const padding = ' '.repeat(maxLength - (0, miscellaneous_1.cleanColors)(line).length);
87
- const extraSpaces = index !== 0 ? ' '.repeat(SPACE_TO_BORDER) : '';
88
87
  return `${extraSpaces}${(0, colorette_1.yellow)('║')} ${line}${padding} ${(0, colorette_1.yellow)('║')}`;
89
88
  };
90
89
  const isNeedToBeCached = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/cli",
3
- "version": "1.8.1",
3
+ "version": "1.9.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -36,7 +36,7 @@
36
36
  "Roman Hotsiy <roman@redoc.ly> (https://redoc.ly/)"
37
37
  ],
38
38
  "dependencies": {
39
- "@redocly/openapi-core": "1.8.1",
39
+ "@redocly/openapi-core": "1.9.0",
40
40
  "abort-controller": "^3.0.0",
41
41
  "chokidar": "^3.5.1",
42
42
  "colorette": "^1.2.0",
@@ -283,8 +283,7 @@ describe('transformPush', () => {
283
283
  const cb = jest.fn();
284
284
  transformPush(cb)(
285
285
  {
286
- api: 'openapi.yaml',
287
- maybeDestination: '@testing_org/main@v1',
286
+ apis: ['openapi.yaml', '@testing_org/main@v1'],
288
287
  },
289
288
  {} as any
290
289
  );
@@ -300,9 +299,7 @@ describe('transformPush', () => {
300
299
  const cb = jest.fn();
301
300
  transformPush(cb)(
302
301
  {
303
- api: 'openapi.yaml',
304
- maybeDestination: '@testing_org/main@v1',
305
- maybeBranchName: 'other',
302
+ apis: ['openapi.yaml', '@testing_org/main@v1', 'other'],
306
303
  },
307
304
  {} as any
308
305
  );
@@ -319,9 +316,7 @@ describe('transformPush', () => {
319
316
  const cb = jest.fn();
320
317
  transformPush(cb)(
321
318
  {
322
- api: 'openapi.yaml',
323
- maybeDestination: '@testing_org/main@v1',
324
- maybeBranchName: 'other',
319
+ apis: ['openapi.yaml', '@testing_org/main@v1', 'other'],
325
320
  branch: 'priority-branch',
326
321
  },
327
322
  {} as any
@@ -339,13 +334,13 @@ describe('transformPush', () => {
339
334
  const cb = jest.fn();
340
335
  transformPush(cb)(
341
336
  {
342
- api: '@testing_org/main@v1',
337
+ apis: ['main@v1'],
343
338
  },
344
339
  {} as any
345
340
  );
346
341
  expect(cb).toBeCalledWith(
347
342
  {
348
- destination: '@testing_org/main@v1',
343
+ destination: 'main@v1',
349
344
  },
350
345
  {}
351
346
  );
@@ -354,7 +349,7 @@ describe('transformPush', () => {
354
349
  const cb = jest.fn();
355
350
  transformPush(cb)(
356
351
  {
357
- api: 'test.yaml',
352
+ apis: ['test.yaml'],
358
353
  },
359
354
  {} as any
360
355
  );
@@ -365,31 +360,32 @@ describe('transformPush', () => {
365
360
  {}
366
361
  );
367
362
  });
368
- it('should accept aliases for the old syntax', () => {
363
+
364
+ it('should use destination from option', () => {
369
365
  const cb = jest.fn();
370
366
  transformPush(cb)(
371
367
  {
372
- api: 'alias',
373
- maybeDestination: '@testing_org/main@v1',
368
+ apis: ['test.yaml', 'test@v1'],
369
+ destination: 'main@v1',
374
370
  },
375
371
  {} as any
376
372
  );
377
373
  expect(cb).toBeCalledWith(
378
374
  {
379
- destination: '@testing_org/main@v1',
380
- api: 'alias',
375
+ destination: 'main@v1',
376
+ api: 'test.yaml',
381
377
  },
382
378
  {}
383
379
  );
384
380
  });
381
+
385
382
  it('should use --job-id option firstly', () => {
386
383
  const cb = jest.fn();
387
384
  transformPush(cb)(
388
385
  {
389
386
  'batch-id': 'b-123',
390
387
  'job-id': 'j-123',
391
- api: 'test',
392
- maybeDestination: 'main@v1',
388
+ apis: ['test'],
393
389
  branch: 'test',
394
390
  destination: 'main@v1',
395
391
  },
@@ -90,7 +90,7 @@ describe('handlePushStatus()', () => {
90
90
  );
91
91
  expect(process.stdout.write).toHaveBeenCalledTimes(1);
92
92
  expect(process.stdout.write).toHaveBeenCalledWith(
93
- '🚀 PREVIEW deployment succeeded.\nPreview URL: https://test-url\n'
93
+ '🚀 Preview deploy success.\nPreview URL: https://test-url\n'
94
94
  );
95
95
  });
96
96
 
@@ -110,10 +110,10 @@ describe('handlePushStatus()', () => {
110
110
  );
111
111
  expect(process.stdout.write).toHaveBeenCalledTimes(2);
112
112
  expect(process.stdout.write).toHaveBeenCalledWith(
113
- '🚀 PREVIEW deployment succeeded.\nPreview URL: https://test-url\n'
113
+ '🚀 Preview deploy success.\nPreview URL: https://test-url\n'
114
114
  );
115
115
  expect(process.stdout.write).toHaveBeenCalledWith(
116
- '🚀 PRODUCTION deployment succeeded.\nPreview URL: https://test-url\n'
116
+ '🚀 Production deploy success.\nProduction URL: https://test-url\n'
117
117
  );
118
118
  });
119
119
 
@@ -139,7 +139,7 @@ describe('handlePushStatus()', () => {
139
139
  mockConfig
140
140
  );
141
141
  expect(exitWithError).toHaveBeenCalledWith(
142
- '❌ PREVIEW deployment failed.\nPreview URL: https://test-url'
142
+ '❌ Preview deploy fail.\nPreview URL: https://test-url'
143
143
  );
144
144
  });
145
145
 
@@ -176,7 +176,7 @@ describe('handlePushStatus()', () => {
176
176
  );
177
177
  expect(process.stdout.write).toHaveBeenCalledTimes(4);
178
178
  expect(process.stdout.write).toHaveBeenCalledWith(
179
- '🚀 PREVIEW deployment succeeded.\nPreview URL: https://test-url\n'
179
+ '🚀 Preview deploy success.\nPreview URL: https://test-url\n'
180
180
  );
181
181
  expect(process.stdout.write).toHaveBeenCalledWith('\nScorecard:');
182
182
  expect(process.stdout.write).toHaveBeenCalledWith(