oas 20.3.0 → 20.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +3 -1
- package/CHANGELOG.md +14 -0
- package/dist/operation/get-parameters-as-json-schema.d.ts +1 -0
- package/dist/operation/get-parameters-as-json-schema.js +51 -27
- package/dist/operation.d.ts +1 -1
- package/dist/operation.js +13 -1
- package/package.json +12 -12
- package/src/index.ts +1 -1
- package/src/lib/matches-mimetype.ts +1 -1
- package/src/operation/get-parameters-as-json-schema.ts +57 -23
- package/src/operation.ts +6 -2
package/.vscode/settings.json
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 20.5.0 (2023-03-02)
|
|
2
|
+
|
|
3
|
+
* chore: bumping out of date deps ([a905664](https://github.com/readmeio/oas/commit/a905664))
|
|
4
|
+
* chore(deps): bumping deps ([f0de8b9](https://github.com/readmeio/oas/commit/f0de8b9))
|
|
5
|
+
* fix: only adding components to generated JSON Schema if we need to (#732) ([9787b4d](https://github.com/readmeio/oas/commit/9787b4d)), closes [#732](https://github.com/readmeio/oas/issues/732)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## 20.4.0 (2023-01-12)
|
|
10
|
+
|
|
11
|
+
* feat: pass through requestBody descriptions (#730) ([3272137](https://github.com/readmeio/oas/commit/3272137)), closes [#730](https://github.com/readmeio/oas/issues/730)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
1
15
|
## 20.3.0 (2023-01-03)
|
|
2
16
|
|
|
3
17
|
* chore: bumping deps ([ed5e473](https://github.com/readmeio/oas/commit/ed5e473))
|
|
@@ -127,7 +127,7 @@ function getParametersAsJSONSchema(operation, api, opts) {
|
|
|
127
127
|
var requestBody = operation.getRequestBody();
|
|
128
128
|
if (!requestBody || !Array.isArray(requestBody))
|
|
129
129
|
return null;
|
|
130
|
-
var mediaType = requestBody[0], mediaTypeObject = requestBody[1];
|
|
130
|
+
var mediaType = requestBody[0], mediaTypeObject = requestBody[1], description = requestBody[2];
|
|
131
131
|
var type = mediaType === 'application/x-www-form-urlencoded' ? 'formData' : 'body';
|
|
132
132
|
// If this schema is completely empty, don't bother processing it.
|
|
133
133
|
if (!mediaTypeObject.schema || !Object.keys(mediaTypeObject.schema).length) {
|
|
@@ -157,30 +157,38 @@ function getParametersAsJSONSchema(operation, api, opts) {
|
|
|
157
157
|
if (!Object.keys(cleanedSchema).length) {
|
|
158
158
|
return null;
|
|
159
159
|
}
|
|
160
|
-
return {
|
|
161
|
-
type: type,
|
|
162
|
-
label: exports.types[type],
|
|
163
|
-
schema: (0, openapi_to_json_schema_1.isPrimitive)(cleanedSchema)
|
|
160
|
+
return __assign({ type: type, label: exports.types[type], schema: (0, openapi_to_json_schema_1.isPrimitive)(cleanedSchema)
|
|
164
161
|
? cleanedSchema
|
|
165
|
-
: __assign(__assign({}, cleanedSchema), { $schema: (0, openapi_to_json_schema_1.getSchemaVersionString)(cleanedSchema, api) }),
|
|
166
|
-
deprecatedProps: getDeprecated(cleanedSchema, type)
|
|
167
|
-
};
|
|
162
|
+
: __assign(__assign({}, cleanedSchema), { $schema: (0, openapi_to_json_schema_1.getSchemaVersionString)(cleanedSchema, api) }), deprecatedProps: getDeprecated(cleanedSchema, type) }, (description ? { description: description } : {}));
|
|
168
163
|
}
|
|
169
164
|
function transformComponents() {
|
|
170
165
|
if (!('components' in api)) {
|
|
171
166
|
return false;
|
|
172
167
|
}
|
|
173
|
-
var components = {
|
|
168
|
+
var components = {
|
|
169
|
+
/**
|
|
170
|
+
* Initializing an empty `components[componentType] = {}` object within the `forEach` below
|
|
171
|
+
* is incredibly slow because each of these component types has a wide variety of shapes. So
|
|
172
|
+
* in order to not have TS compilation times that takes literally **seconds** because of a
|
|
173
|
+
* single line we're instead opting to prefill this object with some empty placeholders that
|
|
174
|
+
* we'll later remove if they didn't get used.
|
|
175
|
+
*
|
|
176
|
+
* Obviously not ideal but I'd rather have a couple lines of boilerplate nonsense than having
|
|
177
|
+
* to wait a noticeably frustrating amount of time for TS Intellisense to reload itself after
|
|
178
|
+
* you save a line in any file.
|
|
179
|
+
*/
|
|
180
|
+
examples: {},
|
|
181
|
+
schemas: {},
|
|
182
|
+
responses: {},
|
|
183
|
+
parameters: {},
|
|
184
|
+
requestBodies: {},
|
|
185
|
+
headers: {},
|
|
186
|
+
securitySchemes: {},
|
|
187
|
+
links: {},
|
|
188
|
+
callbacks: {}
|
|
189
|
+
};
|
|
174
190
|
Object.keys(api.components).forEach(function (componentType) {
|
|
175
191
|
if (typeof api.components[componentType] === 'object' && !Array.isArray(api.components[componentType])) {
|
|
176
|
-
/**
|
|
177
|
-
* Typescript is INCREDIBLY SLOW parsing this one line. I think it's because of the large
|
|
178
|
-
* variety of types that that object could represent but I can't yet think of a way to get
|
|
179
|
-
* around that.
|
|
180
|
-
*
|
|
181
|
-
* @todo
|
|
182
|
-
*/
|
|
183
|
-
components[componentType] = {};
|
|
184
192
|
Object.keys(api.components[componentType]).forEach(function (schemaName) {
|
|
185
193
|
var componentSchema = (0, clone_object_1["default"])(api.components[componentType][schemaName]);
|
|
186
194
|
components[componentType][schemaName] = (0, openapi_to_json_schema_1["default"])(componentSchema, {
|
|
@@ -191,6 +199,22 @@ function getParametersAsJSONSchema(operation, api, opts) {
|
|
|
191
199
|
});
|
|
192
200
|
}
|
|
193
201
|
});
|
|
202
|
+
// If none of our above component type placeholders got used let's clean them up.
|
|
203
|
+
[
|
|
204
|
+
'examples',
|
|
205
|
+
'schemas',
|
|
206
|
+
'responses',
|
|
207
|
+
'parameters',
|
|
208
|
+
'requestBodies',
|
|
209
|
+
'headers',
|
|
210
|
+
'securitySchemes',
|
|
211
|
+
'links',
|
|
212
|
+
'callbacks',
|
|
213
|
+
].forEach(function (componentType) {
|
|
214
|
+
if (!Object.keys(components[componentType]).length) {
|
|
215
|
+
delete components[componentType];
|
|
216
|
+
}
|
|
217
|
+
});
|
|
194
218
|
return components;
|
|
195
219
|
}
|
|
196
220
|
function transformParameters() {
|
|
@@ -345,10 +369,14 @@ function getParametersAsJSONSchema(operation, api, opts) {
|
|
|
345
369
|
if (!operation.hasParameters() && !operation.hasRequestBody()) {
|
|
346
370
|
return null;
|
|
347
371
|
}
|
|
348
|
-
var components = transformComponents();
|
|
349
372
|
var typeKeys = Object.keys(exports.types);
|
|
350
|
-
|
|
351
|
-
|
|
373
|
+
var jsonSchema = (_a = [transformRequestBody()]).concat.apply(_a, transformParameters()).filter(Boolean);
|
|
374
|
+
// We should only include `components`, or even bother transforming components into JSON Schema,
|
|
375
|
+
// if we either have circular refs or if we have discriminator mapping refs somewhere and want to
|
|
376
|
+
// include them.
|
|
377
|
+
var shouldIncludeComponents = hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs);
|
|
378
|
+
var components = shouldIncludeComponents ? transformComponents() : false;
|
|
379
|
+
return jsonSchema
|
|
352
380
|
.map(function (group) {
|
|
353
381
|
/**
|
|
354
382
|
* Since this library assumes that the schema has already been dereferenced, adding every
|
|
@@ -357,13 +385,9 @@ function getParametersAsJSONSchema(operation, api, opts) {
|
|
|
357
385
|
*
|
|
358
386
|
* @todo
|
|
359
387
|
*/
|
|
360
|
-
if (components) {
|
|
361
|
-
//
|
|
362
|
-
|
|
363
|
-
if (hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs)) {
|
|
364
|
-
// Fixing typing and confused version mismatches
|
|
365
|
-
group.schema.components = components;
|
|
366
|
-
}
|
|
388
|
+
if (components && shouldIncludeComponents) {
|
|
389
|
+
// Fixing typing and confused version mismatches
|
|
390
|
+
group.schema.components = components;
|
|
367
391
|
}
|
|
368
392
|
// Delete deprecatedProps if it's null on the schema.
|
|
369
393
|
if (!group.deprecatedProps)
|
package/dist/operation.d.ts
CHANGED
|
@@ -210,7 +210,7 @@ export default class Operation {
|
|
|
210
210
|
* @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#mediaTypeObject}
|
|
211
211
|
* @param mediaType Specific request body media type to retrieve if present.
|
|
212
212
|
*/
|
|
213
|
-
getRequestBody(mediaType?: string): false | RMOAS.MediaTypeObject | [string, RMOAS.MediaTypeObject];
|
|
213
|
+
getRequestBody(mediaType?: string): false | RMOAS.MediaTypeObject | [string, RMOAS.MediaTypeObject, ...string[]];
|
|
214
214
|
/**
|
|
215
215
|
* Retrieve an array of request body examples that this operation has.
|
|
216
216
|
*
|
package/dist/operation.js
CHANGED
|
@@ -48,6 +48,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
48
48
|
__setModuleDefault(result, mod);
|
|
49
49
|
return result;
|
|
50
50
|
};
|
|
51
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
52
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
53
|
+
if (ar || !(i in from)) {
|
|
54
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
55
|
+
ar[i] = from[i];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
59
|
+
};
|
|
51
60
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
52
61
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
53
62
|
};
|
|
@@ -543,7 +552,10 @@ var Operation = /** @class */ (function () {
|
|
|
543
552
|
});
|
|
544
553
|
}
|
|
545
554
|
if (availableMediaType) {
|
|
546
|
-
return [
|
|
555
|
+
return __spreadArray([
|
|
556
|
+
availableMediaType,
|
|
557
|
+
requestBody.content[availableMediaType]
|
|
558
|
+
], (requestBody.description ? [requestBody.description] : []), true);
|
|
547
559
|
}
|
|
548
560
|
return false;
|
|
549
561
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oas",
|
|
3
|
-
"version": "20.
|
|
3
|
+
"version": "20.5.0",
|
|
4
4
|
"description": "Comprehensive tooling for working with OpenAPI definitions",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ReadMe <support@readme.io> (https://readme.com)",
|
|
@@ -52,26 +52,26 @@
|
|
|
52
52
|
"jsonpath-plus": "^7.2.0",
|
|
53
53
|
"jsonpointer": "^5.0.0",
|
|
54
54
|
"memoizee": "^0.4.14",
|
|
55
|
-
"oas-normalize": "^8.3.
|
|
55
|
+
"oas-normalize": "^8.3.2",
|
|
56
56
|
"openapi-types": "^12.1.0",
|
|
57
57
|
"path-to-regexp": "^6.2.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@commitlint/cli": "^17.
|
|
61
|
-
"@commitlint/config-conventional": "^17.
|
|
62
|
-
"@readme/eslint-config": "^10.
|
|
60
|
+
"@commitlint/cli": "^17.4.4",
|
|
61
|
+
"@commitlint/config-conventional": "^17.4.4",
|
|
62
|
+
"@readme/eslint-config": "^10.5.1",
|
|
63
63
|
"@readme/oas-examples": "^5.7.1",
|
|
64
64
|
"@readme/openapi-parser": "^2.4.0",
|
|
65
|
-
"@types/jest": "^29.
|
|
65
|
+
"@types/jest": "^29.4.0",
|
|
66
66
|
"@types/json-schema-merge-allof": "^0.6.1",
|
|
67
67
|
"@types/memoizee": "^0.4.6",
|
|
68
|
-
"@types/node": "^18.
|
|
69
|
-
"eslint": "^8.
|
|
68
|
+
"@types/node": "^18.14.4",
|
|
69
|
+
"eslint": "^8.35.0",
|
|
70
70
|
"husky": "^8.0.3",
|
|
71
|
-
"jest": "^29.3
|
|
72
|
-
"prettier": "^2.8.
|
|
73
|
-
"ts-jest": "^29.0.
|
|
74
|
-
"typescript": "^4.9.
|
|
71
|
+
"jest": "^29.4.3",
|
|
72
|
+
"prettier": "^2.8.4",
|
|
73
|
+
"ts-jest": "^29.0.5",
|
|
74
|
+
"typescript": "^4.9.5"
|
|
75
75
|
},
|
|
76
76
|
"prettier": "@readme/eslint-config/prettier",
|
|
77
77
|
"commitlint": {
|
package/src/index.ts
CHANGED
|
@@ -110,7 +110,7 @@ function normalizePath(path: string) {
|
|
|
110
110
|
// also handling quirks here like if there's an optional proceeding or trailing curly bracket
|
|
111
111
|
// (`{{pathParam}` or `{pathParam}}`) as any unescaped curlys, which would be present in
|
|
112
112
|
// `:pathParam}`, will throw a regex exception.
|
|
113
|
-
.replace(/({?){(.*?)}(}?)/g,
|
|
113
|
+
.replace(/({?){(.*?)}(}?)/g, (str, ...args) => {
|
|
114
114
|
// If a path contains a path parameter with hyphens, like `:dlc-release`, when it's regexd
|
|
115
115
|
// with `path-to-regexp` it match against the `:dlc` portion of the parameter, breaking all
|
|
116
116
|
// matching against the full path.
|
|
@@ -13,6 +13,7 @@ export interface SchemaWrapper {
|
|
|
13
13
|
type: string;
|
|
14
14
|
label?: string;
|
|
15
15
|
schema: SchemaObject;
|
|
16
|
+
description?: string;
|
|
16
17
|
deprecatedProps?: SchemaWrapper;
|
|
17
18
|
}
|
|
18
19
|
|
|
@@ -124,7 +125,7 @@ export default function getParametersAsJSONSchema(
|
|
|
124
125
|
const requestBody = operation.getRequestBody();
|
|
125
126
|
if (!requestBody || !Array.isArray(requestBody)) return null;
|
|
126
127
|
|
|
127
|
-
const [mediaType, mediaTypeObject] = requestBody;
|
|
128
|
+
const [mediaType, mediaTypeObject, description] = requestBody;
|
|
128
129
|
const type = mediaType === 'application/x-www-form-urlencoded' ? 'formData' : 'body';
|
|
129
130
|
|
|
130
131
|
// If this schema is completely empty, don't bother processing it.
|
|
@@ -146,6 +147,7 @@ export default function getParametersAsJSONSchema(
|
|
|
146
147
|
// We're cloning the request schema because we've had issues with request schemas that were
|
|
147
148
|
// dereferenced being processed multiple times because their component is also processed.
|
|
148
149
|
const requestSchema = cloneObject(mediaTypeObject.schema);
|
|
150
|
+
|
|
149
151
|
const cleanedSchema = toJSONSchema(requestSchema, {
|
|
150
152
|
globalDefaults: opts.globalDefaults,
|
|
151
153
|
prevSchemas,
|
|
@@ -168,6 +170,7 @@ export default function getParametersAsJSONSchema(
|
|
|
168
170
|
$schema: getSchemaVersionString(cleanedSchema, api),
|
|
169
171
|
},
|
|
170
172
|
deprecatedProps: getDeprecated(cleanedSchema, type),
|
|
173
|
+
...(description ? { description } : {}),
|
|
171
174
|
};
|
|
172
175
|
}
|
|
173
176
|
|
|
@@ -176,19 +179,31 @@ export default function getParametersAsJSONSchema(
|
|
|
176
179
|
return false;
|
|
177
180
|
}
|
|
178
181
|
|
|
179
|
-
const components: Partial<ComponentsObject> = {
|
|
182
|
+
const components: Partial<ComponentsObject> = {
|
|
183
|
+
/**
|
|
184
|
+
* Initializing an empty `components[componentType] = {}` object within the `forEach` below
|
|
185
|
+
* is incredibly slow because each of these component types has a wide variety of shapes. So
|
|
186
|
+
* in order to not have TS compilation times that takes literally **seconds** because of a
|
|
187
|
+
* single line we're instead opting to prefill this object with some empty placeholders that
|
|
188
|
+
* we'll later remove if they didn't get used.
|
|
189
|
+
*
|
|
190
|
+
* Obviously not ideal but I'd rather have a couple lines of boilerplate nonsense than having
|
|
191
|
+
* to wait a noticeably frustrating amount of time for TS Intellisense to reload itself after
|
|
192
|
+
* you save a line in any file.
|
|
193
|
+
*/
|
|
194
|
+
examples: {},
|
|
195
|
+
schemas: {},
|
|
196
|
+
responses: {},
|
|
197
|
+
parameters: {},
|
|
198
|
+
requestBodies: {},
|
|
199
|
+
headers: {},
|
|
200
|
+
securitySchemes: {},
|
|
201
|
+
links: {},
|
|
202
|
+
callbacks: {},
|
|
203
|
+
};
|
|
180
204
|
|
|
181
205
|
Object.keys(api.components).forEach((componentType: keyof ComponentsObject) => {
|
|
182
206
|
if (typeof api.components[componentType] === 'object' && !Array.isArray(api.components[componentType])) {
|
|
183
|
-
/**
|
|
184
|
-
* Typescript is INCREDIBLY SLOW parsing this one line. I think it's because of the large
|
|
185
|
-
* variety of types that that object could represent but I can't yet think of a way to get
|
|
186
|
-
* around that.
|
|
187
|
-
*
|
|
188
|
-
* @todo
|
|
189
|
-
*/
|
|
190
|
-
components[componentType] = {};
|
|
191
|
-
|
|
192
207
|
Object.keys(api.components[componentType]).forEach(schemaName => {
|
|
193
208
|
const componentSchema = cloneObject(api.components[componentType][schemaName]);
|
|
194
209
|
components[componentType][schemaName] = toJSONSchema(componentSchema as SchemaObject, {
|
|
@@ -200,6 +215,23 @@ export default function getParametersAsJSONSchema(
|
|
|
200
215
|
}
|
|
201
216
|
});
|
|
202
217
|
|
|
218
|
+
// If none of our above component type placeholders got used let's clean them up.
|
|
219
|
+
[
|
|
220
|
+
'examples',
|
|
221
|
+
'schemas',
|
|
222
|
+
'responses',
|
|
223
|
+
'parameters',
|
|
224
|
+
'requestBodies',
|
|
225
|
+
'headers',
|
|
226
|
+
'securitySchemes',
|
|
227
|
+
'links',
|
|
228
|
+
'callbacks',
|
|
229
|
+
].forEach((componentType: keyof ComponentsObject) => {
|
|
230
|
+
if (!Object.keys(components[componentType]).length) {
|
|
231
|
+
delete components[componentType];
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
203
235
|
return components;
|
|
204
236
|
}
|
|
205
237
|
|
|
@@ -375,12 +407,18 @@ export default function getParametersAsJSONSchema(
|
|
|
375
407
|
return null;
|
|
376
408
|
}
|
|
377
409
|
|
|
378
|
-
const components = transformComponents();
|
|
379
|
-
|
|
380
410
|
const typeKeys = Object.keys(types);
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
411
|
+
const jsonSchema = [transformRequestBody()].concat(...transformParameters()).filter(Boolean);
|
|
412
|
+
|
|
413
|
+
// We should only include `components`, or even bother transforming components into JSON Schema,
|
|
414
|
+
// if we either have circular refs or if we have discriminator mapping refs somewhere and want to
|
|
415
|
+
// include them.
|
|
416
|
+
const shouldIncludeComponents =
|
|
417
|
+
hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs);
|
|
418
|
+
|
|
419
|
+
const components = shouldIncludeComponents ? transformComponents() : false;
|
|
420
|
+
|
|
421
|
+
return jsonSchema
|
|
384
422
|
.map(group => {
|
|
385
423
|
/**
|
|
386
424
|
* Since this library assumes that the schema has already been dereferenced, adding every
|
|
@@ -389,13 +427,9 @@ export default function getParametersAsJSONSchema(
|
|
|
389
427
|
*
|
|
390
428
|
* @todo
|
|
391
429
|
*/
|
|
392
|
-
if (components) {
|
|
393
|
-
//
|
|
394
|
-
|
|
395
|
-
if (hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs)) {
|
|
396
|
-
// Fixing typing and confused version mismatches
|
|
397
|
-
(group.schema.components as ComponentsObject) = components;
|
|
398
|
-
}
|
|
430
|
+
if (components && shouldIncludeComponents) {
|
|
431
|
+
// Fixing typing and confused version mismatches
|
|
432
|
+
(group.schema.components as ComponentsObject) = components;
|
|
399
433
|
}
|
|
400
434
|
|
|
401
435
|
// Delete deprecatedProps if it's null on the schema.
|
package/src/operation.ts
CHANGED
|
@@ -621,7 +621,7 @@ export default class Operation {
|
|
|
621
621
|
* @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#mediaTypeObject}
|
|
622
622
|
* @param mediaType Specific request body media type to retrieve if present.
|
|
623
623
|
*/
|
|
624
|
-
getRequestBody(mediaType?: string): false | RMOAS.MediaTypeObject | [string, RMOAS.MediaTypeObject] {
|
|
624
|
+
getRequestBody(mediaType?: string): false | RMOAS.MediaTypeObject | [string, RMOAS.MediaTypeObject, ...string[]] {
|
|
625
625
|
if (!this.hasRequestBody()) {
|
|
626
626
|
return false;
|
|
627
627
|
}
|
|
@@ -660,7 +660,11 @@ export default class Operation {
|
|
|
660
660
|
}
|
|
661
661
|
|
|
662
662
|
if (availableMediaType) {
|
|
663
|
-
return [
|
|
663
|
+
return [
|
|
664
|
+
availableMediaType,
|
|
665
|
+
requestBody.content[availableMediaType],
|
|
666
|
+
...(requestBody.description ? [requestBody.description] : []),
|
|
667
|
+
];
|
|
664
668
|
}
|
|
665
669
|
|
|
666
670
|
return false;
|