@redocly/cli 1.0.0-beta.126 → 1.0.0-beta.127
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/lib/__tests__/utils.test.js +7 -0
- package/lib/index.js +4 -0
- package/lib/update-version-notifier.d.ts +2 -0
- package/lib/update-version-notifier.js +100 -0
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +7 -2
- package/package.json +5 -3
- package/src/__mocks__/@redocly/openapi-core.ts +0 -80
- package/src/__mocks__/documents.ts +0 -63
- package/src/__mocks__/fs.ts +0 -6
- package/src/__mocks__/perf_hooks.ts +0 -3
- package/src/__mocks__/redoc.ts +0 -2
- package/src/__mocks__/utils.ts +0 -19
- package/src/__tests__/commands/build-docs.test.ts +0 -61
- package/src/__tests__/commands/bundle.test.ts +0 -169
- package/src/__tests__/commands/join.test.ts +0 -114
- package/src/__tests__/commands/lint.test.ts +0 -166
- package/src/__tests__/commands/push-region.test.ts +0 -51
- package/src/__tests__/commands/push.test.ts +0 -364
- package/src/__tests__/fixtures/config.ts +0 -21
- package/src/__tests__/utils.test.ts +0 -441
- package/src/assert-node-version.ts +0 -8
- package/src/commands/build-docs/index.ts +0 -56
- package/src/commands/build-docs/template.hbs +0 -23
- package/src/commands/build-docs/types.ts +0 -26
- package/src/commands/build-docs/utils.ts +0 -112
- package/src/commands/bundle.ts +0 -170
- package/src/commands/join.ts +0 -810
- package/src/commands/lint.ts +0 -161
- package/src/commands/login.ts +0 -21
- package/src/commands/preview-docs/index.ts +0 -183
- package/src/commands/preview-docs/preview-server/default.hbs +0 -24
- package/src/commands/preview-docs/preview-server/hot.js +0 -42
- package/src/commands/preview-docs/preview-server/oauth2-redirect.html +0 -21
- package/src/commands/preview-docs/preview-server/preview-server.ts +0 -156
- package/src/commands/preview-docs/preview-server/server.ts +0 -91
- package/src/commands/push.ts +0 -387
- package/src/commands/split/__tests__/fixtures/samples.json +0 -61
- package/src/commands/split/__tests__/fixtures/spec.json +0 -70
- package/src/commands/split/__tests__/fixtures/webhooks.json +0 -88
- package/src/commands/split/__tests__/index.test.ts +0 -137
- package/src/commands/split/index.ts +0 -378
- package/src/commands/split/types.ts +0 -85
- package/src/commands/stats.ts +0 -117
- package/src/custom.d.ts +0 -1
- package/src/index.ts +0 -431
- package/src/js-utils.ts +0 -17
- package/src/types.ts +0 -28
- package/src/utils.ts +0 -472
- package/tsconfig.json +0 -9
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -357,3 +357,10 @@ describe('checkIfRulesetExist', () => {
|
|
|
357
357
|
expect(process.exit).not.toHaveBeenCalled();
|
|
358
358
|
});
|
|
359
359
|
});
|
|
360
|
+
describe('cleanColors', () => {
|
|
361
|
+
it('should remove colors from string', () => {
|
|
362
|
+
const stringWithColors = `String for ${colorette_1.red('test')}`;
|
|
363
|
+
const result = utils_1.cleanColors(stringWithColors);
|
|
364
|
+
expect(result).not.toMatch(/\x1b\[\d+m/g);
|
|
365
|
+
});
|
|
366
|
+
});
|
package/lib/index.js
CHANGED
|
@@ -23,10 +23,13 @@ const lint_1 = require("./commands/lint");
|
|
|
23
23
|
const bundle_1 = require("./commands/bundle");
|
|
24
24
|
const login_1 = require("./commands/login");
|
|
25
25
|
const build_docs_1 = require("./commands/build-docs");
|
|
26
|
+
const update_version_notifier_1 = require("./update-version-notifier");
|
|
26
27
|
const version = require('../package.json').version;
|
|
28
|
+
update_version_notifier_1.cacheLatestVersion();
|
|
27
29
|
yargs
|
|
28
30
|
.version('version', 'Show version number.', version)
|
|
29
31
|
.help('help', 'Show help.')
|
|
32
|
+
.parserConfiguration({ 'greedy-arrays': false })
|
|
30
33
|
.command('stats [api]', 'Gathering statistics for a document.', (yargs) => yargs.positional('api', { type: 'string' }).option({
|
|
31
34
|
config: { description: 'Specify path to the config file.', type: 'string' },
|
|
32
35
|
format: {
|
|
@@ -378,4 +381,5 @@ yargs
|
|
|
378
381
|
}))
|
|
379
382
|
.completion('completion', 'Generate completion script.')
|
|
380
383
|
.demandCommand(1)
|
|
384
|
+
.middleware([update_version_notifier_1.notifyUpdateCliVersion])
|
|
381
385
|
.strict().argv;
|
|
@@ -0,0 +1,100 @@
|
|
|
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.cacheLatestVersion = exports.notifyUpdateCliVersion = void 0;
|
|
13
|
+
const os_1 = require("os");
|
|
14
|
+
const path_1 = require("path");
|
|
15
|
+
const fs_1 = require("fs");
|
|
16
|
+
const semver_1 = require("semver");
|
|
17
|
+
const node_fetch_1 = require("node-fetch");
|
|
18
|
+
const colorette_1 = require("colorette");
|
|
19
|
+
const utils_1 = require("./utils");
|
|
20
|
+
const { version, name } = require('../package.json');
|
|
21
|
+
const VERSION_CACHE_FILE = 'redocly-cli-version';
|
|
22
|
+
const SPACE_TO_BORDER = 4;
|
|
23
|
+
const INTERVAL_TO_CHECK = 1000 * 60 * 60 * 12;
|
|
24
|
+
const SHOULD_NOT_NOTIFY = process.env.NODE_ENV === 'test' || process.env.CI || !!process.env.LAMBDA_TASK_ROOT;
|
|
25
|
+
const notifyUpdateCliVersion = () => {
|
|
26
|
+
if (SHOULD_NOT_NOTIFY) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const latestVersion = fs_1.readFileSync(path_1.join(os_1.tmpdir(), VERSION_CACHE_FILE)).toString();
|
|
31
|
+
if (isNewVersionAvailable(version, latestVersion)) {
|
|
32
|
+
renderUpdateBanner(version, latestVersion);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
exports.notifyUpdateCliVersion = notifyUpdateCliVersion;
|
|
40
|
+
const isNewVersionAvailable = (current, latest) => semver_1.compare(current, latest) < 0;
|
|
41
|
+
const getLatestVersion = (packageName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
|
+
const latestUrl = `http://registry.npmjs.org/${packageName}/latest`;
|
|
43
|
+
const response = yield node_fetch_1.default(latestUrl);
|
|
44
|
+
const info = yield response.json();
|
|
45
|
+
return info.version;
|
|
46
|
+
});
|
|
47
|
+
const cacheLatestVersion = () => {
|
|
48
|
+
if (!isNeedToBeCached() || SHOULD_NOT_NOTIFY) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
getLatestVersion(name)
|
|
52
|
+
.then((version) => {
|
|
53
|
+
const lastCheckFile = path_1.join(os_1.tmpdir(), VERSION_CACHE_FILE);
|
|
54
|
+
fs_1.writeFileSync(lastCheckFile, version);
|
|
55
|
+
})
|
|
56
|
+
.catch(() => { });
|
|
57
|
+
};
|
|
58
|
+
exports.cacheLatestVersion = cacheLatestVersion;
|
|
59
|
+
const renderUpdateBanner = (current, latest) => {
|
|
60
|
+
const messageLines = [
|
|
61
|
+
`A new version of ${colorette_1.cyan('Redocly CLI')} (${colorette_1.green(latest)}) is available.`,
|
|
62
|
+
`Update now: \`${colorette_1.cyan('npm i -g @redocly/cli@latest')}\`.`,
|
|
63
|
+
`Changelog: https://redocly.com/docs/cli/changelog/`,
|
|
64
|
+
];
|
|
65
|
+
const maxLength = Math.max(...messageLines.map((line) => utils_1.cleanColors(line).length));
|
|
66
|
+
const border = colorette_1.yellow('═'.repeat(maxLength + SPACE_TO_BORDER));
|
|
67
|
+
const banner = `
|
|
68
|
+
${colorette_1.yellow('╔' + border + '╗')}
|
|
69
|
+
${colorette_1.yellow('║' + ' '.repeat(maxLength + SPACE_TO_BORDER) + '║')}
|
|
70
|
+
${messageLines
|
|
71
|
+
.map((line, index) => {
|
|
72
|
+
return getLineWithPadding(maxLength, line, index);
|
|
73
|
+
})
|
|
74
|
+
.join('\n')}
|
|
75
|
+
${colorette_1.yellow('║' + ' '.repeat(maxLength + SPACE_TO_BORDER) + '║')}
|
|
76
|
+
${colorette_1.yellow('╚' + border + '╝')}
|
|
77
|
+
`;
|
|
78
|
+
process.stderr.write(banner);
|
|
79
|
+
};
|
|
80
|
+
const getLineWithPadding = (maxLength, line, index) => {
|
|
81
|
+
const padding = ' '.repeat(maxLength - utils_1.cleanColors(line).length);
|
|
82
|
+
const extraSpaces = index !== 0 ? ' '.repeat(SPACE_TO_BORDER) : '';
|
|
83
|
+
return `${extraSpaces}${colorette_1.yellow('║')} ${line}${padding} ${colorette_1.yellow('║')}`;
|
|
84
|
+
};
|
|
85
|
+
const isNeedToBeCached = () => {
|
|
86
|
+
try {
|
|
87
|
+
// Last version from npm is stored in a file in the OS temp folder
|
|
88
|
+
const versionFile = path_1.join(os_1.tmpdir(), VERSION_CACHE_FILE);
|
|
89
|
+
if (!fs_1.existsSync(versionFile)) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
const now = new Date().getTime();
|
|
93
|
+
const stats = fs_1.statSync(versionFile);
|
|
94
|
+
const lastCheck = stats.mtime.getTime();
|
|
95
|
+
return now - lastCheck >= INTERVAL_TO_CHECK;
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
};
|
package/lib/utils.d.ts
CHANGED
|
@@ -38,3 +38,4 @@ export declare function loadConfigAndHandleErrors(options?: {
|
|
|
38
38
|
}): Promise<Config>;
|
|
39
39
|
export declare function sortTopLevelKeysForOas(document: Oas3Definition | Oas2Definition): Oas3Definition | Oas2Definition;
|
|
40
40
|
export declare function checkIfRulesetExist(rules: typeof StyleguideConfig.prototype.rules): void;
|
|
41
|
+
export declare function cleanColors(input: string): string;
|
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.checkIfRulesetExist = exports.sortTopLevelKeysForOas = exports.loadConfigAndHandleErrors = 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.langToExt = exports.escapeLanguageName = exports.pathToFilename = exports.printExecutionTime = exports.getExecutionTime = exports.getFallbackApisOrExit = void 0;
|
|
12
|
+
exports.cleanColors = exports.checkIfRulesetExist = exports.sortTopLevelKeysForOas = exports.loadConfigAndHandleErrors = 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.langToExt = 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");
|
|
@@ -238,7 +238,7 @@ function printLintTotals(totals, definitionsCount) {
|
|
|
238
238
|
process.stderr.write(colorette_1.green(`Woohoo! Your OpenAPI ${pluralize('definition is', definitionsCount)} valid. 🎉\n${ignored}`));
|
|
239
239
|
}
|
|
240
240
|
if (totals.errors > 0) {
|
|
241
|
-
process.stderr.write(colorette_1.gray(`run \`
|
|
241
|
+
process.stderr.write(colorette_1.gray(`run \`redocly lint --generate-ignore-file\` to add all problems to the ignore file.\n`));
|
|
242
242
|
}
|
|
243
243
|
process.stderr.write('\n');
|
|
244
244
|
}
|
|
@@ -384,3 +384,8 @@ function checkIfRulesetExist(rules) {
|
|
|
384
384
|
}
|
|
385
385
|
}
|
|
386
386
|
exports.checkIfRulesetExist = checkIfRulesetExist;
|
|
387
|
+
function cleanColors(input) {
|
|
388
|
+
// eslint-disable-next-line no-control-regex
|
|
389
|
+
return input.replace(/\x1b\[\d+m/g, '');
|
|
390
|
+
}
|
|
391
|
+
exports.cleanColors = cleanColors;
|
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.127",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"Roman Hotsiy <roman@redoc.ly> (https://redoc.ly/)"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@redocly/openapi-core": "1.0.0-beta.
|
|
36
|
+
"@redocly/openapi-core": "1.0.0-beta.127",
|
|
37
37
|
"assert-node-version": "^1.0.3",
|
|
38
38
|
"chokidar": "^3.5.1",
|
|
39
39
|
"colorette": "^1.2.0",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"react": "^17.0.1",
|
|
46
46
|
"react-dom": "^17.0.1",
|
|
47
47
|
"redoc": "~2.0.0",
|
|
48
|
+
"semver": "^7.5.1",
|
|
48
49
|
"simple-websocket": "^9.0.0",
|
|
49
50
|
"styled-components": "5.3.3",
|
|
50
51
|
"yargs": "17.0.1"
|
|
@@ -54,7 +55,8 @@
|
|
|
54
55
|
"@types/react": "^17.0.8",
|
|
55
56
|
"@types/react-dom": "^17.0.5",
|
|
56
57
|
"@types/styled-components": "^5.1.1",
|
|
57
|
-
"@types/yargs": "
|
|
58
|
+
"@types/yargs": "17.0.5",
|
|
59
|
+
"@types/semver": "^7.5.0",
|
|
58
60
|
"typescript": "^4.0.3"
|
|
59
61
|
}
|
|
60
62
|
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { ConfigFixture } from './../../__tests__/fixtures/config';
|
|
2
|
-
import { Document } from '@redocly/openapi-core';
|
|
3
|
-
import { firstDocument, secondDocument } from '../documents';
|
|
4
|
-
|
|
5
|
-
export const __redoclyClient = {
|
|
6
|
-
isAuthorizedWithRedocly: jest.fn().mockResolvedValue(true),
|
|
7
|
-
isAuthorizedWithRedoclyByRegion: jest.fn().mockResolvedValue(true),
|
|
8
|
-
login: jest.fn(),
|
|
9
|
-
registryApi: {
|
|
10
|
-
setAccessTokens: jest.fn(),
|
|
11
|
-
authStatus: jest.fn(),
|
|
12
|
-
prepareFileUpload: jest.fn().mockResolvedValue({
|
|
13
|
-
signedUploadUrl: 'signedUploadUrl',
|
|
14
|
-
filePath: 'filePath',
|
|
15
|
-
}),
|
|
16
|
-
pushApi: jest.fn(),
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const RedoclyClient = jest.fn(() => __redoclyClient);
|
|
21
|
-
export const loadConfig = jest.fn(() => ConfigFixture);
|
|
22
|
-
export const getMergedConfig = jest.fn();
|
|
23
|
-
export const lint = jest.fn();
|
|
24
|
-
export const bundle = jest.fn(() => ({ bundle: { parsed: null }, problems: null }));
|
|
25
|
-
export const getTotals = jest.fn(() => ({ errors: 0 }));
|
|
26
|
-
export const formatProblems = jest.fn();
|
|
27
|
-
export const slash = jest.fn();
|
|
28
|
-
export const findConfig = jest.fn();
|
|
29
|
-
export const doesYamlFileExist = jest.fn();
|
|
30
|
-
export const bundleDocument = jest.fn(() => Promise.resolve({ problems: {} }));
|
|
31
|
-
export const detectOpenAPI = jest.fn();
|
|
32
|
-
export const isAbsoluteUrl = jest.fn();
|
|
33
|
-
|
|
34
|
-
export class BaseResolver {
|
|
35
|
-
cache = new Map<string, Promise<Document | ResolveError>>();
|
|
36
|
-
|
|
37
|
-
getFiles = jest.fn();
|
|
38
|
-
resolveExternalRef = jest.fn();
|
|
39
|
-
loadExternalRef = jest.fn;
|
|
40
|
-
parseDocument = jest.fn();
|
|
41
|
-
resolveDocument = jest
|
|
42
|
-
.fn()
|
|
43
|
-
.mockImplementationOnce(() =>
|
|
44
|
-
Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: firstDocument })
|
|
45
|
-
)
|
|
46
|
-
.mockImplementationOnce(() =>
|
|
47
|
-
Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: secondDocument })
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export class ResolveError extends Error {
|
|
52
|
-
constructor(public originalError: Error) {
|
|
53
|
-
super(originalError.message);
|
|
54
|
-
Object.setPrototypeOf(this, ResolveError.prototype);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export class YamlParseError extends Error {
|
|
59
|
-
constructor(public originalError: Error) {
|
|
60
|
-
super(originalError.message);
|
|
61
|
-
Object.setPrototypeOf(this, YamlParseError.prototype);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export enum OasVersion {
|
|
66
|
-
Version2 = 'oas2',
|
|
67
|
-
Version3_0 = 'oas3_0',
|
|
68
|
-
Version3_1 = 'oas3_1',
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export enum Oas3Operations {
|
|
72
|
-
get = 'get',
|
|
73
|
-
put = 'put',
|
|
74
|
-
post = 'post',
|
|
75
|
-
delete = 'delete',
|
|
76
|
-
options = 'options',
|
|
77
|
-
head = 'head',
|
|
78
|
-
patch = 'patch',
|
|
79
|
-
trace = 'trace',
|
|
80
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
export const firstDocument = {
|
|
2
|
-
openapi: '3.0.0',
|
|
3
|
-
servers: [{ url: 'http://localhost:8080' }],
|
|
4
|
-
info: {
|
|
5
|
-
description: 'example test',
|
|
6
|
-
version: '1.0.0',
|
|
7
|
-
title: 'Swagger Petstore',
|
|
8
|
-
termsOfService: 'http://swagger.io/terms/',
|
|
9
|
-
license: {
|
|
10
|
-
name: 'Apache 2.0',
|
|
11
|
-
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
paths: {
|
|
15
|
-
'/GETUser/{userId}': {
|
|
16
|
-
summary: 'get user by id',
|
|
17
|
-
description: 'user info',
|
|
18
|
-
servers: [{ url: '/user' }, { url: '/pet', description: 'pet server' }],
|
|
19
|
-
|
|
20
|
-
get: {
|
|
21
|
-
tags: ['pet'],
|
|
22
|
-
summary: 'Find pet by ID',
|
|
23
|
-
description: 'Returns a single pet',
|
|
24
|
-
operationId: 'getPetById',
|
|
25
|
-
servers: [{ url: '/pet' }],
|
|
26
|
-
},
|
|
27
|
-
parameters: [{ name: 'param1', in: 'header', schema: { description: 'string' } }],
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
components: {},
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export const secondDocument = {
|
|
34
|
-
openapi: '3.0.0',
|
|
35
|
-
servers: [{ url: 'http://localhost:8080' }],
|
|
36
|
-
info: {
|
|
37
|
-
description: 'example test',
|
|
38
|
-
version: '1.0.0',
|
|
39
|
-
title: 'Swagger Petstore',
|
|
40
|
-
termsOfService: 'http://swagger.io/terms/',
|
|
41
|
-
license: {
|
|
42
|
-
name: 'Apache 2.0',
|
|
43
|
-
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
post: {
|
|
47
|
-
'/GETUser/{userId}': {
|
|
48
|
-
summary: 'get user',
|
|
49
|
-
description: 'user information',
|
|
50
|
-
servers: [{ url: '/user' }, { url: '/pet', description: '' }],
|
|
51
|
-
|
|
52
|
-
get: {
|
|
53
|
-
tags: ['pet'],
|
|
54
|
-
summary: 'Find pet by ID',
|
|
55
|
-
description: 'Returns a single pet',
|
|
56
|
-
operationId: 'getPetById',
|
|
57
|
-
servers: [{ url: '/pet' }],
|
|
58
|
-
},
|
|
59
|
-
parameters: [{ name: 'param1', in: 'header', schema: { description: 'string' } }],
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
components: {},
|
|
63
|
-
};
|
package/src/__mocks__/fs.ts
DELETED
package/src/__mocks__/redoc.ts
DELETED
package/src/__mocks__/utils.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ConfigFixture } from '../__tests__/fixtures/config';
|
|
2
|
-
|
|
3
|
-
export const getFallbackApisOrExit = jest.fn((entrypoints) =>
|
|
4
|
-
entrypoints.map((path: string) => ({ path }))
|
|
5
|
-
);
|
|
6
|
-
export const dumpBundle = jest.fn(() => '');
|
|
7
|
-
export const slash = jest.fn();
|
|
8
|
-
export const pluralize = jest.fn();
|
|
9
|
-
export const getExecutionTime = jest.fn();
|
|
10
|
-
export const printExecutionTime = jest.fn();
|
|
11
|
-
export const printUnusedWarnings = jest.fn();
|
|
12
|
-
export const printLintTotals = jest.fn();
|
|
13
|
-
export const getOutputFileName = jest.fn(() => ({ outputFile: 'test.yaml', ext: 'yaml' }));
|
|
14
|
-
export const handleError = jest.fn();
|
|
15
|
-
export const exitWithError = jest.fn();
|
|
16
|
-
export const writeYaml = jest.fn();
|
|
17
|
-
export const loadConfigAndHandleErrors = jest.fn(() => ConfigFixture);
|
|
18
|
-
export const checkIfRulesetExist = jest.fn();
|
|
19
|
-
export const sortTopLevelKeysForOas = jest.fn((document) => document);
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { createStore, loadAndBundleSpec } from 'redoc';
|
|
2
|
-
import { renderToString } from 'react-dom/server';
|
|
3
|
-
import { handlerBuildCommand } from '../../commands/build-docs';
|
|
4
|
-
import { BuildDocsArgv } from '../../commands/build-docs/types';
|
|
5
|
-
import { getPageHTML } from '../../commands/build-docs/utils';
|
|
6
|
-
import { getFallbackApisOrExit } from '../../utils';
|
|
7
|
-
|
|
8
|
-
jest.mock('redoc');
|
|
9
|
-
jest.mock('fs');
|
|
10
|
-
jest.mock('../../utils');
|
|
11
|
-
|
|
12
|
-
const config = {
|
|
13
|
-
output: '',
|
|
14
|
-
cdn: false,
|
|
15
|
-
title: 'Test',
|
|
16
|
-
disableGoogleFont: false,
|
|
17
|
-
templateFileName: '',
|
|
18
|
-
templateOptions: {},
|
|
19
|
-
redocOptions: {},
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
jest.mock('react-dom/server', () => ({
|
|
23
|
-
renderToString: jest.fn(),
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
|
-
jest.mock('handlebars', () => ({
|
|
27
|
-
compile: jest.fn(() => jest.fn(() => '<html></html>')),
|
|
28
|
-
}));
|
|
29
|
-
|
|
30
|
-
jest.mock('mkdirp', () => ({
|
|
31
|
-
sync: jest.fn(),
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
|
-
describe('build-docs', () => {
|
|
35
|
-
it('should return correct html and call function for ssr', async () => {
|
|
36
|
-
const result = await getPageHTML({}, '../some-path/openapi.yaml', {
|
|
37
|
-
...config,
|
|
38
|
-
redocCurrentVersion: '2.0.0',
|
|
39
|
-
});
|
|
40
|
-
expect(renderToString).toBeCalledTimes(1);
|
|
41
|
-
expect(createStore).toBeCalledTimes(1);
|
|
42
|
-
expect(result).toBe('<html></html>');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should work correctly when calling handlerBuildCommand', async () => {
|
|
46
|
-
const processExitMock = jest.spyOn(process, 'exit').mockImplementation();
|
|
47
|
-
await handlerBuildCommand({
|
|
48
|
-
o: '',
|
|
49
|
-
cdn: false,
|
|
50
|
-
title: 'test',
|
|
51
|
-
disableGoogleFont: false,
|
|
52
|
-
template: '',
|
|
53
|
-
templateOptions: {},
|
|
54
|
-
theme: { openapi: {} },
|
|
55
|
-
api: '../some-path/openapi.yaml',
|
|
56
|
-
} as BuildDocsArgv);
|
|
57
|
-
expect(loadAndBundleSpec).toBeCalledTimes(1);
|
|
58
|
-
expect(getFallbackApisOrExit).toBeCalledTimes(1);
|
|
59
|
-
expect(processExitMock).toBeCalledTimes(0);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { lint, bundle, getTotals, getMergedConfig } from '@redocly/openapi-core';
|
|
2
|
-
|
|
3
|
-
import { handleBundle } from '../../commands/bundle';
|
|
4
|
-
import { handleError } from '../../utils';
|
|
5
|
-
import SpyInstance = jest.SpyInstance;
|
|
6
|
-
|
|
7
|
-
jest.mock('@redocly/openapi-core');
|
|
8
|
-
jest.mock('../../utils');
|
|
9
|
-
|
|
10
|
-
(getMergedConfig as jest.Mock).mockImplementation((config) => config);
|
|
11
|
-
|
|
12
|
-
describe('bundle', () => {
|
|
13
|
-
let processExitMock: SpyInstance;
|
|
14
|
-
let exitCb: any;
|
|
15
|
-
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
processExitMock = jest.spyOn(process, 'exit').mockImplementation();
|
|
18
|
-
jest.spyOn(process, 'once').mockImplementation((_e, cb) => {
|
|
19
|
-
exitCb = cb;
|
|
20
|
-
return process.on(_e, cb);
|
|
21
|
-
});
|
|
22
|
-
jest.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
afterEach(() => {
|
|
26
|
-
(lint as jest.Mock).mockClear();
|
|
27
|
-
(bundle as jest.Mock).mockClear();
|
|
28
|
-
(getTotals as jest.Mock).mockReset();
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('bundles definitions w/o linting', async () => {
|
|
32
|
-
const apis = ['foo.yaml', 'bar.yaml'];
|
|
33
|
-
|
|
34
|
-
await handleBundle(
|
|
35
|
-
{
|
|
36
|
-
apis,
|
|
37
|
-
ext: 'yaml',
|
|
38
|
-
format: 'codeframe',
|
|
39
|
-
},
|
|
40
|
-
'1.0.0'
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
expect(lint).toBeCalledTimes(0);
|
|
44
|
-
expect(bundle).toBeCalledTimes(apis.length);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('exits with code 0 when bundles definitions', async () => {
|
|
48
|
-
const apis = ['foo.yaml', 'bar.yaml', 'foobar.yaml'];
|
|
49
|
-
|
|
50
|
-
await handleBundle(
|
|
51
|
-
{
|
|
52
|
-
apis,
|
|
53
|
-
ext: 'yaml',
|
|
54
|
-
format: 'codeframe',
|
|
55
|
-
},
|
|
56
|
-
'1.0.0'
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
exitCb?.();
|
|
60
|
-
expect(processExitMock).toHaveBeenCalledWith(0);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('bundles definitions w/ linting', async () => {
|
|
64
|
-
const apis = ['foo.yaml', 'bar.yaml', 'foobar.yaml'];
|
|
65
|
-
|
|
66
|
-
(getTotals as jest.Mock).mockReturnValue({
|
|
67
|
-
errors: 0,
|
|
68
|
-
warnings: 0,
|
|
69
|
-
ignored: 0,
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
await handleBundle(
|
|
73
|
-
{
|
|
74
|
-
apis,
|
|
75
|
-
ext: 'yaml',
|
|
76
|
-
format: 'codeframe',
|
|
77
|
-
lint: true,
|
|
78
|
-
},
|
|
79
|
-
'1.0.0'
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
expect(lint).toBeCalledTimes(apis.length);
|
|
83
|
-
expect(bundle).toBeCalledTimes(apis.length);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('exits with code 0 when bundles definitions w/linting w/o errors', async () => {
|
|
87
|
-
const apis = ['foo.yaml', 'bar.yaml', 'foobar.yaml'];
|
|
88
|
-
|
|
89
|
-
await handleBundle(
|
|
90
|
-
{
|
|
91
|
-
apis,
|
|
92
|
-
ext: 'yaml',
|
|
93
|
-
format: 'codeframe',
|
|
94
|
-
lint: true,
|
|
95
|
-
},
|
|
96
|
-
'1.0.0'
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
exitCb?.();
|
|
100
|
-
expect(processExitMock).toHaveBeenCalledWith(0);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('exits with code 1 when bundles definitions w/linting w/errors', async () => {
|
|
104
|
-
const apis = ['foo.yaml'];
|
|
105
|
-
|
|
106
|
-
(getTotals as jest.Mock).mockReturnValue({
|
|
107
|
-
errors: 1,
|
|
108
|
-
warnings: 0,
|
|
109
|
-
ignored: 0,
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
await handleBundle(
|
|
113
|
-
{
|
|
114
|
-
apis,
|
|
115
|
-
ext: 'yaml',
|
|
116
|
-
format: 'codeframe',
|
|
117
|
-
lint: true,
|
|
118
|
-
},
|
|
119
|
-
'1.0.0'
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
expect(lint).toBeCalledTimes(apis.length);
|
|
123
|
-
exitCb?.();
|
|
124
|
-
expect(processExitMock).toHaveBeenCalledWith(1);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it('handleError is called when bundles an invalid definition', async () => {
|
|
128
|
-
const apis = ['invalid.json'];
|
|
129
|
-
|
|
130
|
-
(bundle as jest.Mock).mockImplementationOnce(() => {
|
|
131
|
-
throw new Error('Invalid definition');
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
await handleBundle(
|
|
135
|
-
{
|
|
136
|
-
apis,
|
|
137
|
-
ext: 'json',
|
|
138
|
-
format: 'codeframe',
|
|
139
|
-
lint: false,
|
|
140
|
-
},
|
|
141
|
-
'1.0.0'
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
expect(handleError).toHaveBeenCalledTimes(1);
|
|
145
|
-
expect(handleError).toHaveBeenCalledWith(new Error('Invalid definition'), 'invalid.json');
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("handleError isn't called when bundles a valid definition", async () => {
|
|
149
|
-
const apis = ['foo.yaml'];
|
|
150
|
-
|
|
151
|
-
(getTotals as jest.Mock).mockReturnValue({
|
|
152
|
-
errors: 0,
|
|
153
|
-
warnings: 0,
|
|
154
|
-
ignored: 0,
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
await handleBundle(
|
|
158
|
-
{
|
|
159
|
-
apis,
|
|
160
|
-
ext: 'yaml',
|
|
161
|
-
format: 'codeframe',
|
|
162
|
-
lint: false,
|
|
163
|
-
},
|
|
164
|
-
'1.0.0'
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
expect(handleError).toHaveBeenCalledTimes(0);
|
|
168
|
-
});
|
|
169
|
-
});
|