@redocly/cli 1.8.2 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/lib/__mocks__/@redocly/openapi-core.js +2 -1
- package/lib/__mocks__/documents.d.ts +58 -0
- package/lib/__mocks__/documents.js +63 -3
- package/lib/__tests__/commands/join.test.js +126 -3
- package/lib/cms/commands/__tests__/push-status.test.js +5 -5
- package/lib/cms/commands/push-status.js +3 -2
- package/lib/commands/join.d.ts +2 -1
- package/lib/commands/join.js +36 -50
- package/lib/commands/split/index.d.ts +3 -1
- package/lib/commands/split/index.js +10 -9
- package/lib/commands/split/types.d.ts +1 -2
- package/lib/commands/split/types.js +1 -2
- package/lib/utils/js-utils.d.ts +2 -1
- package/lib/utils/js-utils.js +8 -1
- package/package.json +2 -2
- package/src/__mocks__/@redocly/openapi-core.ts +4 -1
- package/src/__mocks__/documents.ts +63 -2
- package/src/__tests__/commands/join.test.ts +137 -3
- package/src/cms/commands/__tests__/push-status.test.ts +5 -5
- package/src/cms/commands/push-status.ts +6 -5
- package/src/commands/join.ts +56 -63
- package/src/commands/split/index.ts +24 -25
- package/src/commands/split/types.ts +1 -3
- package/src/utils/js-utils.ts +8 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @redocly/cli
|
|
2
2
|
|
|
3
|
+
## 1.9.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Adds support for using logical AND for the security schema so that the `join` command generates the correct schema.
|
|
8
|
+
- Fixed a bug with resolving $refs to file names that contain the hash symbol.
|
|
9
|
+
- Fixed a problem where the `join` command did not process schemas containing `null` values when the `--prefix-components-with-info-prop` option was used.'
|
|
10
|
+
- Updated @redocly/openapi-core to v1.9.1.
|
|
11
|
+
|
|
12
|
+
## 1.9.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- - Removed descriptions adding for x-tagGroups for the `join` command. Descriptions in x-tagGroups are not supported and cause errors on linting.
|
|
17
|
+
- Updated `info.title` to be used as a name in x-tagGroups instead of a file name for the `join` command, so you can now join files with the same names.
|
|
18
|
+
- Added new `no-required-schema-properties-undefined` rule to check if each required schema property is defined.
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Fixed an issue where using the `--prefix-components-with-info-prop` option with the `join` command caused `$refs` to include duplicated prefixes.
|
|
23
|
+
- Fixed an issue where `$ref`s ending in `#` (instead of `#/`) would break the application.
|
|
24
|
+
- Updated @redocly/openapi-core to v1.9.0.
|
|
25
|
+
|
|
3
26
|
## 1.8.2
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -41,7 +41,8 @@ class BaseResolver {
|
|
|
41
41
|
this.resolveDocument = jest
|
|
42
42
|
.fn()
|
|
43
43
|
.mockImplementationOnce(() => Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: documents_1.firstDocument }))
|
|
44
|
-
.mockImplementationOnce(() => Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: documents_1.secondDocument }))
|
|
44
|
+
.mockImplementationOnce(() => Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: documents_1.secondDocument }))
|
|
45
|
+
.mockImplementationOnce(() => Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: documents_1.thirdDocument }));
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
48
|
exports.BaseResolver = BaseResolver;
|
|
@@ -90,3 +90,61 @@ export declare const secondDocument: {
|
|
|
90
90
|
};
|
|
91
91
|
components: {};
|
|
92
92
|
};
|
|
93
|
+
export declare const thirdDocument: {
|
|
94
|
+
openapi: string;
|
|
95
|
+
info: {
|
|
96
|
+
title: string;
|
|
97
|
+
version: string;
|
|
98
|
+
};
|
|
99
|
+
servers: {
|
|
100
|
+
url: string;
|
|
101
|
+
}[];
|
|
102
|
+
paths: {};
|
|
103
|
+
components: {
|
|
104
|
+
schemas: {
|
|
105
|
+
SchemaWithNull: {
|
|
106
|
+
type: string;
|
|
107
|
+
default: null;
|
|
108
|
+
nullable: boolean;
|
|
109
|
+
};
|
|
110
|
+
SchemaWithRef: {
|
|
111
|
+
type: string;
|
|
112
|
+
properties: {
|
|
113
|
+
schemaType: {
|
|
114
|
+
type: string;
|
|
115
|
+
enum: string[];
|
|
116
|
+
};
|
|
117
|
+
foo: {
|
|
118
|
+
$ref: string;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
SchemaWithDiscriminator: {
|
|
123
|
+
discriminator: {
|
|
124
|
+
propertyName: string;
|
|
125
|
+
mapping: {
|
|
126
|
+
foo: string;
|
|
127
|
+
bar: string;
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
oneOf: ({
|
|
131
|
+
$ref: string;
|
|
132
|
+
type?: undefined;
|
|
133
|
+
properties?: undefined;
|
|
134
|
+
} | {
|
|
135
|
+
type: string;
|
|
136
|
+
properties: {
|
|
137
|
+
schemaType: {
|
|
138
|
+
type: string;
|
|
139
|
+
enum: string[];
|
|
140
|
+
};
|
|
141
|
+
bar: {
|
|
142
|
+
type: string;
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
$ref?: undefined;
|
|
146
|
+
})[];
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.secondDocument = exports.firstDocument = void 0;
|
|
3
|
+
exports.thirdDocument = exports.secondDocument = exports.firstDocument = void 0;
|
|
4
4
|
exports.firstDocument = {
|
|
5
5
|
openapi: '3.0.0',
|
|
6
6
|
servers: [{ url: 'http://localhost:8080' }],
|
|
7
7
|
info: {
|
|
8
8
|
description: 'example test',
|
|
9
9
|
version: '1.0.0',
|
|
10
|
-
title: '
|
|
10
|
+
title: 'First API',
|
|
11
11
|
termsOfService: 'http://swagger.io/terms/',
|
|
12
12
|
license: {
|
|
13
13
|
name: 'Apache 2.0',
|
|
@@ -37,7 +37,7 @@ exports.secondDocument = {
|
|
|
37
37
|
info: {
|
|
38
38
|
description: 'example test',
|
|
39
39
|
version: '1.0.0',
|
|
40
|
-
title: '
|
|
40
|
+
title: 'Second API',
|
|
41
41
|
termsOfService: 'http://swagger.io/terms/',
|
|
42
42
|
license: {
|
|
43
43
|
name: 'Apache 2.0',
|
|
@@ -61,3 +61,63 @@ exports.secondDocument = {
|
|
|
61
61
|
},
|
|
62
62
|
components: {},
|
|
63
63
|
};
|
|
64
|
+
exports.thirdDocument = {
|
|
65
|
+
openapi: '3.0.0',
|
|
66
|
+
info: {
|
|
67
|
+
title: 'Third API',
|
|
68
|
+
version: '1.0',
|
|
69
|
+
},
|
|
70
|
+
servers: [
|
|
71
|
+
{
|
|
72
|
+
url: 'https://api.server.test/v1',
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
paths: {},
|
|
76
|
+
components: {
|
|
77
|
+
schemas: {
|
|
78
|
+
SchemaWithNull: {
|
|
79
|
+
type: 'string',
|
|
80
|
+
default: null,
|
|
81
|
+
nullable: true,
|
|
82
|
+
},
|
|
83
|
+
SchemaWithRef: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: {
|
|
86
|
+
schemaType: {
|
|
87
|
+
type: 'string',
|
|
88
|
+
enum: ['foo'],
|
|
89
|
+
},
|
|
90
|
+
foo: {
|
|
91
|
+
$ref: '#/components/schemas/SchemaWithNull',
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
SchemaWithDiscriminator: {
|
|
96
|
+
discriminator: {
|
|
97
|
+
propertyName: 'schemaType',
|
|
98
|
+
mapping: {
|
|
99
|
+
foo: '#/components/schemas/SchemaWithRef',
|
|
100
|
+
bar: '#/components/schemas/SchemaWithNull',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
oneOf: [
|
|
104
|
+
{
|
|
105
|
+
$ref: '#/components/schemas/SchemaWithRef',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
type: 'object',
|
|
109
|
+
properties: {
|
|
110
|
+
schemaType: {
|
|
111
|
+
type: 'string',
|
|
112
|
+
enum: ['bar'],
|
|
113
|
+
},
|
|
114
|
+
bar: {
|
|
115
|
+
type: 'string',
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
};
|
|
@@ -9,15 +9,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const join_1 = require("../../commands/join");
|
|
13
|
-
const miscellaneous_1 = require("../../utils/miscellaneous");
|
|
14
12
|
const colorette_1 = require("colorette");
|
|
15
13
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
14
|
+
const join_1 = require("../../commands/join");
|
|
15
|
+
const miscellaneous_1 = require("../../utils/miscellaneous");
|
|
16
16
|
const openapi_core_2 = require("../../__mocks__/@redocly/openapi-core");
|
|
17
17
|
const config_1 = require("../fixtures/config");
|
|
18
18
|
jest.mock('../../utils/miscellaneous');
|
|
19
19
|
jest.mock('colorette');
|
|
20
|
-
describe('handleJoin
|
|
20
|
+
describe('handleJoin', () => {
|
|
21
21
|
const colloreteYellowMock = colorette_1.yellow;
|
|
22
22
|
colloreteYellowMock.mockImplementation((string) => string);
|
|
23
23
|
it('should call exitWithError because only one entrypoint', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -105,4 +105,127 @@ describe('handleJoin fails', () => {
|
|
|
105
105
|
expect(config.styleguide.skipDecorators).not.toHaveBeenCalled();
|
|
106
106
|
expect(config.styleguide.skipPreprocessors).not.toHaveBeenCalled();
|
|
107
107
|
}));
|
|
108
|
+
it('should handle join with prefix-components-with-info-prop and null values', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
109
|
+
openapi_core_1.detectSpec.mockReturnValue('oas3_0');
|
|
110
|
+
yield (0, join_1.handleJoin)({
|
|
111
|
+
apis: ['first.yaml', 'second.yaml', 'third.yaml'],
|
|
112
|
+
'prefix-components-with-info-prop': 'title',
|
|
113
|
+
output: 'join-result.yaml',
|
|
114
|
+
}, config_1.ConfigFixture, 'cli-version');
|
|
115
|
+
expect(miscellaneous_1.writeToFileByExtension).toHaveBeenCalledWith({
|
|
116
|
+
openapi: '3.0.0',
|
|
117
|
+
info: {
|
|
118
|
+
description: 'example test',
|
|
119
|
+
version: '1.0.0',
|
|
120
|
+
title: 'First API',
|
|
121
|
+
termsOfService: 'http://swagger.io/terms/',
|
|
122
|
+
license: {
|
|
123
|
+
name: 'Apache 2.0',
|
|
124
|
+
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
servers: [
|
|
128
|
+
{
|
|
129
|
+
url: 'http://localhost:8080',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
url: 'https://api.server.test/v1',
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
tags: [
|
|
136
|
+
{
|
|
137
|
+
name: 'pet',
|
|
138
|
+
'x-displayName': 'pet',
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
paths: {
|
|
142
|
+
'/GETUser/{userId}': {
|
|
143
|
+
summary: 'get user by id',
|
|
144
|
+
description: 'user info',
|
|
145
|
+
servers: [
|
|
146
|
+
{
|
|
147
|
+
url: '/user',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
url: '/pet',
|
|
151
|
+
description: 'pet server',
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
get: {
|
|
155
|
+
tags: ['pet'],
|
|
156
|
+
summary: 'Find pet by ID',
|
|
157
|
+
description: 'Returns a single pet',
|
|
158
|
+
operationId: 'getPetById',
|
|
159
|
+
servers: [
|
|
160
|
+
{
|
|
161
|
+
url: '/pet',
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
},
|
|
165
|
+
parameters: [
|
|
166
|
+
{
|
|
167
|
+
name: 'param1',
|
|
168
|
+
in: 'header',
|
|
169
|
+
schema: {
|
|
170
|
+
description: 'string',
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
components: {
|
|
177
|
+
schemas: {
|
|
178
|
+
'Third API_SchemaWithNull': {
|
|
179
|
+
type: 'string',
|
|
180
|
+
default: null,
|
|
181
|
+
nullable: true,
|
|
182
|
+
},
|
|
183
|
+
'Third API_SchemaWithRef': {
|
|
184
|
+
type: 'object',
|
|
185
|
+
properties: {
|
|
186
|
+
schemaType: {
|
|
187
|
+
type: 'string',
|
|
188
|
+
enum: ['foo'],
|
|
189
|
+
},
|
|
190
|
+
foo: {
|
|
191
|
+
$ref: '#/components/schemas/Third API_SchemaWithNull',
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
'Third API_SchemaWithDiscriminator': {
|
|
196
|
+
discriminator: {
|
|
197
|
+
propertyName: 'schemaType',
|
|
198
|
+
mapping: {
|
|
199
|
+
foo: '#/components/schemas/Third API_SchemaWithRef',
|
|
200
|
+
bar: '#/components/schemas/Third API_SchemaWithNull',
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
oneOf: [
|
|
204
|
+
{
|
|
205
|
+
$ref: '#/components/schemas/Third API_SchemaWithRef',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
type: 'object',
|
|
209
|
+
properties: {
|
|
210
|
+
schemaType: {
|
|
211
|
+
type: 'string',
|
|
212
|
+
enum: ['bar'],
|
|
213
|
+
},
|
|
214
|
+
bar: {
|
|
215
|
+
type: 'string',
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
'x-tagGroups': [
|
|
224
|
+
{
|
|
225
|
+
name: 'First API',
|
|
226
|
+
tags: ['pet'],
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
}, 'join-result.yaml', true);
|
|
230
|
+
}));
|
|
108
231
|
});
|
|
@@ -76,7 +76,7 @@ describe('handlePushStatus()', () => {
|
|
|
76
76
|
'max-execution-time': 1000,
|
|
77
77
|
}, mockConfig);
|
|
78
78
|
expect(process.stdout.write).toHaveBeenCalledTimes(1);
|
|
79
|
-
expect(process.stdout.write).toHaveBeenCalledWith('🚀
|
|
79
|
+
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://test-url\n');
|
|
80
80
|
}));
|
|
81
81
|
it('should return success push status for preview and production builds', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
82
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
@@ -89,8 +89,8 @@ describe('handlePushStatus()', () => {
|
|
|
89
89
|
'max-execution-time': 1000,
|
|
90
90
|
}, mockConfig);
|
|
91
91
|
expect(process.stdout.write).toHaveBeenCalledTimes(2);
|
|
92
|
-
expect(process.stdout.write).toHaveBeenCalledWith('🚀
|
|
93
|
-
expect(process.stdout.write).toHaveBeenCalledWith('🚀
|
|
92
|
+
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://test-url\n');
|
|
93
|
+
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Production deploy success.\nProduction URL: https://test-url\n');
|
|
94
94
|
}));
|
|
95
95
|
it('should return failed push status for preview build', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
96
96
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
@@ -108,7 +108,7 @@ describe('handlePushStatus()', () => {
|
|
|
108
108
|
pushId: 'test-push-id',
|
|
109
109
|
'max-execution-time': 1000,
|
|
110
110
|
}, mockConfig);
|
|
111
|
-
expect(miscellaneous_1.exitWithError).toHaveBeenCalledWith('❌
|
|
111
|
+
expect(miscellaneous_1.exitWithError).toHaveBeenCalledWith('❌ Preview deploy fail.\nPreview URL: https://test-url');
|
|
112
112
|
}));
|
|
113
113
|
it('should return success push status for preview build and print scorecards', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
114
114
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
@@ -137,7 +137,7 @@ describe('handlePushStatus()', () => {
|
|
|
137
137
|
'max-execution-time': 1000,
|
|
138
138
|
}, mockConfig);
|
|
139
139
|
expect(process.stdout.write).toHaveBeenCalledTimes(4);
|
|
140
|
-
expect(process.stdout.write).toHaveBeenCalledWith('🚀
|
|
140
|
+
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://test-url\n');
|
|
141
141
|
expect(process.stdout.write).toHaveBeenCalledWith('\nScorecard:');
|
|
142
142
|
expect(process.stdout.write).toHaveBeenCalledWith('\n Name: test-name\n Status: success\n URL: test-url\n Description: test-description\n');
|
|
143
143
|
expect(process.stdout.write).toHaveBeenCalledWith('\n');
|
|
@@ -16,6 +16,7 @@ const spinner_1 = require("../../utils/spinner");
|
|
|
16
16
|
const utils_1 = require("../utils");
|
|
17
17
|
const colorette_1 = require("colorette");
|
|
18
18
|
const api_1 = require("../api");
|
|
19
|
+
const js_utils_1 = require("../../utils/js-utils");
|
|
19
20
|
const INTERVAL = 5000;
|
|
20
21
|
function handlePushStatus(argv, config) {
|
|
21
22
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -131,10 +132,10 @@ function displayDeploymentAndBuildStatus({ status, previewUrl, spinner, buildTyp
|
|
|
131
132
|
switch (status) {
|
|
132
133
|
case 'success':
|
|
133
134
|
spinner.stop();
|
|
134
|
-
return process.stdout.write(`${colors.green(`🚀 ${
|
|
135
|
+
return process.stdout.write(`${colors.green(`🚀 ${(0, js_utils_1.capitalize)(buildType)} deploy success.`)}\n${colors.magenta(`${(0, js_utils_1.capitalize)(buildType)} URL`)}: ${colors.cyan(previewUrl)}\n`);
|
|
135
136
|
case 'failed':
|
|
136
137
|
spinner.stop();
|
|
137
|
-
throw new utils_1.DeploymentError(`${colors.red(`❌ ${
|
|
138
|
+
throw new utils_1.DeploymentError(`${colors.red(`❌ ${(0, js_utils_1.capitalize)(buildType)} deploy fail.`)}\n${colors.magenta(`${(0, js_utils_1.capitalize)(buildType)} URL`)}: ${colors.cyan(previewUrl)}`);
|
|
138
139
|
case 'pending':
|
|
139
140
|
return wait
|
|
140
141
|
? spinner.start(`${colors.yellow(`Pending ${buildType}`)}`)
|
package/lib/commands/join.d.ts
CHANGED
package/lib/commands/join.js
CHANGED
|
@@ -18,7 +18,7 @@ const openapi_core_1 = require("@redocly/openapi-core");
|
|
|
18
18
|
const miscellaneous_1 = require("../utils/miscellaneous");
|
|
19
19
|
const js_utils_1 = require("../utils/js-utils");
|
|
20
20
|
const types_1 = require("./split/types");
|
|
21
|
-
const
|
|
21
|
+
const split_1 = require("./split");
|
|
22
22
|
const Tags = 'tags';
|
|
23
23
|
const xTagGroups = 'x-tagGroups';
|
|
24
24
|
let potentialConflictsTotal = 0;
|
|
@@ -112,13 +112,14 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
112
112
|
const tagsPrefix = prefixTagsWithFilename
|
|
113
113
|
? apiFilename
|
|
114
114
|
: getInfoPrefix(info, prefixTagsWithInfoProp, 'tags');
|
|
115
|
-
const componentsPrefix = getInfoPrefix(info, prefixComponentsWithInfoProp, COMPONENTS);
|
|
115
|
+
const componentsPrefix = getInfoPrefix(info, prefixComponentsWithInfoProp, types_1.COMPONENTS);
|
|
116
116
|
if (openapi.hasOwnProperty('x-tagGroups')) {
|
|
117
117
|
process.stderr.write((0, colorette_1.yellow)(`warning: x-tagGroups at ${(0, colorette_1.blue)(api)} will be skipped \n`));
|
|
118
118
|
}
|
|
119
119
|
const context = {
|
|
120
120
|
api,
|
|
121
121
|
apiFilename,
|
|
122
|
+
apiTitle: info === null || info === void 0 ? void 0 : info.title,
|
|
122
123
|
tags,
|
|
123
124
|
potentialConflicts,
|
|
124
125
|
tagsPrefix,
|
|
@@ -128,7 +129,6 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
128
129
|
populateTags(context);
|
|
129
130
|
}
|
|
130
131
|
collectServers(openapi);
|
|
131
|
-
collectInfoDescriptions(openapi, context);
|
|
132
132
|
collectExternalDocs(openapi, context);
|
|
133
133
|
collectPaths(openapi, context);
|
|
134
134
|
collectComponents(openapi, context);
|
|
@@ -144,7 +144,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
144
144
|
}
|
|
145
145
|
(0, miscellaneous_1.writeToFileByExtension)((0, miscellaneous_1.sortTopLevelKeysForOas)(joinedDef), specFilename, noRefs);
|
|
146
146
|
(0, miscellaneous_1.printExecutionTime)('join', startedAt, specFilename);
|
|
147
|
-
function populateTags({ api, apiFilename, tags, potentialConflicts, tagsPrefix, componentsPrefix, }) {
|
|
147
|
+
function populateTags({ api, apiFilename, apiTitle, tags, potentialConflicts, tagsPrefix, componentsPrefix, }) {
|
|
148
148
|
if (!joinedDef.hasOwnProperty(Tags)) {
|
|
149
149
|
joinedDef[Tags] = [];
|
|
150
150
|
}
|
|
@@ -176,9 +176,10 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
if (!withoutXTagGroups) {
|
|
179
|
-
|
|
179
|
+
const groupName = apiTitle || apiFilename;
|
|
180
|
+
createXTagGroups(groupName);
|
|
180
181
|
if (!tagDuplicate) {
|
|
181
|
-
populateXTagGroups(entrypointTagName, getIndexGroup(
|
|
182
|
+
populateXTagGroups(entrypointTagName, getIndexGroup(groupName));
|
|
182
183
|
}
|
|
183
184
|
}
|
|
184
185
|
const doesEntrypointExist = !potentialConflicts.tags.all[entrypointTagName] ||
|
|
@@ -190,17 +191,17 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
190
191
|
];
|
|
191
192
|
}
|
|
192
193
|
}
|
|
193
|
-
function getIndexGroup(
|
|
194
|
-
return joinedDef[xTagGroups].findIndex((item) => item.name ===
|
|
194
|
+
function getIndexGroup(name) {
|
|
195
|
+
return joinedDef[xTagGroups].findIndex((item) => item.name === name);
|
|
195
196
|
}
|
|
196
|
-
function createXTagGroups(
|
|
197
|
+
function createXTagGroups(name) {
|
|
197
198
|
if (!joinedDef.hasOwnProperty(xTagGroups)) {
|
|
198
199
|
joinedDef[xTagGroups] = [];
|
|
199
200
|
}
|
|
200
|
-
if (!joinedDef[xTagGroups].some((g) => g.name ===
|
|
201
|
-
joinedDef[xTagGroups].push({ name
|
|
201
|
+
if (!joinedDef[xTagGroups].some((g) => g.name === name)) {
|
|
202
|
+
joinedDef[xTagGroups].push({ name, tags: [] });
|
|
202
203
|
}
|
|
203
|
-
const indexGroup = getIndexGroup(
|
|
204
|
+
const indexGroup = getIndexGroup(name);
|
|
204
205
|
if (!joinedDef[xTagGroups][indexGroup].hasOwnProperty(Tags)) {
|
|
205
206
|
joinedDef[xTagGroups][indexGroup][Tags] = [];
|
|
206
207
|
}
|
|
@@ -223,18 +224,6 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
223
224
|
}
|
|
224
225
|
}
|
|
225
226
|
}
|
|
226
|
-
function collectInfoDescriptions(openapi, { apiFilename, componentsPrefix }) {
|
|
227
|
-
const { info } = openapi;
|
|
228
|
-
if (info === null || info === void 0 ? void 0 : info.description) {
|
|
229
|
-
const groupIndex = joinedDef[xTagGroups] ? getIndexGroup(apiFilename) : -1;
|
|
230
|
-
if (joinedDef.hasOwnProperty(xTagGroups) &&
|
|
231
|
-
groupIndex !== -1 &&
|
|
232
|
-
joinedDef[xTagGroups][groupIndex]['tags'] &&
|
|
233
|
-
joinedDef[xTagGroups][groupIndex]['tags'].length) {
|
|
234
|
-
joinedDef[xTagGroups][groupIndex]['description'] = addComponentsPrefix(info.description, componentsPrefix);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
227
|
function collectExternalDocs(openapi, { api }) {
|
|
239
228
|
const { externalDocs } = openapi;
|
|
240
229
|
if (externalDocs) {
|
|
@@ -245,7 +234,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
245
234
|
joinedDef['externalDocs'] = externalDocs;
|
|
246
235
|
}
|
|
247
236
|
}
|
|
248
|
-
function collectPaths(openapi, { apiFilename, api, potentialConflicts, tagsPrefix, componentsPrefix }) {
|
|
237
|
+
function collectPaths(openapi, { apiFilename, apiTitle, api, potentialConflicts, tagsPrefix, componentsPrefix, }) {
|
|
249
238
|
const { paths } = openapi;
|
|
250
239
|
const operationsSet = new Set((0, js_utils_1.keysOf)(types_1.OPENAPI3_METHOD));
|
|
251
240
|
if (paths) {
|
|
@@ -365,6 +354,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
365
354
|
populateTags({
|
|
366
355
|
api,
|
|
367
356
|
apiFilename,
|
|
357
|
+
apiTitle,
|
|
368
358
|
tags: formatTags(tags),
|
|
369
359
|
potentialConflicts,
|
|
370
360
|
tagsPrefix,
|
|
@@ -376,6 +366,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
376
366
|
populateTags({
|
|
377
367
|
api,
|
|
378
368
|
apiFilename,
|
|
369
|
+
apiTitle,
|
|
379
370
|
tags: formatTags(['other']),
|
|
380
371
|
potentialConflicts,
|
|
381
372
|
tagsPrefix: tagsPrefix || apiFilename,
|
|
@@ -399,13 +390,13 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
399
390
|
function collectComponents(openapi, { api, potentialConflicts, componentsPrefix }) {
|
|
400
391
|
const { components } = openapi;
|
|
401
392
|
if (components) {
|
|
402
|
-
if (!joinedDef.hasOwnProperty(COMPONENTS)) {
|
|
403
|
-
joinedDef[COMPONENTS] = {};
|
|
393
|
+
if (!joinedDef.hasOwnProperty(types_1.COMPONENTS)) {
|
|
394
|
+
joinedDef[types_1.COMPONENTS] = {};
|
|
404
395
|
}
|
|
405
396
|
for (const [component, componentObj] of Object.entries(components)) {
|
|
406
|
-
if (!potentialConflicts[COMPONENTS].hasOwnProperty(component)) {
|
|
407
|
-
potentialConflicts[COMPONENTS][component] = {};
|
|
408
|
-
joinedDef[COMPONENTS][component] = {};
|
|
397
|
+
if (!potentialConflicts[types_1.COMPONENTS].hasOwnProperty(component)) {
|
|
398
|
+
potentialConflicts[types_1.COMPONENTS][component] = {};
|
|
399
|
+
joinedDef[types_1.COMPONENTS][component] = {};
|
|
409
400
|
}
|
|
410
401
|
for (const item of Object.keys(componentObj)) {
|
|
411
402
|
const componentPrefix = addPrefix(item, componentsPrefix);
|
|
@@ -418,7 +409,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
418
409
|
}
|
|
419
410
|
}
|
|
420
411
|
}
|
|
421
|
-
function collectWebhooks(oasVersion, openapi, { apiFilename, api, potentialConflicts, tagsPrefix, componentsPrefix }) {
|
|
412
|
+
function collectWebhooks(oasVersion, openapi, { apiFilename, apiTitle, api, potentialConflicts, tagsPrefix, componentsPrefix, }) {
|
|
422
413
|
const webhooks = oasVersion === openapi_core_1.SpecVersion.OAS3_1 ? 'webhooks' : 'x-webhooks';
|
|
423
414
|
const openapiWebhooks = openapi[webhooks];
|
|
424
415
|
if (openapiWebhooks) {
|
|
@@ -443,6 +434,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
443
434
|
populateTags({
|
|
444
435
|
api,
|
|
445
436
|
apiFilename,
|
|
437
|
+
apiTitle,
|
|
446
438
|
tags: formatTags(tags),
|
|
447
439
|
potentialConflicts,
|
|
448
440
|
tagsPrefix,
|
|
@@ -457,7 +449,7 @@ function handleJoin(argv, config, packageVersion) {
|
|
|
457
449
|
var _a;
|
|
458
450
|
const firstApi = documents[0];
|
|
459
451
|
const openapi = firstApi.parsed;
|
|
460
|
-
const componentsPrefix = getInfoPrefix(openapi.info, prefixComponentsWithInfoProp, COMPONENTS);
|
|
452
|
+
const componentsPrefix = getInfoPrefix(openapi.info, prefixComponentsWithInfoProp, types_1.COMPONENTS);
|
|
461
453
|
if (!openapi.openapi)
|
|
462
454
|
(0, miscellaneous_1.exitWithError)('Version of specification is not found in. \n');
|
|
463
455
|
if (!openapi.info)
|
|
@@ -489,7 +481,7 @@ function iteratePotentialConflicts(potentialConflicts, withoutXTagGroups) {
|
|
|
489
481
|
for (const [key, value] of Object.entries(potentialConflicts[group])) {
|
|
490
482
|
const conflicts = filterConflicts(value);
|
|
491
483
|
if (conflicts.length) {
|
|
492
|
-
if (group === COMPONENTS) {
|
|
484
|
+
if (group === types_1.COMPONENTS) {
|
|
493
485
|
for (const [_, conflict] of Object.entries(conflicts)) {
|
|
494
486
|
if (validateComponentsDifference(conflict[1])) {
|
|
495
487
|
conflict[1] = conflict[1].map((c) => Object.keys(c)[0]);
|
|
@@ -548,8 +540,11 @@ function addComponentsPrefix(description, componentsPrefix) {
|
|
|
548
540
|
function addSecurityPrefix(security, componentsPrefix) {
|
|
549
541
|
return componentsPrefix
|
|
550
542
|
? security === null || security === void 0 ? void 0 : security.map((s) => {
|
|
551
|
-
const
|
|
552
|
-
|
|
543
|
+
const joinedSecuritySchema = {};
|
|
544
|
+
for (const [key, value] of Object.entries(s)) {
|
|
545
|
+
Object.assign(joinedSecuritySchema, { [componentsPrefix + '_' + key]: value });
|
|
546
|
+
}
|
|
547
|
+
return joinedSecuritySchema;
|
|
553
548
|
})
|
|
554
549
|
: security;
|
|
555
550
|
}
|
|
@@ -579,27 +574,18 @@ function validateApi(document, config, externalRefResolver, packageVersion) {
|
|
|
579
574
|
}
|
|
580
575
|
});
|
|
581
576
|
}
|
|
582
|
-
function crawl(object, visitor) {
|
|
583
|
-
if (!(0, js_utils_1.isObject)(object))
|
|
584
|
-
return;
|
|
585
|
-
for (const key of Object.keys(object)) {
|
|
586
|
-
visitor(object, key);
|
|
587
|
-
crawl(object[key], visitor);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
577
|
function replace$Refs(obj, componentsPrefix) {
|
|
591
|
-
crawl(obj, (node) => {
|
|
592
|
-
if (node.$ref && (0,
|
|
578
|
+
(0, split_1.crawl)(obj, (node) => {
|
|
579
|
+
if (node.$ref && typeof node.$ref === 'string' && (0, split_1.startsWithComponents)(node.$ref)) {
|
|
593
580
|
const name = path.basename(node.$ref);
|
|
594
581
|
node.$ref = node.$ref.replace(name, componentsPrefix + '_' + name);
|
|
595
582
|
}
|
|
596
|
-
else if (node.discriminator &&
|
|
597
|
-
node.discriminator.mapping &&
|
|
598
|
-
(0, js_utils_1.isObject)(node.discriminator.mapping)) {
|
|
583
|
+
else if ((0, js_utils_1.isObject)(node.discriminator) && (0, js_utils_1.isObject)(node.discriminator.mapping)) {
|
|
599
584
|
const { mapping } = node.discriminator;
|
|
600
585
|
for (const name of Object.keys(mapping)) {
|
|
601
|
-
|
|
602
|
-
|
|
586
|
+
const mappingPointer = mapping[name];
|
|
587
|
+
if (typeof mappingPointer === 'string' && (0, split_1.startsWithComponents)(mappingPointer)) {
|
|
588
|
+
mapping[name] = mappingPointer
|
|
603
589
|
.split('/')
|
|
604
590
|
.map((name, i, arr) => {
|
|
605
591
|
return arr.length - 1 === i && !name.includes(componentsPrefix)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Oas3PathItem, Referenced } from './types';
|
|
1
|
+
import type { Oas3PathItem, Referenced } from './types';
|
|
2
2
|
export type SplitOptions = {
|
|
3
3
|
api: string;
|
|
4
4
|
outDir: string;
|
|
@@ -6,5 +6,7 @@ export type SplitOptions = {
|
|
|
6
6
|
config?: string;
|
|
7
7
|
};
|
|
8
8
|
export declare function handleSplit(argv: SplitOptions): Promise<void>;
|
|
9
|
+
export declare function startsWithComponents(node: string): boolean;
|
|
10
|
+
export declare function crawl(object: unknown, visitor: (node: Record<string, unknown>) => void): void;
|
|
9
11
|
declare function iteratePathItems(pathItems: Record<string, Referenced<Oas3PathItem>> | undefined, openapiDir: string, outDir: string, componentsFiles: object, pathSeparator: string, codeSamplesPathPrefix: string | undefined, ext: string): void;
|
|
10
12
|
export { iteratePathItems };
|