@redocly/cli 1.0.0-beta.99 → 1.0.0-rc.2
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/README.md +83 -22
- package/bin/cli.js +1 -1
- package/lib/__mocks__/@redocly/openapi-core.d.ts +53 -1
- package/lib/__mocks__/@redocly/openapi-core.js +56 -5
- 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__/perf_hooks.d.ts +4 -0
- package/lib/__mocks__/perf_hooks.js +6 -0
- package/lib/__mocks__/redoc.d.ts +7 -0
- package/lib/__mocks__/redoc.js +5 -0
- package/lib/__mocks__/utils.d.ts +26 -4
- package/lib/__mocks__/utils.js +8 -3
- package/lib/__tests__/commands/build-docs.test.d.ts +1 -0
- package/lib/__tests__/commands/build-docs.test.js +59 -0
- package/lib/__tests__/commands/bundle.test.js +66 -30
- package/lib/__tests__/commands/join.test.d.ts +1 -0
- package/lib/__tests__/commands/join.test.js +85 -0
- package/lib/__tests__/commands/lint.test.d.ts +1 -0
- package/lib/__tests__/commands/lint.test.js +149 -0
- package/lib/__tests__/commands/push-region.test.js +5 -4
- package/lib/__tests__/commands/push.test.js +254 -39
- package/lib/__tests__/fetch-with-timeout.test.d.ts +1 -0
- package/lib/__tests__/fetch-with-timeout.test.js +38 -0
- package/lib/__tests__/fixtures/config.d.ts +22 -0
- package/lib/__tests__/fixtures/config.js +24 -0
- package/lib/__tests__/utils.test.js +429 -1
- package/lib/__tests__/wrapper.test.d.ts +1 -0
- package/lib/__tests__/wrapper.test.js +57 -0
- package/lib/commands/build-docs/index.d.ts +3 -0
- package/lib/commands/build-docs/index.js +50 -0
- package/{src/commands/preview-docs/preview-server/default.hbs → lib/commands/build-docs/template.hbs} +2 -3
- package/lib/commands/build-docs/types.d.ts +23 -0
- package/lib/commands/build-docs/types.js +2 -0
- package/lib/commands/build-docs/utils.d.ts +7 -0
- package/lib/commands/build-docs/utils.js +99 -0
- package/lib/commands/bundle.d.ts +10 -12
- package/lib/commands/bundle.js +25 -24
- package/lib/commands/join.d.ts +12 -3
- package/lib/commands/join.js +295 -109
- package/lib/commands/lint.d.ts +11 -8
- package/lib/commands/lint.js +49 -19
- package/lib/commands/login.d.ts +5 -3
- package/lib/commands/login.js +2 -2
- package/lib/commands/preview-docs/index.d.ts +6 -6
- package/lib/commands/preview-docs/index.js +30 -20
- package/lib/commands/preview-docs/preview-server/oauth2-redirect.html +1 -1
- package/lib/commands/preview-docs/preview-server/preview-server.js +5 -4
- package/lib/commands/preview-docs/preview-server/server.d.ts +1 -1
- package/lib/commands/push.d.ts +21 -10
- package/lib/commands/push.js +110 -63
- package/lib/commands/split/__tests__/index.test.js +10 -8
- package/lib/commands/split/index.d.ts +5 -3
- package/lib/commands/split/index.js +15 -24
- package/lib/commands/split/types.d.ts +11 -11
- package/lib/commands/split/types.js +19 -19
- package/lib/commands/stats.d.ts +7 -4
- package/lib/commands/stats.js +13 -12
- package/lib/fetch-with-timeout.d.ts +2 -0
- package/lib/fetch-with-timeout.js +30 -0
- package/lib/index.js +194 -40
- package/lib/js-utils.d.ts +1 -0
- package/lib/js-utils.js +9 -3
- package/lib/types.d.ts +17 -1
- package/lib/update-version-notifier.d.ts +3 -0
- package/lib/update-version-notifier.js +105 -0
- package/lib/utils.d.ts +38 -5
- package/lib/utils.js +270 -41
- package/lib/wrapper.d.ts +4 -0
- package/lib/wrapper.js +52 -0
- package/package.json +18 -8
- package/src/__mocks__/@redocly/openapi-core.ts +0 -26
- package/src/__mocks__/fs.ts +0 -4
- package/src/__mocks__/utils.ts +0 -11
- package/src/__tests__/commands/bundle.test.ts +0 -120
- package/src/__tests__/commands/push-region.test.ts +0 -51
- package/src/__tests__/commands/push.test.ts +0 -158
- package/src/__tests__/utils.test.ts +0 -50
- package/src/assert-node-version.ts +0 -8
- package/src/commands/bundle.ts +0 -180
- package/src/commands/join.ts +0 -488
- package/src/commands/lint.ts +0 -110
- package/src/commands/login.ts +0 -21
- package/src/commands/preview-docs/index.ts +0 -188
- 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 -155
- package/src/commands/preview-docs/preview-server/server.ts +0 -91
- package/src/commands/push.ts +0 -357
- 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 -117
- package/src/commands/split/index.ts +0 -349
- package/src/commands/split/types.ts +0 -73
- package/src/commands/stats.ts +0 -115
- package/src/index.ts +0 -316
- package/src/js-utils.ts +0 -12
- package/src/types.ts +0 -13
- package/src/utils.ts +0 -307
- package/tsconfig.json +0 -9
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { lint, bundle, getTotals, getMergedConfig } from '@redocly/openapi-core';
|
|
2
|
-
|
|
3
|
-
import { handleBundle } from '../../commands/bundle';
|
|
4
|
-
import SpyInstance = jest.SpyInstance;
|
|
5
|
-
|
|
6
|
-
jest.mock('@redocly/openapi-core');
|
|
7
|
-
jest.mock('../../utils');
|
|
8
|
-
|
|
9
|
-
(getMergedConfig as jest.Mock).mockImplementation(config => config)
|
|
10
|
-
|
|
11
|
-
describe('bundle', () => {
|
|
12
|
-
let processExitMock: SpyInstance;
|
|
13
|
-
let exitCb: any;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
processExitMock = jest.spyOn(process, 'exit').mockImplementation();
|
|
17
|
-
jest.spyOn(process, 'once').mockImplementation((_e, cb) => {
|
|
18
|
-
exitCb = cb;
|
|
19
|
-
return process.on(_e, cb);
|
|
20
|
-
});
|
|
21
|
-
jest.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
afterEach(() => {
|
|
25
|
-
(lint as jest.Mock).mockClear();
|
|
26
|
-
(bundle as jest.Mock).mockClear();
|
|
27
|
-
(getTotals as jest.Mock).mockClear();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('bundles definitions w/o linting', async () => {
|
|
31
|
-
const entrypoints = ['foo.yaml', 'bar.yaml'];
|
|
32
|
-
|
|
33
|
-
await handleBundle(
|
|
34
|
-
{
|
|
35
|
-
entrypoints,
|
|
36
|
-
ext: 'yaml',
|
|
37
|
-
format: 'codeframe',
|
|
38
|
-
},
|
|
39
|
-
'1.0.0',
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
expect(lint).toBeCalledTimes(0);
|
|
43
|
-
expect(bundle).toBeCalledTimes(entrypoints.length);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('exits with code 0 when bundles definitions', async () => {
|
|
47
|
-
const entrypoints = ['foo.yaml', 'bar.yaml', 'foobar.yaml'];
|
|
48
|
-
|
|
49
|
-
await handleBundle(
|
|
50
|
-
{
|
|
51
|
-
entrypoints,
|
|
52
|
-
ext: 'yaml',
|
|
53
|
-
format: 'codeframe',
|
|
54
|
-
},
|
|
55
|
-
'1.0.0',
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
exitCb?.();
|
|
59
|
-
expect(processExitMock).toHaveBeenCalledWith(0);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('bundles definitions w/ linting', async () => {
|
|
63
|
-
const entrypoints = ['foo.yaml', 'bar.yaml', 'foobar.yaml'];
|
|
64
|
-
|
|
65
|
-
await handleBundle(
|
|
66
|
-
{
|
|
67
|
-
entrypoints,
|
|
68
|
-
ext: 'yaml',
|
|
69
|
-
format: 'codeframe',
|
|
70
|
-
lint: true,
|
|
71
|
-
},
|
|
72
|
-
'1.0.0',
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
expect(lint).toBeCalledTimes(entrypoints.length);
|
|
76
|
-
expect(bundle).toBeCalledTimes(entrypoints.length);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('exits with code 0 when bundles definitions w/linting w/o errors', async () => {
|
|
80
|
-
const entrypoints = ['foo.yaml', 'bar.yaml', 'foobar.yaml'];
|
|
81
|
-
|
|
82
|
-
await handleBundle(
|
|
83
|
-
{
|
|
84
|
-
entrypoints,
|
|
85
|
-
ext: 'yaml',
|
|
86
|
-
format: 'codeframe',
|
|
87
|
-
lint: true,
|
|
88
|
-
},
|
|
89
|
-
'1.0.0',
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
exitCb?.();
|
|
93
|
-
expect(processExitMock).toHaveBeenCalledWith(0);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('exits with code 1 when bundles definitions w/linting w/errors', async () => {
|
|
97
|
-
const entrypoints = ['foo.yaml'];
|
|
98
|
-
|
|
99
|
-
(getTotals as jest.Mock).mockReturnValue({
|
|
100
|
-
errors: 1,
|
|
101
|
-
warnings: 0,
|
|
102
|
-
ignored: 0
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
await handleBundle(
|
|
106
|
-
{
|
|
107
|
-
entrypoints,
|
|
108
|
-
ext: 'yaml',
|
|
109
|
-
format: 'codeframe',
|
|
110
|
-
lint: true,
|
|
111
|
-
},
|
|
112
|
-
'1.0.0',
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
expect(lint).toBeCalledTimes(entrypoints.length);
|
|
116
|
-
exitCb?.();
|
|
117
|
-
expect(processExitMock).toHaveBeenCalledWith(1);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
});
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { getMergedConfig } from '@redocly/openapi-core';
|
|
2
|
-
import { handlePush } from '../../commands/push';
|
|
3
|
-
import { promptClientToken } from '../../commands/login';
|
|
4
|
-
|
|
5
|
-
jest.mock('fs');
|
|
6
|
-
jest.mock('node-fetch', () => ({
|
|
7
|
-
default: jest.fn(() => ({
|
|
8
|
-
ok: true,
|
|
9
|
-
json: jest.fn().mockResolvedValue({}),
|
|
10
|
-
})),
|
|
11
|
-
}));
|
|
12
|
-
jest.mock('@redocly/openapi-core');
|
|
13
|
-
jest.mock('../../commands/login');
|
|
14
|
-
jest.mock('../../utils');
|
|
15
|
-
|
|
16
|
-
(getMergedConfig as jest.Mock).mockImplementation((config) => config);
|
|
17
|
-
|
|
18
|
-
const mockPromptClientToken = promptClientToken as jest.MockedFunction<typeof promptClientToken>;
|
|
19
|
-
|
|
20
|
-
describe('push-with-region', () => {
|
|
21
|
-
const redoclyClient = require('@redocly/openapi-core').__redoclyClient;
|
|
22
|
-
redoclyClient.isAuthorizedWithRedoclyByRegion = jest.fn().mockResolvedValue(false);
|
|
23
|
-
|
|
24
|
-
beforeAll(() => {
|
|
25
|
-
jest.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('should call login with default domain when region is US', async () => {
|
|
29
|
-
redoclyClient.domain = 'redoc.ly';
|
|
30
|
-
await handlePush({
|
|
31
|
-
upsert: true,
|
|
32
|
-
entrypoint: 'spec.json',
|
|
33
|
-
destination: '@org/my-api@1.0.0',
|
|
34
|
-
branchName: 'test',
|
|
35
|
-
});
|
|
36
|
-
expect(mockPromptClientToken).toBeCalledTimes(1);
|
|
37
|
-
expect(mockPromptClientToken).toHaveBeenCalledWith(redoclyClient.domain);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('should call login with EU domain when region is EU', async () => {
|
|
41
|
-
redoclyClient.domain = 'eu.redocly.com';
|
|
42
|
-
await handlePush({
|
|
43
|
-
upsert: true,
|
|
44
|
-
entrypoint: 'spec.json',
|
|
45
|
-
destination: '@org/my-api@1.0.0',
|
|
46
|
-
branchName: 'test',
|
|
47
|
-
});
|
|
48
|
-
expect(mockPromptClientToken).toBeCalledTimes(1);
|
|
49
|
-
expect(mockPromptClientToken).toHaveBeenCalledWith(redoclyClient.domain);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { Config, getMergedConfig } from '@redocly/openapi-core';
|
|
2
|
-
import {
|
|
3
|
-
getApiEntrypoint,
|
|
4
|
-
getDestinationProps,
|
|
5
|
-
handlePush,
|
|
6
|
-
transformPush,
|
|
7
|
-
} from '../../commands/push';
|
|
8
|
-
|
|
9
|
-
jest.mock('fs');
|
|
10
|
-
jest.mock('node-fetch', () => ({
|
|
11
|
-
default: jest.fn(() => ({
|
|
12
|
-
ok: true,
|
|
13
|
-
json: jest.fn().mockResolvedValue({}),
|
|
14
|
-
})),
|
|
15
|
-
}));
|
|
16
|
-
jest.mock('@redocly/openapi-core');
|
|
17
|
-
jest.mock('../../utils');
|
|
18
|
-
|
|
19
|
-
(getMergedConfig as jest.Mock).mockImplementation((config) => config);
|
|
20
|
-
|
|
21
|
-
describe('push', () => {
|
|
22
|
-
const redoclyClient = require('@redocly/openapi-core').__redoclyClient;
|
|
23
|
-
|
|
24
|
-
beforeEach(() => {
|
|
25
|
-
jest.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('pushes definition', async () => {
|
|
29
|
-
await handlePush({
|
|
30
|
-
upsert: true,
|
|
31
|
-
entrypoint: 'spec.json',
|
|
32
|
-
destination: '@org/my-api@1.0.0',
|
|
33
|
-
branchName: 'test',
|
|
34
|
-
'public': true
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
expect(redoclyClient.registryApi.prepareFileUpload).toBeCalledTimes(1);
|
|
38
|
-
expect(redoclyClient.registryApi.pushApi).toBeCalledTimes(1);
|
|
39
|
-
expect(redoclyClient.registryApi.pushApi).toHaveBeenLastCalledWith({
|
|
40
|
-
branch: 'test',
|
|
41
|
-
filePaths: ['filePath'],
|
|
42
|
-
isUpsert: true,
|
|
43
|
-
isPublic: true,
|
|
44
|
-
name: 'my-api',
|
|
45
|
-
organizationId: 'org',
|
|
46
|
-
rootFilePath: 'filePath',
|
|
47
|
-
version: '1.0.0',
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('transformPush', () => {
|
|
53
|
-
it('should adapt the existing syntax', () => {
|
|
54
|
-
const cb = jest.fn();
|
|
55
|
-
transformPush(cb)({
|
|
56
|
-
maybeEntrypointOrAliasOrDestination: 'openapi.yaml',
|
|
57
|
-
maybeDestination: '@testing_org/main@v1',
|
|
58
|
-
});
|
|
59
|
-
expect(cb).toBeCalledWith({
|
|
60
|
-
entrypoint: 'openapi.yaml',
|
|
61
|
-
destination: '@testing_org/main@v1',
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
it('should adapt the existing syntax (including branchName)', () => {
|
|
65
|
-
const cb = jest.fn();
|
|
66
|
-
transformPush(cb)({
|
|
67
|
-
maybeEntrypointOrAliasOrDestination: 'openapi.yaml',
|
|
68
|
-
maybeDestination: '@testing_org/main@v1',
|
|
69
|
-
maybeBranchName: 'other',
|
|
70
|
-
});
|
|
71
|
-
expect(cb).toBeCalledWith({
|
|
72
|
-
entrypoint: 'openapi.yaml',
|
|
73
|
-
destination: '@testing_org/main@v1',
|
|
74
|
-
branchName: 'other',
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
it('should use --branch option firstly', () => {
|
|
78
|
-
const cb = jest.fn();
|
|
79
|
-
transformPush(cb)({
|
|
80
|
-
maybeEntrypointOrAliasOrDestination: 'openapi.yaml',
|
|
81
|
-
maybeDestination: '@testing_org/main@v1',
|
|
82
|
-
maybeBranchName: 'other',
|
|
83
|
-
branch: 'priority-branch',
|
|
84
|
-
});
|
|
85
|
-
expect(cb).toBeCalledWith({
|
|
86
|
-
entrypoint: 'openapi.yaml',
|
|
87
|
-
destination: '@testing_org/main@v1',
|
|
88
|
-
branchName: 'priority-branch',
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
it('should work for a destination only', () => {
|
|
92
|
-
const cb = jest.fn();
|
|
93
|
-
transformPush(cb)({
|
|
94
|
-
maybeEntrypointOrAliasOrDestination: '@testing_org/main@v1',
|
|
95
|
-
});
|
|
96
|
-
expect(cb).toBeCalledWith({
|
|
97
|
-
destination: '@testing_org/main@v1',
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
it('should accept aliases for the old syntax', () => {
|
|
101
|
-
const cb = jest.fn();
|
|
102
|
-
transformPush(cb)({
|
|
103
|
-
maybeEntrypointOrAliasOrDestination: 'alias',
|
|
104
|
-
maybeDestination: '@testing_org/main@v1',
|
|
105
|
-
});
|
|
106
|
-
expect(cb).toBeCalledWith({
|
|
107
|
-
destination: '@testing_org/main@v1',
|
|
108
|
-
entrypoint: 'alias',
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
it('should accept no arguments at all', () => {
|
|
112
|
-
const cb = jest.fn();
|
|
113
|
-
transformPush(cb)({});
|
|
114
|
-
expect(cb).toBeCalledWith({});
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
describe('getDestinationProps', () => {
|
|
119
|
-
it('should get valid destination props for the full destination syntax', () => {
|
|
120
|
-
expect(getDestinationProps('@testing_org/main@v1', 'org-from-config')).toEqual([
|
|
121
|
-
'testing_org',
|
|
122
|
-
'main',
|
|
123
|
-
'v1',
|
|
124
|
-
]);
|
|
125
|
-
});
|
|
126
|
-
it('should fallback the organizationId from a config for the short destination syntax', () => {
|
|
127
|
-
expect(getDestinationProps('main@v1', 'org-from-config')).toEqual([
|
|
128
|
-
'org-from-config',
|
|
129
|
-
'main',
|
|
130
|
-
'v1',
|
|
131
|
-
]);
|
|
132
|
-
});
|
|
133
|
-
it('should fallback the organizationId from a config if no destination provided', () => {
|
|
134
|
-
expect(getDestinationProps(undefined, 'org-from-config')).toEqual(['org-from-config']);
|
|
135
|
-
});
|
|
136
|
-
it('should return empty organizationId if there is no one found', () => {
|
|
137
|
-
expect(getDestinationProps('main@v1', undefined)).toEqual([, 'main', 'v1']);
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe('getApiEntrypoint', () => {
|
|
142
|
-
let config: Config = {
|
|
143
|
-
apis: {
|
|
144
|
-
'main@v1': {
|
|
145
|
-
root: 'openapi.yaml',
|
|
146
|
-
},
|
|
147
|
-
main: {
|
|
148
|
-
root: 'latest.yaml',
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
} as unknown as Config;
|
|
152
|
-
it('should resolve the correct api for a valid name & version', () => {
|
|
153
|
-
expect(getApiEntrypoint({ name: 'main', version: 'v1', config })).toEqual('openapi.yaml');
|
|
154
|
-
});
|
|
155
|
-
it('should resolve the latest version of api if there is no matching version', () => {
|
|
156
|
-
expect(getApiEntrypoint({ name: 'main', version: 'latest', config })).toEqual('latest.yaml');
|
|
157
|
-
});
|
|
158
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { isSubdir, pathToFilename } from '../utils';
|
|
2
|
-
|
|
3
|
-
jest.mock("os");
|
|
4
|
-
|
|
5
|
-
describe('isSubdir', () => {
|
|
6
|
-
it('can correctly determine if subdir', () => {
|
|
7
|
-
(
|
|
8
|
-
[
|
|
9
|
-
['/foo', '/foo', false],
|
|
10
|
-
['/foo', '/bar', false],
|
|
11
|
-
['/foo', '/foobar', false],
|
|
12
|
-
['/foo', '/foo/bar', true],
|
|
13
|
-
['/foo', '/foo/../bar', false],
|
|
14
|
-
['/foo', '/foo/./bar', true],
|
|
15
|
-
['/bar/../foo', '/foo/bar', true],
|
|
16
|
-
['/foo', './bar', false],
|
|
17
|
-
['/foo', '/foo/..bar', true],
|
|
18
|
-
] as [string, string, boolean][]
|
|
19
|
-
).forEach(([parent, child, expectRes]) => {
|
|
20
|
-
expect(isSubdir(parent, child)).toBe(expectRes);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('can correctly determine if subdir for windows-based paths', () => {
|
|
25
|
-
const os = require('os');
|
|
26
|
-
os.platform.mockImplementation(() => 'win32');
|
|
27
|
-
|
|
28
|
-
(
|
|
29
|
-
[
|
|
30
|
-
['C:/Foo', 'C:/Foo/Bar', true],
|
|
31
|
-
['C:\\Foo', 'C:\\Bar', false],
|
|
32
|
-
['C:\\Foo', 'D:\\Foo\\Bar', false],
|
|
33
|
-
] as [string, string, boolean][]
|
|
34
|
-
).forEach(([parent, child, expectRes]) => {
|
|
35
|
-
expect(isSubdir(parent, child)).toBe(expectRes);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
afterEach(() => {
|
|
40
|
-
jest.resetModules()
|
|
41
|
-
})
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
describe('pathToFilename', () => {
|
|
46
|
-
it('should use correct path separator', () => {
|
|
47
|
-
const processedPath = pathToFilename('/user/createWithList', '_');
|
|
48
|
-
expect(processedPath).toEqual('user_createWithList');
|
|
49
|
-
});
|
|
50
|
-
});
|
package/src/commands/bundle.ts
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
formatProblems,
|
|
3
|
-
getTotals,
|
|
4
|
-
loadConfig,
|
|
5
|
-
getMergedConfig,
|
|
6
|
-
OutputFormat,
|
|
7
|
-
lint,
|
|
8
|
-
bundle,
|
|
9
|
-
} from '@redocly/openapi-core';
|
|
10
|
-
import {
|
|
11
|
-
dumpBundle,
|
|
12
|
-
getExecutionTime,
|
|
13
|
-
getFallbackEntryPointsOrExit,
|
|
14
|
-
getOutputFileName,
|
|
15
|
-
handleError,
|
|
16
|
-
printUnusedWarnings,
|
|
17
|
-
saveBundle,
|
|
18
|
-
printLintTotals,
|
|
19
|
-
} from '../utils';
|
|
20
|
-
import { OutputExtensions, Totals } from '../types';
|
|
21
|
-
import { performance } from 'perf_hooks';
|
|
22
|
-
import { blue, gray, green, red, yellow } from 'colorette';
|
|
23
|
-
import { writeFileSync } from 'fs';
|
|
24
|
-
|
|
25
|
-
export async function handleBundle(
|
|
26
|
-
argv: {
|
|
27
|
-
entrypoints: string[];
|
|
28
|
-
output?: string;
|
|
29
|
-
ext: OutputExtensions;
|
|
30
|
-
'max-problems'?: number;
|
|
31
|
-
'skip-rule'?: string[];
|
|
32
|
-
'skip-preprocessor'?: string[];
|
|
33
|
-
'skip-decorator'?: string[];
|
|
34
|
-
dereferenced?: boolean;
|
|
35
|
-
force?: boolean;
|
|
36
|
-
config?: string;
|
|
37
|
-
lint?: boolean;
|
|
38
|
-
format: OutputFormat;
|
|
39
|
-
metafile?: string;
|
|
40
|
-
extends?: string[];
|
|
41
|
-
'remove-unused-components'?: boolean;
|
|
42
|
-
'keep-url-references'?: boolean;
|
|
43
|
-
},
|
|
44
|
-
version: string,
|
|
45
|
-
) {
|
|
46
|
-
const config = await loadConfig(argv.config, argv.extends);
|
|
47
|
-
const removeUnusedComponents =
|
|
48
|
-
argv['remove-unused-components'] &&
|
|
49
|
-
!config.rawConfig.lint?.decorators?.hasOwnProperty('remove-unused-components');
|
|
50
|
-
const entrypoints = await getFallbackEntryPointsOrExit(argv.entrypoints, config);
|
|
51
|
-
const totals: Totals = { errors: 0, warnings: 0, ignored: 0 };
|
|
52
|
-
const maxProblems = argv['max-problems'];
|
|
53
|
-
|
|
54
|
-
for (const { path, alias } of entrypoints) {
|
|
55
|
-
try {
|
|
56
|
-
const startedAt = performance.now();
|
|
57
|
-
const resolvedConfig = getMergedConfig(config, alias);
|
|
58
|
-
resolvedConfig.lint.skipRules(argv['skip-rule']);
|
|
59
|
-
resolvedConfig.lint.skipPreprocessors(argv['skip-preprocessor']);
|
|
60
|
-
resolvedConfig.lint.skipDecorators(argv['skip-decorator']);
|
|
61
|
-
|
|
62
|
-
if (argv.lint) {
|
|
63
|
-
if (config.lint.recommendedFallback) {
|
|
64
|
-
process.stderr.write(
|
|
65
|
-
`No configurations were defined in extends -- using built in ${blue(
|
|
66
|
-
'recommended',
|
|
67
|
-
)} configuration by default.\n${red(
|
|
68
|
-
'Warning! This default behavior is going to be deprecated soon.',
|
|
69
|
-
)}\n\n`,
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
const results = await lint({
|
|
73
|
-
ref: path,
|
|
74
|
-
config: resolvedConfig,
|
|
75
|
-
});
|
|
76
|
-
const fileLintTotals = getTotals(results);
|
|
77
|
-
|
|
78
|
-
totals.errors += fileLintTotals.errors;
|
|
79
|
-
totals.warnings += fileLintTotals.warnings;
|
|
80
|
-
totals.ignored += fileLintTotals.ignored;
|
|
81
|
-
|
|
82
|
-
formatProblems(results, {
|
|
83
|
-
format: argv.format || 'codeframe',
|
|
84
|
-
totals: fileLintTotals,
|
|
85
|
-
version,
|
|
86
|
-
maxProblems,
|
|
87
|
-
});
|
|
88
|
-
printLintTotals(fileLintTotals, 2);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
process.stderr.write(gray(`bundling ${path}...\n`));
|
|
92
|
-
|
|
93
|
-
const {
|
|
94
|
-
bundle: result,
|
|
95
|
-
problems,
|
|
96
|
-
...meta
|
|
97
|
-
} = await bundle({
|
|
98
|
-
config: resolvedConfig,
|
|
99
|
-
ref: path,
|
|
100
|
-
dereference: argv.dereferenced,
|
|
101
|
-
removeUnusedComponents,
|
|
102
|
-
keepUrlRefs: argv['keep-url-references'],
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
const fileTotals = getTotals(problems);
|
|
106
|
-
const { outputFile, ext } = getOutputFileName(
|
|
107
|
-
path,
|
|
108
|
-
entrypoints.length,
|
|
109
|
-
argv.output,
|
|
110
|
-
argv.ext,
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
if (fileTotals.errors === 0 || argv.force) {
|
|
114
|
-
if (!argv.output) {
|
|
115
|
-
const output = dumpBundle(result.parsed, argv.ext || 'yaml', argv.dereferenced);
|
|
116
|
-
process.stdout.write(output);
|
|
117
|
-
} else {
|
|
118
|
-
const output = dumpBundle(result.parsed, ext, argv.dereferenced);
|
|
119
|
-
saveBundle(outputFile, output);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
totals.errors += fileTotals.errors;
|
|
124
|
-
totals.warnings += fileTotals.warnings;
|
|
125
|
-
totals.ignored += fileTotals.ignored;
|
|
126
|
-
|
|
127
|
-
formatProblems(problems, {
|
|
128
|
-
format: argv.format,
|
|
129
|
-
maxProblems,
|
|
130
|
-
totals: fileTotals,
|
|
131
|
-
version,
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
if (argv.metafile) {
|
|
135
|
-
if (entrypoints.length > 1) {
|
|
136
|
-
process.stderr.write(
|
|
137
|
-
yellow(`[WARNING] "--metafile" cannot be used with multiple entrypoints. Skipping...`),
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
{
|
|
141
|
-
writeFileSync(argv.metafile, JSON.stringify(meta), 'utf-8');
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const elapsed = getExecutionTime(startedAt);
|
|
146
|
-
if (fileTotals.errors > 0) {
|
|
147
|
-
if (argv.force) {
|
|
148
|
-
process.stderr.write(
|
|
149
|
-
`❓ Created a bundle for ${blue(path)} at ${blue(outputFile)} with errors ${green(
|
|
150
|
-
elapsed,
|
|
151
|
-
)}.\n${yellow('Errors ignored because of --force')}.\n`,
|
|
152
|
-
);
|
|
153
|
-
} else {
|
|
154
|
-
process.stderr.write(
|
|
155
|
-
`❌ Errors encountered while bundling ${blue(
|
|
156
|
-
path,
|
|
157
|
-
)}: bundle not created (use --force to ignore errors).\n`,
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
} else {
|
|
161
|
-
process.stderr.write(
|
|
162
|
-
`📦 Created a bundle for ${blue(path)} at ${blue(outputFile)} ${green(elapsed)}.\n`,
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const removedCount = meta.visitorsData?.['remove-unused-components']?.removedCount;
|
|
167
|
-
if (removedCount) {
|
|
168
|
-
process.stderr.write(gray(`🧹 Removed ${removedCount} unused components.\n`));
|
|
169
|
-
}
|
|
170
|
-
} catch (e) {
|
|
171
|
-
handleError(e, path);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
printUnusedWarnings(config.lint);
|
|
176
|
-
|
|
177
|
-
// defer process exit to allow STDOUT pipe to flush
|
|
178
|
-
// see https://github.com/nodejs/node-v0.x-archive/issues/3737#issuecomment-19156072
|
|
179
|
-
process.once('exit', () => process.exit(totals.errors === 0 || argv.force ? 0 : 1));
|
|
180
|
-
}
|