@redocly/cli 1.0.0-beta.103 → 1.0.0-beta.106
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/bin/cli.js +1 -1
- package/lib/__mocks__/@redocly/openapi-core.d.ts +2 -1
- package/lib/__mocks__/@redocly/openapi-core.js +2 -1
- package/lib/__mocks__/perf_hooks.js +1 -1
- package/lib/__mocks__/utils.d.ts +1 -1
- package/lib/__mocks__/utils.js +2 -2
- package/lib/__tests__/commands/bundle.test.js +52 -17
- package/lib/__tests__/commands/join.test.js +4 -4
- package/lib/__tests__/commands/lint.test.js +14 -8
- package/lib/__tests__/commands/push-region.test.js +2 -2
- package/lib/__tests__/commands/push.test.js +18 -18
- package/lib/__tests__/fixtures/config.d.ts +1 -1
- package/lib/__tests__/fixtures/config.js +1 -1
- package/lib/commands/bundle.d.ts +4 -12
- package/lib/commands/bundle.js +12 -11
- package/lib/commands/join.d.ts +1 -1
- package/lib/commands/join.js +109 -58
- package/lib/commands/lint.d.ts +3 -9
- package/lib/commands/lint.js +14 -11
- package/lib/commands/preview-docs/index.d.ts +3 -5
- package/lib/commands/preview-docs/index.js +14 -14
- package/lib/commands/push.d.ts +6 -6
- package/lib/commands/push.js +26 -26
- package/lib/commands/split/__tests__/index.test.js +8 -8
- package/lib/commands/split/index.d.ts +1 -1
- package/lib/commands/split/index.js +12 -11
- package/lib/commands/split/types.d.ts +2 -2
- package/lib/commands/split/types.js +2 -2
- package/lib/commands/stats.d.ts +1 -1
- package/lib/commands/stats.js +9 -7
- package/lib/index.js +12 -16
- package/lib/js-utils.js +2 -2
- package/lib/types.d.ts +13 -1
- package/lib/utils.d.ts +4 -4
- package/lib/utils.js +15 -17
- package/package.json +2 -2
- package/src/__mocks__/@redocly/openapi-core.ts +1 -0
- package/src/__mocks__/perf_hooks.ts +2 -2
- package/src/__mocks__/utils.ts +3 -1
- package/src/__tests__/commands/bundle.test.ts +71 -22
- package/src/__tests__/commands/join.test.ts +8 -8
- package/src/__tests__/commands/lint.test.ts +24 -11
- package/src/__tests__/commands/push-region.test.ts +2 -2
- package/src/__tests__/commands/push.test.ts +19 -24
- package/src/__tests__/fixtures/config.ts +1 -1
- package/src/__tests__/utils.test.ts +5 -8
- package/src/commands/bundle.ts +28 -40
- package/src/commands/join.ts +213 -121
- package/src/commands/lint.ts +30 -30
- package/src/commands/login.ts +2 -2
- package/src/commands/preview-docs/index.ts +33 -40
- package/src/commands/preview-docs/preview-server/preview-server.ts +6 -6
- package/src/commands/preview-docs/preview-server/server.ts +1 -1
- package/src/commands/push.ts +44 -53
- package/src/commands/split/__tests__/index.test.ts +47 -30
- package/src/commands/split/index.ts +84 -46
- package/src/commands/split/types.ts +19 -7
- package/src/commands/stats.ts +27 -24
- package/src/index.ts +16 -20
- package/src/js-utils.ts +2 -2
- package/src/types.ts +14 -1
- package/src/utils.ts +53 -53
- package/tsconfig.tsbuildinfo +1 -1
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.
|
|
23
|
+
exports.getApiRoot = exports.transformPush = exports.getDestinationProps = exports.handlePush = void 0;
|
|
24
24
|
const fs = require("fs");
|
|
25
25
|
const path = require("path");
|
|
26
26
|
const node_fetch_1 = require("node-fetch");
|
|
@@ -53,9 +53,9 @@ function handlePush(argv) {
|
|
|
53
53
|
if (!organizationId) {
|
|
54
54
|
return utils_1.exitWithError(`No organization provided, please use the right format: ${colorette_1.yellow('<@organization-id/api-name@api-version>')} or specify the 'organization' field in the config file.`);
|
|
55
55
|
}
|
|
56
|
-
const
|
|
57
|
-
if (name && version && !
|
|
58
|
-
utils_1.exitWithError(`No
|
|
56
|
+
const api = argv.api || (name && version && getApiRoot({ name, version, config }));
|
|
57
|
+
if (name && version && !api) {
|
|
58
|
+
utils_1.exitWithError(`No api found that matches ${colorette_1.blue(`${name}@${version}`)}. Please make sure you have provided the correct data in the config file.`);
|
|
59
59
|
}
|
|
60
60
|
if (batchId && !batchId.trim()) {
|
|
61
61
|
utils_1.exitWithError(`The ${colorette_1.blue(`batch-id`)} option value is not valid, please avoid using an empty string.`);
|
|
@@ -63,15 +63,15 @@ function handlePush(argv) {
|
|
|
63
63
|
if (batchSize && batchSize < 2) {
|
|
64
64
|
utils_1.exitWithError(`The ${colorette_1.blue(`batch-size`)} option value is not valid, please use the integer bigger than 1.`);
|
|
65
65
|
}
|
|
66
|
-
const apis =
|
|
67
|
-
for (const [apiNameAndVersion, { root:
|
|
66
|
+
const apis = api ? { [`${name}@${version}`]: { root: api } } : config.apis;
|
|
67
|
+
for (const [apiNameAndVersion, { root: api }] of Object.entries(apis)) {
|
|
68
68
|
const resolvedConfig = openapi_core_1.getMergedConfig(config, apiNameAndVersion);
|
|
69
|
-
resolvedConfig.
|
|
69
|
+
resolvedConfig.styleguide.skipDecorators(argv['skip-decorator']);
|
|
70
70
|
const [name, version = DEFAULT_VERSION] = apiNameAndVersion.split('@');
|
|
71
71
|
try {
|
|
72
72
|
let rootFilePath = '';
|
|
73
73
|
const filePaths = [];
|
|
74
|
-
const filesToUpload = yield collectFilesToUpload(
|
|
74
|
+
const filesToUpload = yield collectFilesToUpload(api, resolvedConfig);
|
|
75
75
|
const filesHash = hashFiles(filesToUpload.files);
|
|
76
76
|
process.stdout.write(`Uploading ${filesToUpload.files.length} ${utils_1.pluralize('file', filesToUpload.files.length)}:\n`);
|
|
77
77
|
let uploaded = 0;
|
|
@@ -120,9 +120,9 @@ function handlePush(argv) {
|
|
|
120
120
|
}
|
|
121
121
|
throw error;
|
|
122
122
|
}
|
|
123
|
-
process.stdout.write(`Definition: ${colorette_1.blue(
|
|
123
|
+
process.stdout.write(`Definition: ${colorette_1.blue(api)} is successfully pushed to Redocly API Registry \n`);
|
|
124
124
|
}
|
|
125
|
-
utils_1.printExecutionTime('push', startedAt,
|
|
125
|
+
utils_1.printExecutionTime('push', startedAt, api || `apis in organization ${organizationId}`);
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
128
|
exports.handlePush = handlePush;
|
|
@@ -140,25 +140,25 @@ function getFilesList(dir, files) {
|
|
|
140
140
|
}
|
|
141
141
|
return files;
|
|
142
142
|
}
|
|
143
|
-
function collectFilesToUpload(
|
|
143
|
+
function collectFilesToUpload(api, config) {
|
|
144
144
|
return __awaiter(this, void 0, void 0, function* () {
|
|
145
145
|
let files = [];
|
|
146
|
-
const [{ path:
|
|
146
|
+
const [{ path: apiPath }] = yield utils_1.getFallbackApisOrExit([api], config);
|
|
147
147
|
process.stdout.write('Bundling definition\n');
|
|
148
148
|
const { bundle: openapiBundle, problems } = yield openapi_core_1.bundle({
|
|
149
149
|
config,
|
|
150
|
-
ref:
|
|
150
|
+
ref: apiPath,
|
|
151
151
|
skipRedoclyRegistryRefs: true,
|
|
152
152
|
});
|
|
153
153
|
const fileTotals = openapi_core_1.getTotals(problems);
|
|
154
154
|
if (fileTotals.errors === 0) {
|
|
155
|
-
process.stdout.write(`Created a bundle for ${colorette_1.blue(
|
|
155
|
+
process.stdout.write(`Created a bundle for ${colorette_1.blue(api)} ${fileTotals.warnings > 0 ? 'with warnings' : ''}\n`);
|
|
156
156
|
}
|
|
157
157
|
else {
|
|
158
|
-
utils_1.exitWithError(`Failed to create a bundle for ${colorette_1.blue(
|
|
158
|
+
utils_1.exitWithError(`Failed to create a bundle for ${colorette_1.blue(api)}\n`);
|
|
159
159
|
}
|
|
160
|
-
const fileExt = path.extname(
|
|
161
|
-
files.push(getFileEntry(
|
|
160
|
+
const fileExt = path.extname(apiPath).split('.').pop();
|
|
161
|
+
files.push(getFileEntry(apiPath, utils_1.dumpBundle(openapiBundle.parsed, fileExt)));
|
|
162
162
|
if (fs.existsSync('package.json')) {
|
|
163
163
|
files.push(getFileEntry('package.json'));
|
|
164
164
|
}
|
|
@@ -167,14 +167,14 @@ function collectFilesToUpload(entrypoint, config) {
|
|
|
167
167
|
}
|
|
168
168
|
if (config.configFile) {
|
|
169
169
|
// All config file paths including the root one
|
|
170
|
-
files.push(...[...new Set(config.
|
|
170
|
+
files.push(...[...new Set(config.styleguide.extendPaths)].map((f) => getFileEntry(f)));
|
|
171
171
|
if (config['features.openapi'].htmlTemplate) {
|
|
172
172
|
const dir = getFolder(config['features.openapi'].htmlTemplate);
|
|
173
173
|
const fileList = getFilesList(dir, []);
|
|
174
174
|
files.push(...fileList.map((f) => getFileEntry(f)));
|
|
175
175
|
}
|
|
176
176
|
let pluginFiles = new Set();
|
|
177
|
-
for (const plugin of config.
|
|
177
|
+
for (const plugin of config.styleguide.pluginPaths) {
|
|
178
178
|
if (typeof plugin !== 'string')
|
|
179
179
|
continue;
|
|
180
180
|
const fileList = getFilesList(getFolder(plugin), []);
|
|
@@ -184,7 +184,7 @@ function collectFilesToUpload(entrypoint, config) {
|
|
|
184
184
|
}
|
|
185
185
|
return {
|
|
186
186
|
files,
|
|
187
|
-
root: path.resolve(
|
|
187
|
+
root: path.resolve(apiPath),
|
|
188
188
|
};
|
|
189
189
|
function filterPluginFilesByExt(files) {
|
|
190
190
|
return files.filter((file) => {
|
|
@@ -228,21 +228,21 @@ function getDestinationProps(destination, organization) {
|
|
|
228
228
|
}
|
|
229
229
|
exports.getDestinationProps = getDestinationProps;
|
|
230
230
|
const transformPush = (callback) => (_a) => {
|
|
231
|
-
var {
|
|
231
|
+
var { maybeApiOrDestination, maybeDestination, maybeBranchName, branch } = _a, rest = __rest(_a, ["maybeApiOrDestination", "maybeDestination", "maybeBranchName", "branch"]);
|
|
232
232
|
if (!!maybeBranchName) {
|
|
233
233
|
process.stderr.write(colorette_1.yellow('Deprecation warning: Do not use the third parameter as a branch name. Please use a separate --branch option instead.'));
|
|
234
234
|
}
|
|
235
|
-
const
|
|
236
|
-
const destination = maybeDestination ||
|
|
235
|
+
const api = maybeDestination ? maybeApiOrDestination : undefined;
|
|
236
|
+
const destination = maybeDestination || maybeApiOrDestination;
|
|
237
237
|
return callback(Object.assign(Object.assign({}, rest), { destination,
|
|
238
|
-
|
|
238
|
+
api, branchName: branch !== null && branch !== void 0 ? branch : maybeBranchName }));
|
|
239
239
|
};
|
|
240
240
|
exports.transformPush = transformPush;
|
|
241
|
-
function
|
|
241
|
+
function getApiRoot({ name, version, config: { apis }, }) {
|
|
242
242
|
const api = (apis === null || apis === void 0 ? void 0 : apis[`${name}@${version}`]) || (version === DEFAULT_VERSION && (apis === null || apis === void 0 ? void 0 : apis[name]));
|
|
243
243
|
return api === null || api === void 0 ? void 0 : api.root;
|
|
244
244
|
}
|
|
245
|
-
exports.
|
|
245
|
+
exports.getApiRoot = getApiRoot;
|
|
246
246
|
function uploadFileToS3(url, filePathOrBuffer) {
|
|
247
247
|
const fileSizeInBytes = typeof filePathOrBuffer === 'string'
|
|
248
248
|
? fs.statSync(filePathOrBuffer).size
|
|
@@ -20,10 +20,10 @@ describe('#split', () => {
|
|
|
20
20
|
const openapiDir = 'test';
|
|
21
21
|
const componentsFiles = {};
|
|
22
22
|
it('should split the file and show the success message', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
|
-
const filePath =
|
|
23
|
+
const filePath = 'packages/cli/src/commands/split/__tests__/fixtures/spec.json';
|
|
24
24
|
jest.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
25
25
|
yield index_1.handleSplit({
|
|
26
|
-
|
|
26
|
+
api: filePath,
|
|
27
27
|
outDir: openapiDir,
|
|
28
28
|
separator: '_',
|
|
29
29
|
});
|
|
@@ -33,10 +33,10 @@ describe('#split', () => {
|
|
|
33
33
|
expect(process.stderr.write.mock.calls[1][0]).toContain(`${filePath}: split processed in <test>ms`);
|
|
34
34
|
}));
|
|
35
35
|
it('should use the correct separator', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
-
const filePath =
|
|
36
|
+
const filePath = 'packages/cli/src/commands/split/__tests__/fixtures/spec.json';
|
|
37
37
|
jest.spyOn(utils, 'pathToFilename').mockImplementation(() => 'newFilePath');
|
|
38
38
|
yield index_1.handleSplit({
|
|
39
|
-
|
|
39
|
+
api: filePath,
|
|
40
40
|
outDir: openapiDir,
|
|
41
41
|
separator: '_',
|
|
42
42
|
});
|
|
@@ -44,7 +44,7 @@ describe('#split', () => {
|
|
|
44
44
|
utils.pathToFilename.mockRestore();
|
|
45
45
|
}));
|
|
46
46
|
it('should have correct path with paths', () => {
|
|
47
|
-
const openapi = require(
|
|
47
|
+
const openapi = require('./fixtures/spec.json');
|
|
48
48
|
jest.spyOn(openapiCore, 'slash').mockImplementation(() => 'paths/test.yaml');
|
|
49
49
|
jest.spyOn(path, 'relative').mockImplementation(() => 'paths/test.yaml');
|
|
50
50
|
index_1.iteratePathItems(openapi.paths, openapiDir, path.join(openapiDir, 'paths'), componentsFiles, '_');
|
|
@@ -52,7 +52,7 @@ describe('#split', () => {
|
|
|
52
52
|
expect(path.relative).toHaveBeenCalledWith('test', 'test/paths/test.yaml');
|
|
53
53
|
});
|
|
54
54
|
it('should have correct path with webhooks', () => {
|
|
55
|
-
const openapi = require(
|
|
55
|
+
const openapi = require('./fixtures/webhooks.json');
|
|
56
56
|
jest.spyOn(openapiCore, 'slash').mockImplementation(() => 'webhooks/test.yaml');
|
|
57
57
|
jest.spyOn(path, 'relative').mockImplementation(() => 'webhooks/test.yaml');
|
|
58
58
|
index_1.iteratePathItems(openapi.webhooks, openapiDir, path.join(openapiDir, 'webhooks'), componentsFiles, 'webhook_');
|
|
@@ -60,7 +60,7 @@ describe('#split', () => {
|
|
|
60
60
|
expect(path.relative).toHaveBeenCalledWith('test', 'test/webhooks/test.yaml');
|
|
61
61
|
});
|
|
62
62
|
it('should have correct path with x-webhooks', () => {
|
|
63
|
-
const openapi = require(
|
|
63
|
+
const openapi = require('./fixtures/spec.json');
|
|
64
64
|
jest.spyOn(openapiCore, 'slash').mockImplementation(() => 'webhooks/test.yaml');
|
|
65
65
|
jest.spyOn(path, 'relative').mockImplementation(() => 'webhooks/test.yaml');
|
|
66
66
|
index_1.iteratePathItems(openapi['x-webhooks'], openapiDir, path.join(openapiDir, 'webhooks'), componentsFiles, 'webhook_');
|
|
@@ -68,7 +68,7 @@ describe('#split', () => {
|
|
|
68
68
|
expect(path.relative).toHaveBeenCalledWith('test', 'test/webhooks/test.yaml');
|
|
69
69
|
});
|
|
70
70
|
it('should create correct folder name for code samples', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
-
const openapi = require(
|
|
71
|
+
const openapi = require('./fixtures/samples.json');
|
|
72
72
|
const fs = require('fs');
|
|
73
73
|
jest.spyOn(fs, 'writeFileSync').mockImplementation(() => { });
|
|
74
74
|
jest.spyOn(utils, 'escapeLanguageName');
|
|
@@ -22,13 +22,13 @@ const types_1 = require("./types");
|
|
|
22
22
|
function handleSplit(argv) {
|
|
23
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
24
24
|
const startedAt = perf_hooks_1.performance.now();
|
|
25
|
-
const {
|
|
26
|
-
validateDefinitionFileName(
|
|
27
|
-
const openapi = utils_1.readYaml(
|
|
25
|
+
const { api, outDir, separator } = argv;
|
|
26
|
+
validateDefinitionFileName(api);
|
|
27
|
+
const openapi = utils_1.readYaml(api);
|
|
28
28
|
splitDefinition(openapi, outDir, separator);
|
|
29
|
-
process.stderr.write(`🪓 Document: ${colorette_1.blue(
|
|
29
|
+
process.stderr.write(`🪓 Document: ${colorette_1.blue(api)} ${colorette_1.green('is successfully split')}
|
|
30
30
|
and all related files are saved to the directory: ${colorette_1.blue(outDir)} \n`);
|
|
31
|
-
utils_1.printExecutionTime('split', startedAt,
|
|
31
|
+
utils_1.printExecutionTime('split', startedAt, api);
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
exports.handleSplit = handleSplit;
|
|
@@ -76,7 +76,7 @@ function langToExt(lang) {
|
|
|
76
76
|
bash: '.sh',
|
|
77
77
|
javascript: '.js',
|
|
78
78
|
js: '.js',
|
|
79
|
-
python: '.py'
|
|
79
|
+
python: '.py',
|
|
80
80
|
};
|
|
81
81
|
return langObj[lang];
|
|
82
82
|
}
|
|
@@ -169,8 +169,7 @@ function isNotSecurityComponentType(componentType) {
|
|
|
169
169
|
return componentType !== types_1.OPENAPI3_COMPONENT.SecuritySchemes;
|
|
170
170
|
}
|
|
171
171
|
function findComponentTypes(components) {
|
|
172
|
-
return types_1.OPENAPI3_COMPONENT_NAMES
|
|
173
|
-
.filter(item => isNotSecurityComponentType(item) && Object.keys(components).includes(item));
|
|
172
|
+
return types_1.OPENAPI3_COMPONENT_NAMES.filter((item) => isNotSecurityComponentType(item) && Object.keys(components).includes(item));
|
|
174
173
|
}
|
|
175
174
|
function doesFileDiffer(filename, componentData) {
|
|
176
175
|
return fs.existsSync(filename) && !isEqual(utils_1.readYaml(filename), componentData);
|
|
@@ -198,7 +197,9 @@ function gatherComponentsFiles(components, componentsFiles, componentType, compo
|
|
|
198
197
|
var _a, _b;
|
|
199
198
|
let inherits = [];
|
|
200
199
|
if (componentType === types_1.OPENAPI3_COMPONENT.Schemas) {
|
|
201
|
-
inherits = (((_b = (_a = components === null || components === void 0 ? void 0 : components[componentType]) === null || _a === void 0 ? void 0 : _a[componentName]) === null || _b === void 0 ? void 0 : _b.allOf) || [])
|
|
200
|
+
inherits = (((_b = (_a = components === null || components === void 0 ? void 0 : components[componentType]) === null || _a === void 0 ? void 0 : _a[componentName]) === null || _b === void 0 ? void 0 : _b.allOf) || [])
|
|
201
|
+
.map((s) => s.$ref)
|
|
202
|
+
.filter(Boolean);
|
|
202
203
|
}
|
|
203
204
|
componentsFiles[componentType] = componentsFiles[componentType] || {};
|
|
204
205
|
componentsFiles[componentType][componentName] = { inherits, filename };
|
|
@@ -226,13 +227,13 @@ function iteratePathItems(pathItems, openapiDir, outDir, componentsFiles, pathSe
|
|
|
226
227
|
fs.writeFileSync(sampleFileName, sample.source);
|
|
227
228
|
// @ts-ignore
|
|
228
229
|
sample.source = {
|
|
229
|
-
$ref: openapi_core_1.slash(path.relative(outDir, sampleFileName))
|
|
230
|
+
$ref: openapi_core_1.slash(path.relative(outDir, sampleFileName)),
|
|
230
231
|
};
|
|
231
232
|
}
|
|
232
233
|
}
|
|
233
234
|
utils_1.writeYaml(pathData, pathFile);
|
|
234
235
|
pathItems[pathName] = {
|
|
235
|
-
$ref: openapi_core_1.slash(path.relative(openapiDir, pathFile))
|
|
236
|
+
$ref: openapi_core_1.slash(path.relative(openapiDir, pathFile)),
|
|
236
237
|
};
|
|
237
238
|
traverseDirectoryDeep(outDir, traverseDirectoryDeepCallback, componentsFiles);
|
|
238
239
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Oas3Schema, Oas3_1Schema, Oas3Definition, Oas3_1Definition, Oas3Components, Oas3PathItem, Oas3Paths, Oas3ComponentName, Oas3_1Webhooks, Oas2Definition, Referenced } from
|
|
2
|
-
export { Oas3_1Definition, Oas3Definition, Oas2Definition, Oas3Components, Oas3Paths, Oas3PathItem, Oas3ComponentName, Oas3_1Schema, Oas3Schema, Oas3_1Webhooks, Referenced };
|
|
1
|
+
import { Oas3Schema, Oas3_1Schema, Oas3Definition, Oas3_1Definition, Oas3Components, Oas3PathItem, Oas3Paths, Oas3ComponentName, Oas3_1Webhooks, Oas2Definition, Referenced } from '@redocly/openapi-core';
|
|
2
|
+
export { Oas3_1Definition, Oas3Definition, Oas2Definition, Oas3Components, Oas3Paths, Oas3PathItem, Oas3ComponentName, Oas3_1Schema, Oas3Schema, Oas3_1Webhooks, Referenced, };
|
|
3
3
|
export declare type Definition = Oas3_1Definition | Oas3Definition | Oas2Definition;
|
|
4
4
|
export interface ComponentsFiles {
|
|
5
5
|
[schemas: string]: any;
|
|
@@ -25,7 +25,7 @@ exports.OPENAPI3_METHOD_NAMES = [
|
|
|
25
25
|
OPENAPI3_METHOD.Options,
|
|
26
26
|
OPENAPI3_METHOD.Head,
|
|
27
27
|
OPENAPI3_METHOD.Patch,
|
|
28
|
-
OPENAPI3_METHOD.Trace
|
|
28
|
+
OPENAPI3_METHOD.Trace,
|
|
29
29
|
];
|
|
30
30
|
var OPENAPI3_COMPONENT;
|
|
31
31
|
(function (OPENAPI3_COMPONENT) {
|
|
@@ -48,5 +48,5 @@ exports.OPENAPI3_COMPONENT_NAMES = [
|
|
|
48
48
|
OPENAPI3_COMPONENT.Headers,
|
|
49
49
|
OPENAPI3_COMPONENT.Links,
|
|
50
50
|
OPENAPI3_COMPONENT.Callbacks,
|
|
51
|
-
OPENAPI3_COMPONENT.SecuritySchemes
|
|
51
|
+
OPENAPI3_COMPONENT.SecuritySchemes,
|
|
52
52
|
];
|
package/lib/commands/stats.d.ts
CHANGED
package/lib/commands/stats.js
CHANGED
|
@@ -41,8 +41,8 @@ function printStatsJson(statsAccumulator) {
|
|
|
41
41
|
}
|
|
42
42
|
process.stdout.write(JSON.stringify(json, null, 2));
|
|
43
43
|
}
|
|
44
|
-
function printStats(statsAccumulator,
|
|
45
|
-
process.stderr.write(`Document: ${colors.magenta(
|
|
44
|
+
function printStats(statsAccumulator, api, format) {
|
|
45
|
+
process.stderr.write(`Document: ${colors.magenta(api)} stats:\n\n`);
|
|
46
46
|
switch (format) {
|
|
47
47
|
case 'stylish':
|
|
48
48
|
printStatsStylish(statsAccumulator);
|
|
@@ -55,10 +55,10 @@ function printStats(statsAccumulator, entrypoint, format) {
|
|
|
55
55
|
function handleStats(argv) {
|
|
56
56
|
return __awaiter(this, void 0, void 0, function* () {
|
|
57
57
|
const config = yield openapi_core_1.loadConfig(argv.config);
|
|
58
|
-
const [{ path }] = yield utils_1.
|
|
58
|
+
const [{ path }] = yield utils_1.getFallbackApisOrExit(argv.api ? [argv.api] : [], config);
|
|
59
59
|
const externalRefResolver = new openapi_core_1.BaseResolver(config.resolve);
|
|
60
60
|
const { bundle: document } = yield openapi_core_1.bundle({ config, ref: path });
|
|
61
|
-
const lintConfig = config.
|
|
61
|
+
const lintConfig = config.styleguide;
|
|
62
62
|
const oasVersion = openapi_core_1.detectOpenAPI(document.parsed);
|
|
63
63
|
const oasMajorVersion = openapi_core_1.openAPIMajor(oasVersion);
|
|
64
64
|
const types = openapi_core_1.normalizeTypes(lintConfig.extendTypes(oasMajorVersion === openapi_core_1.OasMajorVersion.Version3 ? openapi_core_1.Oas3Types : openapi_core_1.Oas2Types, oasVersion), lintConfig);
|
|
@@ -73,11 +73,13 @@ function handleStats(argv) {
|
|
|
73
73
|
rootType: types.DefinitionRoot,
|
|
74
74
|
externalRefResolver,
|
|
75
75
|
});
|
|
76
|
-
const statsVisitor = openapi_core_1.normalizeVisitors([
|
|
76
|
+
const statsVisitor = openapi_core_1.normalizeVisitors([
|
|
77
|
+
{
|
|
77
78
|
severity: 'warn',
|
|
78
79
|
ruleId: 'stats',
|
|
79
|
-
visitor: openapi_core_1.Stats(statsAccumulator)
|
|
80
|
-
}
|
|
80
|
+
visitor: openapi_core_1.Stats(statsAccumulator),
|
|
81
|
+
},
|
|
82
|
+
], types);
|
|
81
83
|
openapi_core_1.walkDocument({
|
|
82
84
|
document,
|
|
83
85
|
rootType: types.DefinitionRoot,
|
package/lib/index.js
CHANGED
|
@@ -26,7 +26,7 @@ const version = require('../package.json').version;
|
|
|
26
26
|
yargs
|
|
27
27
|
.version('version', 'Show version number.', version)
|
|
28
28
|
.help('help', 'Show help.')
|
|
29
|
-
.command('stats [
|
|
29
|
+
.command('stats [api]', 'Gathering statistics for a document.', (yargs) => yargs.positional('api', { type: 'string' }).option({
|
|
30
30
|
config: { description: 'Specify path to the config file.', type: 'string' },
|
|
31
31
|
format: {
|
|
32
32
|
description: 'Use a specific output format.',
|
|
@@ -34,8 +34,8 @@ yargs
|
|
|
34
34
|
default: 'stylish',
|
|
35
35
|
},
|
|
36
36
|
}), stats_1.handleStats)
|
|
37
|
-
.command('split [
|
|
38
|
-
.positional('
|
|
37
|
+
.command('split [api]', 'Split definition into a multi-file structure.', (yargs) => yargs
|
|
38
|
+
.positional('api', {
|
|
39
39
|
description: 'API definition file that you want to split',
|
|
40
40
|
type: 'string',
|
|
41
41
|
})
|
|
@@ -52,9 +52,9 @@ yargs
|
|
|
52
52
|
default: '_',
|
|
53
53
|
},
|
|
54
54
|
})
|
|
55
|
-
.demandOption('
|
|
56
|
-
.command('join [
|
|
57
|
-
.positional('
|
|
55
|
+
.demandOption('api'), split_1.handleSplit)
|
|
56
|
+
.command('join [apis...]', 'Join definitions [experimental].', (yargs) => yargs
|
|
57
|
+
.positional('apis', {
|
|
58
58
|
array: true,
|
|
59
59
|
type: 'string',
|
|
60
60
|
demandOption: true,
|
|
@@ -83,8 +83,8 @@ yargs
|
|
|
83
83
|
}), (argv) => {
|
|
84
84
|
join_1.handleJoin(argv, version);
|
|
85
85
|
})
|
|
86
|
-
.command('push [
|
|
87
|
-
.positional('
|
|
86
|
+
.command('push [maybeApiOrDestination] [maybeDestination] [maybeBranchName]', 'Push an API definition to the Redocly API registry.', (yargs) => yargs
|
|
87
|
+
.positional('maybeApiOrDestination', { type: 'string' })
|
|
88
88
|
.positional('maybeDestination', { type: 'string' })
|
|
89
89
|
.positional('maybeBranchName', { type: 'string' })
|
|
90
90
|
.option({
|
|
@@ -113,7 +113,7 @@ yargs
|
|
|
113
113
|
})
|
|
114
114
|
.implies('batch-id', 'batch-size')
|
|
115
115
|
.implies('batch-size', 'batch-id'), push_1.transformPush(push_1.handlePush))
|
|
116
|
-
.command('lint [
|
|
116
|
+
.command('lint [apis...]', 'Lint definition.', (yargs) => yargs.positional('apis', { array: true, type: 'string', demandOption: true }).option({
|
|
117
117
|
format: {
|
|
118
118
|
description: 'Use a specific output format.',
|
|
119
119
|
choices: [
|
|
@@ -147,11 +147,7 @@ yargs
|
|
|
147
147
|
},
|
|
148
148
|
'lint-config': {
|
|
149
149
|
description: 'Apply severity for linting the config file.',
|
|
150
|
-
choices: [
|
|
151
|
-
'warn',
|
|
152
|
-
'error',
|
|
153
|
-
'off',
|
|
154
|
-
],
|
|
150
|
+
choices: ['warn', 'error', 'off'],
|
|
155
151
|
default: 'warn',
|
|
156
152
|
},
|
|
157
153
|
config: {
|
|
@@ -168,7 +164,7 @@ yargs
|
|
|
168
164
|
}), (argv) => {
|
|
169
165
|
lint_1.handleLint(argv, version);
|
|
170
166
|
})
|
|
171
|
-
.command('bundle [
|
|
167
|
+
.command('bundle [apis...]', 'Bundle definition.', (yargs) => yargs.positional('apis', { array: true, type: 'string', demandOption: true }).options({
|
|
172
168
|
output: { type: 'string', alias: 'o' },
|
|
173
169
|
format: {
|
|
174
170
|
description: 'Use a specific output format.',
|
|
@@ -256,7 +252,7 @@ yargs
|
|
|
256
252
|
client.logout();
|
|
257
253
|
process.stdout.write('Logged out from the Redocly account. ✋\n');
|
|
258
254
|
}))
|
|
259
|
-
.command('preview-docs [
|
|
255
|
+
.command('preview-docs [api]', 'Preview API reference docs for the specified definition.', (yargs) => yargs.positional('api', { type: 'string' }).options({
|
|
260
256
|
port: {
|
|
261
257
|
alias: 'p',
|
|
262
258
|
type: 'number',
|
package/lib/js-utils.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.isString = exports.isEmptyObject = exports.isObject = void 0;
|
|
4
4
|
function isObject(obj) {
|
|
5
5
|
const type = typeof obj;
|
|
6
|
-
return type === 'function' || type === 'object' && !!obj;
|
|
6
|
+
return type === 'function' || (type === 'object' && !!obj);
|
|
7
7
|
}
|
|
8
8
|
exports.isObject = isObject;
|
|
9
9
|
function isEmptyObject(obj) {
|
|
@@ -11,6 +11,6 @@ function isEmptyObject(obj) {
|
|
|
11
11
|
}
|
|
12
12
|
exports.isEmptyObject = isEmptyObject;
|
|
13
13
|
function isString(str) {
|
|
14
|
-
return Object.prototype.toString.call(str) ===
|
|
14
|
+
return Object.prototype.toString.call(str) === '[object String]';
|
|
15
15
|
}
|
|
16
16
|
exports.isString = isString;
|
package/lib/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BundleOutputFormat, Region } from '@redocly/openapi-core';
|
|
1
|
+
import type { BundleOutputFormat, OutputFormat, Region } from '@redocly/openapi-core';
|
|
2
2
|
export declare type Totals = {
|
|
3
3
|
errors: number;
|
|
4
4
|
warnings: number;
|
|
@@ -11,3 +11,15 @@ export declare type Entrypoint = {
|
|
|
11
11
|
export declare const outputExtensions: readonly BundleOutputFormat[];
|
|
12
12
|
export declare type OutputExtensions = 'json' | 'yaml' | 'yml' | undefined;
|
|
13
13
|
export declare const regionChoices: readonly Region[];
|
|
14
|
+
export declare type CommonOptions = {
|
|
15
|
+
apis: string[];
|
|
16
|
+
'max-problems'?: number;
|
|
17
|
+
extends?: string[];
|
|
18
|
+
config?: string;
|
|
19
|
+
format: OutputFormat;
|
|
20
|
+
};
|
|
21
|
+
export declare type Skips = {
|
|
22
|
+
'skip-rule'?: string[];
|
|
23
|
+
'skip-decorator'?: string[];
|
|
24
|
+
'skip-preprocessor'?: string[];
|
|
25
|
+
};
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BundleOutputFormat, Config,
|
|
1
|
+
import { BundleOutputFormat, Config, StyleguideConfig } from '@redocly/openapi-core';
|
|
2
2
|
import { Totals, Entrypoint } from './types';
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function getFallbackApisOrExit(argsApis: string[] | undefined, config: Config): Promise<Entrypoint[]>;
|
|
4
4
|
export declare function getExecutionTime(startedAt: number): string;
|
|
5
|
-
export declare function printExecutionTime(commandName: string, startedAt: number,
|
|
5
|
+
export declare function printExecutionTime(commandName: string, startedAt: number, api: string): void;
|
|
6
6
|
export declare function pathToFilename(path: string, pathSeparator: string): string;
|
|
7
7
|
export declare function escapeLanguageName(lang: string): string;
|
|
8
8
|
export declare class CircularJSONNotSupportedError extends Error {
|
|
@@ -22,7 +22,7 @@ export declare function getOutputFileName(entrypoint: string, entries: number, o
|
|
|
22
22
|
outputFile: string;
|
|
23
23
|
ext: BundleOutputFormat;
|
|
24
24
|
};
|
|
25
|
-
export declare function printUnusedWarnings(config:
|
|
25
|
+
export declare function printUnusedWarnings(config: StyleguideConfig): void;
|
|
26
26
|
export declare function exitWithError(message: string): void;
|
|
27
27
|
/**
|
|
28
28
|
* Checks if dir is subdir of parent
|
package/lib/utils.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.isSubdir = exports.exitWithError = exports.printUnusedWarnings = exports.getOutputFileName = exports.printConfigLintTotals = exports.printLintTotals = exports.handleError = exports.pluralize = exports.writeYaml = exports.readYaml = exports.promptUser = exports.saveBundle = exports.dumpBundle = exports.CircularJSONNotSupportedError = exports.escapeLanguageName = exports.pathToFilename = exports.printExecutionTime = exports.getExecutionTime = exports.
|
|
12
|
+
exports.isSubdir = exports.exitWithError = exports.printUnusedWarnings = exports.getOutputFileName = exports.printConfigLintTotals = exports.printLintTotals = exports.handleError = exports.pluralize = exports.writeYaml = exports.readYaml = exports.promptUser = exports.saveBundle = exports.dumpBundle = exports.CircularJSONNotSupportedError = exports.escapeLanguageName = exports.pathToFilename = exports.printExecutionTime = exports.getExecutionTime = exports.getFallbackApisOrExit = void 0;
|
|
13
13
|
const path_1 = require("path");
|
|
14
14
|
const colorette_1 = require("colorette");
|
|
15
15
|
const perf_hooks_1 = require("perf_hooks");
|
|
@@ -20,24 +20,24 @@ const readline = require("readline");
|
|
|
20
20
|
const stream_1 = require("stream");
|
|
21
21
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
22
22
|
const types_1 = require("./types");
|
|
23
|
-
function
|
|
23
|
+
function getFallbackApisOrExit(argsApis, config) {
|
|
24
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
25
|
const { apis } = config;
|
|
26
|
-
const shouldFallbackToAllDefinitions = !isNotEmptyArray(
|
|
26
|
+
const shouldFallbackToAllDefinitions = !isNotEmptyArray(argsApis) && apis && Object.keys(apis).length > 0;
|
|
27
27
|
const res = shouldFallbackToAllDefinitions
|
|
28
28
|
? Object.entries(apis).map(([alias, { root }]) => ({
|
|
29
29
|
path: path_1.resolve(getConfigDirectory(config), root),
|
|
30
30
|
alias,
|
|
31
31
|
}))
|
|
32
|
-
:
|
|
32
|
+
: yield expandGlobsInEntrypoints(argsApis, config);
|
|
33
33
|
if (!isNotEmptyArray(res)) {
|
|
34
|
-
process.stderr.write('error: missing required argument `
|
|
34
|
+
process.stderr.write('error: missing required argument `apis`.\n');
|
|
35
35
|
process.exit(1);
|
|
36
36
|
}
|
|
37
37
|
return res;
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
|
-
exports.
|
|
40
|
+
exports.getFallbackApisOrExit = getFallbackApisOrExit;
|
|
41
41
|
function getConfigDirectory(config) {
|
|
42
42
|
return config.configFile ? path_1.dirname(config.configFile) : process.cwd();
|
|
43
43
|
}
|
|
@@ -65,9 +65,9 @@ function getExecutionTime(startedAt) {
|
|
|
65
65
|
: `${Math.ceil(perf_hooks_1.performance.now() - startedAt)}ms`;
|
|
66
66
|
}
|
|
67
67
|
exports.getExecutionTime = getExecutionTime;
|
|
68
|
-
function printExecutionTime(commandName, startedAt,
|
|
68
|
+
function printExecutionTime(commandName, startedAt, api) {
|
|
69
69
|
const elapsed = getExecutionTime(startedAt);
|
|
70
|
-
process.stderr.write(colorette_1.gray(`\n${
|
|
70
|
+
process.stderr.write(colorette_1.gray(`\n${api}: ${commandName} processed in ${elapsed}\n\n`));
|
|
71
71
|
}
|
|
72
72
|
exports.printExecutionTime = printExecutionTime;
|
|
73
73
|
function pathToFilename(path, pathSeparator) {
|
|
@@ -79,10 +79,7 @@ function pathToFilename(path, pathSeparator) {
|
|
|
79
79
|
}
|
|
80
80
|
exports.pathToFilename = pathToFilename;
|
|
81
81
|
function escapeLanguageName(lang) {
|
|
82
|
-
return lang
|
|
83
|
-
.replace(/#/g, "_sharp")
|
|
84
|
-
.replace(/\//, '_')
|
|
85
|
-
.replace(/\s/g, '');
|
|
82
|
+
return lang.replace(/#/g, '_sharp').replace(/\//, '_').replace(/\s/g, '');
|
|
86
83
|
}
|
|
87
84
|
exports.escapeLanguageName = escapeLanguageName;
|
|
88
85
|
class CircularJSONNotSupportedError extends Error {
|
|
@@ -171,22 +168,24 @@ function pluralize(label, num) {
|
|
|
171
168
|
exports.pluralize = pluralize;
|
|
172
169
|
function handleError(e, ref) {
|
|
173
170
|
if (e instanceof openapi_core_1.ResolveError) {
|
|
174
|
-
process.stderr.write(`Failed to resolve
|
|
171
|
+
process.stderr.write(`Failed to resolve api definition at ${ref}:\n\n - ${e.message}.\n\n`);
|
|
175
172
|
}
|
|
176
173
|
else if (e instanceof openapi_core_1.YamlParseError) {
|
|
177
|
-
process.stderr.write(`Failed to parse
|
|
174
|
+
process.stderr.write(`Failed to parse api definition at ${ref}:\n\n - ${e.message}.\n\n`);
|
|
178
175
|
// TODO: codeframe
|
|
179
176
|
}
|
|
180
|
-
else {
|
|
177
|
+
else {
|
|
178
|
+
// @ts-ignore
|
|
181
179
|
if (e instanceof CircularJSONNotSupportedError) {
|
|
182
180
|
process.stderr.write(colorette_1.red(`Detected circular reference which can't be converted to JSON.\n`) +
|
|
183
181
|
`Try to use ${colorette_1.blue('yaml')} output or remove ${colorette_1.blue('--dereferenced')}.\n\n`);
|
|
184
182
|
}
|
|
185
183
|
else {
|
|
186
184
|
process.stderr.write(`Something went wrong when processing ${ref}:\n\n - ${e.message}.\n\n`);
|
|
187
|
-
throw e;
|
|
188
185
|
}
|
|
189
186
|
}
|
|
187
|
+
process.exitCode = 1;
|
|
188
|
+
throw e;
|
|
190
189
|
}
|
|
191
190
|
exports.handleError = handleError;
|
|
192
191
|
function printLintTotals(totals, definitionsCount) {
|
|
@@ -220,7 +219,6 @@ function printConfigLintTotals(totals) {
|
|
|
220
219
|
else if (totals.warnings > 0) {
|
|
221
220
|
process.stderr.write(colorette_1.yellow(`You have ${totals.warnings} ${pluralize('warning', totals.warnings)}.\n`));
|
|
222
221
|
}
|
|
223
|
-
;
|
|
224
222
|
}
|
|
225
223
|
exports.printConfigLintTotals = printConfigLintTotals;
|
|
226
224
|
function getOutputFileName(entrypoint, entries, output, ext) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/cli",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.106",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"Andriy Leliv <andriy@redoc.ly> (https://redoc.ly/)"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@redocly/openapi-core": "1.0.0-beta.
|
|
38
|
+
"@redocly/openapi-core": "1.0.0-beta.106",
|
|
39
39
|
"assert-node-version": "^1.0.3",
|
|
40
40
|
"chokidar": "^3.5.1",
|
|
41
41
|
"colorette": "^1.2.0",
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export const performance = {
|
|
2
|
-
|
|
3
|
-
}
|
|
2
|
+
now: jest.fn(),
|
|
3
|
+
};
|
package/src/__mocks__/utils.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const getFallbackApisOrExit = jest.fn((entrypoints) =>
|
|
2
|
+
entrypoints.map((path: string) => ({ path }))
|
|
3
|
+
);
|
|
2
4
|
export const dumpBundle = jest.fn(() => '');
|
|
3
5
|
export const slash = jest.fn();
|
|
4
6
|
export const pluralize = jest.fn();
|