@redocly/cli 1.0.0-beta.108 → 1.0.0-beta.110
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/__mocks__/@redocly/openapi-core.d.ts +28 -0
- package/lib/__mocks__/@redocly/openapi-core.js +35 -1
- package/lib/__mocks__/documents.d.ts +92 -0
- package/lib/__mocks__/documents.js +63 -0
- package/lib/__mocks__/fs.d.ts +2 -0
- package/lib/__mocks__/fs.js +3 -1
- package/lib/__mocks__/redoc.d.ts +7 -0
- package/lib/__mocks__/redoc.js +5 -0
- package/lib/__mocks__/utils.d.ts +1 -0
- package/lib/__mocks__/utils.js +2 -1
- package/lib/__tests__/commands/build-docs.test.d.ts +1 -0
- package/lib/__tests__/commands/build-docs.test.js +58 -0
- package/lib/__tests__/commands/join.test.js +14 -0
- package/lib/__tests__/commands/lint.test.js +10 -2
- package/lib/__tests__/commands/push.test.js +28 -0
- package/lib/commands/build-docs/index.d.ts +2 -0
- package/lib/commands/build-docs/index.js +45 -0
- package/lib/commands/build-docs/types.d.ts +22 -0
- package/lib/commands/build-docs/types.js +2 -0
- package/lib/commands/build-docs/utils.d.ts +8 -0
- package/lib/commands/build-docs/utils.js +108 -0
- package/lib/commands/bundle.js +1 -1
- package/lib/commands/join.js +121 -43
- package/lib/commands/lint.js +9 -1
- package/lib/commands/preview-docs/index.d.ts +1 -1
- package/lib/commands/preview-docs/index.js +1 -1
- package/lib/commands/push.d.ts +1 -0
- package/lib/commands/push.js +15 -3
- package/lib/commands/split/types.d.ts +9 -9
- package/lib/commands/split/types.js +18 -18
- package/lib/commands/stats.js +3 -3
- package/lib/index.js +48 -0
- package/lib/js-utils.d.ts +1 -0
- package/lib/js-utils.js +7 -1
- package/lib/utils.js +1 -0
- package/package.json +12 -5
- package/src/__mocks__/@redocly/openapi-core.ts +38 -0
- package/src/__mocks__/documents.ts +63 -0
- package/src/__mocks__/fs.ts +2 -0
- package/src/__mocks__/redoc.ts +2 -0
- package/src/__mocks__/utils.ts +1 -0
- package/src/__tests__/commands/build-docs.test.ts +58 -0
- package/src/__tests__/commands/join.test.ts +23 -1
- package/src/__tests__/commands/lint.test.ts +10 -2
- package/src/__tests__/commands/push.test.ts +33 -1
- package/src/commands/build-docs/index.ts +39 -0
- package/src/commands/build-docs/template.hbs +23 -0
- package/src/commands/build-docs/types.ts +23 -0
- package/src/commands/build-docs/utils.ts +116 -0
- package/src/commands/bundle.ts +1 -1
- package/src/commands/join.ts +161 -52
- package/src/commands/lint.ts +10 -5
- package/src/commands/preview-docs/index.ts +2 -2
- package/src/commands/push.ts +17 -3
- package/src/commands/split/types.ts +17 -17
- package/src/commands/stats.ts +3 -3
- package/src/custom.d.ts +1 -0
- package/src/index.ts +63 -0
- package/src/js-utils.ts +5 -0
- package/src/utils.ts +1 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="jest" />
|
|
2
|
+
import { Document, ResolveError } from '@redocly/openapi-core';
|
|
2
3
|
export declare const __redoclyClient: {
|
|
3
4
|
isAuthorizedWithRedocly: jest.Mock<any, any>;
|
|
4
5
|
isAuthorizedWithRedoclyByRegion: jest.Mock<any, any>;
|
|
@@ -47,3 +48,30 @@ export declare const formatProblems: jest.Mock<any, any>;
|
|
|
47
48
|
export declare const slash: jest.Mock<any, any>;
|
|
48
49
|
export declare const findConfig: jest.Mock<any, any>;
|
|
49
50
|
export declare const doesYamlFileExist: jest.Mock<any, any>;
|
|
51
|
+
export declare const bundleDocument: jest.Mock<Promise<{
|
|
52
|
+
problems: {};
|
|
53
|
+
}>, []>;
|
|
54
|
+
export declare const detectOpenAPI: jest.Mock<any, any>;
|
|
55
|
+
export declare class BaseResolver {
|
|
56
|
+
cache: Map<string, Promise<ResolveError | Document>>;
|
|
57
|
+
getFiles: jest.Mock<any, any>;
|
|
58
|
+
resolveExternalRef: jest.Mock<any, any>;
|
|
59
|
+
loadExternalRef: typeof jest.fn;
|
|
60
|
+
parseDocument: jest.Mock<any, any>;
|
|
61
|
+
resolveDocument: jest.Mock<any, any>;
|
|
62
|
+
}
|
|
63
|
+
export declare enum OasVersion {
|
|
64
|
+
Version2 = "oas2",
|
|
65
|
+
Version3_0 = "oas3_0",
|
|
66
|
+
Version3_1 = "oas3_1"
|
|
67
|
+
}
|
|
68
|
+
export declare enum Oas3Operations {
|
|
69
|
+
get = "get",
|
|
70
|
+
put = "put",
|
|
71
|
+
post = "post",
|
|
72
|
+
delete = "delete",
|
|
73
|
+
options = "options",
|
|
74
|
+
head = "head",
|
|
75
|
+
patch = "patch",
|
|
76
|
+
trace = "trace"
|
|
77
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.doesYamlFileExist = exports.findConfig = exports.slash = exports.formatProblems = exports.getTotals = exports.bundle = exports.lint = exports.getMergedConfig = exports.loadConfig = exports.RedoclyClient = exports.__redoclyClient = void 0;
|
|
3
|
+
exports.Oas3Operations = exports.OasVersion = exports.BaseResolver = exports.detectOpenAPI = exports.bundleDocument = exports.doesYamlFileExist = exports.findConfig = exports.slash = exports.formatProblems = exports.getTotals = exports.bundle = exports.lint = exports.getMergedConfig = exports.loadConfig = exports.RedoclyClient = exports.__redoclyClient = void 0;
|
|
4
4
|
const config_1 = require("./../../__tests__/fixtures/config");
|
|
5
|
+
const documents_1 = require("../documents");
|
|
5
6
|
exports.__redoclyClient = {
|
|
6
7
|
isAuthorizedWithRedocly: jest.fn().mockResolvedValue(true),
|
|
7
8
|
isAuthorizedWithRedoclyByRegion: jest.fn().mockResolvedValue(true),
|
|
@@ -26,3 +27,36 @@ exports.formatProblems = jest.fn();
|
|
|
26
27
|
exports.slash = jest.fn();
|
|
27
28
|
exports.findConfig = jest.fn();
|
|
28
29
|
exports.doesYamlFileExist = jest.fn();
|
|
30
|
+
exports.bundleDocument = jest.fn(() => Promise.resolve({ problems: {} }));
|
|
31
|
+
exports.detectOpenAPI = jest.fn();
|
|
32
|
+
class BaseResolver {
|
|
33
|
+
constructor() {
|
|
34
|
+
this.cache = new Map();
|
|
35
|
+
this.getFiles = jest.fn();
|
|
36
|
+
this.resolveExternalRef = jest.fn();
|
|
37
|
+
this.loadExternalRef = jest.fn;
|
|
38
|
+
this.parseDocument = jest.fn();
|
|
39
|
+
this.resolveDocument = jest
|
|
40
|
+
.fn()
|
|
41
|
+
.mockImplementationOnce(() => Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: documents_1.firstDocument }))
|
|
42
|
+
.mockImplementationOnce(() => Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: documents_1.secondDocument }));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.BaseResolver = BaseResolver;
|
|
46
|
+
var OasVersion;
|
|
47
|
+
(function (OasVersion) {
|
|
48
|
+
OasVersion["Version2"] = "oas2";
|
|
49
|
+
OasVersion["Version3_0"] = "oas3_0";
|
|
50
|
+
OasVersion["Version3_1"] = "oas3_1";
|
|
51
|
+
})(OasVersion = exports.OasVersion || (exports.OasVersion = {}));
|
|
52
|
+
var Oas3Operations;
|
|
53
|
+
(function (Oas3Operations) {
|
|
54
|
+
Oas3Operations["get"] = "get";
|
|
55
|
+
Oas3Operations["put"] = "put";
|
|
56
|
+
Oas3Operations["post"] = "post";
|
|
57
|
+
Oas3Operations["delete"] = "delete";
|
|
58
|
+
Oas3Operations["options"] = "options";
|
|
59
|
+
Oas3Operations["head"] = "head";
|
|
60
|
+
Oas3Operations["patch"] = "patch";
|
|
61
|
+
Oas3Operations["trace"] = "trace";
|
|
62
|
+
})(Oas3Operations = exports.Oas3Operations || (exports.Oas3Operations = {}));
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export declare const firstDocument: {
|
|
2
|
+
openapi: string;
|
|
3
|
+
servers: {
|
|
4
|
+
url: string;
|
|
5
|
+
}[];
|
|
6
|
+
info: {
|
|
7
|
+
description: string;
|
|
8
|
+
version: string;
|
|
9
|
+
title: string;
|
|
10
|
+
termsOfService: string;
|
|
11
|
+
license: {
|
|
12
|
+
name: string;
|
|
13
|
+
url: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
paths: {
|
|
17
|
+
'/GETUser/{userId}': {
|
|
18
|
+
summary: string;
|
|
19
|
+
description: string;
|
|
20
|
+
servers: ({
|
|
21
|
+
url: string;
|
|
22
|
+
description?: undefined;
|
|
23
|
+
} | {
|
|
24
|
+
url: string;
|
|
25
|
+
description: string;
|
|
26
|
+
})[];
|
|
27
|
+
get: {
|
|
28
|
+
tags: string[];
|
|
29
|
+
summary: string;
|
|
30
|
+
description: string;
|
|
31
|
+
operationId: string;
|
|
32
|
+
servers: {
|
|
33
|
+
url: string;
|
|
34
|
+
}[];
|
|
35
|
+
};
|
|
36
|
+
parameters: {
|
|
37
|
+
name: string;
|
|
38
|
+
in: string;
|
|
39
|
+
schema: {
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
}[];
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
components: {};
|
|
46
|
+
};
|
|
47
|
+
export declare const secondDocument: {
|
|
48
|
+
openapi: string;
|
|
49
|
+
servers: {
|
|
50
|
+
url: string;
|
|
51
|
+
}[];
|
|
52
|
+
info: {
|
|
53
|
+
description: string;
|
|
54
|
+
version: string;
|
|
55
|
+
title: string;
|
|
56
|
+
termsOfService: string;
|
|
57
|
+
license: {
|
|
58
|
+
name: string;
|
|
59
|
+
url: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
post: {
|
|
63
|
+
'/GETUser/{userId}': {
|
|
64
|
+
summary: string;
|
|
65
|
+
description: string;
|
|
66
|
+
servers: ({
|
|
67
|
+
url: string;
|
|
68
|
+
description?: undefined;
|
|
69
|
+
} | {
|
|
70
|
+
url: string;
|
|
71
|
+
description: string;
|
|
72
|
+
})[];
|
|
73
|
+
get: {
|
|
74
|
+
tags: string[];
|
|
75
|
+
summary: string;
|
|
76
|
+
description: string;
|
|
77
|
+
operationId: string;
|
|
78
|
+
servers: {
|
|
79
|
+
url: string;
|
|
80
|
+
}[];
|
|
81
|
+
};
|
|
82
|
+
parameters: {
|
|
83
|
+
name: string;
|
|
84
|
+
in: string;
|
|
85
|
+
schema: {
|
|
86
|
+
description: string;
|
|
87
|
+
};
|
|
88
|
+
}[];
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
components: {};
|
|
92
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.secondDocument = exports.firstDocument = void 0;
|
|
4
|
+
exports.firstDocument = {
|
|
5
|
+
openapi: '3.0.0',
|
|
6
|
+
servers: [{ url: 'http://localhost:8080' }],
|
|
7
|
+
info: {
|
|
8
|
+
description: 'example test',
|
|
9
|
+
version: '1.0.0',
|
|
10
|
+
title: 'Swagger Petstore',
|
|
11
|
+
termsOfService: 'http://swagger.io/terms/',
|
|
12
|
+
license: {
|
|
13
|
+
name: 'Apache 2.0',
|
|
14
|
+
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
paths: {
|
|
18
|
+
'/GETUser/{userId}': {
|
|
19
|
+
summary: 'get user by id',
|
|
20
|
+
description: 'user info',
|
|
21
|
+
servers: [{ url: '/user' }, { url: '/pet', description: 'pet server' }],
|
|
22
|
+
get: {
|
|
23
|
+
tags: ['pet'],
|
|
24
|
+
summary: 'Find pet by ID',
|
|
25
|
+
description: 'Returns a single pet',
|
|
26
|
+
operationId: 'getPetById',
|
|
27
|
+
servers: [{ url: '/pet' }],
|
|
28
|
+
},
|
|
29
|
+
parameters: [{ name: 'param1', in: 'header', schema: { description: 'string' } }],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
components: {},
|
|
33
|
+
};
|
|
34
|
+
exports.secondDocument = {
|
|
35
|
+
openapi: '3.0.0',
|
|
36
|
+
servers: [{ url: 'http://localhost:8080' }],
|
|
37
|
+
info: {
|
|
38
|
+
description: 'example test',
|
|
39
|
+
version: '1.0.0',
|
|
40
|
+
title: 'Swagger Petstore',
|
|
41
|
+
termsOfService: 'http://swagger.io/terms/',
|
|
42
|
+
license: {
|
|
43
|
+
name: 'Apache 2.0',
|
|
44
|
+
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
post: {
|
|
48
|
+
'/GETUser/{userId}': {
|
|
49
|
+
summary: 'get user',
|
|
50
|
+
description: 'user information',
|
|
51
|
+
servers: [{ url: '/user' }, { url: '/pet', description: '' }],
|
|
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/lib/__mocks__/fs.d.ts
CHANGED
package/lib/__mocks__/fs.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createReadStream = exports.statSync = exports.readFileSync = exports.existsSync = void 0;
|
|
3
|
+
exports.mkdirSync = exports.writeFileSync = exports.createReadStream = exports.statSync = exports.readFileSync = exports.existsSync = void 0;
|
|
4
4
|
exports.existsSync = jest.fn();
|
|
5
5
|
exports.readFileSync = jest.fn(() => '');
|
|
6
6
|
exports.statSync = jest.fn(() => ({ size: 0 }));
|
|
7
7
|
exports.createReadStream = jest.fn();
|
|
8
|
+
exports.writeFileSync = jest.fn();
|
|
9
|
+
exports.mkdirSync = jest.fn();
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createStore = exports.loadAndBundleSpec = void 0;
|
|
4
|
+
exports.loadAndBundleSpec = jest.fn(() => Promise.resolve({ openapi: '3.0.0' }));
|
|
5
|
+
exports.createStore = jest.fn(() => Promise.resolve({ toJS: jest.fn(() => '{}') }));
|
package/lib/__mocks__/utils.d.ts
CHANGED
package/lib/__mocks__/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.exitWithError = exports.handleError = exports.getOutputFileName = exports.printLintTotals = exports.printUnusedWarnings = exports.printExecutionTime = exports.getExecutionTime = exports.pluralize = exports.slash = exports.dumpBundle = exports.getFallbackApisOrExit = void 0;
|
|
3
|
+
exports.writeYaml = exports.exitWithError = exports.handleError = exports.getOutputFileName = exports.printLintTotals = exports.printUnusedWarnings = exports.printExecutionTime = exports.getExecutionTime = exports.pluralize = exports.slash = exports.dumpBundle = exports.getFallbackApisOrExit = void 0;
|
|
4
4
|
exports.getFallbackApisOrExit = jest.fn((entrypoints) => entrypoints.map((path) => ({ path })));
|
|
5
5
|
exports.dumpBundle = jest.fn(() => '');
|
|
6
6
|
exports.slash = jest.fn();
|
|
@@ -12,3 +12,4 @@ exports.printLintTotals = jest.fn();
|
|
|
12
12
|
exports.getOutputFileName = jest.fn(() => ({ outputFile: 'test.yaml', ext: 'yaml' }));
|
|
13
13
|
exports.handleError = jest.fn();
|
|
14
14
|
exports.exitWithError = jest.fn();
|
|
15
|
+
exports.writeYaml = jest.fn();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
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
|
+
const redoc_1 = require("redoc");
|
|
13
|
+
const server_1 = require("react-dom/server");
|
|
14
|
+
const build_docs_1 = require("../../commands/build-docs");
|
|
15
|
+
const utils_1 = require("../../commands/build-docs/utils");
|
|
16
|
+
jest.mock('redoc');
|
|
17
|
+
jest.mock('fs');
|
|
18
|
+
const config = {
|
|
19
|
+
output: '',
|
|
20
|
+
cdn: false,
|
|
21
|
+
title: 'Test',
|
|
22
|
+
disableGoogleFont: false,
|
|
23
|
+
templateFileName: '',
|
|
24
|
+
templateOptions: {},
|
|
25
|
+
redocOptions: {},
|
|
26
|
+
};
|
|
27
|
+
jest.mock('react-dom/server', () => ({
|
|
28
|
+
renderToString: jest.fn(),
|
|
29
|
+
}));
|
|
30
|
+
jest.mock('handlebars', () => ({
|
|
31
|
+
compile: jest.fn(() => jest.fn(() => '<html></html>')),
|
|
32
|
+
}));
|
|
33
|
+
jest.mock('mkdirp', () => ({
|
|
34
|
+
sync: jest.fn(),
|
|
35
|
+
}));
|
|
36
|
+
describe('build-docs', () => {
|
|
37
|
+
it('should return correct html and call function for ssr', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
const result = yield utils_1.getPageHTML({}, '../some-path/openapi.yaml', Object.assign(Object.assign({}, config), { redocCurrentVersion: '2.0.0' }));
|
|
39
|
+
expect(server_1.renderToString).toBeCalledTimes(1);
|
|
40
|
+
expect(redoc_1.createStore).toBeCalledTimes(1);
|
|
41
|
+
expect(result).toBe('<html></html>');
|
|
42
|
+
}));
|
|
43
|
+
it('should work correctly when calling handlerBuildCommand', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
|
+
const processExitMock = jest.spyOn(process, 'exit').mockImplementation();
|
|
45
|
+
yield build_docs_1.handlerBuildCommand({
|
|
46
|
+
o: '',
|
|
47
|
+
cdn: false,
|
|
48
|
+
title: 'test',
|
|
49
|
+
disableGoogleFont: false,
|
|
50
|
+
template: '',
|
|
51
|
+
templateOptions: {},
|
|
52
|
+
options: {},
|
|
53
|
+
api: '../some-path/openapi.yaml',
|
|
54
|
+
});
|
|
55
|
+
expect(redoc_1.loadAndBundleSpec).toBeCalledTimes(1);
|
|
56
|
+
expect(processExitMock).toBeCalledTimes(0);
|
|
57
|
+
}));
|
|
58
|
+
});
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const join_1 = require("../../commands/join");
|
|
13
13
|
const utils_1 = require("../../utils");
|
|
14
14
|
const colorette_1 = require("colorette");
|
|
15
|
+
const openapi_core_1 = require("@redocly/openapi-core");
|
|
15
16
|
jest.mock('../../utils');
|
|
16
17
|
jest.mock('colorette');
|
|
17
18
|
describe('handleJoin fails', () => {
|
|
@@ -38,4 +39,17 @@ describe('handleJoin fails', () => {
|
|
|
38
39
|
}, 'cli-version');
|
|
39
40
|
expect(utils_1.exitWithError).toHaveBeenCalledWith(`You use prefix-tags-with-filename, without-x-tag-groups together.\nPlease choose only one! \n\n`);
|
|
40
41
|
}));
|
|
42
|
+
it('should call exitWithError because Only OpenAPI 3 is supported', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
yield join_1.handleJoin({
|
|
44
|
+
apis: ['first.yaml', 'second.yaml'],
|
|
45
|
+
}, 'cli-version');
|
|
46
|
+
expect(utils_1.exitWithError).toHaveBeenCalledWith('Only OpenAPI 3 is supported: undefined \n\n');
|
|
47
|
+
}));
|
|
48
|
+
it('should call writeYaml function', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
openapi_core_1.detectOpenAPI.mockReturnValue('oas3_0');
|
|
50
|
+
yield join_1.handleJoin({
|
|
51
|
+
apis: ['first.yaml', 'second.yaml'],
|
|
52
|
+
}, 'cli-version');
|
|
53
|
+
expect(utils_1.writeYaml).toHaveBeenCalled();
|
|
54
|
+
}));
|
|
41
55
|
});
|
|
@@ -49,12 +49,20 @@ describe('handleLint', () => {
|
|
|
49
49
|
}));
|
|
50
50
|
it('should call loadConfig and getFallbackApisOrExit', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
51
|
yield lint_1.handleLint(argvMock, versionMock);
|
|
52
|
-
expect(openapi_core_1.loadConfig).toHaveBeenCalledWith(
|
|
52
|
+
expect(openapi_core_1.loadConfig).toHaveBeenCalledWith({
|
|
53
|
+
configPath: undefined,
|
|
54
|
+
customExtends: undefined,
|
|
55
|
+
processRawConfig: undefined,
|
|
56
|
+
});
|
|
53
57
|
expect(utils_1.getFallbackApisOrExit).toHaveBeenCalled();
|
|
54
58
|
}));
|
|
55
59
|
it('should call loadConfig with args if such exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
60
|
yield lint_1.handleLint(Object.assign(Object.assign({}, argvMock), { config: 'redocly.yaml', extends: ['some/path'] }), versionMock);
|
|
57
|
-
expect(openapi_core_1.loadConfig).toHaveBeenCalledWith(
|
|
61
|
+
expect(openapi_core_1.loadConfig).toHaveBeenCalledWith({
|
|
62
|
+
configPath: 'redocly.yaml',
|
|
63
|
+
customExtends: ['some/path'],
|
|
64
|
+
processRawConfig: undefined,
|
|
65
|
+
});
|
|
58
66
|
}));
|
|
59
67
|
it('should call mergedConfig with clear ignore if `generate-ignore-file` argv', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
68
|
yield lint_1.handleLint(Object.assign(Object.assign({}, argvMock), { 'generate-ignore-file': true }), versionMock);
|
|
@@ -9,9 +9,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const fs = require("fs");
|
|
12
13
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
13
14
|
const utils_1 = require("../../utils");
|
|
14
15
|
const push_1 = require("../../commands/push");
|
|
16
|
+
const config_1 = require("../fixtures/config");
|
|
15
17
|
jest.mock('fs');
|
|
16
18
|
jest.mock('node-fetch', () => ({
|
|
17
19
|
default: jest.fn(() => ({
|
|
@@ -76,6 +78,32 @@ describe('push', () => {
|
|
|
76
78
|
});
|
|
77
79
|
expect(utils_1.exitWithError).toBeCalledTimes(1);
|
|
78
80
|
}));
|
|
81
|
+
it('push with --files', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
|
+
openapi_core_1.loadConfig.mockImplementation(({ files }) => {
|
|
83
|
+
return Object.assign(Object.assign({}, config_1.ConfigFixture), { files });
|
|
84
|
+
});
|
|
85
|
+
//@ts-ignore
|
|
86
|
+
fs.statSync.mockImplementation(() => {
|
|
87
|
+
return { isDirectory: () => false, size: 10 };
|
|
88
|
+
});
|
|
89
|
+
yield push_1.handlePush({
|
|
90
|
+
upsert: true,
|
|
91
|
+
api: 'spec.json',
|
|
92
|
+
destination: '@org/my-api@1.0.0',
|
|
93
|
+
public: true,
|
|
94
|
+
files: ['./resouces/1.md', './resouces/2.md'],
|
|
95
|
+
});
|
|
96
|
+
expect(redoclyClient.registryApi.pushApi).toHaveBeenLastCalledWith({
|
|
97
|
+
filePaths: ['filePath', 'filePath', 'filePath'],
|
|
98
|
+
isUpsert: true,
|
|
99
|
+
isPublic: true,
|
|
100
|
+
name: 'my-api',
|
|
101
|
+
organizationId: 'org',
|
|
102
|
+
rootFilePath: 'filePath',
|
|
103
|
+
version: '1.0.0',
|
|
104
|
+
});
|
|
105
|
+
expect(redoclyClient.registryApi.prepareFileUpload).toBeCalledTimes(3);
|
|
106
|
+
}));
|
|
79
107
|
});
|
|
80
108
|
describe('transformPush', () => {
|
|
81
109
|
it('should adapt the existing syntax', () => {
|
|
@@ -0,0 +1,45 @@
|
|
|
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.handlerBuildCommand = void 0;
|
|
13
|
+
const redoc_1 = require("redoc");
|
|
14
|
+
const path_1 = require("path");
|
|
15
|
+
const fs_1 = require("fs");
|
|
16
|
+
const perf_hooks_1 = require("perf_hooks");
|
|
17
|
+
const utils_1 = require("./utils");
|
|
18
|
+
const utils_2 = require("../../utils");
|
|
19
|
+
const handlerBuildCommand = (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
const startedAt = perf_hooks_1.performance.now();
|
|
21
|
+
const config = {
|
|
22
|
+
output: argv.o,
|
|
23
|
+
cdn: argv.cdn,
|
|
24
|
+
title: argv.title,
|
|
25
|
+
disableGoogleFont: argv.disableGoogleFont,
|
|
26
|
+
templateFileName: argv.template,
|
|
27
|
+
templateOptions: argv.templateOptions || {},
|
|
28
|
+
redocOptions: utils_1.getObjectOrJSON(argv.options),
|
|
29
|
+
};
|
|
30
|
+
const redocCurrentVersion = require('../../../package.json').dependencies.redoc.substring(1); // remove ~
|
|
31
|
+
const pathToApi = argv.api;
|
|
32
|
+
try {
|
|
33
|
+
const elapsed = utils_2.getExecutionTime(startedAt);
|
|
34
|
+
const api = yield redoc_1.loadAndBundleSpec(utils_1.isURL(pathToApi) ? pathToApi : path_1.resolve(pathToApi));
|
|
35
|
+
const pageHTML = yield utils_1.getPageHTML(api, pathToApi, Object.assign(Object.assign({}, config), { redocCurrentVersion }));
|
|
36
|
+
fs_1.mkdirSync(path_1.dirname(config.output), { recursive: true });
|
|
37
|
+
fs_1.writeFileSync(config.output, pageHTML);
|
|
38
|
+
const sizeInKiB = Math.ceil(Buffer.byteLength(pageHTML) / 1024);
|
|
39
|
+
process.stderr.write(`\n🎉 bundled successfully in: ${config.output} (${sizeInKiB} KiB) [⏱ ${elapsed}].\n`);
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
utils_2.exitWithError(e);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
exports.handlerBuildCommand = handlerBuildCommand;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare type BuildDocsOptions = {
|
|
2
|
+
watch?: boolean;
|
|
3
|
+
cdn?: boolean;
|
|
4
|
+
output?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
disableGoogleFont?: boolean;
|
|
7
|
+
port?: number;
|
|
8
|
+
templateFileName?: string;
|
|
9
|
+
templateOptions?: any;
|
|
10
|
+
redocOptions?: any;
|
|
11
|
+
redocCurrentVersion: string;
|
|
12
|
+
};
|
|
13
|
+
export declare type BuildDocsArgv = {
|
|
14
|
+
api: string;
|
|
15
|
+
o: string;
|
|
16
|
+
cdn: boolean;
|
|
17
|
+
title?: string;
|
|
18
|
+
disableGoogleFont?: boolean;
|
|
19
|
+
template?: string;
|
|
20
|
+
templateOptions: Record<string, any>;
|
|
21
|
+
options: string | Record<string, unknown>;
|
|
22
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Config } from '@redocly/openapi-core';
|
|
2
|
+
import type { BuildDocsOptions } from './types';
|
|
3
|
+
export declare function getObjectOrJSON(options: string | Record<string, unknown>): JSON | Record<string, unknown> | Config;
|
|
4
|
+
export declare function getPageHTML(api: any, pathToApi: string, { cdn, title, disableGoogleFont, templateFileName, templateOptions, redocOptions, redocCurrentVersion, }: BuildDocsOptions): Promise<string>;
|
|
5
|
+
export declare function isURL(str: string): boolean;
|
|
6
|
+
export declare function sanitizeJSONString(str: string): string;
|
|
7
|
+
export declare function escapeClosingScriptTag(str: string): string;
|
|
8
|
+
export declare function escapeUnicode(str: string): string;
|
|
@@ -0,0 +1,108 @@
|
|
|
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.escapeUnicode = exports.escapeClosingScriptTag = exports.sanitizeJSONString = exports.isURL = exports.getPageHTML = exports.getObjectOrJSON = void 0;
|
|
13
|
+
const React = require("react");
|
|
14
|
+
const redoc_1 = require("redoc");
|
|
15
|
+
const openapi_core_1 = require("@redocly/openapi-core");
|
|
16
|
+
const server_1 = require("react-dom/server");
|
|
17
|
+
const styled_components_1 = require("styled-components");
|
|
18
|
+
const handlebars_1 = require("handlebars");
|
|
19
|
+
const path_1 = require("path");
|
|
20
|
+
const fs_1 = require("fs");
|
|
21
|
+
const colorette_1 = require("colorette");
|
|
22
|
+
const utils_1 = require("../../utils");
|
|
23
|
+
function getObjectOrJSON(options) {
|
|
24
|
+
switch (typeof options) {
|
|
25
|
+
case 'object':
|
|
26
|
+
return options;
|
|
27
|
+
case 'string':
|
|
28
|
+
try {
|
|
29
|
+
if (fs_1.existsSync(options) && fs_1.lstatSync(options).isFile()) {
|
|
30
|
+
return JSON.parse(fs_1.readFileSync(options, 'utf-8'));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
return JSON.parse(options);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
process.stderr.write(colorette_1.red(`Encountered error:\n\n${options}\n\nis neither a file with a valid JSON object neither a stringified JSON object.`));
|
|
38
|
+
utils_1.exitWithError(e);
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
default: {
|
|
42
|
+
const configFile = openapi_core_1.findConfig();
|
|
43
|
+
if (configFile) {
|
|
44
|
+
process.stderr.write(`Found ${configFile} and using features.openapi options`);
|
|
45
|
+
try {
|
|
46
|
+
const config = openapi_core_1.parseYaml(fs_1.readFileSync(configFile, 'utf-8'));
|
|
47
|
+
return config['features.openapi'];
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
process.stderr.write(colorette_1.yellow(`Found ${configFile} but failed to parse: ${e.message}`));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
exports.getObjectOrJSON = getObjectOrJSON;
|
|
59
|
+
function getPageHTML(api, pathToApi, { cdn, title, disableGoogleFont, templateFileName, templateOptions, redocOptions = {}, redocCurrentVersion, }) {
|
|
60
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
process.stderr.write('Prerendering docs');
|
|
62
|
+
const apiUrl = redocOptions.specUrl || (isURL(pathToApi) ? pathToApi : undefined);
|
|
63
|
+
const store = yield redoc_1.createStore(api, apiUrl, redocOptions);
|
|
64
|
+
const sheet = new styled_components_1.ServerStyleSheet();
|
|
65
|
+
const html = server_1.renderToString(sheet.collectStyles(React.createElement(redoc_1.Redoc, { store })));
|
|
66
|
+
const state = yield store.toJS();
|
|
67
|
+
const css = sheet.getStyleTags();
|
|
68
|
+
templateFileName = templateFileName ? templateFileName : path_1.join(__dirname, './template.hbs');
|
|
69
|
+
const template = handlebars_1.compile(fs_1.readFileSync(templateFileName).toString());
|
|
70
|
+
return template({
|
|
71
|
+
redocHTML: `
|
|
72
|
+
<div id="redoc">${html || ''}</div>
|
|
73
|
+
<script>
|
|
74
|
+
${`const __redoc_state = ${sanitizeJSONString(JSON.stringify(state))};` || ''}
|
|
75
|
+
|
|
76
|
+
var container = document.getElementById('redoc');
|
|
77
|
+
Redoc.${'hydrate(__redoc_state, container)'};
|
|
78
|
+
|
|
79
|
+
</script>`,
|
|
80
|
+
redocHead: (cdn
|
|
81
|
+
? '<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script>'
|
|
82
|
+
: `<script src="https://cdn.redoc.ly/redoc/v${redocCurrentVersion}/bundles/redoc.standalone.js"></script>`) +
|
|
83
|
+
css,
|
|
84
|
+
title: title || api.info.title || 'ReDoc documentation',
|
|
85
|
+
disableGoogleFont,
|
|
86
|
+
templateOptions,
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
exports.getPageHTML = getPageHTML;
|
|
91
|
+
function isURL(str) {
|
|
92
|
+
return /^(https?:)\/\//m.test(str);
|
|
93
|
+
}
|
|
94
|
+
exports.isURL = isURL;
|
|
95
|
+
function sanitizeJSONString(str) {
|
|
96
|
+
return escapeClosingScriptTag(escapeUnicode(str));
|
|
97
|
+
}
|
|
98
|
+
exports.sanitizeJSONString = sanitizeJSONString;
|
|
99
|
+
// see http://www.thespanner.co.uk/2011/07/25/the-json-specification-is-now-wrong/
|
|
100
|
+
function escapeClosingScriptTag(str) {
|
|
101
|
+
return str.replace(/<\/script>/g, '<\\/script>');
|
|
102
|
+
}
|
|
103
|
+
exports.escapeClosingScriptTag = escapeClosingScriptTag;
|
|
104
|
+
// see http://www.thespanner.co.uk/2011/07/25/the-json-specification-is-now-wrong/
|
|
105
|
+
function escapeUnicode(str) {
|
|
106
|
+
return str.replace(/\u2028|\u2029/g, (m) => '\\u202' + (m === '\u2028' ? '8' : '9'));
|
|
107
|
+
}
|
|
108
|
+
exports.escapeUnicode = escapeUnicode;
|
package/lib/commands/bundle.js
CHANGED
|
@@ -29,7 +29,7 @@ const fs_1 = require("fs");
|
|
|
29
29
|
function handleBundle(argv, version) {
|
|
30
30
|
var _a, _b, _c, _d;
|
|
31
31
|
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
-
const config = yield openapi_core_1.loadConfig(argv.config, argv.extends);
|
|
32
|
+
const config = yield openapi_core_1.loadConfig({ configPath: argv.config, customExtends: argv.extends });
|
|
33
33
|
const removeUnusedComponents = argv['remove-unused-components'] &&
|
|
34
34
|
!((_b = (_a = config.rawConfig.styleguide) === null || _a === void 0 ? void 0 : _a.decorators) === null || _b === void 0 ? void 0 : _b.hasOwnProperty('remove-unused-components'));
|
|
35
35
|
const apis = yield utils_1.getFallbackApisOrExit(argv.apis, config);
|