oas 19.0.0 → 19.0.2
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 +12 -0
- package/dist/lib/openapi-to-json-schema.d.ts +1 -1
- package/dist/lib/openapi-to-json-schema.js +4 -4
- package/dist/operation/get-parameters-as-json-schema.d.ts +1 -0
- package/dist/operation/get-parameters-as-json-schema.js +39 -19
- package/dist/operation/get-response-as-json-schema.d.ts +1 -5
- package/dist/operation/get-response-as-json-schema.js +17 -5
- package/dist/operation.d.ts +10 -0
- package/dist/operation.js +3 -8
- package/package.json +1 -1
- package/src/lib/openapi-to-json-schema.ts +5 -5
- package/src/operation/get-parameters-as-json-schema.ts +62 -40
- package/src/operation/get-response-as-json-schema.ts +21 -14
- package/src/operation.ts +23 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## <small>19.0.2 (2022-10-26)</small>
|
|
2
|
+
|
|
3
|
+
* fix: quirks with discriminators and the `transformer` JSON Schema option (#698) ([b84c57f](https://github.com/readmeio/oas/commit/b84c57f)), closes [#698](https://github.com/readmeio/oas/issues/698)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## <small>19.0.1 (2022-10-14)</small>
|
|
8
|
+
|
|
9
|
+
* feat: supporting transforming a schema object to a primitive (#697) ([048bfc6](https://github.com/readmeio/oas/commit/048bfc6)), closes [#697](https://github.com/readmeio/oas/issues/697)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
1
13
|
## 19.0.0 (2022-10-10)
|
|
2
14
|
|
|
3
15
|
* docs: cleaning up some typescript options docs (#696) ([d200fef](https://github.com/readmeio/oas/commit/d200fef)), closes [#696](https://github.com/readmeio/oas/issues/696)
|
|
@@ -24,7 +24,7 @@ export declare type toJSONSchemaOptions = {
|
|
|
24
24
|
/**
|
|
25
25
|
* A function that's called anytime a (circular) `$ref` is found.
|
|
26
26
|
*/
|
|
27
|
-
refLogger?: (ref: string) => void;
|
|
27
|
+
refLogger?: (ref: string, type: 'ref' | 'discriminator') => void;
|
|
28
28
|
/**
|
|
29
29
|
* A function that's called to potentially transform any discovered schema.
|
|
30
30
|
*/
|
|
@@ -269,7 +269,7 @@ function toJSONSchema(data, opts) {
|
|
|
269
269
|
// If this schema contains a `$ref`, it's circular and we shouldn't try to resolve it. Just
|
|
270
270
|
// return and move along.
|
|
271
271
|
if (RMOAS.isRef(schema)) {
|
|
272
|
-
refLogger(schema.$ref);
|
|
272
|
+
refLogger(schema.$ref, 'ref');
|
|
273
273
|
return transformer({
|
|
274
274
|
$ref: schema.$ref
|
|
275
275
|
});
|
|
@@ -345,7 +345,7 @@ function toJSONSchema(data, opts) {
|
|
|
345
345
|
// them to the supplied `refLogger`.
|
|
346
346
|
var mapping_1 = schema.discriminator.mapping;
|
|
347
347
|
Object.keys(mapping_1).forEach(function (k) {
|
|
348
|
-
refLogger(mapping_1[k]);
|
|
348
|
+
refLogger(mapping_1[k], 'discriminator');
|
|
349
349
|
});
|
|
350
350
|
}
|
|
351
351
|
}
|
|
@@ -393,7 +393,7 @@ function toJSONSchema(data, opts) {
|
|
|
393
393
|
if ('$ref' in example) {
|
|
394
394
|
// no-op because any `$ref` example here after dereferencing is circular so we should
|
|
395
395
|
// ignore it
|
|
396
|
-
refLogger(example.$ref);
|
|
396
|
+
refLogger(example.$ref, 'ref');
|
|
397
397
|
}
|
|
398
398
|
else if ('value' in example) {
|
|
399
399
|
if (isPrimitive(example.value)) {
|
|
@@ -446,7 +446,7 @@ function toJSONSchema(data, opts) {
|
|
|
446
446
|
if (!Array.isArray(schema.items) && Object.keys(schema.items).length === 1 && RMOAS.isRef(schema.items)) {
|
|
447
447
|
// `items` contains a `$ref`, so since it's circular we should do a no-op here and log
|
|
448
448
|
// and ignore it.
|
|
449
|
-
refLogger(schema.items.$ref);
|
|
449
|
+
refLogger(schema.items.$ref, 'ref');
|
|
450
450
|
}
|
|
451
451
|
else if (schema.items !== true) {
|
|
452
452
|
// Run through the arrays contents and clean them up.
|
|
@@ -17,6 +17,7 @@ export declare type SchemaWrapper = {
|
|
|
17
17
|
export declare const types: Record<keyof OASDocument, string>;
|
|
18
18
|
export default function getParametersAsJSONSchema(operation: Operation, api: OASDocument, opts?: {
|
|
19
19
|
globalDefaults?: Record<string, unknown>;
|
|
20
|
+
includeDiscriminatorMappingRefs?: boolean;
|
|
20
21
|
mergeIntoBodyAndMetadata?: boolean;
|
|
21
22
|
retainDeprecatedProperties?: boolean;
|
|
22
23
|
transformer?: (schema: SchemaObject) => SchemaObject;
|
|
@@ -61,8 +61,14 @@ exports.types = {
|
|
|
61
61
|
function getParametersAsJSONSchema(operation, api, opts) {
|
|
62
62
|
var _a;
|
|
63
63
|
var hasCircularRefs = false;
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
var hasDiscriminatorMappingRefs = false;
|
|
65
|
+
function refLogger(ref, type) {
|
|
66
|
+
if (type === 'ref') {
|
|
67
|
+
hasCircularRefs = true;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
hasDiscriminatorMappingRefs = true;
|
|
71
|
+
}
|
|
66
72
|
}
|
|
67
73
|
function getDeprecated(schema, type) {
|
|
68
74
|
// If we wish to retain deprecated properties then we shouldn't split them out into the
|
|
@@ -109,7 +115,9 @@ function getParametersAsJSONSchema(operation, api, opts) {
|
|
|
109
115
|
});
|
|
110
116
|
return {
|
|
111
117
|
type: type,
|
|
112
|
-
schema:
|
|
118
|
+
schema: (0, openapi_to_json_schema_1.isPrimitive)(deprecatedSchema)
|
|
119
|
+
? deprecatedSchema
|
|
120
|
+
: __assign(__assign({}, deprecatedSchema), { $schema: (0, openapi_to_json_schema_1.getSchemaVersionString)(deprecatedSchema, api) })
|
|
113
121
|
};
|
|
114
122
|
}
|
|
115
123
|
/**
|
|
@@ -152,7 +160,9 @@ function getParametersAsJSONSchema(operation, api, opts) {
|
|
|
152
160
|
return {
|
|
153
161
|
type: type,
|
|
154
162
|
label: exports.types[type],
|
|
155
|
-
schema:
|
|
163
|
+
schema: (0, openapi_to_json_schema_1.isPrimitive)(cleanedSchema)
|
|
164
|
+
? cleanedSchema
|
|
165
|
+
: __assign(__assign({}, cleanedSchema), { $schema: (0, openapi_to_json_schema_1.getSchemaVersionString)(cleanedSchema, api) }),
|
|
156
166
|
deprecatedProps: getDeprecated(cleanedSchema, type)
|
|
157
167
|
};
|
|
158
168
|
}
|
|
@@ -210,16 +220,19 @@ function getParametersAsJSONSchema(operation, api, opts) {
|
|
|
210
220
|
}
|
|
211
221
|
if (current.deprecated)
|
|
212
222
|
currentSchema.deprecated = current.deprecated;
|
|
213
|
-
|
|
223
|
+
var interimSchema = (0, openapi_to_json_schema_1["default"])(currentSchema, {
|
|
214
224
|
currentLocation: "/".concat(current.name),
|
|
215
225
|
globalDefaults: opts.globalDefaults,
|
|
216
226
|
refLogger: refLogger,
|
|
217
227
|
transformer: opts.transformer
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
228
|
+
});
|
|
229
|
+
schema = (0, openapi_to_json_schema_1.isPrimitive)(interimSchema)
|
|
230
|
+
? interimSchema
|
|
231
|
+
: __assign(__assign({}, interimSchema), {
|
|
232
|
+
// Note: this applies a `$schema` version to each field in the larger schema
|
|
233
|
+
// object. It's not really **correct** but it's what we have to do because
|
|
234
|
+
// there's a chance that the end user has indicated the schemas are different.
|
|
235
|
+
$schema: (0, openapi_to_json_schema_1.getSchemaVersionString)(currentSchema, api) });
|
|
223
236
|
}
|
|
224
237
|
else if ('content' in current && typeof current.content === 'object') {
|
|
225
238
|
var contentKeys = Object.keys(current.content);
|
|
@@ -256,16 +269,19 @@ function getParametersAsJSONSchema(operation, api, opts) {
|
|
|
256
269
|
}
|
|
257
270
|
if (current.deprecated)
|
|
258
271
|
currentSchema.deprecated = current.deprecated;
|
|
259
|
-
|
|
272
|
+
var interimSchema = (0, openapi_to_json_schema_1["default"])(currentSchema, {
|
|
260
273
|
currentLocation: "/".concat(current.name),
|
|
261
274
|
globalDefaults: opts.globalDefaults,
|
|
262
275
|
refLogger: refLogger,
|
|
263
276
|
transformer: opts.transformer
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
277
|
+
});
|
|
278
|
+
schema = (0, openapi_to_json_schema_1.isPrimitive)(interimSchema)
|
|
279
|
+
? interimSchema
|
|
280
|
+
: __assign(__assign({}, interimSchema), {
|
|
281
|
+
// Note: this applies a `$schema` version to each field in the larger schema
|
|
282
|
+
// object. It's not really **correct** but it's what we have to do because
|
|
283
|
+
// there's a chance that the end user has indicated the schemas are different.
|
|
284
|
+
$schema: (0, openapi_to_json_schema_1.getSchemaVersionString)(currentSchema, api) });
|
|
269
285
|
}
|
|
270
286
|
}
|
|
271
287
|
}
|
|
@@ -339,9 +355,13 @@ function getParametersAsJSONSchema(operation, api, opts) {
|
|
|
339
355
|
*
|
|
340
356
|
* @todo
|
|
341
357
|
*/
|
|
342
|
-
if (
|
|
343
|
-
//
|
|
344
|
-
|
|
358
|
+
if (components) {
|
|
359
|
+
// We should only include components if we've got circular refs or we have discriminator
|
|
360
|
+
// mapping refs (we want to include them).
|
|
361
|
+
if (hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs)) {
|
|
362
|
+
// Fixing typing and confused version mismatches
|
|
363
|
+
group.schema.components = components;
|
|
364
|
+
}
|
|
345
365
|
}
|
|
346
366
|
// Delete deprecatedProps if it's null on the schema.
|
|
347
367
|
if (!group.deprecatedProps)
|
|
@@ -10,11 +10,7 @@ import type { OASDocument, SchemaObject } from 'rmoas.types';
|
|
|
10
10
|
* @param statusCode The response status code to generate a schema for.
|
|
11
11
|
*/
|
|
12
12
|
export default function getResponseAsJSONSchema(operation: Operation, api: OASDocument, statusCode: string | number, opts?: {
|
|
13
|
-
|
|
14
|
-
* With a transformer you can transform any data within a given schema, like say if you want to
|
|
15
|
-
* rewrite a potentially unsafe `title` that might be eventually used as a JS variable name,
|
|
16
|
-
* just make sure to return your transformed schema.
|
|
17
|
-
*/
|
|
13
|
+
includeDiscriminatorMappingRefs?: boolean;
|
|
18
14
|
transformer?: (schema: SchemaObject) => SchemaObject;
|
|
19
15
|
}): {
|
|
20
16
|
type: string | string[];
|
|
@@ -97,8 +97,14 @@ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
|
|
|
97
97
|
return null;
|
|
98
98
|
}
|
|
99
99
|
var hasCircularRefs = false;
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
var hasDiscriminatorMappingRefs = false;
|
|
101
|
+
function refLogger(ref, type) {
|
|
102
|
+
if (type === 'ref') {
|
|
103
|
+
hasCircularRefs = true;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
hasDiscriminatorMappingRefs = true;
|
|
107
|
+
}
|
|
102
108
|
}
|
|
103
109
|
/**
|
|
104
110
|
* @param content An array of `MediaTypeObject`'s to retrieve a preferred schema out of. We
|
|
@@ -139,7 +145,9 @@ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
|
|
|
139
145
|
// able to render so instead of generating a JSON Schema with an `undefined` type we should
|
|
140
146
|
// default to `string` so there's at least *something* the end-user can interact with.
|
|
141
147
|
type: foundSchema.type || 'string',
|
|
142
|
-
schema:
|
|
148
|
+
schema: (0, openapi_to_json_schema_1.isPrimitive)(schema)
|
|
149
|
+
? schema
|
|
150
|
+
: __assign(__assign({}, schema), { $schema: (0, openapi_to_json_schema_1.getSchemaVersionString)(schema, api) }),
|
|
143
151
|
label: 'Response body'
|
|
144
152
|
};
|
|
145
153
|
if (response.description && schemaWrapper.schema) {
|
|
@@ -152,8 +160,12 @@ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
|
|
|
152
160
|
*
|
|
153
161
|
* @todo
|
|
154
162
|
*/
|
|
155
|
-
if (
|
|
156
|
-
|
|
163
|
+
if (api.components && schemaWrapper.schema) {
|
|
164
|
+
// We should only include components if we've got circular refs or we have discriminator
|
|
165
|
+
// mapping refs (we want to include them).
|
|
166
|
+
if (hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs)) {
|
|
167
|
+
schemaWrapper.schema.components = api.components;
|
|
168
|
+
}
|
|
157
169
|
}
|
|
158
170
|
jsonSchema.push(schemaWrapper);
|
|
159
171
|
}
|
package/dist/operation.d.ts
CHANGED
|
@@ -131,6 +131,11 @@ export default class Operation {
|
|
|
131
131
|
* Contains an object of user defined schema defaults.
|
|
132
132
|
*/
|
|
133
133
|
globalDefaults?: Record<string, unknown>;
|
|
134
|
+
/**
|
|
135
|
+
* If you wish to include discriminator mapping `$ref` components alongside your
|
|
136
|
+
* `discriminator` in schemas. Defaults to `true`.
|
|
137
|
+
*/
|
|
138
|
+
includeDiscriminatorMappingRefs?: boolean;
|
|
134
139
|
/**
|
|
135
140
|
* If you want the output to be two objects: body (contains `body` and `formData` JSON
|
|
136
141
|
* Schema) and metadata (contains `path`, `query`, `cookie`, and `header`).
|
|
@@ -154,6 +159,11 @@ export default class Operation {
|
|
|
154
159
|
* @param statusCode Status code to pull a JSON Schema response for.
|
|
155
160
|
*/
|
|
156
161
|
getResponseAsJSONSchema(statusCode: string | number, opts?: {
|
|
162
|
+
/**
|
|
163
|
+
* If you wish to include discriminator mapping `$ref` components alongside your
|
|
164
|
+
* `discriminator` in schemas. Defaults to `true`.
|
|
165
|
+
*/
|
|
166
|
+
includeDiscriminatorMappingRefs?: boolean;
|
|
157
167
|
/**
|
|
158
168
|
* With a transformer you can transform any data within a given schema, like say if you want
|
|
159
169
|
* to rewrite a potentially unsafe `title` that might be eventually used as a JS variable
|
package/dist/operation.js
CHANGED
|
@@ -414,10 +414,7 @@ var Operation = /** @class */ (function () {
|
|
|
414
414
|
*/
|
|
415
415
|
Operation.prototype.getParametersAsJSONSchema = function (opts) {
|
|
416
416
|
if (opts === void 0) { opts = {}; }
|
|
417
|
-
|
|
418
|
-
opts.transformer = function (s) { return s; };
|
|
419
|
-
}
|
|
420
|
-
return (0, get_parameters_as_json_schema_1["default"])(this, this.api, opts);
|
|
417
|
+
return (0, get_parameters_as_json_schema_1["default"])(this, this.api, __assign({ includeDiscriminatorMappingRefs: true, transformer: function (s) { return s; } }, opts));
|
|
421
418
|
};
|
|
422
419
|
/**
|
|
423
420
|
* Get a single response for this status code, formatted as JSON schema.
|
|
@@ -425,10 +422,8 @@ var Operation = /** @class */ (function () {
|
|
|
425
422
|
* @param statusCode Status code to pull a JSON Schema response for.
|
|
426
423
|
*/
|
|
427
424
|
Operation.prototype.getResponseAsJSONSchema = function (statusCode, opts) {
|
|
428
|
-
if (opts === void 0) { opts = {
|
|
429
|
-
|
|
430
|
-
}; }
|
|
431
|
-
return (0, get_response_as_json_schema_1["default"])(this, this.api, statusCode, opts);
|
|
425
|
+
if (opts === void 0) { opts = {}; }
|
|
426
|
+
return (0, get_response_as_json_schema_1["default"])(this, this.api, statusCode, __assign({ includeDiscriminatorMappingRefs: true, transformer: function (s) { return s; } }, opts));
|
|
432
427
|
};
|
|
433
428
|
/**
|
|
434
429
|
* Get an array of all valid response status codes for this operation.
|
package/package.json
CHANGED
|
@@ -56,7 +56,7 @@ export type toJSONSchemaOptions = {
|
|
|
56
56
|
/**
|
|
57
57
|
* A function that's called anytime a (circular) `$ref` is found.
|
|
58
58
|
*/
|
|
59
|
-
refLogger?: (ref: string) => void;
|
|
59
|
+
refLogger?: (ref: string, type: 'ref' | 'discriminator') => void;
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* A function that's called to potentially transform any discovered schema.
|
|
@@ -295,7 +295,7 @@ export default function toJSONSchema(
|
|
|
295
295
|
// If this schema contains a `$ref`, it's circular and we shouldn't try to resolve it. Just
|
|
296
296
|
// return and move along.
|
|
297
297
|
if (RMOAS.isRef(schema)) {
|
|
298
|
-
refLogger(schema.$ref);
|
|
298
|
+
refLogger(schema.$ref, 'ref');
|
|
299
299
|
|
|
300
300
|
return transformer({
|
|
301
301
|
$ref: schema.$ref,
|
|
@@ -381,7 +381,7 @@ export default function toJSONSchema(
|
|
|
381
381
|
// them to the supplied `refLogger`.
|
|
382
382
|
const mapping = schema.discriminator.mapping;
|
|
383
383
|
Object.keys(mapping).forEach(k => {
|
|
384
|
-
refLogger(mapping[k]);
|
|
384
|
+
refLogger(mapping[k], 'discriminator');
|
|
385
385
|
});
|
|
386
386
|
}
|
|
387
387
|
}
|
|
@@ -427,7 +427,7 @@ export default function toJSONSchema(
|
|
|
427
427
|
if ('$ref' in example) {
|
|
428
428
|
// no-op because any `$ref` example here after dereferencing is circular so we should
|
|
429
429
|
// ignore it
|
|
430
|
-
refLogger(example.$ref);
|
|
430
|
+
refLogger(example.$ref, 'ref');
|
|
431
431
|
} else if ('value' in example) {
|
|
432
432
|
if (isPrimitive(example.value)) {
|
|
433
433
|
examples.push(example.value);
|
|
@@ -480,7 +480,7 @@ export default function toJSONSchema(
|
|
|
480
480
|
if (!Array.isArray(schema.items) && Object.keys(schema.items).length === 1 && RMOAS.isRef(schema.items)) {
|
|
481
481
|
// `items` contains a `$ref`, so since it's circular we should do a no-op here and log
|
|
482
482
|
// and ignore it.
|
|
483
|
-
refLogger(schema.items.$ref);
|
|
483
|
+
refLogger(schema.items.$ref, 'ref');
|
|
484
484
|
} else if (schema.items !== true) {
|
|
485
485
|
// Run through the arrays contents and clean them up.
|
|
486
486
|
schema.items = toJSONSchema(schema.items as RMOAS.SchemaObject, {
|
|
@@ -4,7 +4,7 @@ import type { OpenAPIV3_1 } from 'openapi-types';
|
|
|
4
4
|
|
|
5
5
|
import cloneObject from '../lib/clone-object';
|
|
6
6
|
import matchesMimetype from '../lib/matches-mimetype';
|
|
7
|
-
import toJSONSchema, { getSchemaVersionString } from '../lib/openapi-to-json-schema';
|
|
7
|
+
import toJSONSchema, { isPrimitive, getSchemaVersionString } from '../lib/openapi-to-json-schema';
|
|
8
8
|
|
|
9
9
|
const isJSON = matchesMimetype.json;
|
|
10
10
|
|
|
@@ -38,15 +38,21 @@ export default function getParametersAsJSONSchema(
|
|
|
38
38
|
api: OASDocument,
|
|
39
39
|
opts?: {
|
|
40
40
|
globalDefaults?: Record<string, unknown>;
|
|
41
|
+
includeDiscriminatorMappingRefs?: boolean;
|
|
41
42
|
mergeIntoBodyAndMetadata?: boolean;
|
|
42
43
|
retainDeprecatedProperties?: boolean;
|
|
43
44
|
transformer?: (schema: SchemaObject) => SchemaObject;
|
|
44
45
|
}
|
|
45
46
|
) {
|
|
46
47
|
let hasCircularRefs = false;
|
|
48
|
+
let hasDiscriminatorMappingRefs = false;
|
|
47
49
|
|
|
48
|
-
function refLogger() {
|
|
49
|
-
|
|
50
|
+
function refLogger(ref: string, type: 'ref' | 'discriminator') {
|
|
51
|
+
if (type === 'ref') {
|
|
52
|
+
hasCircularRefs = true;
|
|
53
|
+
} else {
|
|
54
|
+
hasDiscriminatorMappingRefs = true;
|
|
55
|
+
}
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
function getDeprecated(schema: SchemaObject, type: string) {
|
|
@@ -102,10 +108,12 @@ export default function getParametersAsJSONSchema(
|
|
|
102
108
|
|
|
103
109
|
return {
|
|
104
110
|
type,
|
|
105
|
-
schema:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
111
|
+
schema: isPrimitive(deprecatedSchema)
|
|
112
|
+
? deprecatedSchema
|
|
113
|
+
: {
|
|
114
|
+
...deprecatedSchema,
|
|
115
|
+
$schema: getSchemaVersionString(deprecatedSchema, api),
|
|
116
|
+
},
|
|
109
117
|
};
|
|
110
118
|
}
|
|
111
119
|
|
|
@@ -153,10 +161,12 @@ export default function getParametersAsJSONSchema(
|
|
|
153
161
|
return {
|
|
154
162
|
type,
|
|
155
163
|
label: types[type],
|
|
156
|
-
schema:
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
164
|
+
schema: isPrimitive(cleanedSchema)
|
|
165
|
+
? cleanedSchema
|
|
166
|
+
: {
|
|
167
|
+
...cleanedSchema,
|
|
168
|
+
$schema: getSchemaVersionString(cleanedSchema, api),
|
|
169
|
+
},
|
|
160
170
|
deprecatedProps: getDeprecated(cleanedSchema, type),
|
|
161
171
|
};
|
|
162
172
|
}
|
|
@@ -224,19 +234,23 @@ export default function getParametersAsJSONSchema(
|
|
|
224
234
|
|
|
225
235
|
if (current.deprecated) currentSchema.deprecated = current.deprecated;
|
|
226
236
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
237
|
+
const interimSchema = toJSONSchema(currentSchema, {
|
|
238
|
+
currentLocation: `/${current.name}`,
|
|
239
|
+
globalDefaults: opts.globalDefaults,
|
|
240
|
+
refLogger,
|
|
241
|
+
transformer: opts.transformer,
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
schema = isPrimitive(interimSchema)
|
|
245
|
+
? interimSchema
|
|
246
|
+
: {
|
|
247
|
+
...interimSchema,
|
|
248
|
+
|
|
249
|
+
// Note: this applies a `$schema` version to each field in the larger schema
|
|
250
|
+
// object. It's not really **correct** but it's what we have to do because
|
|
251
|
+
// there's a chance that the end user has indicated the schemas are different.
|
|
252
|
+
$schema: getSchemaVersionString(currentSchema, api),
|
|
253
|
+
};
|
|
240
254
|
} else if ('content' in current && typeof current.content === 'object') {
|
|
241
255
|
const contentKeys = Object.keys(current.content);
|
|
242
256
|
if (contentKeys.length) {
|
|
@@ -272,19 +286,23 @@ export default function getParametersAsJSONSchema(
|
|
|
272
286
|
|
|
273
287
|
if (current.deprecated) currentSchema.deprecated = current.deprecated;
|
|
274
288
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
289
|
+
const interimSchema = toJSONSchema(currentSchema, {
|
|
290
|
+
currentLocation: `/${current.name}`,
|
|
291
|
+
globalDefaults: opts.globalDefaults,
|
|
292
|
+
refLogger,
|
|
293
|
+
transformer: opts.transformer,
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
schema = isPrimitive(interimSchema)
|
|
297
|
+
? interimSchema
|
|
298
|
+
: {
|
|
299
|
+
...interimSchema,
|
|
300
|
+
|
|
301
|
+
// Note: this applies a `$schema` version to each field in the larger schema
|
|
302
|
+
// object. It's not really **correct** but it's what we have to do because
|
|
303
|
+
// there's a chance that the end user has indicated the schemas are different.
|
|
304
|
+
$schema: getSchemaVersionString(currentSchema, api),
|
|
305
|
+
};
|
|
288
306
|
}
|
|
289
307
|
}
|
|
290
308
|
}
|
|
@@ -369,9 +387,13 @@ export default function getParametersAsJSONSchema(
|
|
|
369
387
|
*
|
|
370
388
|
* @todo
|
|
371
389
|
*/
|
|
372
|
-
if (
|
|
373
|
-
//
|
|
374
|
-
(
|
|
390
|
+
if (components) {
|
|
391
|
+
// We should only include components if we've got circular refs or we have discriminator
|
|
392
|
+
// mapping refs (we want to include them).
|
|
393
|
+
if (hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs)) {
|
|
394
|
+
// Fixing typing and confused version mismatches
|
|
395
|
+
(group.schema.components as ComponentsObject) = components;
|
|
396
|
+
}
|
|
375
397
|
}
|
|
376
398
|
|
|
377
399
|
// Delete deprecatedProps if it's null on the schema.
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
|
|
11
11
|
import cloneObject from '../lib/clone-object';
|
|
12
12
|
import matches from '../lib/matches-mimetype';
|
|
13
|
-
import toJSONSchema, { getSchemaVersionString } from '../lib/openapi-to-json-schema';
|
|
13
|
+
import toJSONSchema, { isPrimitive, getSchemaVersionString } from '../lib/openapi-to-json-schema';
|
|
14
14
|
|
|
15
15
|
const isJSON = matches.json;
|
|
16
16
|
|
|
@@ -91,11 +91,7 @@ export default function getResponseAsJSONSchema(
|
|
|
91
91
|
api: OASDocument,
|
|
92
92
|
statusCode: string | number,
|
|
93
93
|
opts?: {
|
|
94
|
-
|
|
95
|
-
* With a transformer you can transform any data within a given schema, like say if you want to
|
|
96
|
-
* rewrite a potentially unsafe `title` that might be eventually used as a JS variable name,
|
|
97
|
-
* just make sure to return your transformed schema.
|
|
98
|
-
*/
|
|
94
|
+
includeDiscriminatorMappingRefs?: boolean;
|
|
99
95
|
transformer?: (schema: SchemaObject) => SchemaObject;
|
|
100
96
|
}
|
|
101
97
|
) {
|
|
@@ -107,9 +103,14 @@ export default function getResponseAsJSONSchema(
|
|
|
107
103
|
}
|
|
108
104
|
|
|
109
105
|
let hasCircularRefs = false;
|
|
106
|
+
let hasDiscriminatorMappingRefs = false;
|
|
110
107
|
|
|
111
|
-
function refLogger() {
|
|
112
|
-
|
|
108
|
+
function refLogger(ref: string, type: 'ref' | 'discriminator') {
|
|
109
|
+
if (type === 'ref') {
|
|
110
|
+
hasCircularRefs = true;
|
|
111
|
+
} else {
|
|
112
|
+
hasDiscriminatorMappingRefs = true;
|
|
113
|
+
}
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
/**
|
|
@@ -160,10 +161,12 @@ export default function getResponseAsJSONSchema(
|
|
|
160
161
|
// able to render so instead of generating a JSON Schema with an `undefined` type we should
|
|
161
162
|
// default to `string` so there's at least *something* the end-user can interact with.
|
|
162
163
|
type: foundSchema.type || 'string',
|
|
163
|
-
schema:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
schema: isPrimitive(schema)
|
|
165
|
+
? schema
|
|
166
|
+
: {
|
|
167
|
+
...schema,
|
|
168
|
+
$schema: getSchemaVersionString(schema, api),
|
|
169
|
+
},
|
|
167
170
|
label: 'Response body',
|
|
168
171
|
};
|
|
169
172
|
|
|
@@ -178,8 +181,12 @@ export default function getResponseAsJSONSchema(
|
|
|
178
181
|
*
|
|
179
182
|
* @todo
|
|
180
183
|
*/
|
|
181
|
-
if (
|
|
182
|
-
|
|
184
|
+
if (api.components && schemaWrapper.schema) {
|
|
185
|
+
// We should only include components if we've got circular refs or we have discriminator
|
|
186
|
+
// mapping refs (we want to include them).
|
|
187
|
+
if (hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs)) {
|
|
188
|
+
((schemaWrapper.schema as SchemaObject).components as ComponentsObject) = api.components as ComponentsObject;
|
|
189
|
+
}
|
|
183
190
|
}
|
|
184
191
|
|
|
185
192
|
jsonSchema.push(schemaWrapper);
|
package/src/operation.ts
CHANGED
|
@@ -465,6 +465,12 @@ export default class Operation {
|
|
|
465
465
|
*/
|
|
466
466
|
globalDefaults?: Record<string, unknown>;
|
|
467
467
|
|
|
468
|
+
/**
|
|
469
|
+
* If you wish to include discriminator mapping `$ref` components alongside your
|
|
470
|
+
* `discriminator` in schemas. Defaults to `true`.
|
|
471
|
+
*/
|
|
472
|
+
includeDiscriminatorMappingRefs?: boolean;
|
|
473
|
+
|
|
468
474
|
/**
|
|
469
475
|
* If you want the output to be two objects: body (contains `body` and `formData` JSON
|
|
470
476
|
* Schema) and metadata (contains `path`, `query`, `cookie`, and `header`).
|
|
@@ -485,11 +491,11 @@ export default class Operation {
|
|
|
485
491
|
transformer?: (schema: RMOAS.SchemaObject) => RMOAS.SchemaObject;
|
|
486
492
|
} = {}
|
|
487
493
|
) {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
494
|
+
return getParametersAsJSONSchema(this, this.api, {
|
|
495
|
+
includeDiscriminatorMappingRefs: true,
|
|
496
|
+
transformer: (s: RMOAS.SchemaObject) => s,
|
|
497
|
+
...opts,
|
|
498
|
+
});
|
|
493
499
|
}
|
|
494
500
|
|
|
495
501
|
/**
|
|
@@ -500,17 +506,25 @@ export default class Operation {
|
|
|
500
506
|
getResponseAsJSONSchema(
|
|
501
507
|
statusCode: string | number,
|
|
502
508
|
opts: {
|
|
509
|
+
/**
|
|
510
|
+
* If you wish to include discriminator mapping `$ref` components alongside your
|
|
511
|
+
* `discriminator` in schemas. Defaults to `true`.
|
|
512
|
+
*/
|
|
513
|
+
includeDiscriminatorMappingRefs?: boolean;
|
|
514
|
+
|
|
503
515
|
/**
|
|
504
516
|
* With a transformer you can transform any data within a given schema, like say if you want
|
|
505
517
|
* to rewrite a potentially unsafe `title` that might be eventually used as a JS variable
|
|
506
518
|
* name, just make sure to return your transformed schema.
|
|
507
519
|
*/
|
|
508
520
|
transformer?: (schema: RMOAS.SchemaObject) => RMOAS.SchemaObject;
|
|
509
|
-
} = {
|
|
510
|
-
transformer: (s: RMOAS.SchemaObject) => s,
|
|
511
|
-
}
|
|
521
|
+
} = {}
|
|
512
522
|
) {
|
|
513
|
-
return getResponseAsJSONSchema(this, this.api, statusCode,
|
|
523
|
+
return getResponseAsJSONSchema(this, this.api, statusCode, {
|
|
524
|
+
includeDiscriminatorMappingRefs: true,
|
|
525
|
+
transformer: (s: RMOAS.SchemaObject) => s,
|
|
526
|
+
...opts,
|
|
527
|
+
});
|
|
514
528
|
}
|
|
515
529
|
|
|
516
530
|
/**
|