@redocly/cli 1.10.6 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/lib/__tests__/commands/bundle.test.js +3 -32
  3. package/lib/__tests__/commands/join.test.js +0 -11
  4. package/lib/__tests__/utils.test.js +3 -3
  5. package/lib/cms/api/types.d.ts +22 -11
  6. package/lib/cms/commands/__tests__/push-status.test.js +338 -29
  7. package/lib/cms/commands/__tests__/push.test.js +32 -2
  8. package/lib/cms/commands/__tests__/utils.test.d.ts +1 -0
  9. package/lib/cms/commands/__tests__/utils.test.js +60 -0
  10. package/lib/cms/commands/push-status.d.ts +14 -4
  11. package/lib/cms/commands/push-status.js +160 -90
  12. package/lib/cms/commands/push.d.ts +6 -2
  13. package/lib/cms/commands/push.js +8 -2
  14. package/lib/cms/commands/utils.d.ts +22 -0
  15. package/lib/cms/commands/utils.js +53 -0
  16. package/lib/commands/bundle.d.ts +1 -4
  17. package/lib/commands/bundle.js +2 -32
  18. package/lib/commands/join.d.ts +0 -3
  19. package/lib/commands/join.js +13 -36
  20. package/lib/index.js +69 -27
  21. package/lib/utils/miscellaneous.js +5 -4
  22. package/lib/wrapper.d.ts +1 -1
  23. package/package.json +2 -2
  24. package/src/__tests__/commands/bundle.test.ts +4 -37
  25. package/src/__tests__/commands/join.test.ts +0 -17
  26. package/src/__tests__/utils.test.ts +3 -3
  27. package/src/cms/api/types.ts +19 -12
  28. package/src/cms/commands/__tests__/push-status.test.ts +473 -47
  29. package/src/cms/commands/__tests__/push.test.ts +40 -2
  30. package/src/cms/commands/__tests__/utils.test.ts +62 -0
  31. package/src/cms/commands/push-status.ts +242 -120
  32. package/src/cms/commands/push.ts +21 -5
  33. package/src/cms/commands/utils.ts +52 -0
  34. package/src/commands/bundle.ts +3 -53
  35. package/src/commands/join.ts +13 -49
  36. package/src/index.ts +89 -28
  37. package/src/utils/miscellaneous.ts +5 -4
  38. package/src/wrapper.ts +1 -1
  39. package/tsconfig.tsbuildinfo +1 -1
@@ -14,10 +14,10 @@ const colors = require("colorette");
14
14
  const miscellaneous_1 = require("../../utils/miscellaneous");
15
15
  const spinner_1 = require("../../utils/spinner");
16
16
  const utils_1 = require("../utils");
17
- const colorette_1 = require("colorette");
18
17
  const api_1 = require("../api");
19
18
  const js_utils_1 = require("../../utils/js-utils");
20
- const INTERVAL = 5000;
19
+ const utils_2 = require("./utils");
20
+ const RETRY_INTERVAL_MS = 5000; // 5 sec
21
21
  function handlePushStatus(argv, config) {
22
22
  return __awaiter(this, void 0, void 0, function* () {
23
23
  const startedAt = performance.now();
@@ -25,97 +25,154 @@ function handlePushStatus(argv, config) {
25
25
  const { organization, project: projectId, pushId, wait } = argv;
26
26
  const orgId = organization || config.organization;
27
27
  if (!orgId) {
28
- return (0, miscellaneous_1.exitWithError)(`No organization provided, please use --organization option or specify the 'organization' field in the config file.`);
28
+ (0, miscellaneous_1.exitWithError)(`No organization provided, please use --organization option or specify the 'organization' field in the config file.`);
29
+ return;
29
30
  }
30
31
  const domain = argv.domain || (0, api_1.getDomain)();
31
- if (!domain) {
32
- return (0, miscellaneous_1.exitWithError)(`No domain provided, please use --domain option or environment variable REDOCLY_DOMAIN.`);
33
- }
34
- const maxExecutionTime = argv['max-execution-time'] || 600;
32
+ const maxExecutionTime = argv['max-execution-time'] || 1200; // 20 min
33
+ const retryIntervalMs = argv['retry-interval']
34
+ ? argv['retry-interval'] * 1000
35
+ : RETRY_INTERVAL_MS;
36
+ const startTime = argv['start-time'] || Date.now();
37
+ const retryTimeoutMs = maxExecutionTime * 1000;
38
+ const continueOnDeployFailures = argv['continue-on-deploy-failures'] || false;
35
39
  try {
36
40
  const apiKey = (0, api_1.getApiKeys)(domain);
37
41
  const client = new api_1.ReuniteApiClient(domain, apiKey);
38
- if (wait) {
39
- const push = yield waitForDeployment(client, 'preview');
40
- if (push.isMainBranch && push.status.preview.deploy.status === 'success') {
41
- yield waitForDeployment(client, 'production');
42
- }
43
- printPushStatusInfo();
44
- return;
42
+ let pushResponse;
43
+ pushResponse = yield (0, utils_2.retryUntilConditionMet)({
44
+ operation: () => client.remotes.getPush({
45
+ organizationId: orgId,
46
+ projectId,
47
+ pushId,
48
+ }),
49
+ condition: wait
50
+ ? // Keep retrying if status is "pending" or "running" (returning false, so the operation will be retried)
51
+ (result) => !['pending', 'running'].includes(result.status['preview'].deploy.status)
52
+ : null,
53
+ onConditionNotMet: (lastResult) => {
54
+ displayDeploymentAndBuildStatus({
55
+ status: lastResult.status['preview'].deploy.status,
56
+ url: lastResult.status['preview'].deploy.url,
57
+ spinner,
58
+ buildType: 'preview',
59
+ continueOnDeployFailures,
60
+ wait,
61
+ });
62
+ },
63
+ onRetry: (lastResult) => {
64
+ if (argv.onRetry) {
65
+ argv.onRetry({
66
+ preview: lastResult.status.preview,
67
+ production: lastResult.isMainBranch ? lastResult.status.production : null,
68
+ commit: lastResult.commit,
69
+ });
70
+ }
71
+ },
72
+ startTime,
73
+ retryTimeoutMs,
74
+ retryIntervalMs,
75
+ });
76
+ printPushStatus({
77
+ buildType: 'preview',
78
+ spinner,
79
+ wait,
80
+ push: pushResponse,
81
+ continueOnDeployFailures,
82
+ });
83
+ printScorecard(pushResponse.status.preview.scorecard);
84
+ const shouldWaitForProdDeployment = pushResponse.isMainBranch &&
85
+ (wait ? pushResponse.status.preview.deploy.status === 'success' : true);
86
+ if (shouldWaitForProdDeployment) {
87
+ pushResponse = yield (0, utils_2.retryUntilConditionMet)({
88
+ operation: () => client.remotes.getPush({
89
+ organizationId: orgId,
90
+ projectId,
91
+ pushId,
92
+ }),
93
+ condition: wait
94
+ ? // Keep retrying if status is "pending" or "running" (returning false, so the operation will be retried)
95
+ (result) => !['pending', 'running'].includes(result.status['production'].deploy.status)
96
+ : null,
97
+ onConditionNotMet: (lastResult) => {
98
+ displayDeploymentAndBuildStatus({
99
+ status: lastResult.status['production'].deploy.status,
100
+ url: lastResult.status['production'].deploy.url,
101
+ spinner,
102
+ buildType: 'production',
103
+ continueOnDeployFailures,
104
+ wait,
105
+ });
106
+ },
107
+ onRetry: (lastResult) => {
108
+ if (argv.onRetry) {
109
+ argv.onRetry({
110
+ preview: lastResult.status.preview,
111
+ production: lastResult.isMainBranch ? lastResult.status.production : null,
112
+ commit: lastResult.commit,
113
+ });
114
+ }
115
+ },
116
+ startTime,
117
+ retryTimeoutMs,
118
+ retryIntervalMs,
119
+ });
45
120
  }
46
- const pushPreview = yield getAndPrintPushStatus(client, 'preview');
47
- printScorecard(pushPreview.status.preview.scorecard);
48
- if (pushPreview.isMainBranch) {
49
- yield getAndPrintPushStatus(client, 'production');
50
- printScorecard(pushPreview.status.production.scorecard);
121
+ if (pushResponse.isMainBranch) {
122
+ printPushStatus({
123
+ buildType: 'production',
124
+ spinner,
125
+ wait,
126
+ push: pushResponse,
127
+ continueOnDeployFailures,
128
+ });
129
+ printScorecard(pushResponse.status.production.scorecard);
51
130
  }
52
- printPushStatusInfo();
131
+ printPushStatusInfo({ orgId, projectId, pushId, startedAt });
132
+ const summary = {
133
+ preview: pushResponse.status.preview,
134
+ production: pushResponse.isMainBranch ? pushResponse.status.production : null,
135
+ commit: pushResponse.commit,
136
+ };
137
+ return summary;
53
138
  }
54
139
  catch (err) {
140
+ spinner.stop(); // Spinner can block process exit, so we need to stop it explicitly.
55
141
  const message = err instanceof utils_1.DeploymentError
56
142
  ? err.message
57
143
  : `✗ Failed to get push status. Reason: ${err.message}\n`;
58
144
  (0, miscellaneous_1.exitWithError)(message);
145
+ return;
59
146
  }
60
- function printPushStatusInfo() {
61
- process.stderr.write(`\nProcessed push-status for ${colors.yellow(orgId)}, ${colors.yellow(projectId)} and pushID ${colors.yellow(pushId)}.\n`);
62
- (0, miscellaneous_1.printExecutionTime)('push-status', startedAt, 'Finished');
63
- }
64
- function waitForDeployment(client, buildType) {
65
- return __awaiter(this, void 0, void 0, function* () {
66
- return new Promise((resolve, reject) => {
67
- if (performance.now() - startedAt > maxExecutionTime * 1000) {
68
- spinner.stop();
69
- reject(new Error(`Time limit exceeded.`));
70
- }
71
- getAndPrintPushStatus(client, buildType)
72
- .then((push) => {
73
- if (!['pending', 'running'].includes(push.status[buildType].deploy.status)) {
74
- printScorecard(push.status[buildType].scorecard);
75
- resolve(push);
76
- return;
77
- }
78
- setTimeout(() => __awaiter(this, void 0, void 0, function* () {
79
- try {
80
- const pushResponse = yield waitForDeployment(client, buildType);
81
- resolve(pushResponse);
82
- }
83
- catch (e) {
84
- reject(e);
85
- }
86
- }), INTERVAL);
87
- })
88
- .catch(reject);
89
- });
90
- });
91
- }
92
- function getAndPrintPushStatus(client, buildType) {
93
- return __awaiter(this, void 0, void 0, function* () {
94
- const push = yield client.remotes.getPush({
95
- organizationId: orgId,
96
- projectId,
97
- pushId,
98
- });
99
- if (push.isOutdated || !push.hasChanges) {
100
- process.stderr.write((0, colorette_1.yellow)(`Files not uploaded. Reason: ${push.isOutdated ? 'outdated' : 'no changes'}.\n`));
101
- }
102
- else {
103
- displayDeploymentAndBuildStatus({
104
- status: push.status[buildType].deploy.status,
105
- previewUrl: push.status[buildType].deploy.url,
106
- buildType,
107
- spinner,
108
- wait,
109
- });
110
- }
111
- return push;
112
- });
147
+ finally {
148
+ spinner.stop(); // Spinner can block process exit, so we need to stop it explicitly.
113
149
  }
114
150
  });
115
151
  }
116
152
  exports.handlePushStatus = handlePushStatus;
153
+ function printPushStatusInfo({ orgId, projectId, pushId, startedAt, }) {
154
+ process.stderr.write(`\nProcessed push-status for ${colors.yellow(orgId)}, ${colors.yellow(projectId)} and pushID ${colors.yellow(pushId)}.\n`);
155
+ (0, miscellaneous_1.printExecutionTime)('push-status', startedAt, 'Finished');
156
+ }
157
+ function printPushStatus({ buildType, spinner, push, continueOnDeployFailures, }) {
158
+ if (!push) {
159
+ return;
160
+ }
161
+ if (push.isOutdated || !push.hasChanges) {
162
+ process.stderr.write(colors.yellow(`Files not added to your project. Reason: ${push.isOutdated ? 'outdated' : 'no changes'}.\n`));
163
+ }
164
+ else {
165
+ displayDeploymentAndBuildStatus({
166
+ status: push.status[buildType].deploy.status,
167
+ url: push.status[buildType].deploy.url,
168
+ buildType,
169
+ spinner,
170
+ continueOnDeployFailures,
171
+ });
172
+ }
173
+ }
117
174
  function printScorecard(scorecard) {
118
- if (!scorecard.length) {
175
+ if (!scorecard || scorecard.length === 0) {
119
176
  return;
120
177
  }
121
178
  process.stdout.write(`\n${colors.magenta('Scorecard')}:`);
@@ -128,24 +185,37 @@ function printScorecard(scorecard) {
128
185
  }
129
186
  process.stdout.write(`\n`);
130
187
  }
131
- function displayDeploymentAndBuildStatus({ status, previewUrl, spinner, buildType, wait, }) {
188
+ function displayDeploymentAndBuildStatus({ status, url, spinner, buildType, continueOnDeployFailures, wait, }) {
189
+ const message = getMessage({ status, url, buildType, wait });
190
+ if (status === 'failed' && !continueOnDeployFailures) {
191
+ spinner.stop();
192
+ throw new utils_1.DeploymentError(message);
193
+ }
194
+ if (wait && (status === 'pending' || status === 'running')) {
195
+ return spinner.start(message);
196
+ }
197
+ spinner.stop();
198
+ return process.stdout.write(message);
199
+ }
200
+ function getMessage({ status, url, buildType, wait, }) {
132
201
  switch (status) {
202
+ case 'skipped':
203
+ return `${colors.yellow(`Skipped ${buildType}`)}\n`;
204
+ case 'pending': {
205
+ const message = `${colors.yellow(`Pending ${buildType}`)}`;
206
+ return wait ? message : `Status: ${message}\n`;
207
+ }
208
+ case 'running': {
209
+ const message = `${colors.yellow(`Running ${buildType}`)}`;
210
+ return wait ? message : `Status: ${message}\n`;
211
+ }
133
212
  case 'success':
134
- spinner.stop();
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`);
213
+ return `${colors.green(`🚀 ${(0, js_utils_1.capitalize)(buildType)} deploy success.`)}\n${colors.magenta(`${(0, js_utils_1.capitalize)(buildType)} URL`)}: ${colors.cyan(url || 'No URL yet.')}\n`;
136
214
  case 'failed':
137
- spinner.stop();
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)}`);
139
- case 'pending':
140
- return wait
141
- ? spinner.start(`${colors.yellow(`Pending ${buildType}`)}`)
142
- : process.stdout.write(`Status: ${colors.yellow(`Pending ${buildType}`)}\n`);
143
- case 'skipped':
144
- spinner.stop();
145
- return process.stdout.write(`${colors.yellow(`Skipped ${buildType}`)}\n`);
146
- case 'running':
147
- return wait
148
- ? spinner.start(`${colors.yellow(`Running ${buildType}`)}`)
149
- : process.stdout.write(`Status: ${colors.yellow(`Running ${buildType}`)}\n`);
215
+ return `${colors.red(`❌ ${(0, js_utils_1.capitalize)(buildType)} deploy fail.`)}\n${colors.magenta(`${(0, js_utils_1.capitalize)(buildType)} URL`)}: ${colors.cyan(url || 'No URL yet.')}`;
216
+ default: {
217
+ const message = `${colors.yellow(`No status yet for ${buildType} deploy`)}`;
218
+ return wait ? message : `Status: ${message}\n`;
219
+ }
150
220
  }
151
221
  }
@@ -1,4 +1,4 @@
1
- import { Config } from '@redocly/openapi-core';
1
+ import type { OutputFormat, Config } from '@redocly/openapi-core';
2
2
  export type PushOptions = {
3
3
  apis?: string[];
4
4
  organization?: string;
@@ -18,6 +18,10 @@ export type PushOptions = {
18
18
  config?: string;
19
19
  'wait-for-deployment'?: boolean;
20
20
  'max-execution-time': number;
21
+ 'continue-on-deploy-failures'?: boolean;
21
22
  verbose?: boolean;
23
+ format?: Extract<OutputFormat, 'stylish'>;
22
24
  };
23
- export declare function handlePush(argv: PushOptions, config: Config): Promise<void>;
25
+ export declare function handlePush(argv: PushOptions, config: Config): Promise<{
26
+ pushId: string;
27
+ } | void>;
@@ -13,14 +13,15 @@ exports.handlePush = void 0;
13
13
  const fs = require("fs");
14
14
  const path = require("path");
15
15
  const openapi_core_1 = require("@redocly/openapi-core");
16
- const miscellaneous_1 = require("../../utils/miscellaneous");
17
16
  const colorette_1 = require("colorette");
18
17
  const pluralize = require("pluralize");
18
+ const miscellaneous_1 = require("../../utils/miscellaneous");
19
19
  const push_status_1 = require("./push-status");
20
20
  const api_1 = require("../api");
21
21
  function handlePush(argv, config) {
22
22
  return __awaiter(this, void 0, void 0, function* () {
23
- const startedAt = performance.now();
23
+ const startedAt = performance.now(); // for printing execution time
24
+ const startTime = Date.now(); // for push-status command
24
25
  const { organization, project: projectId, 'mount-path': mountPath, verbose } = argv;
25
26
  const orgId = organization || config.organization;
26
27
  if (!argv.message || !argv.author || !argv.branch) {
@@ -76,10 +77,15 @@ function handlePush(argv, config) {
76
77
  wait: true,
77
78
  domain,
78
79
  'max-execution-time': maxExecutionTime,
80
+ 'start-time': startTime,
81
+ 'continue-on-deploy-failures': argv['continue-on-deploy-failures'],
79
82
  }, config);
80
83
  }
81
84
  verbose &&
82
85
  (0, miscellaneous_1.printExecutionTime)('push', startedAt, `${pluralize('file', filesToUpload.length)} uploaded to organization ${orgId}, project ${projectId}. Push ID: ${id}.`);
86
+ return {
87
+ pushId: id,
88
+ };
83
89
  }
84
90
  catch (err) {
85
91
  const message = err instanceof miscellaneous_1.HandledError ? '' : `✗ File upload failed. Reason: ${err.message}`;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * This function retries an operation until a condition is met or a timeout is exceeded.
3
+ * If the condition is not met within the timeout, an error is thrown.
4
+ * @operation The operation to retry.
5
+ * @condition The condition to check after each operation result. Return false to continue retrying. Return true to stop retrying.
6
+ * If not provided, the first result will be returned.
7
+ * @param onConditionNotMet Will be called with the last result right after checking condition and before timeout and retrying.
8
+ * @param onRetry Will be called right before retrying operation with the last result before retrying.
9
+ * @param startTime The start time of the operation. Default is the current time.
10
+ * @param retryTimeoutMs The maximum time to retry the operation. Default is 10 minutes.
11
+ * @param retryIntervalMs The interval between retries. Default is 5 seconds.
12
+ */
13
+ export declare function retryUntilConditionMet<T>({ operation, condition, onConditionNotMet, onRetry, startTime, retryTimeoutMs, // 10 min
14
+ retryIntervalMs, }: {
15
+ operation: () => Promise<T>;
16
+ condition?: ((result: T) => boolean) | null;
17
+ onConditionNotMet?: (lastResult: T) => void;
18
+ onRetry?: (lastResult: T) => void | Promise<void>;
19
+ startTime?: number;
20
+ retryTimeoutMs?: number;
21
+ retryIntervalMs?: number;
22
+ }): Promise<T>;
@@ -0,0 +1,53 @@
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
+ exports.retryUntilConditionMet = void 0;
13
+ const openapi_core_1 = require("@redocly/openapi-core");
14
+ /**
15
+ * This function retries an operation until a condition is met or a timeout is exceeded.
16
+ * If the condition is not met within the timeout, an error is thrown.
17
+ * @operation The operation to retry.
18
+ * @condition The condition to check after each operation result. Return false to continue retrying. Return true to stop retrying.
19
+ * If not provided, the first result will be returned.
20
+ * @param onConditionNotMet Will be called with the last result right after checking condition and before timeout and retrying.
21
+ * @param onRetry Will be called right before retrying operation with the last result before retrying.
22
+ * @param startTime The start time of the operation. Default is the current time.
23
+ * @param retryTimeoutMs The maximum time to retry the operation. Default is 10 minutes.
24
+ * @param retryIntervalMs The interval between retries. Default is 5 seconds.
25
+ */
26
+ function retryUntilConditionMet({ operation, condition, onConditionNotMet, onRetry, startTime = Date.now(), retryTimeoutMs = 600000, // 10 min
27
+ retryIntervalMs = 5000, // 5 sec
28
+ }) {
29
+ return __awaiter(this, void 0, void 0, function* () {
30
+ function attempt() {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ const result = yield operation();
33
+ if (!condition) {
34
+ return result;
35
+ }
36
+ if (condition(result)) {
37
+ return result;
38
+ }
39
+ else if (Date.now() - startTime > retryTimeoutMs) {
40
+ throw new Error('Timeout exceeded');
41
+ }
42
+ else {
43
+ onConditionNotMet === null || onConditionNotMet === void 0 ? void 0 : onConditionNotMet(result);
44
+ yield (0, openapi_core_1.pause)(retryIntervalMs);
45
+ yield (onRetry === null || onRetry === void 0 ? void 0 : onRetry(result));
46
+ return attempt();
47
+ }
48
+ });
49
+ }
50
+ return attempt();
51
+ });
52
+ }
53
+ exports.retryUntilConditionMet = retryUntilConditionMet;
@@ -1,16 +1,13 @@
1
- import { Config, OutputFormat } from '@redocly/openapi-core';
1
+ import { Config } from '@redocly/openapi-core';
2
2
  import type { OutputExtensions, Skips } from '../types';
3
3
  export type BundleOptions = {
4
4
  apis?: string[];
5
- 'max-problems'?: number;
6
5
  extends?: string[];
7
6
  config?: string;
8
- format?: OutputFormat;
9
7
  output?: string;
10
8
  ext: OutputExtensions;
11
9
  dereferenced?: boolean;
12
10
  force?: boolean;
13
- lint?: boolean;
14
11
  metafile?: string;
15
12
  'remove-unused-components'?: boolean;
16
13
  'keep-url-references'?: boolean;
@@ -34,44 +34,15 @@ function handleBundle(argv, config, version) {
34
34
  ((_c = (_b = (_a = config.rawConfig) === null || _a === void 0 ? void 0 : _a.styleguide) === null || _b === void 0 ? void 0 : _b.decorators) === null || _c === void 0 ? void 0 : _c.hasOwnProperty('remove-unused-components'));
35
35
  const apis = yield (0, miscellaneous_1.getFallbackApisOrExit)(argv.apis, config);
36
36
  const totals = { errors: 0, warnings: 0, ignored: 0 };
37
- const maxProblems = argv['max-problems'];
38
- const deprecatedOptions = [
39
- 'lint',
40
- 'format',
41
- 'skip-rule',
42
- 'extends',
43
- 'max-problems',
44
- ];
37
+ const deprecatedOptions = [];
45
38
  (0, miscellaneous_2.checkForDeprecatedOptions)(argv, deprecatedOptions);
46
39
  for (const { path, alias } of apis) {
47
40
  try {
48
41
  const startedAt = perf_hooks_1.performance.now();
49
42
  const resolvedConfig = (0, openapi_core_1.getMergedConfig)(config, alias);
50
43
  const { styleguide } = resolvedConfig;
51
- styleguide.skipRules(argv['skip-rule']);
52
44
  styleguide.skipPreprocessors(argv['skip-preprocessor']);
53
45
  styleguide.skipDecorators(argv['skip-decorator']);
54
- if (argv.lint) {
55
- (0, miscellaneous_1.checkIfRulesetExist)(styleguide.rules);
56
- if (config.styleguide.recommendedFallback) {
57
- process.stderr.write(`No configurations were provided -- using built in ${(0, colorette_1.blue)('recommended')} configuration by default.\n\n`);
58
- }
59
- const results = yield (0, openapi_core_1.lint)({
60
- ref: path,
61
- config: resolvedConfig,
62
- });
63
- const fileLintTotals = (0, openapi_core_1.getTotals)(results);
64
- totals.errors += fileLintTotals.errors;
65
- totals.warnings += fileLintTotals.warnings;
66
- totals.ignored += fileLintTotals.ignored;
67
- (0, openapi_core_1.formatProblems)(results, {
68
- format: argv.format || 'codeframe',
69
- totals: fileLintTotals,
70
- version,
71
- maxProblems: maxProblems,
72
- });
73
- (0, miscellaneous_1.printLintTotals)(fileLintTotals, 2);
74
- }
75
46
  process.stderr.write((0, colorette_1.gray)(`bundling ${path}...\n`));
76
47
  const _f = yield (0, openapi_core_1.bundle)({
77
48
  config: resolvedConfig,
@@ -96,8 +67,7 @@ function handleBundle(argv, config, version) {
96
67
  totals.warnings += fileTotals.warnings;
97
68
  totals.ignored += fileTotals.ignored;
98
69
  (0, openapi_core_1.formatProblems)(problems, {
99
- format: argv.format || 'codeframe',
100
- maxProblems: maxProblems,
70
+ format: 'codeframe',
101
71
  totals: fileTotals,
102
72
  version,
103
73
  });
@@ -2,9 +2,6 @@ import { Config } from '@redocly/openapi-core';
2
2
  import type { RuleSeverity } from '@redocly/openapi-core';
3
3
  export type JoinOptions = {
4
4
  apis: string[];
5
- lint?: boolean;
6
- decorate?: boolean;
7
- preprocess?: boolean;
8
5
  'prefix-tags-with-info-prop'?: string;
9
6
  'prefix-tags-with-filename'?: boolean;
10
7
  'prefix-components-with-info-prop'?: string;
@@ -28,7 +28,6 @@ function handleJoin(argv, config, packageVersion) {
28
28
  if (argv.apis.length < 2) {
29
29
  return (0, miscellaneous_1.exitWithError)(`At least 2 apis should be provided. \n\n`);
30
30
  }
31
- (0, miscellaneous_1.checkForDeprecatedOptions)(argv, ['lint']);
32
31
  const fileExtension = (0, miscellaneous_1.getAndValidateFileExtension)(argv.output || argv.apis[0]);
33
32
  const { 'prefix-components-with-info-prop': prefixComponentsWithInfoProp, 'prefix-tags-with-filename': prefixTagsWithFilename, 'prefix-tags-with-info-prop': prefixTagsWithInfoProp, 'without-x-tag-groups': withoutXTagGroups, output: specFilename = `openapi.${fileExtension}`, } = argv;
34
33
  const usedTagsOptions = [
@@ -42,22 +41,18 @@ function handleJoin(argv, config, packageVersion) {
42
41
  const apis = yield (0, miscellaneous_1.getFallbackApisOrExit)(argv.apis, config);
43
42
  const externalRefResolver = new openapi_core_1.BaseResolver(config.resolve);
44
43
  const documents = yield Promise.all(apis.map(({ path }) => externalRefResolver.resolveDocument(null, path, true)));
45
- if (!argv.decorate) {
46
- const decorators = new Set([
47
- ...Object.keys(config.styleguide.decorators.oas3_0),
48
- ...Object.keys(config.styleguide.decorators.oas3_1),
49
- ...Object.keys(config.styleguide.decorators.oas2),
50
- ]);
51
- config.styleguide.skipDecorators(Array.from(decorators));
52
- }
53
- if (!argv.preprocess) {
54
- const preprocessors = new Set([
55
- ...Object.keys(config.styleguide.preprocessors.oas3_0),
56
- ...Object.keys(config.styleguide.preprocessors.oas3_1),
57
- ...Object.keys(config.styleguide.preprocessors.oas2),
58
- ]);
59
- config.styleguide.skipPreprocessors(Array.from(preprocessors));
60
- }
44
+ const decorators = new Set([
45
+ ...Object.keys(config.styleguide.decorators.oas3_0),
46
+ ...Object.keys(config.styleguide.decorators.oas3_1),
47
+ ...Object.keys(config.styleguide.decorators.oas2),
48
+ ]);
49
+ config.styleguide.skipDecorators(Array.from(decorators));
50
+ const preprocessors = new Set([
51
+ ...Object.keys(config.styleguide.preprocessors.oas3_0),
52
+ ...Object.keys(config.styleguide.preprocessors.oas3_1),
53
+ ...Object.keys(config.styleguide.preprocessors.oas2),
54
+ ]);
55
+ config.styleguide.skipPreprocessors(Array.from(preprocessors));
61
56
  const bundleResults = yield Promise.all(documents.map((document) => (0, openapi_core_1.bundleDocument)({
62
57
  document,
63
58
  config: config.styleguide,
@@ -70,7 +65,7 @@ function handleJoin(argv, config, packageVersion) {
70
65
  if (fileTotals.errors) {
71
66
  (0, openapi_core_1.formatProblems)(problems, {
72
67
  totals: fileTotals,
73
- version: document.parsed.version,
68
+ version: packageVersion,
74
69
  });
75
70
  (0, miscellaneous_1.exitWithError)(`❌ Errors encountered while bundling ${(0, colorette_1.blue)(document.source.absoluteRef)}: join will not proceed.\n`);
76
71
  }
@@ -91,11 +86,6 @@ function handleJoin(argv, config, packageVersion) {
91
86
  return (0, miscellaneous_1.exitWithError)(`${e.message}: ${(0, colorette_1.blue)(document.source.absoluteRef)}`);
92
87
  }
93
88
  }
94
- if (argv.lint) {
95
- for (const document of documents) {
96
- yield validateApi(document, config.styleguide, externalRefResolver, packageVersion);
97
- }
98
- }
99
89
  const joinedDef = {};
100
90
  const potentialConflicts = {
101
91
  tags: {},
@@ -561,19 +551,6 @@ function getInfoPrefix(info, prefixArg, type) {
561
551
  (0, miscellaneous_1.exitWithError)(`${(0, colorette_1.yellow)(`prefix-${type}-with-info-prop`)} argument value length should not exceed 50 characters. \n\n`);
562
552
  return info[prefixArg].replaceAll(/\s/g, '_');
563
553
  }
564
- function validateApi(document, config, externalRefResolver, packageVersion) {
565
- return __awaiter(this, void 0, void 0, function* () {
566
- try {
567
- const results = yield (0, openapi_core_1.lintDocument)({ document, config, externalRefResolver });
568
- const fileTotals = (0, openapi_core_1.getTotals)(results);
569
- (0, openapi_core_1.formatProblems)(results, { format: 'stylish', totals: fileTotals, version: packageVersion });
570
- (0, miscellaneous_1.printLintTotals)(fileTotals, 2);
571
- }
572
- catch (err) {
573
- (0, miscellaneous_1.handleError)(err, document.parsed);
574
- }
575
- });
576
- }
577
554
  function replace$Refs(obj, componentsPrefix) {
578
555
  (0, split_1.crawl)(obj, (node) => {
579
556
  if (node.$ref && typeof node.$ref === 'string' && (0, split_1.startsWithComponents)(node.$ref)) {