@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.
- package/CHANGELOG.md +17 -0
- package/lib/__tests__/commands/build-docs.test.js +3 -3
- package/lib/__tests__/commands/bundle.test.js +5 -5
- package/lib/__tests__/commands/join.test.js +11 -11
- package/lib/__tests__/commands/lint.test.js +14 -14
- package/lib/__tests__/commands/push-region.test.js +1 -1
- package/lib/__tests__/commands/push.test.js +11 -11
- package/lib/__tests__/fetch-with-timeout.test.js +4 -13
- package/lib/__tests__/spinner.test.js +43 -0
- package/lib/__tests__/utils.test.js +36 -36
- package/lib/__tests__/wrapper.test.js +8 -8
- package/lib/cms/api/__tests__/api-keys.test.d.ts +1 -0
- package/lib/cms/api/__tests__/api-keys.test.js +26 -0
- package/lib/cms/api/__tests__/api.client.test.d.ts +1 -0
- package/lib/cms/api/__tests__/api.client.test.js +217 -0
- package/lib/cms/api/__tests__/domains.test.d.ts +1 -0
- package/lib/cms/api/__tests__/domains.test.js +13 -0
- package/lib/cms/api/api-client.d.ts +50 -0
- package/lib/cms/api/api-client.js +148 -0
- package/lib/cms/api/api-keys.d.ts +1 -0
- package/lib/cms/api/api-keys.js +24 -0
- package/lib/cms/api/domains.d.ts +1 -0
- package/lib/cms/api/domains.js +12 -0
- package/lib/cms/api/index.d.ts +3 -0
- package/lib/cms/api/index.js +19 -0
- package/lib/cms/api/types.d.ts +91 -0
- package/lib/cms/api/types.js +2 -0
- package/lib/cms/commands/__tests__/push-status.test.d.ts +1 -0
- package/lib/cms/commands/__tests__/push-status.test.js +164 -0
- package/lib/cms/commands/__tests__/push.test.d.ts +1 -0
- package/lib/cms/commands/__tests__/push.test.js +226 -0
- package/lib/cms/commands/push-status.d.ts +12 -0
- package/lib/cms/commands/push-status.js +150 -0
- package/lib/cms/commands/push.d.ts +23 -0
- package/lib/cms/commands/push.js +142 -0
- package/lib/cms/utils.d.ts +2 -0
- package/lib/cms/utils.js +6 -0
- package/lib/commands/build-docs/index.js +4 -4
- package/lib/commands/build-docs/utils.js +2 -2
- package/lib/commands/bundle.js +13 -13
- package/lib/commands/join.js +25 -25
- package/lib/commands/lint.js +10 -10
- package/lib/commands/login.js +2 -2
- package/lib/commands/preview-docs/index.js +4 -4
- package/lib/commands/preview-docs/preview-server/preview-server.js +2 -2
- package/lib/commands/preview-project/types.d.ts +1 -1
- package/lib/commands/push.d.ts +5 -0
- package/lib/commands/push.js +25 -17
- package/lib/commands/split/__tests__/index.test.js +2 -2
- package/lib/commands/split/index.js +17 -17
- package/lib/commands/stats.js +4 -4
- package/lib/index.d.ts +1 -1
- package/lib/index.js +130 -17
- package/lib/types.d.ts +8 -1
- package/lib/{__mocks__/utils.js → utils/__mocks__/miscellaneous.js} +1 -1
- package/lib/utils/assert-node-version.d.ts +1 -0
- package/lib/{fetch-with-timeout.js → utils/fetch-with-timeout.js} +2 -7
- package/lib/{utils.d.ts → utils/miscellaneous.d.ts} +1 -1
- package/lib/{utils.js → utils/miscellaneous.js} +2 -2
- package/lib/utils/spinner.d.ts +10 -0
- package/lib/utils/spinner.js +42 -0
- package/lib/{update-version-notifier.js → utils/update-version-notifier.js} +4 -4
- package/lib/wrapper.js +5 -5
- package/package.json +5 -3
- package/src/__tests__/commands/build-docs.test.ts +2 -2
- package/src/__tests__/commands/bundle.test.ts +2 -2
- package/src/__tests__/commands/join.test.ts +2 -2
- package/src/__tests__/commands/lint.test.ts +3 -3
- package/src/__tests__/commands/push-region.test.ts +1 -1
- package/src/__tests__/commands/push.test.ts +2 -2
- package/src/__tests__/fetch-with-timeout.test.ts +4 -16
- package/src/__tests__/spinner.test.ts +51 -0
- package/src/__tests__/utils.test.ts +2 -5
- package/src/__tests__/wrapper.test.ts +2 -2
- package/src/cms/api/__tests__/api-keys.test.ts +37 -0
- package/src/cms/api/__tests__/api.client.test.ts +275 -0
- package/src/cms/api/__tests__/domains.test.ts +15 -0
- package/src/cms/api/api-client.ts +199 -0
- package/src/cms/api/api-keys.ts +26 -0
- package/src/cms/api/domains.ts +11 -0
- package/src/cms/api/index.ts +3 -0
- package/src/cms/api/types.ts +101 -0
- package/src/cms/commands/__tests__/push-status.test.ts +212 -0
- package/src/cms/commands/__tests__/push.test.ts +293 -0
- package/src/cms/commands/push-status.ts +203 -0
- package/src/cms/commands/push.ts +215 -0
- package/src/cms/utils.ts +1 -0
- package/src/commands/build-docs/index.ts +1 -1
- package/src/commands/build-docs/utils.ts +1 -1
- package/src/commands/bundle.ts +2 -2
- package/src/commands/join.ts +2 -2
- package/src/commands/lint.ts +1 -1
- package/src/commands/login.ts +1 -1
- package/src/commands/preview-docs/index.ts +5 -1
- package/src/commands/preview-docs/preview-server/preview-server.ts +1 -1
- package/src/commands/preview-project/types.ts +1 -1
- package/src/commands/push.ts +15 -1
- package/src/commands/split/__tests__/index.test.ts +3 -4
- package/src/commands/split/index.ts +2 -2
- package/src/commands/stats.ts +2 -2
- package/src/index.ts +138 -20
- package/src/types.ts +8 -0
- package/src/{__mocks__/utils.ts → utils/__mocks__/miscellaneous.ts} +1 -1
- package/src/{fetch-with-timeout.ts → utils/fetch-with-timeout.ts} +1 -6
- package/src/{utils.ts → utils/miscellaneous.ts} +2 -2
- package/src/utils/spinner.ts +50 -0
- package/src/{update-version-notifier.ts → utils/update-version-notifier.ts} +2 -2
- package/src/wrapper.ts +7 -2
- package/tsconfig.tsbuildinfo +1 -1
- /package/lib/{assert-node-version.d.ts → __tests__/spinner.test.d.ts} +0 -0
- /package/lib/{__mocks__/utils.d.ts → utils/__mocks__/miscellaneous.d.ts} +0 -0
- /package/lib/{assert-node-version.js → utils/assert-node-version.js} +0 -0
- /package/lib/{fetch-with-timeout.d.ts → utils/fetch-with-timeout.d.ts} +0 -0
- /package/lib/{js-utils.d.ts → utils/js-utils.d.ts} +0 -0
- /package/lib/{js-utils.js → utils/js-utils.js} +0 -0
- /package/lib/{update-version-notifier.d.ts → utils/update-version-notifier.d.ts} +0 -0
- /package/src/{assert-node-version.ts → utils/assert-node-version.ts} +0 -0
- /package/src/{js-utils.ts → utils/js-utils.ts} +0 -0
package/lib/commands/bundle.js
CHANGED
|
@@ -22,17 +22,17 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.handleBundle = void 0;
|
|
24
24
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
25
|
-
const
|
|
25
|
+
const miscellaneous_1 = require("../utils/miscellaneous");
|
|
26
26
|
const perf_hooks_1 = require("perf_hooks");
|
|
27
27
|
const colorette_1 = require("colorette");
|
|
28
28
|
const fs_1 = require("fs");
|
|
29
|
-
const
|
|
29
|
+
const miscellaneous_2 = require("../utils/miscellaneous");
|
|
30
30
|
function handleBundle(argv, config, version) {
|
|
31
31
|
var _a, _b, _c, _d, _e;
|
|
32
32
|
return __awaiter(this, void 0, void 0, function* () {
|
|
33
33
|
const removeUnusedComponents = argv['remove-unused-components'] ||
|
|
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
|
-
const apis = yield (0,
|
|
35
|
+
const apis = yield (0, miscellaneous_1.getFallbackApisOrExit)(argv.apis, config);
|
|
36
36
|
const totals = { errors: 0, warnings: 0, ignored: 0 };
|
|
37
37
|
const maxProblems = argv['max-problems'];
|
|
38
38
|
const deprecatedOptions = [
|
|
@@ -42,7 +42,7 @@ function handleBundle(argv, config, version) {
|
|
|
42
42
|
'extends',
|
|
43
43
|
'max-problems',
|
|
44
44
|
];
|
|
45
|
-
(0,
|
|
45
|
+
(0, miscellaneous_2.checkForDeprecatedOptions)(argv, deprecatedOptions);
|
|
46
46
|
for (const { path, alias } of apis) {
|
|
47
47
|
try {
|
|
48
48
|
const startedAt = perf_hooks_1.performance.now();
|
|
@@ -52,7 +52,7 @@ function handleBundle(argv, config, version) {
|
|
|
52
52
|
styleguide.skipPreprocessors(argv['skip-preprocessor']);
|
|
53
53
|
styleguide.skipDecorators(argv['skip-decorator']);
|
|
54
54
|
if (argv.lint) {
|
|
55
|
-
(0,
|
|
55
|
+
(0, miscellaneous_1.checkIfRulesetExist)(styleguide.rules);
|
|
56
56
|
if (config.styleguide.recommendedFallback) {
|
|
57
57
|
process.stderr.write(`No configurations were provided -- using built in ${(0, colorette_1.blue)('recommended')} configuration by default.\n\n`);
|
|
58
58
|
}
|
|
@@ -70,7 +70,7 @@ function handleBundle(argv, config, version) {
|
|
|
70
70
|
version,
|
|
71
71
|
maxProblems: maxProblems,
|
|
72
72
|
});
|
|
73
|
-
(0,
|
|
73
|
+
(0, miscellaneous_1.printLintTotals)(fileLintTotals, 2);
|
|
74
74
|
}
|
|
75
75
|
process.stderr.write((0, colorette_1.gray)(`bundling ${path}...\n`));
|
|
76
76
|
const _f = yield (0, openapi_core_1.bundle)({
|
|
@@ -81,15 +81,15 @@ function handleBundle(argv, config, version) {
|
|
|
81
81
|
keepUrlRefs: argv['keep-url-references'],
|
|
82
82
|
}), { bundle: result, problems } = _f, meta = __rest(_f, ["bundle", "problems"]);
|
|
83
83
|
const fileTotals = (0, openapi_core_1.getTotals)(problems);
|
|
84
|
-
const { outputFile, ext } = (0,
|
|
84
|
+
const { outputFile, ext } = (0, miscellaneous_1.getOutputFileName)(path, apis.length, argv.output, argv.ext);
|
|
85
85
|
if (fileTotals.errors === 0 || argv.force) {
|
|
86
86
|
if (!argv.output) {
|
|
87
|
-
const output = (0,
|
|
87
|
+
const output = (0, miscellaneous_1.dumpBundle)((0, miscellaneous_1.sortTopLevelKeysForOas)(result.parsed), argv.ext || 'yaml', argv.dereferenced);
|
|
88
88
|
process.stdout.write(output);
|
|
89
89
|
}
|
|
90
90
|
else {
|
|
91
|
-
const output = (0,
|
|
92
|
-
(0,
|
|
91
|
+
const output = (0, miscellaneous_1.dumpBundle)((0, miscellaneous_1.sortTopLevelKeysForOas)(result.parsed), ext, argv.dereferenced);
|
|
92
|
+
(0, miscellaneous_1.saveBundle)(outputFile, output);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
totals.errors += fileTotals.errors;
|
|
@@ -109,7 +109,7 @@ function handleBundle(argv, config, version) {
|
|
|
109
109
|
(0, fs_1.writeFileSync)(argv.metafile, JSON.stringify(meta), 'utf-8');
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
const elapsed = (0,
|
|
112
|
+
const elapsed = (0, miscellaneous_1.getExecutionTime)(startedAt);
|
|
113
113
|
if (fileTotals.errors > 0) {
|
|
114
114
|
if (argv.force) {
|
|
115
115
|
process.stderr.write(`❓ Created a bundle for ${(0, colorette_1.blue)(path)} at ${(0, colorette_1.blue)(outputFile)} with errors ${(0, colorette_1.green)(elapsed)}.\n${(0, colorette_1.yellow)('Errors ignored because of --force')}.\n`);
|
|
@@ -127,10 +127,10 @@ function handleBundle(argv, config, version) {
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
catch (e) {
|
|
130
|
-
(0,
|
|
130
|
+
(0, miscellaneous_1.handleError)(e, path);
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
|
-
(0,
|
|
133
|
+
(0, miscellaneous_1.printUnusedWarnings)(config.styleguide);
|
|
134
134
|
if (!(totals.errors === 0 || argv.force)) {
|
|
135
135
|
throw new Error('Bundle failed.');
|
|
136
136
|
}
|
package/lib/commands/join.js
CHANGED
|
@@ -15,8 +15,8 @@ const colorette_1 = require("colorette");
|
|
|
15
15
|
const perf_hooks_1 = require("perf_hooks");
|
|
16
16
|
const isEqual = require('lodash.isequal');
|
|
17
17
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
18
|
-
const
|
|
19
|
-
const js_utils_1 = require("../js-utils");
|
|
18
|
+
const miscellaneous_1 = require("../utils/miscellaneous");
|
|
19
|
+
const js_utils_1 = require("../utils/js-utils");
|
|
20
20
|
const types_1 = require("./split/types");
|
|
21
21
|
const COMPONENTS = 'components';
|
|
22
22
|
const Tags = 'tags';
|
|
@@ -26,10 +26,10 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
26
26
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27
27
|
const startedAt = perf_hooks_1.performance.now();
|
|
28
28
|
if (argv.apis.length < 2) {
|
|
29
|
-
return (0,
|
|
29
|
+
return (0, miscellaneous_1.exitWithError)(`At least 2 apis should be provided. \n\n`);
|
|
30
30
|
}
|
|
31
|
-
(0,
|
|
32
|
-
const fileExtension = (0,
|
|
31
|
+
(0, miscellaneous_1.checkForDeprecatedOptions)(argv, ['lint']);
|
|
32
|
+
const fileExtension = (0, miscellaneous_1.getAndValidateFileExtension)(argv.output || argv.apis[0]);
|
|
33
33
|
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
34
|
const usedTagsOptions = [
|
|
35
35
|
prefixTagsWithFilename && 'prefix-tags-with-filename',
|
|
@@ -37,9 +37,9 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
37
37
|
withoutXTagGroups && 'without-x-tag-groups',
|
|
38
38
|
].filter(Boolean);
|
|
39
39
|
if (usedTagsOptions.length > 1) {
|
|
40
|
-
return (0,
|
|
40
|
+
return (0, miscellaneous_1.exitWithError)(`You use ${(0, colorette_1.yellow)(usedTagsOptions.join(', '))} together.\nPlease choose only one! \n\n`);
|
|
41
41
|
}
|
|
42
|
-
const apis = yield (0,
|
|
42
|
+
const apis = yield (0, miscellaneous_1.getFallbackApisOrExit)(argv.apis, config);
|
|
43
43
|
const externalRefResolver = new openapi_core_1.BaseResolver(config.resolve);
|
|
44
44
|
const documents = yield Promise.all(apis.map(({ path }) => externalRefResolver.resolveDocument(null, path, true)));
|
|
45
45
|
if (!argv.decorate) {
|
|
@@ -63,7 +63,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
63
63
|
config: config.styleguide,
|
|
64
64
|
externalRefResolver: new openapi_core_1.BaseResolver(config.resolve),
|
|
65
65
|
}).catch((e) => {
|
|
66
|
-
(0,
|
|
66
|
+
(0, miscellaneous_1.exitWithError)(`${e.message}: ${(0, colorette_1.blue)(document.source.absoluteRef)}`);
|
|
67
67
|
})));
|
|
68
68
|
for (const { problems, bundle: document } of bundleResults) {
|
|
69
69
|
const fileTotals = (0, openapi_core_1.getTotals)(problems);
|
|
@@ -72,7 +72,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
72
72
|
totals: fileTotals,
|
|
73
73
|
version: document.parsed.version,
|
|
74
74
|
});
|
|
75
|
-
(0,
|
|
75
|
+
(0, miscellaneous_1.exitWithError)(`❌ Errors encountered while bundling ${(0, colorette_1.blue)(document.source.absoluteRef)}: join will not proceed.\n`);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
let oasVersion = null;
|
|
@@ -80,15 +80,15 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
80
80
|
try {
|
|
81
81
|
const version = (0, openapi_core_1.detectSpec)(document.parsed);
|
|
82
82
|
if (version !== openapi_core_1.SpecVersion.OAS3_0 && version !== openapi_core_1.SpecVersion.OAS3_1) {
|
|
83
|
-
return (0,
|
|
83
|
+
return (0, miscellaneous_1.exitWithError)(`Only OpenAPI 3.0 and OpenAPI 3.1 are supported: ${(0, colorette_1.blue)(document.source.absoluteRef)} \n\n`);
|
|
84
84
|
}
|
|
85
85
|
oasVersion = oasVersion !== null && oasVersion !== void 0 ? oasVersion : version;
|
|
86
86
|
if (oasVersion !== version) {
|
|
87
|
-
return (0,
|
|
87
|
+
return (0, miscellaneous_1.exitWithError)(`All APIs must use the same OpenAPI version: ${(0, colorette_1.blue)(document.source.absoluteRef)} \n\n`);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
catch (e) {
|
|
91
|
-
return (0,
|
|
91
|
+
return (0, miscellaneous_1.exitWithError)(`${e.message}: ${(0, colorette_1.blue)(document.source.absoluteRef)}`);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
if (argv.lint) {
|
|
@@ -140,10 +140,10 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
140
140
|
iteratePotentialConflicts(potentialConflicts, withoutXTagGroups);
|
|
141
141
|
const noRefs = true;
|
|
142
142
|
if (potentialConflictsTotal) {
|
|
143
|
-
return (0,
|
|
143
|
+
return (0, miscellaneous_1.exitWithError)(`Please fix conflicts before running ${(0, colorette_1.yellow)('join')}.`);
|
|
144
144
|
}
|
|
145
|
-
(0,
|
|
146
|
-
(0,
|
|
145
|
+
(0, miscellaneous_1.writeToFileByExtension)((0, miscellaneous_1.sortTopLevelKeysForOas)(joinedDef), specFilename, noRefs);
|
|
146
|
+
(0, miscellaneous_1.printExecutionTime)('join', startedAt, specFilename);
|
|
147
147
|
function populateTags({ api, apiFilename, tags, potentialConflicts, tagsPrefix, componentsPrefix, }) {
|
|
148
148
|
if (!joinedDef.hasOwnProperty(Tags)) {
|
|
149
149
|
joinedDef[Tags] = [];
|
|
@@ -297,7 +297,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
297
297
|
for (const pathServer of joinedDef.paths[path].servers) {
|
|
298
298
|
if (pathServer.url === server.url) {
|
|
299
299
|
if (!isServersEqual(pathServer, server)) {
|
|
300
|
-
(0,
|
|
300
|
+
(0, miscellaneous_1.exitWithError)(`Different server values for (${server.url}) in ${path}`);
|
|
301
301
|
}
|
|
302
302
|
isFoundServer = true;
|
|
303
303
|
}
|
|
@@ -328,7 +328,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
328
328
|
if (!(0, openapi_core_1.isRef)(pathParameter) && !(0, openapi_core_1.isRef)(parameter)) {
|
|
329
329
|
if (pathParameter.name === parameter.name && pathParameter.in === parameter.in) {
|
|
330
330
|
if (!isEqual(pathParameter.schema, parameter.schema)) {
|
|
331
|
-
(0,
|
|
331
|
+
(0, miscellaneous_1.exitWithError)(`Different parameter schemas for (${parameter.name}) in ${path}`);
|
|
332
332
|
}
|
|
333
333
|
isFoundParameter = true;
|
|
334
334
|
}
|
|
@@ -459,9 +459,9 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
459
459
|
const openapi = firstApi.parsed;
|
|
460
460
|
const componentsPrefix = getInfoPrefix(openapi.info, prefixComponentsWithInfoProp, COMPONENTS);
|
|
461
461
|
if (!openapi.openapi)
|
|
462
|
-
(0,
|
|
462
|
+
(0, miscellaneous_1.exitWithError)('Version of specification is not found in. \n');
|
|
463
463
|
if (!openapi.info)
|
|
464
|
-
(0,
|
|
464
|
+
(0, miscellaneous_1.exitWithError)('Info section is not found in specification. \n');
|
|
465
465
|
if ((_a = openapi.info) === null || _a === void 0 ? void 0 : _a.description) {
|
|
466
466
|
openapi.info.description = addComponentsPrefix(openapi.info.description, componentsPrefix);
|
|
467
467
|
}
|
|
@@ -557,13 +557,13 @@ function getInfoPrefix(info, prefixArg, type) {
|
|
|
557
557
|
if (!prefixArg)
|
|
558
558
|
return '';
|
|
559
559
|
if (!info)
|
|
560
|
-
(0,
|
|
560
|
+
(0, miscellaneous_1.exitWithError)('Info section is not found in specification. \n');
|
|
561
561
|
if (!info[prefixArg])
|
|
562
|
-
(0,
|
|
562
|
+
(0, miscellaneous_1.exitWithError)(`${(0, colorette_1.yellow)(`prefix-${type}-with-info-prop`)} argument value is not found in info section. \n`);
|
|
563
563
|
if (!(0, js_utils_1.isString)(info[prefixArg]))
|
|
564
|
-
(0,
|
|
564
|
+
(0, miscellaneous_1.exitWithError)(`${(0, colorette_1.yellow)(`prefix-${type}-with-info-prop`)} argument value should be string. \n\n`);
|
|
565
565
|
if (info[prefixArg].length > 50)
|
|
566
|
-
(0,
|
|
566
|
+
(0, miscellaneous_1.exitWithError)(`${(0, colorette_1.yellow)(`prefix-${type}-with-info-prop`)} argument value length should not exceed 50 characters. \n\n`);
|
|
567
567
|
return info[prefixArg];
|
|
568
568
|
}
|
|
569
569
|
function validateApi(document, config, externalRefResolver, packageVersion) {
|
|
@@ -572,10 +572,10 @@ function validateApi(document, config, externalRefResolver, packageVersion) {
|
|
|
572
572
|
const results = yield (0, openapi_core_1.lintDocument)({ document, config, externalRefResolver });
|
|
573
573
|
const fileTotals = (0, openapi_core_1.getTotals)(results);
|
|
574
574
|
(0, openapi_core_1.formatProblems)(results, { format: 'stylish', totals: fileTotals, version: packageVersion });
|
|
575
|
-
(0,
|
|
575
|
+
(0, miscellaneous_1.printLintTotals)(fileTotals, 2);
|
|
576
576
|
}
|
|
577
577
|
catch (err) {
|
|
578
|
-
(0,
|
|
578
|
+
(0, miscellaneous_1.handleError)(err, document.parsed);
|
|
579
579
|
}
|
|
580
580
|
});
|
|
581
581
|
}
|
package/lib/commands/lint.js
CHANGED
|
@@ -12,14 +12,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.lintConfigCallback = exports.handleLint = void 0;
|
|
13
13
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
14
14
|
const config_1 = require("@redocly/openapi-core/lib/config");
|
|
15
|
-
const
|
|
15
|
+
const miscellaneous_1 = require("../utils/miscellaneous");
|
|
16
16
|
const colorette_1 = require("colorette");
|
|
17
17
|
const perf_hooks_1 = require("perf_hooks");
|
|
18
18
|
function handleLint(argv, config, version) {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
-
const apis = yield (0,
|
|
20
|
+
const apis = yield (0, miscellaneous_1.getFallbackApisOrExit)(argv.apis, config);
|
|
21
21
|
if (!apis.length) {
|
|
22
|
-
(0,
|
|
22
|
+
(0, miscellaneous_1.exitWithError)('No APIs were provided');
|
|
23
23
|
}
|
|
24
24
|
if (argv['generate-ignore-file']) {
|
|
25
25
|
config.styleguide.ignore = {}; // clear ignore
|
|
@@ -32,7 +32,7 @@ function handleLint(argv, config, version) {
|
|
|
32
32
|
const startedAt = perf_hooks_1.performance.now();
|
|
33
33
|
const resolvedConfig = (0, openapi_core_1.getMergedConfig)(config, alias);
|
|
34
34
|
const { styleguide } = resolvedConfig;
|
|
35
|
-
(0,
|
|
35
|
+
(0, miscellaneous_1.checkIfRulesetExist)(styleguide.rules);
|
|
36
36
|
styleguide.skipRules(argv['skip-rule']);
|
|
37
37
|
styleguide.skipPreprocessors(argv['skip-preprocessor']);
|
|
38
38
|
if (styleguide.recommendedFallback) {
|
|
@@ -61,21 +61,21 @@ function handleLint(argv, config, version) {
|
|
|
61
61
|
version,
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
|
-
const elapsed = (0,
|
|
64
|
+
const elapsed = (0, miscellaneous_1.getExecutionTime)(startedAt);
|
|
65
65
|
process.stderr.write((0, colorette_1.gray)(`${path.replace(process.cwd(), '')}: validated in ${elapsed}\n\n`));
|
|
66
66
|
}
|
|
67
67
|
catch (e) {
|
|
68
|
-
(0,
|
|
68
|
+
(0, miscellaneous_1.handleError)(e, path);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
if (argv['generate-ignore-file']) {
|
|
72
72
|
config.styleguide.saveIgnore();
|
|
73
|
-
process.stderr.write(`Generated ignore file with ${totalIgnored} ${(0,
|
|
73
|
+
process.stderr.write(`Generated ignore file with ${totalIgnored} ${(0, miscellaneous_1.pluralize)('problem', totalIgnored)}.\n\n`);
|
|
74
74
|
}
|
|
75
75
|
else {
|
|
76
|
-
(0,
|
|
76
|
+
(0, miscellaneous_1.printLintTotals)(totals, apis.length);
|
|
77
77
|
}
|
|
78
|
-
(0,
|
|
78
|
+
(0, miscellaneous_1.printUnusedWarnings)(config.styleguide);
|
|
79
79
|
if (!(totals.errors === 0 || argv['generate-ignore-file'])) {
|
|
80
80
|
throw new Error('Lint failed.');
|
|
81
81
|
}
|
|
@@ -103,7 +103,7 @@ function lintConfigCallback(argv, version) {
|
|
|
103
103
|
totals: fileTotals,
|
|
104
104
|
version,
|
|
105
105
|
});
|
|
106
|
-
(0,
|
|
106
|
+
(0, miscellaneous_1.printConfigLintTotals)(fileTotals);
|
|
107
107
|
if (fileTotals.errors > 0) {
|
|
108
108
|
throw new config_1.ConfigValidationError();
|
|
109
109
|
}
|
package/lib/commands/login.js
CHANGED
|
@@ -12,9 +12,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.handleLogin = exports.promptClientToken = void 0;
|
|
13
13
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
14
14
|
const colorette_1 = require("colorette");
|
|
15
|
-
const
|
|
15
|
+
const miscellaneous_1 = require("../utils/miscellaneous");
|
|
16
16
|
function promptClientToken(domain) {
|
|
17
|
-
return (0,
|
|
17
|
+
return (0, miscellaneous_1.promptUser)((0, colorette_1.green)(`\n 🔑 Copy your API key from ${(0, colorette_1.blue)(`https://app.${domain}/profile`)} and paste it below`), true);
|
|
18
18
|
}
|
|
19
19
|
exports.promptClientToken = promptClientToken;
|
|
20
20
|
function handleLogin(argv, config) {
|
|
@@ -13,14 +13,14 @@ exports.debounce = exports.previewDocs = void 0;
|
|
|
13
13
|
const colorette = require("colorette");
|
|
14
14
|
const chockidar = require("chokidar");
|
|
15
15
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
16
|
-
const
|
|
16
|
+
const miscellaneous_1 = require("../../utils/miscellaneous");
|
|
17
17
|
const preview_server_1 = require("./preview-server/preview-server");
|
|
18
18
|
function previewDocs(argv, configFromFile) {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
20
|
let isAuthorizedWithRedocly = false;
|
|
21
21
|
let redocOptions = {};
|
|
22
22
|
let config = yield reloadConfig(configFromFile);
|
|
23
|
-
const apis = yield (0,
|
|
23
|
+
const apis = yield (0, miscellaneous_1.getFallbackApisOrExit)(argv.api ? [argv.api] : [], config);
|
|
24
24
|
const api = apis[0];
|
|
25
25
|
let cachedBundle;
|
|
26
26
|
const deps = new Set();
|
|
@@ -51,7 +51,7 @@ function previewDocs(argv, configFromFile) {
|
|
|
51
51
|
return openapiBundle.parsed;
|
|
52
52
|
}
|
|
53
53
|
catch (e) {
|
|
54
|
-
(0,
|
|
54
|
+
(0, miscellaneous_1.handleError)(e, api.path);
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
57
|
}
|
|
@@ -97,7 +97,7 @@ function previewDocs(argv, configFromFile) {
|
|
|
97
97
|
return __awaiter(this, void 0, void 0, function* () {
|
|
98
98
|
if (!config) {
|
|
99
99
|
try {
|
|
100
|
-
config = (yield (0,
|
|
100
|
+
config = (yield (0, miscellaneous_1.loadConfigAndHandleErrors)({ configPath: argv.config }));
|
|
101
101
|
}
|
|
102
102
|
catch (err) {
|
|
103
103
|
config = new openapi_core_1.Config({ apis: {}, styleguide: {} });
|
|
@@ -15,7 +15,7 @@ const get_port_please_1 = require("get-port-please");
|
|
|
15
15
|
const fs_1 = require("fs");
|
|
16
16
|
const path = require("path");
|
|
17
17
|
const server_1 = require("./server");
|
|
18
|
-
const
|
|
18
|
+
const miscellaneous_1 = require("../../../utils/miscellaneous");
|
|
19
19
|
function getPageHTML(htmlTemplate, redocOptions = {}, useRedocPro, wsPort, host) {
|
|
20
20
|
let templateSrc = (0, fs_1.readFileSync)(htmlTemplate, 'utf-8');
|
|
21
21
|
// fix template for backward compatibility
|
|
@@ -90,7 +90,7 @@ function startPreviewServer(port, host, { getBundle, getOptions, useRedocPro, })
|
|
|
90
90
|
if (!filePath) {
|
|
91
91
|
const basePath = htmlTemplate ? path.dirname(htmlTemplate) : process.cwd();
|
|
92
92
|
filePath = path.resolve(basePath, `.${request.url}`);
|
|
93
|
-
if (!(0,
|
|
93
|
+
if (!(0, miscellaneous_1.isSubdir)(basePath, filePath)) {
|
|
94
94
|
(0, server_1.respondWithGzip)('404 Not Found', request, response, { 'Content-Type': 'text/html' }, 404);
|
|
95
95
|
console.timeEnd(colorette.dim(`GET ${request.url}`));
|
|
96
96
|
return;
|
package/lib/commands/push.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Config, Region } from '@redocly/openapi-core';
|
|
2
|
+
import { handlePush as handleCMSPush } from '../cms/commands/push';
|
|
2
3
|
export declare const DESTINATION_REGEX: RegExp;
|
|
3
4
|
export type PushOptions = {
|
|
4
5
|
api?: string;
|
|
@@ -14,6 +15,10 @@ export type PushOptions = {
|
|
|
14
15
|
organization?: string;
|
|
15
16
|
config?: string;
|
|
16
17
|
};
|
|
18
|
+
export declare function commonPushHandler({ project, 'mount-path': mountPath, }: {
|
|
19
|
+
project?: string;
|
|
20
|
+
'mount-path'?: string;
|
|
21
|
+
}): typeof handleCMSPush | typeof handlePush;
|
|
17
22
|
export declare function handlePush(argv: PushOptions, config: Config): Promise<void>;
|
|
18
23
|
export declare function getDestinationProps(destination: string | undefined, organization: string | undefined): {
|
|
19
24
|
organizationId: string | undefined;
|
package/lib/commands/push.js
CHANGED
|
@@ -20,7 +20,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
20
20
|
return t;
|
|
21
21
|
};
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.getApiRoot = exports.transformPush = exports.getDestinationProps = exports.handlePush = exports.DESTINATION_REGEX = void 0;
|
|
23
|
+
exports.getApiRoot = exports.transformPush = exports.getDestinationProps = exports.handlePush = exports.commonPushHandler = exports.DESTINATION_REGEX = void 0;
|
|
24
24
|
const fs = require("fs");
|
|
25
25
|
const path = require("path");
|
|
26
26
|
const node_fetch_1 = require("node-fetch");
|
|
@@ -28,10 +28,18 @@ const perf_hooks_1 = require("perf_hooks");
|
|
|
28
28
|
const colorette_1 = require("colorette");
|
|
29
29
|
const crypto_1 = require("crypto");
|
|
30
30
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
31
|
-
const
|
|
31
|
+
const miscellaneous_1 = require("../utils/miscellaneous");
|
|
32
32
|
const login_1 = require("./login");
|
|
33
|
+
const push_1 = require("../cms/commands/push");
|
|
33
34
|
const DEFAULT_VERSION = 'latest';
|
|
34
35
|
exports.DESTINATION_REGEX = /^(@(?<organizationId>[\w\-\s]+)\/)?(?<name>[^@]*)@(?<version>[\w\.\-]+)$/;
|
|
36
|
+
function commonPushHandler({ project, 'mount-path': mountPath, }) {
|
|
37
|
+
if (project && mountPath) {
|
|
38
|
+
return push_1.handlePush;
|
|
39
|
+
}
|
|
40
|
+
return handlePush;
|
|
41
|
+
}
|
|
42
|
+
exports.commonPushHandler = commonPushHandler;
|
|
35
43
|
function handlePush(argv, config) {
|
|
36
44
|
return __awaiter(this, void 0, void 0, function* () {
|
|
37
45
|
const client = new openapi_core_1.RedoclyClient(config.region);
|
|
@@ -45,31 +53,31 @@ function handlePush(argv, config) {
|
|
|
45
53
|
const jobId = argv['job-id'];
|
|
46
54
|
const batchSize = argv['batch-size'];
|
|
47
55
|
if (destination && !exports.DESTINATION_REGEX.test(destination)) {
|
|
48
|
-
(0,
|
|
56
|
+
(0, miscellaneous_1.exitWithError)(`Destination argument value is not valid, please use the right format: ${(0, colorette_1.yellow)('<api-name@api-version>')}`);
|
|
49
57
|
}
|
|
50
58
|
const destinationProps = getDestinationProps(destination, config.organization);
|
|
51
59
|
const organizationId = argv.organization || destinationProps.organizationId;
|
|
52
60
|
const { name, version } = destinationProps;
|
|
53
61
|
if (!organizationId) {
|
|
54
|
-
return (0,
|
|
62
|
+
return (0, miscellaneous_1.exitWithError)(`No organization provided, please use --organization option or specify the 'organization' field in the config file.`);
|
|
55
63
|
}
|
|
56
64
|
const api = argv.api || (name && version && getApiRoot({ name, version, config }));
|
|
57
65
|
if (name && version && !api) {
|
|
58
|
-
(0,
|
|
66
|
+
(0, miscellaneous_1.exitWithError)(`No api found that matches ${(0, colorette_1.blue)(`${name}@${version}`)}. Please make sure you have provided the correct data in the config file.`);
|
|
59
67
|
}
|
|
60
68
|
// Ensure that a destination for the api is provided.
|
|
61
69
|
if (!name && api) {
|
|
62
|
-
return (0,
|
|
70
|
+
return (0, miscellaneous_1.exitWithError)(`No destination provided, please use --destination option to provide destination.`);
|
|
63
71
|
}
|
|
64
72
|
if (jobId && !jobId.trim()) {
|
|
65
|
-
(0,
|
|
73
|
+
(0, miscellaneous_1.exitWithError)(`The ${(0, colorette_1.blue)(`job-id`)} option value is not valid, please avoid using an empty string.`);
|
|
66
74
|
}
|
|
67
75
|
if (batchSize && batchSize < 2) {
|
|
68
|
-
(0,
|
|
76
|
+
(0, miscellaneous_1.exitWithError)(`The ${(0, colorette_1.blue)(`batch-size`)} option value is not valid, please use the integer bigger than 1.`);
|
|
69
77
|
}
|
|
70
78
|
const apis = api ? { [`${name}@${version}`]: { root: api } } : config.apis;
|
|
71
79
|
if (!Object.keys(apis).length) {
|
|
72
|
-
(0,
|
|
80
|
+
(0, miscellaneous_1.exitWithError)(`Api not found. Please make sure you have provided the correct data in the config file.`);
|
|
73
81
|
}
|
|
74
82
|
for (const [apiNameAndVersion, { root: api }] of Object.entries(apis)) {
|
|
75
83
|
const resolvedConfig = (0, openapi_core_1.getMergedConfig)(config, apiNameAndVersion);
|
|
@@ -81,7 +89,7 @@ function handlePush(argv, config) {
|
|
|
81
89
|
const filePaths = [];
|
|
82
90
|
const filesToUpload = yield collectFilesToUpload(api, resolvedConfig);
|
|
83
91
|
const filesHash = hashFiles(filesToUpload.files);
|
|
84
|
-
process.stdout.write(`Uploading ${filesToUpload.files.length} ${(0,
|
|
92
|
+
process.stdout.write(`Uploading ${filesToUpload.files.length} ${(0, miscellaneous_1.pluralize)('file', filesToUpload.files.length)}:\n`);
|
|
85
93
|
let uploaded = 0;
|
|
86
94
|
for (const file of filesToUpload.files) {
|
|
87
95
|
const { signedUploadUrl, filePath } = yield client.registryApi.prepareFileUpload({
|
|
@@ -100,7 +108,7 @@ function handlePush(argv, config) {
|
|
|
100
108
|
const uploadResponse = yield uploadFileToS3(signedUploadUrl, file.contents || file.filePath);
|
|
101
109
|
const fileCounter = `(${++uploaded}/${filesToUpload.files.length})`;
|
|
102
110
|
if (!uploadResponse.ok) {
|
|
103
|
-
(0,
|
|
111
|
+
(0, miscellaneous_1.exitWithError)(`✗ ${fileCounter}\nFile upload failed\n`);
|
|
104
112
|
}
|
|
105
113
|
process.stdout.write((0, colorette_1.green)(`✓ ${fileCounter}\n`));
|
|
106
114
|
}
|
|
@@ -120,16 +128,16 @@ function handlePush(argv, config) {
|
|
|
120
128
|
}
|
|
121
129
|
catch (error) {
|
|
122
130
|
if (error.message === 'ORGANIZATION_NOT_FOUND') {
|
|
123
|
-
(0,
|
|
131
|
+
(0, miscellaneous_1.exitWithError)(`Organization ${(0, colorette_1.blue)(organizationId)} not found`);
|
|
124
132
|
}
|
|
125
133
|
if (error.message === 'API_VERSION_NOT_FOUND') {
|
|
126
|
-
(0,
|
|
134
|
+
(0, miscellaneous_1.exitWithError)(`The definition version ${(0, colorette_1.blue)(`${name}@${version}`)} does not exist in organization ${(0, colorette_1.blue)(organizationId)}!\n${(0, colorette_1.yellow)('Suggestion:')} please use ${(0, colorette_1.blue)('-u')} or ${(0, colorette_1.blue)('--upsert')} to create definition.\n\n`);
|
|
127
135
|
}
|
|
128
136
|
throw error;
|
|
129
137
|
}
|
|
130
138
|
process.stdout.write(`Definition: ${(0, colorette_1.blue)(api)} is successfully pushed to Redocly API Registry \n`);
|
|
131
139
|
}
|
|
132
|
-
(0,
|
|
140
|
+
(0, miscellaneous_1.printExecutionTime)('push', startedAt, api || `apis in organization ${organizationId}`);
|
|
133
141
|
});
|
|
134
142
|
}
|
|
135
143
|
exports.handlePush = handlePush;
|
|
@@ -151,7 +159,7 @@ function collectFilesToUpload(api, config) {
|
|
|
151
159
|
var _a, _b;
|
|
152
160
|
return __awaiter(this, void 0, void 0, function* () {
|
|
153
161
|
const files = [];
|
|
154
|
-
const [{ path: apiPath }] = yield (0,
|
|
162
|
+
const [{ path: apiPath }] = yield (0, miscellaneous_1.getFallbackApisOrExit)([api], config);
|
|
155
163
|
process.stdout.write('Bundling definition\n');
|
|
156
164
|
const { bundle: openapiBundle, problems } = yield (0, openapi_core_1.bundle)({
|
|
157
165
|
config,
|
|
@@ -163,10 +171,10 @@ function collectFilesToUpload(api, config) {
|
|
|
163
171
|
process.stdout.write(`Created a bundle for ${(0, colorette_1.blue)(api)} ${fileTotals.warnings > 0 ? 'with warnings' : ''}\n`);
|
|
164
172
|
}
|
|
165
173
|
else {
|
|
166
|
-
(0,
|
|
174
|
+
(0, miscellaneous_1.exitWithError)(`Failed to create a bundle for ${(0, colorette_1.blue)(api)}\n`);
|
|
167
175
|
}
|
|
168
176
|
const fileExt = path.extname(apiPath).split('.').pop();
|
|
169
|
-
files.push(getFileEntry(apiPath, (0,
|
|
177
|
+
files.push(getFileEntry(apiPath, (0, miscellaneous_1.dumpBundle)(openapiBundle.parsed, fileExt)));
|
|
170
178
|
if (fs.existsSync('package.json')) {
|
|
171
179
|
files.push(getFileEntry('package.json'));
|
|
172
180
|
}
|
|
@@ -13,8 +13,8 @@ const index_1 = require("../index");
|
|
|
13
13
|
const path = require("path");
|
|
14
14
|
const openapiCore = require("@redocly/openapi-core");
|
|
15
15
|
const colorette_1 = require("colorette");
|
|
16
|
-
const utils = require('../../../utils');
|
|
17
|
-
jest.mock('../../../utils', () => (Object.assign(Object.assign({}, jest.requireActual('../../../utils')), { writeToFileByExtension: jest.fn() })));
|
|
16
|
+
const utils = require('../../../utils/miscellaneous');
|
|
17
|
+
jest.mock('../../../utils/miscellaneous', () => (Object.assign(Object.assign({}, jest.requireActual('../../../utils/miscellaneous')), { writeToFileByExtension: jest.fn() })));
|
|
18
18
|
jest.mock('@redocly/openapi-core', () => (Object.assign(Object.assign({}, jest.requireActual('@redocly/openapi-core')), { isRef: jest.fn() })));
|
|
19
19
|
describe('#split', () => {
|
|
20
20
|
const openapiDir = 'test';
|