@redocly/openapi-core 1.0.0-beta.66 → 1.0.0-beta.70
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/__tests__/__snapshots__/bundle.test.ts.snap +126 -0
- package/__tests__/bundle.test.ts +53 -1
- package/__tests__/fixtures/refs/definitions.yaml +3 -0
- package/__tests__/fixtures/refs/external-request-body.yaml +13 -0
- package/__tests__/fixtures/refs/externalref.yaml +35 -0
- package/__tests__/fixtures/refs/hosted.yaml +35 -0
- package/__tests__/fixtures/refs/rename.yaml +1 -0
- package/__tests__/fixtures/refs/requestBody.yaml +9 -0
- package/__tests__/fixtures/refs/simple.yaml +1 -0
- package/__tests__/fixtures/refs/vendor.schema.yaml +20 -0
- package/__tests__/lint.test.ts +1 -1
- package/__tests__/login.test.ts +17 -0
- package/lib/bundle.d.ts +4 -0
- package/lib/bundle.js +25 -7
- package/lib/config/all.js +3 -0
- package/lib/config/config.d.ts +10 -0
- package/lib/config/config.js +7 -1
- package/lib/config/load.js +17 -8
- package/lib/config/minimal.js +1 -0
- package/lib/config/recommended.js +1 -0
- package/lib/index.d.ts +2 -2
- package/lib/lint.js +2 -0
- package/lib/redocly/index.d.ts +25 -20
- package/lib/redocly/index.js +77 -214
- package/lib/redocly/registry-api-types.d.ts +28 -0
- package/lib/redocly/registry-api-types.js +2 -0
- package/lib/redocly/registry-api.d.ts +14 -0
- package/lib/redocly/registry-api.js +105 -0
- package/lib/ref-utils.js +1 -2
- package/lib/rules/common/no-invalid-parameter-examples.d.ts +1 -0
- package/lib/rules/common/no-invalid-parameter-examples.js +25 -0
- package/lib/rules/common/no-invalid-schema-examples.d.ts +1 -0
- package/lib/rules/common/no-invalid-schema-examples.js +23 -0
- package/lib/rules/common/operation-4xx-response.d.ts +2 -0
- package/lib/rules/common/operation-4xx-response.js +17 -0
- package/lib/rules/common/paths-kebab-case.js +1 -1
- package/lib/rules/common/registry-dependencies.js +4 -7
- package/lib/rules/oas2/index.d.ts +3 -0
- package/lib/rules/oas2/index.js +6 -0
- package/lib/rules/oas3/index.js +6 -0
- package/lib/rules/oas3/no-invalid-media-type-examples.js +5 -26
- package/lib/rules/oas3/no-server-trailing-slash.js +1 -1
- package/lib/rules/utils.d.ts +3 -0
- package/lib/rules/utils.js +26 -1
- package/lib/typings/openapi.d.ts +3 -0
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +5 -1
- package/lib/walk.d.ts +2 -0
- package/lib/walk.js +7 -0
- package/package.json +1 -1
- package/src/bundle.ts +51 -9
- package/src/config/__tests__/load.test.ts +35 -0
- package/src/config/all.ts +3 -0
- package/src/config/config.ts +11 -0
- package/src/config/load.ts +20 -9
- package/src/config/minimal.ts +1 -0
- package/src/config/recommended.ts +1 -0
- package/src/index.ts +2 -8
- package/src/lint.ts +2 -0
- package/src/redocly/__tests__/redocly-client.test.ts +114 -0
- package/src/redocly/index.ts +90 -227
- package/src/redocly/registry-api-types.ts +31 -0
- package/src/redocly/registry-api.ts +110 -0
- package/src/ref-utils.ts +1 -3
- package/src/rules/common/__tests__/operation-4xx-response.test.ts +108 -0
- package/src/rules/common/__tests__/paths-kebab-case.test.ts +23 -0
- package/src/rules/common/no-invalid-parameter-examples.ts +36 -0
- package/src/rules/common/no-invalid-schema-examples.ts +27 -0
- package/src/rules/common/operation-4xx-response.ts +17 -0
- package/src/rules/common/paths-kebab-case.ts +1 -1
- package/src/rules/common/registry-dependencies.ts +6 -8
- package/src/rules/oas2/index.ts +6 -0
- package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +19 -0
- package/src/rules/oas3/index.ts +6 -0
- package/src/rules/oas3/no-invalid-media-type-examples.ts +16 -36
- package/src/rules/oas3/no-server-trailing-slash.ts +1 -1
- package/src/rules/utils.ts +43 -2
- package/src/typings/openapi.ts +4 -0
- package/src/utils.ts +5 -1
- package/src/walk.ts +10 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/redocly/query.d.ts +0 -4
- package/lib/redocly/query.js +0 -44
- package/src/redocly/query.ts +0 -38
|
@@ -99,3 +99,129 @@ components:
|
|
|
99
99
|
name: shared-a
|
|
100
100
|
|
|
101
101
|
`;
|
|
102
|
+
|
|
103
|
+
exports[`bundle should not place referened schema inline when component in question is not of type "schemas" 1`] = `
|
|
104
|
+
openapi: 3.0.0
|
|
105
|
+
paths:
|
|
106
|
+
/pet:
|
|
107
|
+
post:
|
|
108
|
+
requestBody:
|
|
109
|
+
content:
|
|
110
|
+
application/json:
|
|
111
|
+
schema:
|
|
112
|
+
$ref: '#/components/schemas/requestBody'
|
|
113
|
+
components:
|
|
114
|
+
schemas:
|
|
115
|
+
requestBody:
|
|
116
|
+
content:
|
|
117
|
+
application/json:
|
|
118
|
+
schema:
|
|
119
|
+
type: object
|
|
120
|
+
properties:
|
|
121
|
+
a:
|
|
122
|
+
type: string
|
|
123
|
+
b:
|
|
124
|
+
type: number
|
|
125
|
+
|
|
126
|
+
`;
|
|
127
|
+
|
|
128
|
+
exports[`bundle should place referenced schema inline when referenced schema name resolves to original schema name 1`] = `
|
|
129
|
+
openapi: 3.1.0
|
|
130
|
+
info:
|
|
131
|
+
title: My API
|
|
132
|
+
description: It ain't so wonderful, but at least it's mine.
|
|
133
|
+
version: '1.0'
|
|
134
|
+
contact:
|
|
135
|
+
email: me@theintenet.com
|
|
136
|
+
name: me
|
|
137
|
+
paths:
|
|
138
|
+
/test:
|
|
139
|
+
get:
|
|
140
|
+
summary: test
|
|
141
|
+
responses:
|
|
142
|
+
'200':
|
|
143
|
+
description: test
|
|
144
|
+
content:
|
|
145
|
+
application/json:
|
|
146
|
+
schema:
|
|
147
|
+
$ref: '#/components/schemas/vendor'
|
|
148
|
+
components:
|
|
149
|
+
schemas:
|
|
150
|
+
vendor:
|
|
151
|
+
title: vendor
|
|
152
|
+
type: object
|
|
153
|
+
description: Vendors
|
|
154
|
+
properties:
|
|
155
|
+
key:
|
|
156
|
+
type: string
|
|
157
|
+
description: System-assigned key for the vendor.
|
|
158
|
+
readOnly: true
|
|
159
|
+
id:
|
|
160
|
+
type: string
|
|
161
|
+
description: >
|
|
162
|
+
Unique identifier of the vendor.
|
|
163
|
+
|
|
164
|
+
You must specify a unique vendor ID when creating a vendor unless
|
|
165
|
+
document sequencing is configured, in which case the ID is
|
|
166
|
+
auto-generated.
|
|
167
|
+
name:
|
|
168
|
+
type: string
|
|
169
|
+
description: Name of the vendor.
|
|
170
|
+
isOneTimeUse:
|
|
171
|
+
type: boolean
|
|
172
|
+
description: One-time use
|
|
173
|
+
default: false
|
|
174
|
+
myvendor:
|
|
175
|
+
$ref: '#/components/schemas/vendor'
|
|
176
|
+
simple:
|
|
177
|
+
type: string
|
|
178
|
+
A:
|
|
179
|
+
type: string
|
|
180
|
+
test:
|
|
181
|
+
$ref: '#/components/schemas/rename-2'
|
|
182
|
+
rename:
|
|
183
|
+
type: string
|
|
184
|
+
rename-2:
|
|
185
|
+
type: number
|
|
186
|
+
|
|
187
|
+
`;
|
|
188
|
+
|
|
189
|
+
exports[`bundle should pull hosted schema 1`] = `
|
|
190
|
+
openapi: 3.0.3
|
|
191
|
+
info:
|
|
192
|
+
title: bugtest
|
|
193
|
+
version: '1.0'
|
|
194
|
+
description: Demo
|
|
195
|
+
license:
|
|
196
|
+
name: DEMO
|
|
197
|
+
url: https://demo.com
|
|
198
|
+
servers:
|
|
199
|
+
- url: http://demo.com/api
|
|
200
|
+
paths:
|
|
201
|
+
/customer:
|
|
202
|
+
summary: Customer scope
|
|
203
|
+
get:
|
|
204
|
+
summary: Get demo no refs
|
|
205
|
+
operationId: GetCustomer
|
|
206
|
+
description: Returns Demo No Refs
|
|
207
|
+
responses:
|
|
208
|
+
'200':
|
|
209
|
+
description: Demo No Refs
|
|
210
|
+
content:
|
|
211
|
+
application/json:
|
|
212
|
+
schema:
|
|
213
|
+
$ref: '#/components/schemas/Customer'
|
|
214
|
+
components:
|
|
215
|
+
schemas:
|
|
216
|
+
Customer:
|
|
217
|
+
type: object
|
|
218
|
+
properties:
|
|
219
|
+
customerName:
|
|
220
|
+
type: string
|
|
221
|
+
accounts:
|
|
222
|
+
type: array
|
|
223
|
+
items:
|
|
224
|
+
$ref: '#/components/schemas/someexternal'
|
|
225
|
+
someexternal: External schema content
|
|
226
|
+
|
|
227
|
+
`;
|
package/__tests__/bundle.test.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { BaseResolver } from '../src/resolve';
|
|
|
10
10
|
describe('bundle', () => {
|
|
11
11
|
expect.addSnapshotSerializer(yamlSerializer);
|
|
12
12
|
|
|
13
|
-
const testDocument =
|
|
13
|
+
const testDocument = parseYamlToDocument(
|
|
14
14
|
outdent`
|
|
15
15
|
openapi: 3.0.0
|
|
16
16
|
paths:
|
|
@@ -77,4 +77,56 @@ describe('bundle', () => {
|
|
|
77
77
|
expect(problems).toHaveLength(0);
|
|
78
78
|
expect(res.parsed).toMatchSnapshot();
|
|
79
79
|
});
|
|
80
|
+
|
|
81
|
+
it('should place referenced schema inline when referenced schema name resolves to original schema name', async () => {
|
|
82
|
+
const { bundle: res, problems } = await bundle({
|
|
83
|
+
config: new Config({}),
|
|
84
|
+
ref: path.join(__dirname, 'fixtures/refs/externalref.yaml'),
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
expect(problems).toHaveLength(0);
|
|
88
|
+
expect(res.parsed).toMatchSnapshot();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should not place referened schema inline when component in question is not of type "schemas"', async () => {
|
|
92
|
+
const { bundle: res, problems } = await bundle({
|
|
93
|
+
config: new Config({}),
|
|
94
|
+
ref: path.join(__dirname, 'fixtures/refs/external-request-body.yaml'),
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expect(problems).toHaveLength(0);
|
|
98
|
+
expect(res.parsed).toMatchSnapshot();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should pull hosted schema', async () => {
|
|
102
|
+
const fetchMock = jest.fn(
|
|
103
|
+
() => Promise.resolve({
|
|
104
|
+
ok: true,
|
|
105
|
+
text: () => 'External schema content',
|
|
106
|
+
headers: {
|
|
107
|
+
get: () => ''
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const { bundle: res, problems } = await bundle({
|
|
113
|
+
config: new Config({}),
|
|
114
|
+
externalRefResolver: new BaseResolver({
|
|
115
|
+
http: {
|
|
116
|
+
customFetch: fetchMock,
|
|
117
|
+
headers: []
|
|
118
|
+
}
|
|
119
|
+
}),
|
|
120
|
+
ref: path.join(__dirname, 'fixtures/refs/hosted.yaml')
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
expect(problems).toHaveLength(0);
|
|
124
|
+
expect(fetchMock).toHaveBeenCalledWith(
|
|
125
|
+
"https://someexternal.schema",
|
|
126
|
+
{
|
|
127
|
+
headers: {}
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
expect(res.parsed).toMatchSnapshot();
|
|
131
|
+
})
|
|
80
132
|
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
openapi: 3.1.0
|
|
2
|
+
info:
|
|
3
|
+
title: My API
|
|
4
|
+
description: It ain't so wonderful, but at least it's mine.
|
|
5
|
+
version: '1.0'
|
|
6
|
+
contact:
|
|
7
|
+
email: me@theintenet.com
|
|
8
|
+
name: me
|
|
9
|
+
paths:
|
|
10
|
+
/test:
|
|
11
|
+
get:
|
|
12
|
+
summary: 'test'
|
|
13
|
+
responses:
|
|
14
|
+
200:
|
|
15
|
+
description: test
|
|
16
|
+
content:
|
|
17
|
+
application/json:
|
|
18
|
+
schema:
|
|
19
|
+
$ref: ./vendor.schema.yaml
|
|
20
|
+
components:
|
|
21
|
+
schemas:
|
|
22
|
+
vendor:
|
|
23
|
+
$ref: ./vendor.schema.yaml
|
|
24
|
+
myvendor:
|
|
25
|
+
$ref: ./vendor.schema.yaml
|
|
26
|
+
simple:
|
|
27
|
+
$ref: ./simple.yaml
|
|
28
|
+
A:
|
|
29
|
+
$ref: ./definitions.yaml#/$defs/A
|
|
30
|
+
test:
|
|
31
|
+
$ref: ./rename.yaml
|
|
32
|
+
rename:
|
|
33
|
+
type: string
|
|
34
|
+
rename-2:
|
|
35
|
+
$ref: ./rename.yaml
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
openapi: "3.0.3"
|
|
2
|
+
info:
|
|
3
|
+
title: bugtest
|
|
4
|
+
version: "1.0"
|
|
5
|
+
description: Demo
|
|
6
|
+
license:
|
|
7
|
+
name: DEMO
|
|
8
|
+
url: https://demo.com
|
|
9
|
+
servers:
|
|
10
|
+
- url: http://demo.com/api
|
|
11
|
+
paths:
|
|
12
|
+
/customer:
|
|
13
|
+
summary: "Customer scope"
|
|
14
|
+
get:
|
|
15
|
+
summary: "Get demo no refs"
|
|
16
|
+
operationId: GetCustomer
|
|
17
|
+
description: "Returns Demo No Refs"
|
|
18
|
+
responses:
|
|
19
|
+
200:
|
|
20
|
+
description: Demo No Refs
|
|
21
|
+
content:
|
|
22
|
+
application/json:
|
|
23
|
+
schema:
|
|
24
|
+
$ref: "#/components/schemas/Customer"
|
|
25
|
+
components:
|
|
26
|
+
schemas:
|
|
27
|
+
Customer:
|
|
28
|
+
type: object
|
|
29
|
+
properties:
|
|
30
|
+
customerName:
|
|
31
|
+
type: string
|
|
32
|
+
accounts:
|
|
33
|
+
type: array
|
|
34
|
+
items:
|
|
35
|
+
$ref: "https://someexternal.schema"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
type: number
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
type: string
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
title: vendor
|
|
2
|
+
type: object
|
|
3
|
+
description: Vendors
|
|
4
|
+
properties:
|
|
5
|
+
key:
|
|
6
|
+
type: string
|
|
7
|
+
description: System-assigned key for the vendor.
|
|
8
|
+
readOnly: true
|
|
9
|
+
id:
|
|
10
|
+
type: string
|
|
11
|
+
description: |
|
|
12
|
+
Unique identifier of the vendor.
|
|
13
|
+
You must specify a unique vendor ID when creating a vendor unless document sequencing is configured, in which case the ID is auto-generated.
|
|
14
|
+
name:
|
|
15
|
+
type: string
|
|
16
|
+
description: Name of the vendor.
|
|
17
|
+
isOneTimeUse:
|
|
18
|
+
type: boolean
|
|
19
|
+
description: One-time use
|
|
20
|
+
default: false
|
package/__tests__/lint.test.ts
CHANGED
|
@@ -2,7 +2,7 @@ import outdent from 'outdent';
|
|
|
2
2
|
import { detectOpenAPI } from '../src/oas-types';
|
|
3
3
|
import { parseYamlToDocument } from './utils';
|
|
4
4
|
|
|
5
|
-
describe
|
|
5
|
+
describe('lint', () => {
|
|
6
6
|
it('detect OpenAPI should throw an error when version is not string', () => {
|
|
7
7
|
|
|
8
8
|
const testDocument = parseYamlToDocument(
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RedoclyClient } from '../src/redocly';
|
|
2
|
+
|
|
3
|
+
describe('login', () => {
|
|
4
|
+
it('should call login with setAccessTokens function', async () => {
|
|
5
|
+
const client = new RedoclyClient();
|
|
6
|
+
Object.defineProperty(client, 'registryApi', {
|
|
7
|
+
value: {
|
|
8
|
+
setAccessTokens: jest.fn(),
|
|
9
|
+
authStatus: jest.fn(() => true)
|
|
10
|
+
},
|
|
11
|
+
writable: true,
|
|
12
|
+
configurable: true
|
|
13
|
+
});
|
|
14
|
+
await client.login('token');
|
|
15
|
+
expect(client.registryApi.setAccessTokens).toHaveBeenCalled();
|
|
16
|
+
});
|
|
17
|
+
});
|
package/lib/bundle.d.ts
CHANGED
|
@@ -15,12 +15,14 @@ export declare function bundle(opts: {
|
|
|
15
15
|
config: Config;
|
|
16
16
|
dereference?: boolean;
|
|
17
17
|
base?: string;
|
|
18
|
+
skipRedoclyRegistryRefs?: boolean;
|
|
18
19
|
}): Promise<{
|
|
19
20
|
bundle: Document;
|
|
20
21
|
problems: import("./walk").NormalizedProblem[];
|
|
21
22
|
fileDependencies: Set<string>;
|
|
22
23
|
rootType: NormalizedNodeType;
|
|
23
24
|
refTypes: Map<string, NormalizedNodeType> | undefined;
|
|
25
|
+
visitorsData: Record<string, Record<string, unknown>>;
|
|
24
26
|
}>;
|
|
25
27
|
export declare function bundleDocument(opts: {
|
|
26
28
|
document: Document;
|
|
@@ -28,10 +30,12 @@ export declare function bundleDocument(opts: {
|
|
|
28
30
|
customTypes?: Record<string, NodeType>;
|
|
29
31
|
externalRefResolver: BaseResolver;
|
|
30
32
|
dereference?: boolean;
|
|
33
|
+
skipRedoclyRegistryRefs?: boolean;
|
|
31
34
|
}): Promise<{
|
|
32
35
|
bundle: Document;
|
|
33
36
|
problems: import("./walk").NormalizedProblem[];
|
|
34
37
|
fileDependencies: Set<string>;
|
|
35
38
|
rootType: NormalizedNodeType;
|
|
36
39
|
refTypes: Map<string, NormalizedNodeType> | undefined;
|
|
40
|
+
visitorsData: Record<string, Record<string, unknown>>;
|
|
37
41
|
}>;
|
package/lib/bundle.js
CHANGED
|
@@ -23,6 +23,7 @@ const ref_utils_1 = require("./ref-utils");
|
|
|
23
23
|
const rules_1 = require("./config/rules");
|
|
24
24
|
const no_unresolved_refs_1 = require("./rules/no-unresolved-refs");
|
|
25
25
|
const utils_1 = require("./utils");
|
|
26
|
+
const redocly_1 = require("./redocly");
|
|
26
27
|
var OasVersion;
|
|
27
28
|
(function (OasVersion) {
|
|
28
29
|
OasVersion["Version2"] = "oas2";
|
|
@@ -45,24 +46,29 @@ function bundle(opts) {
|
|
|
45
46
|
exports.bundle = bundle;
|
|
46
47
|
function bundleDocument(opts) {
|
|
47
48
|
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
const { document, config, customTypes, externalRefResolver, dereference = false } = opts;
|
|
49
|
+
const { document, config, customTypes, externalRefResolver, dereference = false, skipRedoclyRegistryRefs = false, } = opts;
|
|
49
50
|
const oasVersion = oas_types_1.detectOpenAPI(document.parsed);
|
|
50
51
|
const oasMajorVersion = oas_types_1.openAPIMajor(oasVersion);
|
|
51
52
|
const rules = config.getRulesForOasVersion(oasMajorVersion);
|
|
52
|
-
const types = types_1.normalizeTypes(config.extendTypes((customTypes !== null && customTypes !== void 0 ? customTypes : oasMajorVersion === oas_types_1.OasMajorVersion.Version3)
|
|
53
|
+
const types = types_1.normalizeTypes(config.extendTypes((customTypes !== null && customTypes !== void 0 ? customTypes : oasMajorVersion === oas_types_1.OasMajorVersion.Version3)
|
|
54
|
+
? oasVersion === OasVersion.Version3_1
|
|
55
|
+
? oas3_1_1.Oas3_1Types
|
|
56
|
+
: oas3_1.Oas3Types
|
|
57
|
+
: oas2_1.Oas2Types, oasVersion), config);
|
|
53
58
|
const preprocessors = rules_1.initRules(rules, config, 'preprocessors', oasVersion);
|
|
54
59
|
const decorators = rules_1.initRules(rules, config, 'decorators', oasVersion);
|
|
55
60
|
const ctx = {
|
|
56
61
|
problems: [],
|
|
57
62
|
oasVersion: oasVersion,
|
|
58
63
|
refTypes: new Map(),
|
|
64
|
+
visitorsData: {},
|
|
59
65
|
};
|
|
60
66
|
const bundleVisitor = visitors_1.normalizeVisitors([
|
|
61
67
|
...preprocessors,
|
|
62
68
|
{
|
|
63
69
|
severity: 'error',
|
|
64
70
|
ruleId: 'bundler',
|
|
65
|
-
visitor: makeBundleVisitor(oasMajorVersion, dereference, document),
|
|
71
|
+
visitor: makeBundleVisitor(oasMajorVersion, dereference, skipRedoclyRegistryRefs, document),
|
|
66
72
|
},
|
|
67
73
|
...decorators,
|
|
68
74
|
], types);
|
|
@@ -84,6 +90,7 @@ function bundleDocument(opts) {
|
|
|
84
90
|
fileDependencies: externalRefResolver.getFiles(),
|
|
85
91
|
rootType: types.DefinitionRoot,
|
|
86
92
|
refTypes: ctx.refTypes,
|
|
93
|
+
visitorsData: ctx.visitorsData,
|
|
87
94
|
};
|
|
88
95
|
});
|
|
89
96
|
}
|
|
@@ -127,7 +134,7 @@ function mapTypeToComponent(typeName, version) {
|
|
|
127
134
|
}
|
|
128
135
|
}
|
|
129
136
|
// function oas3Move
|
|
130
|
-
function makeBundleVisitor(version, dereference, rootDocument) {
|
|
137
|
+
function makeBundleVisitor(version, dereference, skipRedoclyRegistryRefs, rootDocument) {
|
|
131
138
|
let components;
|
|
132
139
|
const visitor = {
|
|
133
140
|
ref: {
|
|
@@ -142,6 +149,9 @@ function makeBundleVisitor(version, dereference, rootDocument) {
|
|
|
142
149
|
!dereference) {
|
|
143
150
|
return;
|
|
144
151
|
}
|
|
152
|
+
if (skipRedoclyRegistryRefs && redocly_1.isRedoclyRegistryURL(node.$ref)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
145
155
|
const componentType = mapTypeToComponent(ctx.type.name, version);
|
|
146
156
|
if (!componentType) {
|
|
147
157
|
replaceRef(node, resolved, ctx);
|
|
@@ -210,6 +220,14 @@ function makeBundleVisitor(version, dereference, rootDocument) {
|
|
|
210
220
|
return `#/${componentType}/${name}`;
|
|
211
221
|
}
|
|
212
222
|
}
|
|
223
|
+
function isEqualOrEqualRef(node, target, ctx) {
|
|
224
|
+
var _a;
|
|
225
|
+
if (ref_utils_1.isRef(node) &&
|
|
226
|
+
((_a = ctx.resolve(node).location) === null || _a === void 0 ? void 0 : _a.absolutePointer) === target.location.absolutePointer) {
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
return isEqual(node, target.node);
|
|
230
|
+
}
|
|
213
231
|
function getComponentName(target, componentType, ctx) {
|
|
214
232
|
const [fileRef, pointer] = [target.location.source.absoluteRef, target.location.pointer];
|
|
215
233
|
const componentsGroup = components[componentType];
|
|
@@ -219,17 +237,17 @@ function makeBundleVisitor(version, dereference, rootDocument) {
|
|
|
219
237
|
name = refParts.pop() + (name ? `-${name}` : '');
|
|
220
238
|
if (!componentsGroup ||
|
|
221
239
|
!componentsGroup[name] ||
|
|
222
|
-
|
|
240
|
+
isEqualOrEqualRef(componentsGroup[name], target, ctx)) {
|
|
223
241
|
return name;
|
|
224
242
|
}
|
|
225
243
|
}
|
|
226
244
|
name = ref_utils_1.refBaseName(fileRef) + (name ? `_${name}` : '');
|
|
227
|
-
if (!componentsGroup[name] ||
|
|
245
|
+
if (!componentsGroup[name] || isEqualOrEqualRef(componentsGroup[name], target, ctx)) {
|
|
228
246
|
return name;
|
|
229
247
|
}
|
|
230
248
|
const prevName = name;
|
|
231
249
|
let serialId = 2;
|
|
232
|
-
while (componentsGroup[name] && !
|
|
250
|
+
while (componentsGroup[name] && !isEqualOrEqualRef(componentsGroup[name], target, ctx)) {
|
|
233
251
|
name = `${prevName}-${serialId}`;
|
|
234
252
|
serialId++;
|
|
235
253
|
}
|
package/lib/config/all.js
CHANGED
|
@@ -18,6 +18,7 @@ exports.default = {
|
|
|
18
18
|
'path-parameters-defined': 'error',
|
|
19
19
|
'operation-description': 'error',
|
|
20
20
|
'operation-2xx-response': 'error',
|
|
21
|
+
'operation-4xx-response': 'error',
|
|
21
22
|
'operation-operationId': 'error',
|
|
22
23
|
'operation-summary': 'error',
|
|
23
24
|
'operation-operationId-unique': 'error',
|
|
@@ -37,6 +38,8 @@ exports.default = {
|
|
|
37
38
|
},
|
|
38
39
|
'request-mime-type': 'error',
|
|
39
40
|
spec: 'error',
|
|
41
|
+
'no-invalid-schema-examples': 'error',
|
|
42
|
+
'no-invalid-parameter-examples': 'error',
|
|
40
43
|
},
|
|
41
44
|
oas3_0Rules: {
|
|
42
45
|
'no-invalid-media-type-examples': 'error',
|
package/lib/config/config.d.ts
CHANGED
|
@@ -70,11 +70,20 @@ export declare type HttpResolveConfig = {
|
|
|
70
70
|
export declare type ResolveConfig = {
|
|
71
71
|
http: HttpResolveConfig;
|
|
72
72
|
};
|
|
73
|
+
export declare const DEFAULT_REGION = "us";
|
|
74
|
+
export declare type Region = 'us' | 'eu';
|
|
75
|
+
export declare type AccessTokens = {
|
|
76
|
+
[region in Region]?: string;
|
|
77
|
+
};
|
|
78
|
+
export declare const DOMAINS: {
|
|
79
|
+
[region in Region]: string;
|
|
80
|
+
};
|
|
73
81
|
export declare type RawConfig = {
|
|
74
82
|
referenceDocs?: any;
|
|
75
83
|
apiDefinitions?: Record<string, string>;
|
|
76
84
|
lint?: LintRawConfig;
|
|
77
85
|
resolve?: RawResolveConfig;
|
|
86
|
+
region?: Region;
|
|
78
87
|
};
|
|
79
88
|
export declare class LintConfig {
|
|
80
89
|
rawConfig: LintRawConfig;
|
|
@@ -126,5 +135,6 @@ export declare class Config {
|
|
|
126
135
|
lint: LintConfig;
|
|
127
136
|
resolve: ResolveConfig;
|
|
128
137
|
licenseKey?: string;
|
|
138
|
+
region?: Region;
|
|
129
139
|
constructor(rawConfig: RawConfig, configFile?: string | undefined);
|
|
130
140
|
}
|
package/lib/config/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Config = exports.LintConfig = exports.IGNORE_FILE = void 0;
|
|
3
|
+
exports.Config = exports.LintConfig = exports.DOMAINS = exports.DEFAULT_REGION = exports.IGNORE_FILE = void 0;
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const path_1 = require("path");
|
|
@@ -12,6 +12,11 @@ const recommended_1 = require("./recommended");
|
|
|
12
12
|
exports.IGNORE_FILE = '.redocly.lint-ignore.yaml';
|
|
13
13
|
const IGNORE_BANNER = `# This file instructs Redocly's linter to ignore the rules contained for specific parts of your API.\n` +
|
|
14
14
|
`# See https://redoc.ly/docs/cli/ for more information.\n`;
|
|
15
|
+
exports.DEFAULT_REGION = 'us';
|
|
16
|
+
exports.DOMAINS = {
|
|
17
|
+
us: 'redoc.ly',
|
|
18
|
+
eu: 'eu.redocly.com',
|
|
19
|
+
};
|
|
15
20
|
class LintConfig {
|
|
16
21
|
constructor(rawConfig, configFile) {
|
|
17
22
|
this.rawConfig = rawConfig;
|
|
@@ -233,6 +238,7 @@ class Config {
|
|
|
233
238
|
customFetch: undefined,
|
|
234
239
|
},
|
|
235
240
|
};
|
|
241
|
+
this.region = rawConfig.region;
|
|
236
242
|
}
|
|
237
243
|
}
|
|
238
244
|
exports.Config = Config;
|
package/lib/config/load.js
CHANGED
|
@@ -35,20 +35,29 @@ function loadConfig(configPath, customExtends) {
|
|
|
35
35
|
rawConfig.lint.extends = customExtends;
|
|
36
36
|
}
|
|
37
37
|
const redoclyClient = new redocly_1.RedoclyClient();
|
|
38
|
-
|
|
38
|
+
const tokens = yield redoclyClient.getTokens();
|
|
39
|
+
if (tokens.length) {
|
|
39
40
|
if (!rawConfig.resolve)
|
|
40
41
|
rawConfig.resolve = {};
|
|
41
42
|
if (!rawConfig.resolve.http)
|
|
42
43
|
rawConfig.resolve.http = {};
|
|
43
|
-
rawConfig.resolve.http.headers = [
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
rawConfig.resolve.http.headers = [...((_a = rawConfig.resolve.http.headers) !== null && _a !== void 0 ? _a : [])];
|
|
45
|
+
for (const item of tokens) {
|
|
46
|
+
const domain = config_1.DOMAINS[item.region];
|
|
47
|
+
rawConfig.resolve.http.headers.push({
|
|
48
|
+
matches: `https://api.${domain}/registry/**`,
|
|
46
49
|
name: 'Authorization',
|
|
47
50
|
envVariable: undefined,
|
|
48
|
-
value:
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
value: item.token,
|
|
52
|
+
},
|
|
53
|
+
//support redocly.com domain for future compatibility
|
|
54
|
+
...(item.region === 'us' ? [{
|
|
55
|
+
matches: `https://api.redocly.com/registry/**`,
|
|
56
|
+
name: 'Authorization',
|
|
57
|
+
envVariable: undefined,
|
|
58
|
+
value: item.token,
|
|
59
|
+
}] : []));
|
|
60
|
+
}
|
|
52
61
|
}
|
|
53
62
|
return new config_1.Config(Object.assign(Object.assign({}, rawConfig), { lint: Object.assign(Object.assign({}, rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.lint), { plugins: [...(((_b = rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.lint) === null || _b === void 0 ? void 0 : _b.plugins) || []), builtIn_1.defaultPlugin] }) }), configPath);
|
|
54
63
|
});
|
package/lib/config/minimal.js
CHANGED
|
@@ -17,6 +17,7 @@ exports.default = {
|
|
|
17
17
|
'path-parameters-defined': 'warn',
|
|
18
18
|
'operation-description': 'off',
|
|
19
19
|
'operation-2xx-response': 'warn',
|
|
20
|
+
'operation-4xx-response': 'off',
|
|
20
21
|
'operation-operationId': 'warn',
|
|
21
22
|
'operation-summary': 'warn',
|
|
22
23
|
'operation-operationId-unique': 'warn',
|
|
@@ -17,6 +17,7 @@ exports.default = {
|
|
|
17
17
|
'path-parameters-defined': 'error',
|
|
18
18
|
'operation-description': 'off',
|
|
19
19
|
'operation-2xx-response': 'warn',
|
|
20
|
+
'operation-4xx-response': 'warn',
|
|
20
21
|
'operation-operationId': 'warn',
|
|
21
22
|
'operation-summary': 'error',
|
|
22
23
|
'operation-operationId-unique': 'error',
|
package/lib/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { Oas2Definition } from './typings/swagger';
|
|
|
8
8
|
export { StatsAccumulator, StatsName } from './typings/common';
|
|
9
9
|
export { normalizeTypes } from './types';
|
|
10
10
|
export { Stats } from './rules/other/stats';
|
|
11
|
-
export { Config, LintConfig, RawConfig, IGNORE_FILE } from './config/config';
|
|
11
|
+
export { Config, LintConfig, RawConfig, IGNORE_FILE, Region } from './config/config';
|
|
12
12
|
export { loadConfig } from './config/load';
|
|
13
13
|
export { RedoclyClient } from './redocly';
|
|
14
14
|
export { Source, BaseResolver, Document, resolveDocument, ResolveError, YamlParseError, makeDocumentFromString, } from './resolve';
|
|
@@ -19,5 +19,5 @@ export { normalizeVisitors } from './visitors';
|
|
|
19
19
|
export { WalkContext, walkDocument, NormalizedProblem, ProblemSeverity, LineColLocationObject, LocationObject, Loc, } from './walk';
|
|
20
20
|
export { getAstNodeByPointer, getLineColLocation } from './format/codeframes';
|
|
21
21
|
export { formatProblems, OutputFormat, getTotals, Totals } from './format/format';
|
|
22
|
-
export { lint, lint as validate, lintDocument, lintFromString, lintConfig
|
|
22
|
+
export { lint, lint as validate, lintDocument, lintFromString, lintConfig } from './lint';
|
|
23
23
|
export { bundle, bundleDocument } from './bundle';
|
package/lib/lint.js
CHANGED
|
@@ -51,6 +51,7 @@ function lintDocument(opts) {
|
|
|
51
51
|
const ctx = {
|
|
52
52
|
problems: [],
|
|
53
53
|
oasVersion: oasVersion,
|
|
54
|
+
visitorsData: {},
|
|
54
55
|
};
|
|
55
56
|
const preprocessors = rules_1.initRules(rules, config, 'preprocessors', oasVersion);
|
|
56
57
|
const regularRules = rules_1.initRules(rules, config, 'rules', oasVersion);
|
|
@@ -77,6 +78,7 @@ function lintConfig(opts) {
|
|
|
77
78
|
const ctx = {
|
|
78
79
|
problems: [],
|
|
79
80
|
oasVersion: oas_types_1.OasVersion.Version3_0,
|
|
81
|
+
visitorsData: {},
|
|
80
82
|
};
|
|
81
83
|
const config = new config_1.LintConfig({
|
|
82
84
|
plugins: [builtIn_1.defaultPlugin],
|