@redocly/openapi-core 1.18.0 → 1.18.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 +10 -0
- package/lib/bundle.d.ts +1 -1
- package/lib/bundle.js +1 -2
- package/lib/config/load.d.ts +1 -2
- package/lib/oas-types.d.ts +1 -1
- package/lib/rules/common/path-segment-plural.js +2 -1
- package/lib/types/arazzo.d.ts +1299 -73
- package/lib/types/arazzo.js +41 -36
- package/lib/types/asyncapi.js +17 -43
- package/lib/types/oas3_1.js +2 -2
- package/lib/typings/arazzo.d.ts +28 -1
- package/lib/utils.d.ts +8 -4
- package/lib/utils.js +38 -7
- package/package.json +2 -2
- package/src/__tests__/lint.test.ts +0 -50
- package/src/bundle.ts +2 -3
- package/src/config/load.ts +1 -2
- package/src/rules/common/__tests__/spec.test.ts +47 -0
- package/src/rules/common/no-invalid-schema-examples.ts +3 -2
- package/src/rules/common/path-segment-plural.ts +3 -2
- package/src/types/arazzo.ts +28 -23
- package/src/types/asyncapi.ts +22 -43
- package/src/types/oas3_1.ts +2 -2
- package/src/typings/arazzo.ts +41 -1
- package/src/utils.ts +41 -8
- package/tsconfig.tsbuildinfo +1 -1
package/lib/types/arazzo.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ArazzoTypes = exports.arazzoSchema = exports.ARAZZO_ROOT_TYPE = void 0;
|
|
3
|
+
exports.ArazzoTypes = exports.arazzoSchema = exports.workflow = exports.step = exports.inherit = exports.criteriaObject = exports.requestBody = exports.replacement = exports.infoObject = exports.parameter = exports.sourceDescriptionSchema = exports.expectSchema = exports.operationMethod = exports.ARAZZO_ROOT_TYPE = void 0;
|
|
4
4
|
const json_schema_adapter_1 = require("./json-schema-adapter");
|
|
5
5
|
exports.ARAZZO_ROOT_TYPE = 'Root';
|
|
6
|
-
|
|
6
|
+
exports.operationMethod = {
|
|
7
7
|
type: 'string',
|
|
8
8
|
enum: ['get', 'post', 'put', 'delete', 'patch'],
|
|
9
9
|
};
|
|
10
|
-
|
|
10
|
+
exports.expectSchema = {
|
|
11
11
|
type: 'object',
|
|
12
12
|
properties: {
|
|
13
13
|
statusCode: { type: 'number' },
|
|
@@ -57,7 +57,7 @@ const arazzoSourceDescriptionSchema = {
|
|
|
57
57
|
additionalProperties: false,
|
|
58
58
|
required: ['name', 'type', 'url'],
|
|
59
59
|
};
|
|
60
|
-
|
|
60
|
+
exports.sourceDescriptionSchema = {
|
|
61
61
|
type: 'object',
|
|
62
62
|
oneOf: [
|
|
63
63
|
openAPISourceDescriptionSchema,
|
|
@@ -67,20 +67,20 @@ const sourceDescriptionSchema = {
|
|
|
67
67
|
};
|
|
68
68
|
const sourceDescriptionsSchema = {
|
|
69
69
|
type: 'array',
|
|
70
|
-
items: sourceDescriptionSchema,
|
|
70
|
+
items: exports.sourceDescriptionSchema,
|
|
71
71
|
};
|
|
72
72
|
const extendedOperation = {
|
|
73
73
|
type: 'object',
|
|
74
74
|
properties: {
|
|
75
75
|
path: { type: 'string' },
|
|
76
|
-
method: operationMethod,
|
|
76
|
+
method: exports.operationMethod,
|
|
77
77
|
sourceDescriptionName: { type: 'string' },
|
|
78
78
|
serverUrl: { type: 'string' },
|
|
79
79
|
},
|
|
80
80
|
additionalProperties: false,
|
|
81
81
|
required: ['path', 'method'],
|
|
82
82
|
};
|
|
83
|
-
|
|
83
|
+
exports.parameter = {
|
|
84
84
|
type: 'object',
|
|
85
85
|
oneOf: [
|
|
86
86
|
{
|
|
@@ -95,17 +95,6 @@ const parameter = {
|
|
|
95
95
|
required: ['name', 'value'],
|
|
96
96
|
additionalProperties: false,
|
|
97
97
|
},
|
|
98
|
-
{
|
|
99
|
-
type: 'object',
|
|
100
|
-
properties: {
|
|
101
|
-
$ref: { type: 'string' },
|
|
102
|
-
value: {
|
|
103
|
-
oneOf: [{ type: 'string' }, { type: 'number' }, { type: 'boolean' }],
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
required: ['$ref'],
|
|
107
|
-
additionalProperties: false,
|
|
108
|
-
},
|
|
109
98
|
{
|
|
110
99
|
type: 'object',
|
|
111
100
|
properties: {
|
|
@@ -121,9 +110,9 @@ const parameter = {
|
|
|
121
110
|
};
|
|
122
111
|
const parameters = {
|
|
123
112
|
type: 'array',
|
|
124
|
-
items: parameter,
|
|
113
|
+
items: exports.parameter,
|
|
125
114
|
};
|
|
126
|
-
|
|
115
|
+
exports.infoObject = {
|
|
127
116
|
type: 'object',
|
|
128
117
|
properties: {
|
|
129
118
|
title: { type: 'string' },
|
|
@@ -134,7 +123,7 @@ const infoObject = {
|
|
|
134
123
|
additionalProperties: false,
|
|
135
124
|
required: ['title', 'version'],
|
|
136
125
|
};
|
|
137
|
-
|
|
126
|
+
exports.replacement = {
|
|
138
127
|
type: 'object',
|
|
139
128
|
properties: {
|
|
140
129
|
target: { type: 'string' },
|
|
@@ -149,7 +138,7 @@ const replacement = {
|
|
|
149
138
|
},
|
|
150
139
|
},
|
|
151
140
|
};
|
|
152
|
-
|
|
141
|
+
exports.requestBody = {
|
|
153
142
|
type: 'object',
|
|
154
143
|
properties: {
|
|
155
144
|
contentType: { type: 'string' },
|
|
@@ -165,13 +154,13 @@ const requestBody = {
|
|
|
165
154
|
encoding: { type: 'string' },
|
|
166
155
|
replacements: {
|
|
167
156
|
type: 'array',
|
|
168
|
-
items: replacement,
|
|
157
|
+
items: exports.replacement,
|
|
169
158
|
},
|
|
170
159
|
},
|
|
171
160
|
additionalProperties: false,
|
|
172
161
|
required: ['payload'],
|
|
173
162
|
};
|
|
174
|
-
|
|
163
|
+
exports.criteriaObject = {
|
|
175
164
|
type: 'object',
|
|
176
165
|
properties: {
|
|
177
166
|
condition: { type: 'string' },
|
|
@@ -201,9 +190,9 @@ const criteriaObject = {
|
|
|
201
190
|
};
|
|
202
191
|
const criteriaObjects = {
|
|
203
192
|
type: 'array',
|
|
204
|
-
items: criteriaObject,
|
|
193
|
+
items: exports.criteriaObject,
|
|
205
194
|
};
|
|
206
|
-
|
|
195
|
+
exports.inherit = {
|
|
207
196
|
type: 'string',
|
|
208
197
|
enum: ['auto', 'none'],
|
|
209
198
|
};
|
|
@@ -241,7 +230,7 @@ const onFailureList = {
|
|
|
241
230
|
type: 'array',
|
|
242
231
|
items: onFailureObject,
|
|
243
232
|
};
|
|
244
|
-
|
|
233
|
+
exports.step = {
|
|
245
234
|
type: 'object',
|
|
246
235
|
properties: {
|
|
247
236
|
stepId: { type: 'string' },
|
|
@@ -256,14 +245,30 @@ const step = {
|
|
|
256
245
|
outputs: {
|
|
257
246
|
type: 'object',
|
|
258
247
|
additionalProperties: {
|
|
259
|
-
|
|
248
|
+
oneOf: [
|
|
249
|
+
{
|
|
250
|
+
type: 'string',
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
type: 'object',
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
type: 'array',
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
type: 'boolean',
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
type: 'number',
|
|
263
|
+
},
|
|
264
|
+
],
|
|
260
265
|
},
|
|
261
266
|
},
|
|
262
|
-
'x-inherit': inherit,
|
|
263
|
-
'x-expect': expectSchema,
|
|
267
|
+
'x-inherit': exports.inherit,
|
|
268
|
+
'x-expect': exports.expectSchema,
|
|
264
269
|
'x-assert': { type: 'string' },
|
|
265
270
|
'x-operation': extendedOperation,
|
|
266
|
-
requestBody: requestBody,
|
|
271
|
+
requestBody: exports.requestBody,
|
|
267
272
|
},
|
|
268
273
|
required: ['stepId'],
|
|
269
274
|
oneOf: [
|
|
@@ -275,7 +280,7 @@ const step = {
|
|
|
275
280
|
};
|
|
276
281
|
const steps = {
|
|
277
282
|
type: 'array',
|
|
278
|
-
items: step,
|
|
283
|
+
items: exports.step,
|
|
279
284
|
};
|
|
280
285
|
const JSONSchema = {
|
|
281
286
|
type: 'object',
|
|
@@ -300,7 +305,7 @@ const JSONSchema = {
|
|
|
300
305
|
required: ['type'],
|
|
301
306
|
additionalProperties: true,
|
|
302
307
|
};
|
|
303
|
-
|
|
308
|
+
exports.workflow = {
|
|
304
309
|
type: 'object',
|
|
305
310
|
properties: {
|
|
306
311
|
workflowId: { type: 'string' },
|
|
@@ -330,13 +335,13 @@ const workflow = {
|
|
|
330
335
|
};
|
|
331
336
|
const workflows = {
|
|
332
337
|
type: 'array',
|
|
333
|
-
items: workflow,
|
|
338
|
+
items: exports.workflow,
|
|
334
339
|
};
|
|
335
340
|
exports.arazzoSchema = {
|
|
336
341
|
type: 'object',
|
|
337
342
|
properties: {
|
|
338
343
|
arazzo: { type: 'string', enum: ['1.0.0'] },
|
|
339
|
-
info: infoObject,
|
|
344
|
+
info: exports.infoObject,
|
|
340
345
|
sourceDescriptions: sourceDescriptionsSchema,
|
|
341
346
|
'x-parameters': parameters,
|
|
342
347
|
workflows: workflows,
|
|
@@ -362,7 +367,7 @@ exports.arazzoSchema = {
|
|
|
362
367
|
},
|
|
363
368
|
parameters: {
|
|
364
369
|
type: 'object',
|
|
365
|
-
additionalProperties: parameter,
|
|
370
|
+
additionalProperties: exports.parameter,
|
|
366
371
|
},
|
|
367
372
|
successActions: {
|
|
368
373
|
type: 'object',
|
package/lib/types/asyncapi.js
CHANGED
|
@@ -308,11 +308,8 @@ const MessageExample = {
|
|
|
308
308
|
const Schema = {
|
|
309
309
|
properties: {
|
|
310
310
|
$id: { type: 'string' },
|
|
311
|
-
id: { type: 'string' },
|
|
312
311
|
$schema: { type: 'string' },
|
|
313
312
|
definitions: 'NamedSchemas',
|
|
314
|
-
$defs: 'NamedSchemas',
|
|
315
|
-
$vocabulary: { type: 'string' },
|
|
316
313
|
externalDocs: 'ExternalDocs',
|
|
317
314
|
discriminator: 'Discriminator',
|
|
318
315
|
myArbitraryKeyword: { type: 'boolean' },
|
|
@@ -333,17 +330,14 @@ const Schema = {
|
|
|
333
330
|
required: { type: 'array', items: { type: 'string' } },
|
|
334
331
|
enum: { type: 'array' },
|
|
335
332
|
type: (value) => {
|
|
336
|
-
|
|
337
|
-
|
|
333
|
+
return Array.isArray(value)
|
|
334
|
+
? {
|
|
338
335
|
type: 'array',
|
|
339
336
|
items: { enum: ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'] },
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
else {
|
|
343
|
-
return {
|
|
337
|
+
}
|
|
338
|
+
: {
|
|
344
339
|
enum: ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'],
|
|
345
340
|
};
|
|
346
|
-
}
|
|
347
341
|
},
|
|
348
342
|
allOf: (0, _1.listOf)('Schema'),
|
|
349
343
|
anyOf: (0, _1.listOf)('Schema'),
|
|
@@ -352,38 +346,12 @@ const Schema = {
|
|
|
352
346
|
if: 'Schema',
|
|
353
347
|
then: 'Schema',
|
|
354
348
|
else: 'Schema',
|
|
355
|
-
dependentSchemas: (0, _1.listOf)('Schema'),
|
|
356
|
-
prefixItems: (0, _1.listOf)('Schema'),
|
|
357
349
|
contains: 'Schema',
|
|
358
|
-
minContains: { type: 'integer', minimum: 0 },
|
|
359
|
-
maxContains: { type: 'integer', minimum: 0 },
|
|
360
350
|
patternProperties: { type: 'object' },
|
|
361
351
|
propertyNames: 'Schema',
|
|
362
|
-
unevaluatedItems: (value) => {
|
|
363
|
-
if (typeof value === 'boolean') {
|
|
364
|
-
return { type: 'boolean' };
|
|
365
|
-
}
|
|
366
|
-
else {
|
|
367
|
-
return 'Schema';
|
|
368
|
-
}
|
|
369
|
-
},
|
|
370
|
-
unevaluatedProperties: (value) => {
|
|
371
|
-
if (typeof value === 'boolean') {
|
|
372
|
-
return { type: 'boolean' };
|
|
373
|
-
}
|
|
374
|
-
else {
|
|
375
|
-
return 'Schema';
|
|
376
|
-
}
|
|
377
|
-
},
|
|
378
|
-
summary: { type: 'string' },
|
|
379
352
|
properties: 'SchemaProperties',
|
|
380
353
|
items: (value) => {
|
|
381
|
-
|
|
382
|
-
return { type: 'boolean' };
|
|
383
|
-
}
|
|
384
|
-
else {
|
|
385
|
-
return 'Schema';
|
|
386
|
-
}
|
|
354
|
+
return Array.isArray(value) ? (0, _1.listOf)('Schema') : 'Schema';
|
|
387
355
|
},
|
|
388
356
|
additionalProperties: (value) => {
|
|
389
357
|
return typeof value === 'boolean' ? { type: 'boolean' } : 'Schema';
|
|
@@ -395,22 +363,21 @@ const Schema = {
|
|
|
395
363
|
default: null,
|
|
396
364
|
readOnly: { type: 'boolean' },
|
|
397
365
|
writeOnly: { type: 'boolean' },
|
|
398
|
-
// xml: 'Xml',
|
|
399
366
|
examples: { type: 'array' },
|
|
400
367
|
example: { isExample: true },
|
|
401
368
|
deprecated: { type: 'boolean' },
|
|
402
369
|
const: null,
|
|
403
370
|
$comment: { type: 'string' },
|
|
404
|
-
|
|
371
|
+
additionalItems: (value) => {
|
|
372
|
+
return typeof value === 'boolean' ? { type: 'boolean' } : 'Schema';
|
|
373
|
+
},
|
|
374
|
+
dependencies: 'Dependencies',
|
|
405
375
|
},
|
|
406
376
|
};
|
|
407
377
|
const SchemaProperties = {
|
|
408
378
|
properties: {},
|
|
409
379
|
additionalProperties: (value) => {
|
|
410
|
-
|
|
411
|
-
return { type: 'boolean' };
|
|
412
|
-
}
|
|
413
|
-
return 'Schema';
|
|
380
|
+
return typeof value === 'boolean' ? { type: 'boolean' } : 'Schema';
|
|
414
381
|
},
|
|
415
382
|
};
|
|
416
383
|
const DiscriminatorMapping = {
|
|
@@ -552,6 +519,12 @@ const SecurityScheme = {
|
|
|
552
519
|
},
|
|
553
520
|
extensionsPrefix: 'x-',
|
|
554
521
|
};
|
|
522
|
+
const Dependencies = {
|
|
523
|
+
properties: {},
|
|
524
|
+
additionalProperties: (value) => {
|
|
525
|
+
return Array.isArray(value) ? { type: 'array', items: { type: 'string' } } : 'Schema';
|
|
526
|
+
},
|
|
527
|
+
};
|
|
555
528
|
// --- Per-protocol node types
|
|
556
529
|
// http
|
|
557
530
|
const HttpChannelBinding = {
|
|
@@ -1025,4 +998,5 @@ exports.AsyncApi2Types = {
|
|
|
1025
998
|
MessageTrait,
|
|
1026
999
|
MessageTraitList: (0, _1.listOf)('MessageTrait'),
|
|
1027
1000
|
CorrelationId,
|
|
1001
|
+
Dependencies,
|
|
1028
1002
|
};
|
package/lib/types/oas3_1.js
CHANGED
|
@@ -128,13 +128,13 @@ const Schema = {
|
|
|
128
128
|
if: 'Schema',
|
|
129
129
|
then: 'Schema',
|
|
130
130
|
else: 'Schema',
|
|
131
|
-
dependentSchemas: (0, _1.
|
|
131
|
+
dependentSchemas: (0, _1.mapOf)('Schema'),
|
|
132
132
|
dependentRequired: 'DependentRequired',
|
|
133
133
|
prefixItems: (0, _1.listOf)('Schema'),
|
|
134
134
|
contains: 'Schema',
|
|
135
135
|
minContains: { type: 'integer', minimum: 0 },
|
|
136
136
|
maxContains: { type: 'integer', minimum: 0 },
|
|
137
|
-
patternProperties:
|
|
137
|
+
patternProperties: 'SchemaProperties',
|
|
138
138
|
propertyNames: 'Schema',
|
|
139
139
|
unevaluatedItems: (value) => {
|
|
140
140
|
if (typeof value === 'boolean') {
|
package/lib/typings/arazzo.d.ts
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
1
|
import type { FromSchema } from 'json-schema-to-ts';
|
|
2
|
-
import type { arazzoSchema } from '../types/arazzo';
|
|
2
|
+
import type { arazzoSchema, parameter, operationMethod, expectSchema, sourceDescriptionSchema, infoObject, requestBody, replacement, inherit, criteriaObject, step, workflow } from '../types/arazzo';
|
|
3
3
|
export type ArazzoDefinition = FromSchema<typeof arazzoSchema>;
|
|
4
|
+
export type OperationMethod = FromSchema<typeof operationMethod>;
|
|
5
|
+
export type ResponseContext = {
|
|
6
|
+
statusCode: number;
|
|
7
|
+
body: any;
|
|
8
|
+
headers: Headers;
|
|
9
|
+
mimeType: string;
|
|
10
|
+
} & Record<string, any>;
|
|
11
|
+
export type Expect = FromSchema<typeof expectSchema>;
|
|
12
|
+
export type SourceDescription = FromSchema<typeof sourceDescriptionSchema>;
|
|
13
|
+
export type Parameter = FromSchema<typeof parameter>;
|
|
14
|
+
export type InfoObject = FromSchema<typeof infoObject>;
|
|
15
|
+
export type RequestBody = FromSchema<typeof requestBody>;
|
|
16
|
+
export type Replacement = FromSchema<typeof replacement>;
|
|
17
|
+
export type Inherit = FromSchema<typeof inherit>;
|
|
18
|
+
export type CriteriaObject = FromSchema<typeof criteriaObject>;
|
|
19
|
+
export type VerboseLog = {
|
|
20
|
+
method: OperationMethod;
|
|
21
|
+
path: string;
|
|
22
|
+
host: string;
|
|
23
|
+
body?: any;
|
|
24
|
+
headerParams?: Record<string, string>;
|
|
25
|
+
statusCode?: number;
|
|
26
|
+
};
|
|
27
|
+
export type Step = FromSchema<typeof step>;
|
|
28
|
+
export type Workflow = FromSchema<typeof workflow> & {
|
|
29
|
+
steps: Step[];
|
|
30
|
+
};
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { UserContext } from './walk';
|
|
2
|
-
import { HttpResolveConfig } from './config';
|
|
3
1
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
2
|
+
import type { HttpResolveConfig } from './config';
|
|
3
|
+
import type { UserContext } from './walk';
|
|
4
4
|
export { parseYaml, stringifyYaml } from './js-yaml';
|
|
5
5
|
export type StackFrame<T> = {
|
|
6
6
|
prev: StackFrame<T> | null;
|
|
@@ -28,7 +28,6 @@ export declare function omitObjectProps<T extends Record<string, unknown>>(objec
|
|
|
28
28
|
export declare function splitCamelCaseIntoWords(str: string): Set<string>;
|
|
29
29
|
export declare function validateMimeType({ type, value }: any, { report, location }: UserContext, allowedValues: string[]): void;
|
|
30
30
|
export declare function validateMimeTypeOAS3({ type, value }: any, { report, location }: UserContext, allowedValues: string[]): void;
|
|
31
|
-
export declare function isSingular(path: string): boolean;
|
|
32
31
|
export declare function readFileAsStringSync(filePath: string): string;
|
|
33
32
|
export declare function yamlAndJsonSyncReader<T>(filePath: string): T;
|
|
34
33
|
export declare function isPathParameter(pathSegment: string): boolean;
|
|
@@ -50,6 +49,11 @@ export declare function isTruthy<Truthy>(value: Truthy | Falsy): value is Truthy
|
|
|
50
49
|
export declare function identity<T>(value: T): T;
|
|
51
50
|
export declare function keysOf<T>(obj: T): (keyof T)[];
|
|
52
51
|
export declare function pickDefined<T extends Record<string, unknown>>(obj?: T): Record<string, unknown> | undefined;
|
|
53
|
-
export declare function nextTick():
|
|
52
|
+
export declare function nextTick(): Promise<unknown>;
|
|
54
53
|
export declare function pause(ms: number): Promise<void>;
|
|
55
54
|
export declare function getProxyAgent(): HttpsProxyAgent<string> | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Checks if two objects are deeply equal.
|
|
57
|
+
* Borrowed the source code from https://github.com/lukeed/dequal.
|
|
58
|
+
*/
|
|
59
|
+
export declare function dequal(foo: any, bar: any): boolean;
|
package/lib/utils.js
CHANGED
|
@@ -9,12 +9,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.getProxyAgent = exports.pause = exports.nextTick = exports.pickDefined = exports.keysOf = exports.identity = exports.isTruthy = exports.showErrorForDeprecatedField = exports.showWarningForDeprecatedField = exports.doesYamlFileExist = exports.isCustomRuleId = exports.getMatchingStatusCodeRange = exports.assignExisting = exports.isNotString = exports.isString = exports.isNotEmptyObject = exports.slash = exports.isPathParameter = exports.yamlAndJsonSyncReader = exports.readFileAsStringSync = exports.
|
|
12
|
+
exports.dequal = exports.getProxyAgent = exports.pause = exports.nextTick = exports.pickDefined = exports.keysOf = exports.identity = exports.isTruthy = exports.showErrorForDeprecatedField = exports.showWarningForDeprecatedField = exports.doesYamlFileExist = exports.isCustomRuleId = exports.getMatchingStatusCodeRange = exports.assignExisting = exports.isNotString = exports.isString = exports.isNotEmptyObject = exports.slash = exports.isPathParameter = exports.yamlAndJsonSyncReader = exports.readFileAsStringSync = exports.validateMimeTypeOAS3 = exports.validateMimeType = exports.splitCamelCaseIntoWords = exports.omitObjectProps = exports.pickObjectProps = exports.readFileFromUrl = exports.isEmptyArray = exports.isEmptyObject = exports.isPlainObject = exports.isDefined = exports.loadYaml = exports.popStack = exports.pushStack = exports.stringifyYaml = exports.parseYaml = void 0;
|
|
13
13
|
const fs = require("fs");
|
|
14
14
|
const path_1 = require("path");
|
|
15
15
|
const minimatch = require("minimatch");
|
|
16
16
|
const node_fetch_1 = require("node-fetch");
|
|
17
|
-
const pluralize = require("pluralize");
|
|
18
17
|
const js_yaml_1 = require("./js-yaml");
|
|
19
18
|
const env_1 = require("./env");
|
|
20
19
|
const logger_1 = require("./logger");
|
|
@@ -132,10 +131,6 @@ function validateMimeTypeOAS3({ type, value }, { report, location }, allowedValu
|
|
|
132
131
|
}
|
|
133
132
|
}
|
|
134
133
|
exports.validateMimeTypeOAS3 = validateMimeTypeOAS3;
|
|
135
|
-
function isSingular(path) {
|
|
136
|
-
return pluralize.isSingular(path);
|
|
137
|
-
}
|
|
138
|
-
exports.isSingular = isSingular;
|
|
139
134
|
function readFileAsStringSync(filePath) {
|
|
140
135
|
return fs.readFileSync(filePath, 'utf-8');
|
|
141
136
|
}
|
|
@@ -233,7 +228,7 @@ function pickDefined(obj) {
|
|
|
233
228
|
}
|
|
234
229
|
exports.pickDefined = pickDefined;
|
|
235
230
|
function nextTick() {
|
|
236
|
-
new Promise((resolve) => {
|
|
231
|
+
return new Promise((resolve) => {
|
|
237
232
|
setTimeout(resolve);
|
|
238
233
|
});
|
|
239
234
|
}
|
|
@@ -252,3 +247,39 @@ function getProxyAgent() {
|
|
|
252
247
|
return proxy ? new https_proxy_agent_1.HttpsProxyAgent(proxy) : undefined;
|
|
253
248
|
}
|
|
254
249
|
exports.getProxyAgent = getProxyAgent;
|
|
250
|
+
/**
|
|
251
|
+
* Checks if two objects are deeply equal.
|
|
252
|
+
* Borrowed the source code from https://github.com/lukeed/dequal.
|
|
253
|
+
*/
|
|
254
|
+
function dequal(foo, bar) {
|
|
255
|
+
let ctor, len;
|
|
256
|
+
if (foo === bar)
|
|
257
|
+
return true;
|
|
258
|
+
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
|
|
259
|
+
if (ctor === Date)
|
|
260
|
+
return foo.getTime() === bar.getTime();
|
|
261
|
+
if (ctor === RegExp)
|
|
262
|
+
return foo.toString() === bar.toString();
|
|
263
|
+
if (ctor === Array) {
|
|
264
|
+
if ((len = foo.length) === bar.length) {
|
|
265
|
+
while (len-- && dequal(foo[len], bar[len]))
|
|
266
|
+
;
|
|
267
|
+
}
|
|
268
|
+
return len === -1;
|
|
269
|
+
}
|
|
270
|
+
if (!ctor || typeof foo === 'object') {
|
|
271
|
+
len = 0;
|
|
272
|
+
for (ctor in foo) {
|
|
273
|
+
if (Object.prototype.hasOwnProperty.call(foo, ctor) &&
|
|
274
|
+
++len &&
|
|
275
|
+
!Object.prototype.hasOwnProperty.call(bar, ctor))
|
|
276
|
+
return false;
|
|
277
|
+
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor]))
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
return Object.keys(bar).length === len;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return foo !== foo && bar !== bar;
|
|
284
|
+
}
|
|
285
|
+
exports.dequal = dequal;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/openapi-core",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"engines": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@redocly/ajv": "^8.11.0",
|
|
39
|
-
"@redocly/config": "^0.
|
|
39
|
+
"@redocly/config": "^0.7.0",
|
|
40
40
|
"colorette": "^1.2.0",
|
|
41
41
|
"https-proxy-agent": "^7.0.4",
|
|
42
42
|
"js-levenshtein": "^1.1.6",
|
|
@@ -104,14 +104,6 @@ const testPortalConfig = parseYamlToDocument(
|
|
|
104
104
|
# configurationUrl: Must be reported as a missing required prop
|
|
105
105
|
clientSecret: '{{ process.env.secret }}'
|
|
106
106
|
|
|
107
|
-
basic:
|
|
108
|
-
type: BASIC
|
|
109
|
-
credentials:
|
|
110
|
-
- teams:
|
|
111
|
-
- 789 # Must be a string
|
|
112
|
-
- correct
|
|
113
|
-
# username: Must be reported as a missing required prop
|
|
114
|
-
|
|
115
107
|
sso:
|
|
116
108
|
- WRONG # Does not match allowed options
|
|
117
109
|
|
|
@@ -393,20 +385,6 @@ describe('lint', () => {
|
|
|
393
385
|
"severity": "error",
|
|
394
386
|
"suggest": [],
|
|
395
387
|
},
|
|
396
|
-
{
|
|
397
|
-
"from": undefined,
|
|
398
|
-
"location": [
|
|
399
|
-
{
|
|
400
|
-
"pointer": "#/theme/openapi/showConsole",
|
|
401
|
-
"reportOnKey": true,
|
|
402
|
-
"source": "",
|
|
403
|
-
},
|
|
404
|
-
],
|
|
405
|
-
"message": "Property \`showConsole\` is not expected here.",
|
|
406
|
-
"ruleId": "configuration spec",
|
|
407
|
-
"severity": "error",
|
|
408
|
-
"suggest": [],
|
|
409
|
-
},
|
|
410
388
|
{
|
|
411
389
|
"from": undefined,
|
|
412
390
|
"location": [
|
|
@@ -912,34 +890,6 @@ describe('lint', () => {
|
|
|
912
890
|
"severity": "error",
|
|
913
891
|
"suggest": [],
|
|
914
892
|
},
|
|
915
|
-
{
|
|
916
|
-
"from": undefined,
|
|
917
|
-
"location": [
|
|
918
|
-
{
|
|
919
|
-
"pointer": "#/ssoOnPrem/basic/credentials/0",
|
|
920
|
-
"reportOnKey": true,
|
|
921
|
-
"source": "",
|
|
922
|
-
},
|
|
923
|
-
],
|
|
924
|
-
"message": "The field \`username\` must be present on this level.",
|
|
925
|
-
"ruleId": "configuration spec",
|
|
926
|
-
"severity": "error",
|
|
927
|
-
"suggest": [],
|
|
928
|
-
},
|
|
929
|
-
{
|
|
930
|
-
"from": undefined,
|
|
931
|
-
"location": [
|
|
932
|
-
{
|
|
933
|
-
"pointer": "#/ssoOnPrem/basic/credentials/0/teams/0",
|
|
934
|
-
"reportOnKey": false,
|
|
935
|
-
"source": "",
|
|
936
|
-
},
|
|
937
|
-
],
|
|
938
|
-
"message": "Expected type \`string\` but got \`integer\`.",
|
|
939
|
-
"ruleId": "configuration spec",
|
|
940
|
-
"severity": "error",
|
|
941
|
-
"suggest": [],
|
|
942
|
-
},
|
|
943
893
|
{
|
|
944
894
|
"from": undefined,
|
|
945
895
|
"location": [
|
package/src/bundle.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import isEqual = require('lodash.isequal');
|
|
2
1
|
import { BaseResolver, resolveDocument, makeRefId, makeDocumentFromString } from './resolve';
|
|
3
2
|
import { normalizeVisitors } from './visitors';
|
|
4
3
|
import { normalizeTypes } from './types';
|
|
@@ -13,7 +12,7 @@ import {
|
|
|
13
12
|
import { isAbsoluteUrl, isRef, Location, refBaseName } from './ref-utils';
|
|
14
13
|
import { initRules } from './config/rules';
|
|
15
14
|
import { reportUnresolvedRef } from './rules/no-unresolved-refs';
|
|
16
|
-
import { isPlainObject, isTruthy } from './utils';
|
|
15
|
+
import { dequal, isPlainObject, isTruthy } from './utils';
|
|
17
16
|
import { isRedoclyRegistryURL } from './redocly/domains';
|
|
18
17
|
import { RemoveUnusedComponents as RemoveUnusedComponentsOas2 } from './decorators/oas2/remove-unused-components';
|
|
19
18
|
import { RemoveUnusedComponents as RemoveUnusedComponentsOas3 } from './decorators/oas3/remove-unused-components';
|
|
@@ -446,7 +445,7 @@ function makeBundleVisitor(
|
|
|
446
445
|
return true;
|
|
447
446
|
}
|
|
448
447
|
|
|
449
|
-
return
|
|
448
|
+
return dequal(node, target.node);
|
|
450
449
|
}
|
|
451
450
|
|
|
452
451
|
function getComponentName(
|
package/src/config/load.ts
CHANGED
|
@@ -10,10 +10,9 @@ import { bundleConfig } from '../bundle';
|
|
|
10
10
|
import { BaseResolver } from '../resolve';
|
|
11
11
|
import { isBrowser } from '../env';
|
|
12
12
|
|
|
13
|
-
import type { Document } from '../resolve';
|
|
13
|
+
import type { Document, ResolvedRefMap } from '../resolve';
|
|
14
14
|
import type { RegionalToken, RegionalTokenWithValidity } from '../redocly/redocly-client-types';
|
|
15
15
|
import type { RawConfig, RawUniversalConfig, Region } from './types';
|
|
16
|
-
import type { ResolvedRefMap } from '../resolve';
|
|
17
16
|
import { DOMAINS } from '../redocly/domains';
|
|
18
17
|
|
|
19
18
|
async function addConfigMetadata({
|
|
@@ -607,4 +607,51 @@ describe('Oas3.1 spec', () => {
|
|
|
607
607
|
]
|
|
608
608
|
`);
|
|
609
609
|
});
|
|
610
|
+
|
|
611
|
+
it('should flag invalid dependentSchemas', async () => {
|
|
612
|
+
const document = parseYamlToDocument(
|
|
613
|
+
outdent`
|
|
614
|
+
openapi: 3.1.0
|
|
615
|
+
info:
|
|
616
|
+
version: 1.0.0
|
|
617
|
+
title: Example.com
|
|
618
|
+
description: info,
|
|
619
|
+
license:
|
|
620
|
+
name: Apache 2.0
|
|
621
|
+
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
|
|
622
|
+
components:
|
|
623
|
+
schemas:
|
|
624
|
+
withInvalidDependentSchemas:
|
|
625
|
+
dependentSchemas:
|
|
626
|
+
- invalid1
|
|
627
|
+
- invalid2
|
|
628
|
+
`,
|
|
629
|
+
'foobar.yaml'
|
|
630
|
+
);
|
|
631
|
+
|
|
632
|
+
const results = await lintDocument({
|
|
633
|
+
externalRefResolver: new BaseResolver(),
|
|
634
|
+
document,
|
|
635
|
+
config: await makeConfig({ spec: 'error' }),
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
639
|
+
[
|
|
640
|
+
{
|
|
641
|
+
"from": undefined,
|
|
642
|
+
"location": [
|
|
643
|
+
{
|
|
644
|
+
"pointer": "#/components/schemas/withInvalidDependentSchemas/dependentSchemas",
|
|
645
|
+
"reportOnKey": false,
|
|
646
|
+
"source": "foobar.yaml",
|
|
647
|
+
},
|
|
648
|
+
],
|
|
649
|
+
"message": "Expected type \`SchemaMap\` (object) but got \`array\`",
|
|
650
|
+
"ruleId": "spec",
|
|
651
|
+
"severity": "error",
|
|
652
|
+
"suggest": [],
|
|
653
|
+
},
|
|
654
|
+
]
|
|
655
|
+
`);
|
|
656
|
+
});
|
|
610
657
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { UserContext } from '../../walk';
|
|
2
|
-
import { Oas3_1Schema } from '../../typings/openapi';
|
|
3
1
|
import { getAdditionalPropertiesOption, validateExample } from '../utils';
|
|
4
2
|
|
|
3
|
+
import type { UserContext } from '../../walk';
|
|
4
|
+
import type { Oas3_1Schema } from '../../typings/openapi';
|
|
5
|
+
|
|
5
6
|
export const NoInvalidSchemaExamples: any = (opts: any) => {
|
|
6
7
|
const allowAdditionalProperties = getAdditionalPropertiesOption(opts) ?? false;
|
|
7
8
|
return {
|