@redocly/cli 1.9.0 → 1.10.0
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 +20 -0
- package/lib/__mocks__/@redocly/openapi-core.d.ts +1 -0
- package/lib/__mocks__/@redocly/openapi-core.js +4 -2
- 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/api/__tests__/api.client.test.js +3 -0
- package/lib/cms/api/api-client.js +15 -4
- package/lib/commands/join.d.ts +2 -1
- package/lib/commands/join.js +21 -27
- package/lib/commands/push.js +8 -2
- 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/fetch-with-timeout.js +2 -1
- package/lib/utils/js-utils.d.ts +1 -1
- package/package.json +2 -2
- package/src/__mocks__/@redocly/openapi-core.ts +5 -1
- package/src/__mocks__/documents.ts +63 -2
- package/src/__tests__/commands/join.test.ts +137 -3
- package/src/cms/api/__tests__/api.client.test.ts +3 -0
- package/src/cms/api/api-client.ts +18 -5
- package/src/commands/join.ts +26 -32
- package/src/commands/push.ts +9 -2
- package/src/commands/split/index.ts +24 -25
- package/src/commands/split/types.ts +1 -3
- package/src/utils/fetch-with-timeout.ts +6 -1
- package/src/utils/js-utils.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -4,14 +4,13 @@ export type Definition = Oas3_1Definition | Oas3Definition | Oas2Definition;
|
|
|
4
4
|
export interface ComponentsFiles {
|
|
5
5
|
[schemas: string]: any;
|
|
6
6
|
}
|
|
7
|
-
export interface
|
|
7
|
+
export interface RefObject {
|
|
8
8
|
[$ref: string]: string;
|
|
9
9
|
}
|
|
10
10
|
export declare const COMPONENTS = "components";
|
|
11
11
|
export declare const PATHS = "paths";
|
|
12
12
|
export declare const WEBHOOKS = "webhooks";
|
|
13
13
|
export declare const xWEBHOOKS = "x-webhooks";
|
|
14
|
-
export declare const componentsPath = "#/components/";
|
|
15
14
|
export declare enum OPENAPI3_METHOD {
|
|
16
15
|
get = "get",
|
|
17
16
|
put = "put",
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OPENAPI3_COMPONENT_NAMES = exports.OPENAPI3_COMPONENT = exports.OPENAPI3_METHOD_NAMES = exports.OPENAPI3_METHOD = exports.
|
|
3
|
+
exports.OPENAPI3_COMPONENT_NAMES = exports.OPENAPI3_COMPONENT = exports.OPENAPI3_METHOD_NAMES = exports.OPENAPI3_METHOD = exports.xWEBHOOKS = exports.WEBHOOKS = exports.PATHS = exports.COMPONENTS = void 0;
|
|
4
4
|
exports.COMPONENTS = 'components';
|
|
5
5
|
exports.PATHS = 'paths';
|
|
6
6
|
exports.WEBHOOKS = 'webhooks';
|
|
7
7
|
exports.xWEBHOOKS = 'x-webhooks';
|
|
8
|
-
exports.componentsPath = `#/${exports.COMPONENTS}/`;
|
|
9
8
|
var OPENAPI3_METHOD;
|
|
10
9
|
(function (OPENAPI3_METHOD) {
|
|
11
10
|
OPENAPI3_METHOD["get"] = "get";
|
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const node_fetch_1 = require("node-fetch");
|
|
13
13
|
const abort_controller_1 = require("abort-controller");
|
|
14
|
+
const openapi_core_1 = require("@redocly/openapi-core");
|
|
14
15
|
const TIMEOUT = 3000;
|
|
15
16
|
exports.default = (url, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
17
|
try {
|
|
@@ -18,7 +19,7 @@ exports.default = (url, options = {}) => __awaiter(void 0, void 0, void 0, funct
|
|
|
18
19
|
const timeout = setTimeout(() => {
|
|
19
20
|
controller.abort();
|
|
20
21
|
}, TIMEOUT);
|
|
21
|
-
const res = yield (0, node_fetch_1.default)(url, Object.assign({ signal: controller.signal }, options));
|
|
22
|
+
const res = yield (0, node_fetch_1.default)(url, Object.assign(Object.assign({ signal: controller.signal }, options), { agent: (0, openapi_core_1.getProxyAgent)() }));
|
|
22
23
|
clearTimeout(timeout);
|
|
23
24
|
return res;
|
|
24
25
|
}
|
package/lib/utils/js-utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function isObject(obj:
|
|
1
|
+
export declare function isObject(obj: unknown): obj is Record<string, unknown>;
|
|
2
2
|
export declare function isEmptyObject(obj: any): boolean;
|
|
3
3
|
export declare function isString(str: string): boolean;
|
|
4
4
|
export declare function keysOf<T>(obj: T): (keyof T)[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"Roman Hotsiy <roman@redoc.ly> (https://redoc.ly/)"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@redocly/openapi-core": "1.
|
|
39
|
+
"@redocly/openapi-core": "1.10.0",
|
|
40
40
|
"abort-controller": "^3.0.0",
|
|
41
41
|
"chokidar": "^3.5.1",
|
|
42
42
|
"colorette": "^1.2.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ConfigFixture } from './../../__tests__/fixtures/config';
|
|
2
|
-
import { firstDocument, secondDocument } from '../documents';
|
|
2
|
+
import { firstDocument, secondDocument, thirdDocument } from '../documents';
|
|
3
3
|
|
|
4
4
|
import type { Document } from '@redocly/openapi-core';
|
|
5
5
|
|
|
@@ -21,6 +21,7 @@ export const __redoclyClient = {
|
|
|
21
21
|
export const RedoclyClient = jest.fn(() => __redoclyClient);
|
|
22
22
|
export const loadConfig = jest.fn(() => ConfigFixture);
|
|
23
23
|
export const getMergedConfig = jest.fn();
|
|
24
|
+
export const getProxyAgent = jest.fn();
|
|
24
25
|
export const lint = jest.fn();
|
|
25
26
|
export const bundle = jest.fn(() => ({ bundle: { parsed: null }, problems: null }));
|
|
26
27
|
export const getTotals = jest.fn(() => ({ errors: 0 }));
|
|
@@ -47,6 +48,9 @@ export class BaseResolver {
|
|
|
47
48
|
)
|
|
48
49
|
.mockImplementationOnce(() =>
|
|
49
50
|
Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: secondDocument })
|
|
51
|
+
)
|
|
52
|
+
.mockImplementationOnce(() =>
|
|
53
|
+
Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: thirdDocument })
|
|
50
54
|
);
|
|
51
55
|
}
|
|
52
56
|
|
|
@@ -4,7 +4,7 @@ export const firstDocument = {
|
|
|
4
4
|
info: {
|
|
5
5
|
description: 'example test',
|
|
6
6
|
version: '1.0.0',
|
|
7
|
-
title: '
|
|
7
|
+
title: 'First API',
|
|
8
8
|
termsOfService: 'http://swagger.io/terms/',
|
|
9
9
|
license: {
|
|
10
10
|
name: 'Apache 2.0',
|
|
@@ -36,7 +36,7 @@ export const secondDocument = {
|
|
|
36
36
|
info: {
|
|
37
37
|
description: 'example test',
|
|
38
38
|
version: '1.0.0',
|
|
39
|
-
title: '
|
|
39
|
+
title: 'Second API',
|
|
40
40
|
termsOfService: 'http://swagger.io/terms/',
|
|
41
41
|
license: {
|
|
42
42
|
name: 'Apache 2.0',
|
|
@@ -61,3 +61,64 @@ export const secondDocument = {
|
|
|
61
61
|
},
|
|
62
62
|
components: {},
|
|
63
63
|
};
|
|
64
|
+
|
|
65
|
+
export const thirdDocument = {
|
|
66
|
+
openapi: '3.0.0',
|
|
67
|
+
info: {
|
|
68
|
+
title: 'Third API',
|
|
69
|
+
version: '1.0',
|
|
70
|
+
},
|
|
71
|
+
servers: [
|
|
72
|
+
{
|
|
73
|
+
url: 'https://api.server.test/v1',
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
paths: {},
|
|
77
|
+
components: {
|
|
78
|
+
schemas: {
|
|
79
|
+
SchemaWithNull: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
default: null,
|
|
82
|
+
nullable: true,
|
|
83
|
+
},
|
|
84
|
+
SchemaWithRef: {
|
|
85
|
+
type: 'object',
|
|
86
|
+
properties: {
|
|
87
|
+
schemaType: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
enum: ['foo'],
|
|
90
|
+
},
|
|
91
|
+
foo: {
|
|
92
|
+
$ref: '#/components/schemas/SchemaWithNull',
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
SchemaWithDiscriminator: {
|
|
97
|
+
discriminator: {
|
|
98
|
+
propertyName: 'schemaType',
|
|
99
|
+
mapping: {
|
|
100
|
+
foo: '#/components/schemas/SchemaWithRef',
|
|
101
|
+
bar: '#/components/schemas/SchemaWithNull',
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
oneOf: [
|
|
105
|
+
{
|
|
106
|
+
$ref: '#/components/schemas/SchemaWithRef',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
type: 'object',
|
|
110
|
+
properties: {
|
|
111
|
+
schemaType: {
|
|
112
|
+
type: 'string',
|
|
113
|
+
enum: ['bar'],
|
|
114
|
+
},
|
|
115
|
+
bar: {
|
|
116
|
+
type: 'string',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { handleJoin } from '../../commands/join';
|
|
2
|
-
import { exitWithError, writeToFileByExtension, writeYaml } from '../../utils/miscellaneous';
|
|
3
1
|
import { yellow } from 'colorette';
|
|
4
2
|
import { detectSpec } from '@redocly/openapi-core';
|
|
3
|
+
import { handleJoin } from '../../commands/join';
|
|
4
|
+
import { exitWithError, writeToFileByExtension } from '../../utils/miscellaneous';
|
|
5
5
|
import { loadConfig } from '../../__mocks__/@redocly/openapi-core';
|
|
6
6
|
import { ConfigFixture } from '../fixtures/config';
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ jest.mock('../../utils/miscellaneous');
|
|
|
9
9
|
|
|
10
10
|
jest.mock('colorette');
|
|
11
11
|
|
|
12
|
-
describe('handleJoin
|
|
12
|
+
describe('handleJoin', () => {
|
|
13
13
|
const colloreteYellowMock = yellow as jest.Mock<any, any>;
|
|
14
14
|
colloreteYellowMock.mockImplementation((string: string) => string);
|
|
15
15
|
|
|
@@ -181,4 +181,138 @@ describe('handleJoin fails', () => {
|
|
|
181
181
|
expect(config.styleguide.skipDecorators).not.toHaveBeenCalled();
|
|
182
182
|
expect(config.styleguide.skipPreprocessors).not.toHaveBeenCalled();
|
|
183
183
|
});
|
|
184
|
+
|
|
185
|
+
it('should handle join with prefix-components-with-info-prop and null values', async () => {
|
|
186
|
+
(detectSpec as jest.Mock).mockReturnValue('oas3_0');
|
|
187
|
+
|
|
188
|
+
await handleJoin(
|
|
189
|
+
{
|
|
190
|
+
apis: ['first.yaml', 'second.yaml', 'third.yaml'],
|
|
191
|
+
'prefix-components-with-info-prop': 'title',
|
|
192
|
+
output: 'join-result.yaml',
|
|
193
|
+
},
|
|
194
|
+
ConfigFixture as any,
|
|
195
|
+
'cli-version'
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
expect(writeToFileByExtension).toHaveBeenCalledWith(
|
|
199
|
+
{
|
|
200
|
+
openapi: '3.0.0',
|
|
201
|
+
info: {
|
|
202
|
+
description: 'example test',
|
|
203
|
+
version: '1.0.0',
|
|
204
|
+
title: 'First API',
|
|
205
|
+
termsOfService: 'http://swagger.io/terms/',
|
|
206
|
+
license: {
|
|
207
|
+
name: 'Apache 2.0',
|
|
208
|
+
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
servers: [
|
|
212
|
+
{
|
|
213
|
+
url: 'http://localhost:8080',
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
url: 'https://api.server.test/v1',
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
tags: [
|
|
220
|
+
{
|
|
221
|
+
name: 'pet',
|
|
222
|
+
'x-displayName': 'pet',
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
paths: {
|
|
226
|
+
'/GETUser/{userId}': {
|
|
227
|
+
summary: 'get user by id',
|
|
228
|
+
description: 'user info',
|
|
229
|
+
servers: [
|
|
230
|
+
{
|
|
231
|
+
url: '/user',
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
url: '/pet',
|
|
235
|
+
description: 'pet server',
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
get: {
|
|
239
|
+
tags: ['pet'],
|
|
240
|
+
summary: 'Find pet by ID',
|
|
241
|
+
description: 'Returns a single pet',
|
|
242
|
+
operationId: 'getPetById',
|
|
243
|
+
servers: [
|
|
244
|
+
{
|
|
245
|
+
url: '/pet',
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
},
|
|
249
|
+
parameters: [
|
|
250
|
+
{
|
|
251
|
+
name: 'param1',
|
|
252
|
+
in: 'header',
|
|
253
|
+
schema: {
|
|
254
|
+
description: 'string',
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
components: {
|
|
261
|
+
schemas: {
|
|
262
|
+
Third_API_SchemaWithNull: {
|
|
263
|
+
type: 'string',
|
|
264
|
+
default: null,
|
|
265
|
+
nullable: true,
|
|
266
|
+
},
|
|
267
|
+
Third_API_SchemaWithRef: {
|
|
268
|
+
type: 'object',
|
|
269
|
+
properties: {
|
|
270
|
+
schemaType: {
|
|
271
|
+
type: 'string',
|
|
272
|
+
enum: ['foo'],
|
|
273
|
+
},
|
|
274
|
+
foo: {
|
|
275
|
+
$ref: '#/components/schemas/Third_API_SchemaWithNull',
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
Third_API_SchemaWithDiscriminator: {
|
|
280
|
+
discriminator: {
|
|
281
|
+
propertyName: 'schemaType',
|
|
282
|
+
mapping: {
|
|
283
|
+
foo: '#/components/schemas/Third_API_SchemaWithRef',
|
|
284
|
+
bar: '#/components/schemas/Third_API_SchemaWithNull',
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
oneOf: [
|
|
288
|
+
{
|
|
289
|
+
$ref: '#/components/schemas/Third_API_SchemaWithRef',
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
type: 'object',
|
|
293
|
+
properties: {
|
|
294
|
+
schemaType: {
|
|
295
|
+
type: 'string',
|
|
296
|
+
enum: ['bar'],
|
|
297
|
+
},
|
|
298
|
+
bar: {
|
|
299
|
+
type: 'string',
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
'x-tagGroups': [
|
|
308
|
+
{
|
|
309
|
+
name: 'First API',
|
|
310
|
+
tags: ['pet'],
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
},
|
|
314
|
+
'join-result.yaml',
|
|
315
|
+
true
|
|
316
|
+
);
|
|
317
|
+
});
|
|
184
318
|
});
|
|
@@ -42,6 +42,7 @@ describe('ApiClient', () => {
|
|
|
42
42
|
'Content-Type': 'application/json',
|
|
43
43
|
Authorization: `Bearer ${testToken}`,
|
|
44
44
|
},
|
|
45
|
+
signal: expect.any(Object),
|
|
45
46
|
}
|
|
46
47
|
);
|
|
47
48
|
|
|
@@ -122,6 +123,8 @@ describe('ApiClient', () => {
|
|
|
122
123
|
type: 'CICD',
|
|
123
124
|
autoMerge: true,
|
|
124
125
|
}),
|
|
126
|
+
signal: expect.any(Object),
|
|
127
|
+
agent: undefined,
|
|
125
128
|
}
|
|
126
129
|
);
|
|
127
130
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fetchWithTimeout from '../../utils/fetch-with-timeout';
|
|
2
2
|
import fetch from 'node-fetch';
|
|
3
3
|
import * as FormData from 'form-data';
|
|
4
|
-
|
|
4
|
+
import { getProxyAgent } from '@redocly/openapi-core';
|
|
5
5
|
import type { Response } from 'node-fetch';
|
|
6
6
|
import type { ReadStream } from 'fs';
|
|
7
7
|
import type {
|
|
@@ -25,7 +25,7 @@ class RemotesApiClient {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
async getDefaultBranch(organizationId: string, projectId: string) {
|
|
28
|
-
const response = await
|
|
28
|
+
const response = await fetchWithTimeout(
|
|
29
29
|
`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/source`,
|
|
30
30
|
{
|
|
31
31
|
method: 'GET',
|
|
@@ -36,6 +36,10 @@ class RemotesApiClient {
|
|
|
36
36
|
}
|
|
37
37
|
);
|
|
38
38
|
|
|
39
|
+
if (!response) {
|
|
40
|
+
throw new Error(`Failed to get default branch.`);
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
try {
|
|
40
44
|
const source = await this.getParsedResponse<ProjectSourceResponse>(response);
|
|
41
45
|
|
|
@@ -53,7 +57,7 @@ class RemotesApiClient {
|
|
|
53
57
|
mountBranchName: string;
|
|
54
58
|
}
|
|
55
59
|
): Promise<UpsertRemoteResponse> {
|
|
56
|
-
const response = await
|
|
60
|
+
const response = await fetchWithTimeout(
|
|
57
61
|
`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/remotes`,
|
|
58
62
|
{
|
|
59
63
|
method: 'POST',
|
|
@@ -70,6 +74,10 @@ class RemotesApiClient {
|
|
|
70
74
|
}
|
|
71
75
|
);
|
|
72
76
|
|
|
77
|
+
if (!response) {
|
|
78
|
+
throw new Error(`Failed to upsert.`);
|
|
79
|
+
}
|
|
80
|
+
|
|
73
81
|
try {
|
|
74
82
|
return await this.getParsedResponse<UpsertRemoteResponse>(response);
|
|
75
83
|
} catch (err) {
|
|
@@ -110,6 +118,7 @@ class RemotesApiClient {
|
|
|
110
118
|
Authorization: `Bearer ${this.apiKey}`,
|
|
111
119
|
},
|
|
112
120
|
body: formData,
|
|
121
|
+
agent: getProxyAgent(),
|
|
113
122
|
}
|
|
114
123
|
);
|
|
115
124
|
|
|
@@ -121,7 +130,7 @@ class RemotesApiClient {
|
|
|
121
130
|
}
|
|
122
131
|
|
|
123
132
|
async getRemotesList(organizationId: string, projectId: string, mountPath: string) {
|
|
124
|
-
const response = await
|
|
133
|
+
const response = await fetchWithTimeout(
|
|
125
134
|
`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/remotes?filter=mountPath:/${mountPath}/`,
|
|
126
135
|
{
|
|
127
136
|
method: 'GET',
|
|
@@ -132,6 +141,10 @@ class RemotesApiClient {
|
|
|
132
141
|
}
|
|
133
142
|
);
|
|
134
143
|
|
|
144
|
+
if (!response) {
|
|
145
|
+
throw new Error(`Failed to get remotes list.`);
|
|
146
|
+
}
|
|
147
|
+
|
|
135
148
|
try {
|
|
136
149
|
return await this.getParsedResponse<ListRemotesResponse>(response);
|
|
137
150
|
} catch (err) {
|
|
@@ -160,7 +173,7 @@ class RemotesApiClient {
|
|
|
160
173
|
);
|
|
161
174
|
|
|
162
175
|
if (!response) {
|
|
163
|
-
throw new Error(`Failed to get push status
|
|
176
|
+
throw new Error(`Failed to get push status.`);
|
|
164
177
|
}
|
|
165
178
|
|
|
166
179
|
try {
|
package/src/commands/join.ts
CHANGED
|
@@ -4,22 +4,16 @@ import { performance } from 'perf_hooks';
|
|
|
4
4
|
const isEqual = require('lodash.isequal');
|
|
5
5
|
import {
|
|
6
6
|
Config,
|
|
7
|
-
Oas3Definition,
|
|
8
7
|
SpecVersion,
|
|
9
8
|
BaseResolver,
|
|
10
|
-
Document,
|
|
11
9
|
StyleguideConfig,
|
|
12
|
-
Oas3Tag,
|
|
13
10
|
formatProblems,
|
|
14
11
|
getTotals,
|
|
15
12
|
lintDocument,
|
|
16
13
|
detectSpec,
|
|
17
14
|
bundleDocument,
|
|
18
|
-
Referenced,
|
|
19
15
|
isRef,
|
|
20
|
-
RuleSeverity,
|
|
21
16
|
} from '@redocly/openapi-core';
|
|
22
|
-
|
|
23
17
|
import {
|
|
24
18
|
getFallbackApisOrExit,
|
|
25
19
|
printExecutionTime,
|
|
@@ -32,16 +26,24 @@ import {
|
|
|
32
26
|
checkForDeprecatedOptions,
|
|
33
27
|
} from '../utils/miscellaneous';
|
|
34
28
|
import { isObject, isString, keysOf } from '../utils/js-utils';
|
|
35
|
-
import {
|
|
29
|
+
import { COMPONENTS, OPENAPI3_METHOD } from './split/types';
|
|
30
|
+
import { crawl, startsWithComponents } from './split';
|
|
31
|
+
|
|
32
|
+
import type {
|
|
33
|
+
Oas3Definition,
|
|
34
|
+
Document,
|
|
35
|
+
Oas3Tag,
|
|
36
|
+
Referenced,
|
|
37
|
+
RuleSeverity,
|
|
38
|
+
} from '@redocly/openapi-core';
|
|
39
|
+
import type { BundleResult } from '@redocly/openapi-core/lib/bundle';
|
|
40
|
+
import type {
|
|
36
41
|
Oas3Parameter,
|
|
37
42
|
Oas3PathItem,
|
|
38
43
|
Oas3Server,
|
|
39
44
|
Oas3_1Definition,
|
|
40
45
|
} from '@redocly/openapi-core/lib/typings/openapi';
|
|
41
|
-
import { OPENAPI3_METHOD } from './split/types';
|
|
42
|
-
import { BundleResult } from '@redocly/openapi-core/lib/bundle';
|
|
43
46
|
|
|
44
|
-
const COMPONENTS = 'components';
|
|
45
47
|
const Tags = 'tags';
|
|
46
48
|
const xTagGroups = 'x-tagGroups';
|
|
47
49
|
let potentialConflictsTotal = 0;
|
|
@@ -756,8 +758,11 @@ function addComponentsPrefix(description: string, componentsPrefix: string) {
|
|
|
756
758
|
function addSecurityPrefix(security: any, componentsPrefix: string) {
|
|
757
759
|
return componentsPrefix
|
|
758
760
|
? security?.map((s: any) => {
|
|
759
|
-
const
|
|
760
|
-
|
|
761
|
+
const joinedSecuritySchema = {};
|
|
762
|
+
for (const [key, value] of Object.entries(s)) {
|
|
763
|
+
Object.assign(joinedSecuritySchema, { [componentsPrefix + '_' + key]: value });
|
|
764
|
+
}
|
|
765
|
+
return joinedSecuritySchema;
|
|
761
766
|
})
|
|
762
767
|
: security;
|
|
763
768
|
}
|
|
@@ -779,7 +784,7 @@ function getInfoPrefix(info: any, prefixArg: string | undefined, type: string) {
|
|
|
779
784
|
`prefix-${type}-with-info-prop`
|
|
780
785
|
)} argument value length should not exceed 50 characters. \n\n`
|
|
781
786
|
);
|
|
782
|
-
return info[prefixArg];
|
|
787
|
+
return info[prefixArg].replaceAll(/\s/g, '_');
|
|
783
788
|
}
|
|
784
789
|
|
|
785
790
|
async function validateApi(
|
|
@@ -798,30 +803,19 @@ async function validateApi(
|
|
|
798
803
|
}
|
|
799
804
|
}
|
|
800
805
|
|
|
801
|
-
function
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
visitor(object[key], key);
|
|
805
|
-
crawl(object[key], visitor);
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
function replace$Refs(obj: any, componentsPrefix: string) {
|
|
810
|
-
crawl(obj, (node: any) => {
|
|
811
|
-
if (node.$ref && isString(node.$ref) && node.$ref.startsWith(`#/${COMPONENTS}/`)) {
|
|
806
|
+
function replace$Refs(obj: unknown, componentsPrefix: string) {
|
|
807
|
+
crawl(obj, (node: Record<string, unknown>) => {
|
|
808
|
+
if (node.$ref && typeof node.$ref === 'string' && startsWithComponents(node.$ref)) {
|
|
812
809
|
const name = path.basename(node.$ref);
|
|
813
810
|
node.$ref = node.$ref.replace(name, componentsPrefix + '_' + name);
|
|
814
|
-
} else if (
|
|
815
|
-
node.discriminator &&
|
|
816
|
-
node.discriminator.mapping &&
|
|
817
|
-
isObject(node.discriminator.mapping)
|
|
818
|
-
) {
|
|
811
|
+
} else if (isObject(node.discriminator) && isObject(node.discriminator.mapping)) {
|
|
819
812
|
const { mapping } = node.discriminator;
|
|
820
813
|
for (const name of Object.keys(mapping)) {
|
|
821
|
-
|
|
822
|
-
|
|
814
|
+
const mappingPointer = mapping[name];
|
|
815
|
+
if (typeof mappingPointer === 'string' && startsWithComponents(mappingPointer)) {
|
|
816
|
+
mapping[name] = mappingPointer
|
|
823
817
|
.split('/')
|
|
824
|
-
.map((name
|
|
818
|
+
.map((name, i, arr) => {
|
|
825
819
|
return arr.length - 1 === i && !name.includes(componentsPrefix)
|
|
826
820
|
? componentsPrefix + '_' + name
|
|
827
821
|
: name;
|
package/src/commands/push.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
slash,
|
|
15
15
|
Region,
|
|
16
16
|
getMergedConfig,
|
|
17
|
+
getProxyAgent,
|
|
17
18
|
} from '@redocly/openapi-core';
|
|
18
19
|
import {
|
|
19
20
|
exitWithError,
|
|
@@ -62,8 +63,12 @@ export async function handlePush(argv: PushOptions, config: Config): Promise<voi
|
|
|
62
63
|
const client = new RedoclyClient(config.region);
|
|
63
64
|
const isAuthorized = await client.isAuthorizedWithRedoclyByRegion();
|
|
64
65
|
if (!isAuthorized) {
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
try {
|
|
67
|
+
const clientToken = await promptClientToken(client.domain);
|
|
68
|
+
await client.login(clientToken);
|
|
69
|
+
} catch (e) {
|
|
70
|
+
exitWithError(e);
|
|
71
|
+
}
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
const startedAt = performance.now();
|
|
@@ -439,6 +444,7 @@ function uploadFileToS3(url: string, filePathOrBuffer: string | Buffer) {
|
|
|
439
444
|
typeof filePathOrBuffer === 'string'
|
|
440
445
|
? fs.statSync(filePathOrBuffer).size
|
|
441
446
|
: filePathOrBuffer.byteLength;
|
|
447
|
+
|
|
442
448
|
const readStream =
|
|
443
449
|
typeof filePathOrBuffer === 'string' ? fs.createReadStream(filePathOrBuffer) : filePathOrBuffer;
|
|
444
450
|
|
|
@@ -448,5 +454,6 @@ function uploadFileToS3(url: string, filePathOrBuffer: string | Buffer) {
|
|
|
448
454
|
'Content-Length': fileSizeInBytes.toString(),
|
|
449
455
|
},
|
|
450
456
|
body: readStream,
|
|
457
|
+
agent: getProxyAgent(),
|
|
451
458
|
});
|
|
452
459
|
}
|