@redocly/openapi-core 1.0.0-beta.117 → 1.0.0-beta.119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/bundle.d.ts +1 -1
- package/lib/config/config-resolvers.js +13 -8
- package/lib/decorators/common/media-type-examples-override.d.ts +2 -0
- package/lib/decorators/common/media-type-examples-override.js +53 -0
- package/lib/decorators/oas3/index.d.ts +1 -0
- package/lib/decorators/oas3/index.js +2 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +3 -1
- package/lib/resolve.js +3 -0
- package/lib/rules/common/assertions/asserts.js +10 -2
- package/lib/rules/common/assertions/utils.js +12 -6
- package/lib/rules/common/spec.js +7 -4
- package/lib/rules/oas3/spec-components-invalid-map-name.js +26 -5
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +9 -1
- package/lib/types/oas2.js +16 -0
- package/lib/types/oas3.js +28 -0
- package/lib/types/oas3_1.js +7 -0
- package/lib/types/redocly-yaml.js +1 -0
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +6 -1
- package/lib/visitors.d.ts +3 -1
- package/lib/visitors.js +4 -0
- package/lib/walk.js +8 -0
- package/package.json +1 -1
- package/src/__tests__/__snapshots__/bundle.test.ts.snap +10 -0
- package/src/config/config-resolvers.ts +12 -8
- package/src/decorators/__tests__/media-type-examples-override.test.ts +665 -0
- package/src/decorators/__tests__/resources/request.yaml +3 -0
- package/src/decorators/__tests__/resources/response.yaml +3 -0
- package/src/decorators/common/media-type-examples-override.ts +79 -0
- package/src/decorators/oas3/index.ts +2 -0
- package/src/index.ts +2 -1
- package/src/resolve.ts +4 -1
- package/src/rules/common/__tests__/spec.test.ts +119 -0
- package/src/rules/common/assertions/__tests__/asserts.test.ts +89 -19
- package/src/rules/common/assertions/asserts.ts +10 -1
- package/src/rules/common/assertions/utils.ts +15 -6
- package/src/rules/common/spec.ts +8 -5
- package/src/rules/oas3/__tests__/spec-components-invalid-map-name.test.ts +88 -0
- package/src/rules/oas3/spec-components-invalid-map-name.ts +26 -5
- package/src/types/index.ts +11 -0
- package/src/types/oas2.ts +16 -0
- package/src/types/oas3.ts +28 -0
- package/src/types/oas3_1.ts +7 -0
- package/src/types/redocly-yaml.ts +1 -0
- package/src/utils.ts +5 -0
- package/src/visitors.ts +7 -1
- package/src/walk.ts +15 -1
- package/tsconfig.tsbuildinfo +1 -1
package/src/types/oas2.ts
CHANGED
|
@@ -24,6 +24,7 @@ const Root: NodeType = {
|
|
|
24
24
|
'x-ignoredHeaderParameters': { type: 'array', items: { type: 'string' } },
|
|
25
25
|
},
|
|
26
26
|
required: ['swagger', 'paths', 'info'],
|
|
27
|
+
extensionsPrefix: 'x-',
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
const Info: NodeType = {
|
|
@@ -37,6 +38,7 @@ const Info: NodeType = {
|
|
|
37
38
|
'x-logo': 'Logo',
|
|
38
39
|
},
|
|
39
40
|
required: ['title', 'version'],
|
|
41
|
+
extensionsPrefix: 'x-',
|
|
40
42
|
};
|
|
41
43
|
|
|
42
44
|
const Logo: NodeType = {
|
|
@@ -46,6 +48,7 @@ const Logo: NodeType = {
|
|
|
46
48
|
backgroundColor: { type: 'string' },
|
|
47
49
|
href: { type: 'string' },
|
|
48
50
|
},
|
|
51
|
+
extensionsPrefix: 'x-',
|
|
49
52
|
};
|
|
50
53
|
|
|
51
54
|
const Contact: NodeType = {
|
|
@@ -54,6 +57,7 @@ const Contact: NodeType = {
|
|
|
54
57
|
url: { type: 'string' },
|
|
55
58
|
email: { type: 'string' },
|
|
56
59
|
},
|
|
60
|
+
extensionsPrefix: 'x-',
|
|
57
61
|
};
|
|
58
62
|
|
|
59
63
|
const License: NodeType = {
|
|
@@ -62,6 +66,7 @@ const License: NodeType = {
|
|
|
62
66
|
url: { type: 'string' },
|
|
63
67
|
},
|
|
64
68
|
required: ['name'],
|
|
69
|
+
extensionsPrefix: 'x-',
|
|
65
70
|
};
|
|
66
71
|
|
|
67
72
|
const Paths: NodeType = {
|
|
@@ -83,6 +88,7 @@ const PathItem: NodeType = {
|
|
|
83
88
|
head: 'Operation',
|
|
84
89
|
patch: 'Operation',
|
|
85
90
|
},
|
|
91
|
+
extensionsPrefix: 'x-',
|
|
86
92
|
};
|
|
87
93
|
|
|
88
94
|
const Operation: NodeType = {
|
|
@@ -104,6 +110,7 @@ const Operation: NodeType = {
|
|
|
104
110
|
'x-hideTryItPanel': { type: 'boolean' },
|
|
105
111
|
},
|
|
106
112
|
required: ['responses'],
|
|
113
|
+
extensionsPrefix: 'x-',
|
|
107
114
|
};
|
|
108
115
|
|
|
109
116
|
const XCodeSample: NodeType = {
|
|
@@ -128,6 +135,7 @@ const ExternalDocs: NodeType = {
|
|
|
128
135
|
url: { type: 'string' },
|
|
129
136
|
},
|
|
130
137
|
required: ['url'],
|
|
138
|
+
extensionsPrefix: 'x-',
|
|
131
139
|
};
|
|
132
140
|
|
|
133
141
|
const Parameter: NodeType = {
|
|
@@ -172,6 +180,7 @@ const Parameter: NodeType = {
|
|
|
172
180
|
}
|
|
173
181
|
}
|
|
174
182
|
},
|
|
183
|
+
extensionsPrefix: 'x-',
|
|
175
184
|
};
|
|
176
185
|
|
|
177
186
|
const ParameterItems: NodeType = {
|
|
@@ -201,6 +210,7 @@ const ParameterItems: NodeType = {
|
|
|
201
210
|
return ['type'];
|
|
202
211
|
}
|
|
203
212
|
},
|
|
213
|
+
extensionsPrefix: 'x-',
|
|
204
214
|
};
|
|
205
215
|
|
|
206
216
|
const Responses: NodeType = {
|
|
@@ -220,6 +230,7 @@ const Response: NodeType = {
|
|
|
220
230
|
'x-summary': { type: 'string' },
|
|
221
231
|
},
|
|
222
232
|
required: ['description'],
|
|
233
|
+
extensionsPrefix: 'x-',
|
|
223
234
|
};
|
|
224
235
|
|
|
225
236
|
const Examples: NodeType = {
|
|
@@ -255,6 +266,7 @@ const Header: NodeType = {
|
|
|
255
266
|
return ['type'];
|
|
256
267
|
}
|
|
257
268
|
},
|
|
269
|
+
extensionsPrefix: 'x-',
|
|
258
270
|
};
|
|
259
271
|
|
|
260
272
|
const Tag: NodeType = {
|
|
@@ -266,6 +278,7 @@ const Tag: NodeType = {
|
|
|
266
278
|
'x-displayName': { type: 'string' },
|
|
267
279
|
},
|
|
268
280
|
required: ['name'],
|
|
281
|
+
extensionsPrefix: 'x-',
|
|
269
282
|
};
|
|
270
283
|
|
|
271
284
|
const TagGroup: NodeType = {
|
|
@@ -328,6 +341,7 @@ const Schema: NodeType = {
|
|
|
328
341
|
'x-explicitMappingOnly': { type: 'boolean' },
|
|
329
342
|
'x-enumDescriptions': 'EnumDescriptions',
|
|
330
343
|
},
|
|
344
|
+
extensionsPrefix: 'x-',
|
|
331
345
|
};
|
|
332
346
|
|
|
333
347
|
const EnumDescriptions: NodeType = {
|
|
@@ -348,6 +362,7 @@ const Xml: NodeType = {
|
|
|
348
362
|
attribute: { type: 'boolean' },
|
|
349
363
|
wrapped: { type: 'boolean' },
|
|
350
364
|
},
|
|
365
|
+
extensionsPrefix: 'x-',
|
|
351
366
|
};
|
|
352
367
|
|
|
353
368
|
const SecurityScheme: NodeType = {
|
|
@@ -419,6 +434,7 @@ const Example: NodeType = {
|
|
|
419
434
|
description: { type: 'string' },
|
|
420
435
|
externalValue: { type: 'string' },
|
|
421
436
|
},
|
|
437
|
+
extensionsPrefix: 'x-',
|
|
422
438
|
};
|
|
423
439
|
|
|
424
440
|
export const Oas2Types: Record<string, NodeType> = {
|
package/src/types/oas3.ts
CHANGED
|
@@ -17,6 +17,7 @@ const Root: NodeType = {
|
|
|
17
17
|
'x-ignoredHeaderParameters': { type: 'array', items: { type: 'string' } },
|
|
18
18
|
},
|
|
19
19
|
required: ['openapi', 'paths', 'info'],
|
|
20
|
+
extensionsPrefix: 'x-',
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
const Tag: NodeType = {
|
|
@@ -28,6 +29,7 @@ const Tag: NodeType = {
|
|
|
28
29
|
'x-displayName': { type: 'string' },
|
|
29
30
|
},
|
|
30
31
|
required: ['name'],
|
|
32
|
+
extensionsPrefix: 'x-',
|
|
31
33
|
};
|
|
32
34
|
|
|
33
35
|
const TagGroup: NodeType = {
|
|
@@ -35,6 +37,7 @@ const TagGroup: NodeType = {
|
|
|
35
37
|
name: { type: 'string' },
|
|
36
38
|
tags: { type: 'array', items: { type: 'string' } },
|
|
37
39
|
},
|
|
40
|
+
extensionsPrefix: 'x-',
|
|
38
41
|
};
|
|
39
42
|
|
|
40
43
|
const ExternalDocs: NodeType = {
|
|
@@ -43,6 +46,7 @@ const ExternalDocs: NodeType = {
|
|
|
43
46
|
url: { type: 'string' },
|
|
44
47
|
},
|
|
45
48
|
required: ['url'],
|
|
49
|
+
extensionsPrefix: 'x-',
|
|
46
50
|
};
|
|
47
51
|
|
|
48
52
|
const Server: NodeType = {
|
|
@@ -52,6 +56,7 @@ const Server: NodeType = {
|
|
|
52
56
|
variables: 'ServerVariablesMap',
|
|
53
57
|
},
|
|
54
58
|
required: ['url'],
|
|
59
|
+
extensionsPrefix: 'x-',
|
|
55
60
|
};
|
|
56
61
|
|
|
57
62
|
const ServerVariable: NodeType = {
|
|
@@ -64,6 +69,7 @@ const ServerVariable: NodeType = {
|
|
|
64
69
|
description: null,
|
|
65
70
|
},
|
|
66
71
|
required: ['default'],
|
|
72
|
+
extensionsPrefix: 'x-',
|
|
67
73
|
};
|
|
68
74
|
|
|
69
75
|
const SecurityRequirement: NodeType = {
|
|
@@ -82,6 +88,7 @@ const Info: NodeType = {
|
|
|
82
88
|
'x-logo': 'Logo',
|
|
83
89
|
},
|
|
84
90
|
required: ['title', 'version'],
|
|
91
|
+
extensionsPrefix: 'x-',
|
|
85
92
|
};
|
|
86
93
|
|
|
87
94
|
const Logo: NodeType = {
|
|
@@ -99,6 +106,7 @@ const Contact: NodeType = {
|
|
|
99
106
|
url: { type: 'string' },
|
|
100
107
|
email: { type: 'string' },
|
|
101
108
|
},
|
|
109
|
+
extensionsPrefix: 'x-',
|
|
102
110
|
};
|
|
103
111
|
|
|
104
112
|
const License: NodeType = {
|
|
@@ -107,6 +115,7 @@ const License: NodeType = {
|
|
|
107
115
|
url: { type: 'string' },
|
|
108
116
|
},
|
|
109
117
|
required: ['name'],
|
|
118
|
+
extensionsPrefix: 'x-',
|
|
110
119
|
};
|
|
111
120
|
|
|
112
121
|
const Paths: NodeType = {
|
|
@@ -136,6 +145,7 @@ const PathItem: NodeType = {
|
|
|
136
145
|
patch: 'Operation',
|
|
137
146
|
trace: 'Operation',
|
|
138
147
|
},
|
|
148
|
+
extensionsPrefix: 'x-',
|
|
139
149
|
};
|
|
140
150
|
|
|
141
151
|
const Parameter: NodeType = {
|
|
@@ -158,6 +168,7 @@ const Parameter: NodeType = {
|
|
|
158
168
|
},
|
|
159
169
|
required: ['name', 'in'],
|
|
160
170
|
requiredOneOf: ['schema', 'content'],
|
|
171
|
+
extensionsPrefix: 'x-',
|
|
161
172
|
};
|
|
162
173
|
|
|
163
174
|
const Operation: NodeType = {
|
|
@@ -182,6 +193,7 @@ const Operation: NodeType = {
|
|
|
182
193
|
'x-hideTryItPanel': { type: 'boolean' },
|
|
183
194
|
},
|
|
184
195
|
required: ['responses'],
|
|
196
|
+
extensionsPrefix: 'x-',
|
|
185
197
|
};
|
|
186
198
|
|
|
187
199
|
const XCodeSample: NodeType = {
|
|
@@ -199,6 +211,7 @@ const RequestBody: NodeType = {
|
|
|
199
211
|
content: 'MediaTypesMap',
|
|
200
212
|
},
|
|
201
213
|
required: ['content'],
|
|
214
|
+
extensionsPrefix: 'x-',
|
|
202
215
|
};
|
|
203
216
|
|
|
204
217
|
const MediaTypesMap: NodeType = {
|
|
@@ -213,6 +226,7 @@ const MediaType: NodeType = {
|
|
|
213
226
|
examples: 'ExamplesMap',
|
|
214
227
|
encoding: 'EncodingMap',
|
|
215
228
|
},
|
|
229
|
+
extensionsPrefix: 'x-',
|
|
216
230
|
};
|
|
217
231
|
|
|
218
232
|
const Example: NodeType = {
|
|
@@ -222,6 +236,7 @@ const Example: NodeType = {
|
|
|
222
236
|
description: { type: 'string' },
|
|
223
237
|
externalValue: { type: 'string' },
|
|
224
238
|
},
|
|
239
|
+
extensionsPrefix: 'x-',
|
|
225
240
|
};
|
|
226
241
|
|
|
227
242
|
const Encoding: NodeType = {
|
|
@@ -234,6 +249,7 @@ const Encoding: NodeType = {
|
|
|
234
249
|
explode: { type: 'boolean' },
|
|
235
250
|
allowReserved: { type: 'boolean' },
|
|
236
251
|
},
|
|
252
|
+
extensionsPrefix: 'x-',
|
|
237
253
|
};
|
|
238
254
|
|
|
239
255
|
const EnumDescriptions: NodeType = {
|
|
@@ -258,6 +274,7 @@ const Header: NodeType = {
|
|
|
258
274
|
content: 'MediaTypesMap',
|
|
259
275
|
},
|
|
260
276
|
requiredOneOf: ['schema', 'content'],
|
|
277
|
+
extensionsPrefix: 'x-',
|
|
261
278
|
};
|
|
262
279
|
|
|
263
280
|
const Responses: NodeType = {
|
|
@@ -275,6 +292,7 @@ const Response: NodeType = {
|
|
|
275
292
|
'x-summary': { type: 'string' },
|
|
276
293
|
},
|
|
277
294
|
required: ['description'],
|
|
295
|
+
extensionsPrefix: 'x-',
|
|
278
296
|
};
|
|
279
297
|
|
|
280
298
|
const Link: NodeType = {
|
|
@@ -286,6 +304,7 @@ const Link: NodeType = {
|
|
|
286
304
|
description: { type: 'string' },
|
|
287
305
|
server: 'Server',
|
|
288
306
|
},
|
|
307
|
+
extensionsPrefix: 'x-',
|
|
289
308
|
};
|
|
290
309
|
|
|
291
310
|
const Schema: NodeType = {
|
|
@@ -350,6 +369,7 @@ const Schema: NodeType = {
|
|
|
350
369
|
'x-additionalPropertiesName': { type: 'string' },
|
|
351
370
|
'x-explicitMappingOnly': { type: 'boolean' },
|
|
352
371
|
},
|
|
372
|
+
extensionsPrefix: 'x-',
|
|
353
373
|
};
|
|
354
374
|
|
|
355
375
|
const Xml: NodeType = {
|
|
@@ -360,6 +380,7 @@ const Xml: NodeType = {
|
|
|
360
380
|
attribute: { type: 'boolean' },
|
|
361
381
|
wrapped: { type: 'boolean' },
|
|
362
382
|
},
|
|
383
|
+
extensionsPrefix: 'x-',
|
|
363
384
|
};
|
|
364
385
|
|
|
365
386
|
const SchemaProperties: NodeType = {
|
|
@@ -384,6 +405,7 @@ const Discriminator: NodeType = {
|
|
|
384
405
|
mapping: 'DiscriminatorMapping',
|
|
385
406
|
},
|
|
386
407
|
required: ['propertyName'],
|
|
408
|
+
extensionsPrefix: 'x-',
|
|
387
409
|
};
|
|
388
410
|
|
|
389
411
|
const Components: NodeType = {
|
|
@@ -398,6 +420,7 @@ const Components: NodeType = {
|
|
|
398
420
|
links: 'NamedLinks',
|
|
399
421
|
callbacks: 'NamedCallbacks',
|
|
400
422
|
},
|
|
423
|
+
extensionsPrefix: 'x-',
|
|
401
424
|
};
|
|
402
425
|
|
|
403
426
|
const ImplicitFlow: NodeType = {
|
|
@@ -407,6 +430,7 @@ const ImplicitFlow: NodeType = {
|
|
|
407
430
|
authorizationUrl: { type: 'string' },
|
|
408
431
|
},
|
|
409
432
|
required: ['authorizationUrl', 'scopes'],
|
|
433
|
+
extensionsPrefix: 'x-',
|
|
410
434
|
};
|
|
411
435
|
|
|
412
436
|
const PasswordFlow: NodeType = {
|
|
@@ -416,6 +440,7 @@ const PasswordFlow: NodeType = {
|
|
|
416
440
|
tokenUrl: { type: 'string' },
|
|
417
441
|
},
|
|
418
442
|
required: ['tokenUrl', 'scopes'],
|
|
443
|
+
extensionsPrefix: 'x-',
|
|
419
444
|
};
|
|
420
445
|
|
|
421
446
|
const ClientCredentials: NodeType = {
|
|
@@ -425,6 +450,7 @@ const ClientCredentials: NodeType = {
|
|
|
425
450
|
tokenUrl: { type: 'string' },
|
|
426
451
|
},
|
|
427
452
|
required: ['tokenUrl', 'scopes'],
|
|
453
|
+
extensionsPrefix: 'x-',
|
|
428
454
|
};
|
|
429
455
|
|
|
430
456
|
const AuthorizationCode: NodeType = {
|
|
@@ -442,6 +468,7 @@ const AuthorizationCode: NodeType = {
|
|
|
442
468
|
},
|
|
443
469
|
},
|
|
444
470
|
required: ['authorizationUrl', 'tokenUrl', 'scopes'],
|
|
471
|
+
extensionsPrefix: 'x-',
|
|
445
472
|
};
|
|
446
473
|
|
|
447
474
|
const OAuth2Flows: NodeType = {
|
|
@@ -451,6 +478,7 @@ const OAuth2Flows: NodeType = {
|
|
|
451
478
|
clientCredentials: 'ClientCredentials',
|
|
452
479
|
authorizationCode: 'AuthorizationCode',
|
|
453
480
|
},
|
|
481
|
+
extensionsPrefix: 'x-',
|
|
454
482
|
};
|
|
455
483
|
|
|
456
484
|
const SecurityScheme: NodeType = {
|
package/src/types/oas3_1.ts
CHANGED
|
@@ -16,6 +16,7 @@ const Root: NodeType = {
|
|
|
16
16
|
},
|
|
17
17
|
required: ['openapi', 'info'],
|
|
18
18
|
requiredOneOf: ['paths', 'components', 'webhooks'],
|
|
19
|
+
extensionsPrefix: 'x-',
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
const License: NodeType = {
|
|
@@ -25,6 +26,7 @@ const License: NodeType = {
|
|
|
25
26
|
identifier: { type: 'string' },
|
|
26
27
|
},
|
|
27
28
|
required: ['name'],
|
|
29
|
+
extensionsPrefix: 'x-',
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
const Info: NodeType = {
|
|
@@ -36,8 +38,10 @@ const Info: NodeType = {
|
|
|
36
38
|
summary: { type: 'string' },
|
|
37
39
|
contact: 'Contact',
|
|
38
40
|
license: 'License',
|
|
41
|
+
'x-logo': 'Logo',
|
|
39
42
|
},
|
|
40
43
|
required: ['title', 'version'],
|
|
44
|
+
extensionsPrefix: 'x-',
|
|
41
45
|
};
|
|
42
46
|
|
|
43
47
|
const Components: NodeType = {
|
|
@@ -53,6 +57,7 @@ const Components: NodeType = {
|
|
|
53
57
|
callbacks: 'NamedCallbacks',
|
|
54
58
|
pathItems: 'NamedPathItems',
|
|
55
59
|
},
|
|
60
|
+
extensionsPrefix: 'x-',
|
|
56
61
|
};
|
|
57
62
|
|
|
58
63
|
const Operation: NodeType = {
|
|
@@ -76,6 +81,7 @@ const Operation: NodeType = {
|
|
|
76
81
|
'x-code-samples': listOf('XCodeSample'), // deprecated
|
|
77
82
|
'x-hideTryItPanel': { type: 'boolean' },
|
|
78
83
|
},
|
|
84
|
+
extensionsPrefix: 'x-',
|
|
79
85
|
};
|
|
80
86
|
|
|
81
87
|
const Schema: NodeType = {
|
|
@@ -167,6 +173,7 @@ const Schema: NodeType = {
|
|
|
167
173
|
$comment: { type: 'string' },
|
|
168
174
|
'x-tags': { type: 'array', items: { type: 'string' } },
|
|
169
175
|
},
|
|
176
|
+
extensionsPrefix: 'x-',
|
|
170
177
|
};
|
|
171
178
|
|
|
172
179
|
const SecurityScheme: NodeType = {
|
package/src/utils.ts
CHANGED
|
@@ -153,6 +153,11 @@ export function readFileAsStringSync(filePath: string) {
|
|
|
153
153
|
return fs.readFileSync(filePath, 'utf-8');
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
export function yamlAndJsonSyncReader<T>(filePath: string): T {
|
|
157
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
158
|
+
return parseYaml(content) as T;
|
|
159
|
+
}
|
|
160
|
+
|
|
156
161
|
export function isPathParameter(pathSegment: string) {
|
|
157
162
|
return pathSegment.startsWith('{') && pathSegment.endsWith('}');
|
|
158
163
|
}
|
package/src/visitors.ts
CHANGED
|
@@ -45,7 +45,7 @@ import type {
|
|
|
45
45
|
Oas2SecurityScheme,
|
|
46
46
|
} from './typings/swagger';
|
|
47
47
|
|
|
48
|
-
import
|
|
48
|
+
import { NormalizedNodeType, SpecExtension } from './types';
|
|
49
49
|
import type { Stack } from './utils';
|
|
50
50
|
import type { UserContext, ResolveResult, ProblemSeverity } from './walk';
|
|
51
51
|
import type { Location } from './ref-utils';
|
|
@@ -177,6 +177,7 @@ type Oas3FlatVisitor = {
|
|
|
177
177
|
AuthorizationCode?: VisitFunctionOrObject<Oas3SecurityScheme['flows']['authorizationCode']>;
|
|
178
178
|
OAuth2Flows?: VisitFunctionOrObject<Oas3SecurityScheme['flows']>;
|
|
179
179
|
SecurityScheme?: VisitFunctionOrObject<Oas3SecurityScheme>;
|
|
180
|
+
SpecExtension?: VisitFunctionOrObject<unknown>;
|
|
180
181
|
};
|
|
181
182
|
|
|
182
183
|
type Oas2FlatVisitor = {
|
|
@@ -202,6 +203,7 @@ type Oas2FlatVisitor = {
|
|
|
202
203
|
NamedResponses?: VisitFunctionOrObject<Record<string, Oas2Response>>;
|
|
203
204
|
NamedParameters?: VisitFunctionOrObject<Record<string, Oas2Parameter>>;
|
|
204
205
|
SecurityScheme?: VisitFunctionOrObject<Oas2SecurityScheme>;
|
|
206
|
+
SpecExtension?: VisitFunctionOrObject<unknown>;
|
|
205
207
|
};
|
|
206
208
|
|
|
207
209
|
const legacyTypesMap = {
|
|
@@ -354,6 +356,10 @@ export function normalizeVisitors<T extends BaseVisitor>(
|
|
|
354
356
|
}
|
|
355
357
|
}
|
|
356
358
|
|
|
359
|
+
if (from.extensionsPrefix) {
|
|
360
|
+
possibleChildren.add(SpecExtension);
|
|
361
|
+
}
|
|
362
|
+
|
|
357
363
|
for (const fromType of Array.from(possibleChildren.values())) {
|
|
358
364
|
addWeakNodes(ruleConf, fromType, to, parentContext, stack);
|
|
359
365
|
}
|
package/src/walk.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from './resolve';
|
|
18
18
|
import { pushStack, popStack } from './utils';
|
|
19
19
|
import { OasVersion } from './oas-types';
|
|
20
|
-
import { NormalizedNodeType, isNamedType } from './types';
|
|
20
|
+
import { NormalizedNodeType, isNamedType, SpecExtension } from './types';
|
|
21
21
|
import type { RuleSeverity } from './config';
|
|
22
22
|
|
|
23
23
|
type NonUndefined = string | number | boolean | symbol | bigint | object | Record<string, any>;
|
|
@@ -280,6 +280,12 @@ export function walkDocument<T>(opts: {
|
|
|
280
280
|
const props = Object.keys(type.properties);
|
|
281
281
|
if (type.additionalProperties) {
|
|
282
282
|
props.push(...Object.keys(resolvedNode).filter((k) => !props.includes(k)));
|
|
283
|
+
} else if (type.extensionsPrefix) {
|
|
284
|
+
props.push(
|
|
285
|
+
...Object.keys(resolvedNode).filter((k) =>
|
|
286
|
+
k.startsWith(type.extensionsPrefix as string)
|
|
287
|
+
)
|
|
288
|
+
);
|
|
283
289
|
}
|
|
284
290
|
|
|
285
291
|
if (isRef(node)) {
|
|
@@ -300,6 +306,14 @@ export function walkDocument<T>(opts: {
|
|
|
300
306
|
if (propType === undefined) propType = type.additionalProperties;
|
|
301
307
|
if (typeof propType === 'function') propType = propType(value, propName);
|
|
302
308
|
|
|
309
|
+
if (
|
|
310
|
+
propType === undefined &&
|
|
311
|
+
type.extensionsPrefix &&
|
|
312
|
+
propName.startsWith(type.extensionsPrefix)
|
|
313
|
+
) {
|
|
314
|
+
propType = SpecExtension;
|
|
315
|
+
}
|
|
316
|
+
|
|
303
317
|
if (!isNamedType(propType) && propType?.directResolveAs) {
|
|
304
318
|
propType = propType.directResolveAs;
|
|
305
319
|
value = { $ref: value };
|