oas 18.3.4 → 18.4.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/CHANGELOG.md +12 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/lib/dedupe-common-parameters.d.ts +2 -2
- package/dist/lib/dedupe-common-parameters.js +2 -2
- package/dist/lib/openapi-to-json-schema.js +12 -15
- package/dist/lib/reducer.d.ts +24 -0
- package/dist/lib/reducer.js +159 -0
- package/dist/operation/get-parameters-as-json-schema.d.ts +1 -1
- package/dist/operation/get-parameters-as-json-schema.js +4 -2
- package/dist/operation/get-response-as-json-schema.d.ts +1 -1
- package/dist/operation/get-response-as-json-schema.js +3 -2
- package/dist/operation/get-response-examples.js +1 -1
- package/dist/operation.d.ts +5 -5
- package/dist/operation.js +8 -8
- package/dist/rmoas.types.d.ts +1 -1
- package/dist/samples/index.js +2 -2
- package/dist/samples/utils.d.ts +1 -1
- package/dist/samples/utils.js +0 -6
- package/package.json +6 -4
- package/src/cli/commands/endpoint.js +1 -0
- package/src/cli/commands/help.js +2 -1
- package/src/cli/commands/init.js +4 -2
- package/src/cli/index.js +3 -1
- package/src/cli/lib/utils.js +3 -2
- package/src/index.ts +3 -1
- package/src/lib/dedupe-common-parameters.ts +2 -2
- package/src/lib/get-mediatype-examples.ts +2 -0
- package/src/lib/openapi-to-json-schema.ts +14 -15
- package/src/lib/reducer.ts +184 -0
- package/src/operation/get-callback-examples.ts +1 -0
- package/src/operation/get-parameters-as-json-schema.ts +6 -3
- package/src/operation/get-requestbody-examples.ts +1 -0
- package/src/operation/get-response-as-json-schema.ts +5 -3
- package/src/operation/get-response-examples.ts +2 -2
- package/src/operation.ts +10 -10
- package/src/rmoas.types.ts +1 -1
- package/src/samples/index.ts +4 -2
- package/src/samples/utils.ts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## 18.4.0 (2022-08-19)
|
|
2
|
+
|
|
3
|
+
* feat: porting the library portion of `oas-reducer` into this library (#677) ([f3bc07e](https://github.com/readmeio/oas/commit/f3bc07e)), closes [#677](https://github.com/readmeio/oas/issues/677)
|
|
4
|
+
* chore: stop deleting the `@types/` directory that no longer exists ([98e36fe](https://github.com/readmeio/oas/commit/98e36fe))
|
|
5
|
+
* chore: updating our code standards (#676) ([6b19747](https://github.com/readmeio/oas/commit/6b19747)), closes [#676](https://github.com/readmeio/oas/issues/676)
|
|
6
|
+
* chore(deps-dev): bump @readme/eslint-config from 8.8.3 to 9.0.0 (#675) ([f01f047](https://github.com/readmeio/oas/commit/f01f047)), closes [#675](https://github.com/readmeio/oas/issues/675)
|
|
7
|
+
* chore(deps-dev): bump @readme/oas-examples from 5.4.1 to 5.5.0 (#674) ([d6c0f10](https://github.com/readmeio/oas/commit/d6c0f10)), closes [#674](https://github.com/readmeio/oas/issues/674)
|
|
8
|
+
* chore(deps-dev): bump eslint from 8.20.0 to 8.21.0 (#673) ([0ed3e5c](https://github.com/readmeio/oas/commit/0ed3e5c)), closes [#673](https://github.com/readmeio/oas/issues/673)
|
|
9
|
+
* chore(deps): bump jsonpointer from 5.0.0 to 5.0.1 (#672) ([b6bcdc3](https://github.com/readmeio/oas/commit/b6bcdc3)), closes [#672](https://github.com/readmeio/oas/issues/672)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
1
13
|
## <small>18.3.4 (2022-07-22)</small>
|
|
2
14
|
|
|
3
15
|
* chore(deps-dev): bump @commitlint/cli from 16.2.4 to 17.0.2 (#651) ([cedb2da](https://github.com/readmeio/oas/commit/cedb2da)), closes [#651](https://github.com/readmeio/oas/issues/651)
|
package/dist/index.d.ts
CHANGED
|
@@ -220,7 +220,8 @@ export default class Oas {
|
|
|
220
220
|
* Dereference the current OAS definition so it can be parsed free of worries of `$ref` schemas
|
|
221
221
|
* and circular structures.
|
|
222
222
|
*
|
|
223
|
-
* @param opts
|
|
223
|
+
* @param opts Options
|
|
224
|
+
* @param opts.preserveRefAsJSONSchemaTitle Preserve component schema names within themselves as a `title`.
|
|
224
225
|
*/
|
|
225
226
|
dereference(opts?: {
|
|
226
227
|
preserveRefAsJSONSchemaTitle: boolean;
|
package/dist/index.js
CHANGED
|
@@ -724,7 +724,8 @@ var Oas = /** @class */ (function () {
|
|
|
724
724
|
* Dereference the current OAS definition so it can be parsed free of worries of `$ref` schemas
|
|
725
725
|
* and circular structures.
|
|
726
726
|
*
|
|
727
|
-
* @param opts
|
|
727
|
+
* @param opts Options
|
|
728
|
+
* @param opts.preserveRefAsJSONSchemaTitle Preserve component schema names within themselves as a `title`.
|
|
728
729
|
*/
|
|
729
730
|
Oas.prototype.dereference = function (opts) {
|
|
730
731
|
if (opts === void 0) { opts = { preserveRefAsJSONSchemaTitle: false }; }
|
|
@@ -3,7 +3,7 @@ import * as RMOAS from '../rmoas.types';
|
|
|
3
3
|
* With an array of common parameters filter down them to what isn't already present in a list of
|
|
4
4
|
* non-common parameters.
|
|
5
5
|
*
|
|
6
|
-
* @param parameters
|
|
7
|
-
* @param commonParameters
|
|
6
|
+
* @param parameters Array of parameters defined at the operation level.
|
|
7
|
+
* @param commonParameters Array of **common** parameters defined at the path item level.
|
|
8
8
|
*/
|
|
9
9
|
export default function dedupeCommonParameters(parameters: RMOAS.ParameterObject[], commonParameters: RMOAS.ParameterObject[]): import("openapi-types").OpenAPIV3.ParameterObject[];
|
|
@@ -28,8 +28,8 @@ var RMOAS = __importStar(require("../rmoas.types"));
|
|
|
28
28
|
* With an array of common parameters filter down them to what isn't already present in a list of
|
|
29
29
|
* non-common parameters.
|
|
30
30
|
*
|
|
31
|
-
* @param parameters
|
|
32
|
-
* @param commonParameters
|
|
31
|
+
* @param parameters Array of parameters defined at the operation level.
|
|
32
|
+
* @param commonParameters Array of **common** parameters defined at the path item level.
|
|
33
33
|
*/
|
|
34
34
|
function dedupeCommonParameters(parameters, commonParameters) {
|
|
35
35
|
return commonParameters.filter(function (param) {
|
|
@@ -58,9 +58,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
58
58
|
};
|
|
59
59
|
exports.__esModule = true;
|
|
60
60
|
exports.isPrimitive = exports.getSchemaVersionString = void 0;
|
|
61
|
-
var RMOAS = __importStar(require("../rmoas.types"));
|
|
62
|
-
var jsonpointer_1 = __importDefault(require("jsonpointer"));
|
|
63
61
|
var json_schema_merge_allof_1 = __importDefault(require("json-schema-merge-allof"));
|
|
62
|
+
var jsonpointer_1 = __importDefault(require("jsonpointer"));
|
|
63
|
+
var RMOAS = __importStar(require("../rmoas.types"));
|
|
64
64
|
/**
|
|
65
65
|
* This list has been pulled from `openapi-schema-to-json-schema` but been slightly modified to fit
|
|
66
66
|
* within the constraints in which ReadMe uses the output from this library in schema form
|
|
@@ -110,21 +110,23 @@ var FORMAT_OPTIONS = {
|
|
|
110
110
|
* Encode a string to be used as a JSON pointer.
|
|
111
111
|
*
|
|
112
112
|
* @see {@link https://tools.ietf.org/html/rfc6901}
|
|
113
|
-
* @param str
|
|
113
|
+
* @param str String to encode into string that can be used as a JSON pointer.
|
|
114
114
|
*/
|
|
115
115
|
function encodePointer(str) {
|
|
116
116
|
return str.replace('~', '~0').replace('/', '~1');
|
|
117
117
|
}
|
|
118
118
|
function getSchemaVersionString(schema, api) {
|
|
119
|
-
// If we're not on version 3.1.0, we always fall back to the default schema version for pre
|
|
119
|
+
// If we're not on version 3.1.0, we always fall back to the default schema version for pre-3.1.0.
|
|
120
120
|
if (!RMOAS.isOAS31(api)) {
|
|
121
121
|
// This should remain as an HTTP url, not HTTPS.
|
|
122
122
|
return 'http://json-schema.org/draft-04/schema#';
|
|
123
123
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
/**
|
|
125
|
+
* If the schema indicates the version, prefer that.
|
|
126
|
+
*
|
|
127
|
+
* We use `as` here because the schema *should* be an OAS 3.1 schema due to the `isOAS31` check
|
|
128
|
+
* above.
|
|
129
|
+
*/
|
|
128
130
|
if (schema.$schema) {
|
|
129
131
|
return schema.$schema;
|
|
130
132
|
}
|
|
@@ -142,11 +144,6 @@ exports.isPrimitive = isPrimitive;
|
|
|
142
144
|
function isPolymorphicSchema(schema) {
|
|
143
145
|
return 'allOf' in schema || 'anyOf' in schema || 'oneOf' in schema;
|
|
144
146
|
}
|
|
145
|
-
/**
|
|
146
|
-
* Determine if a given schema looks like a `requestBody` schema and contains the `content` object.
|
|
147
|
-
*
|
|
148
|
-
* @param schema
|
|
149
|
-
*/
|
|
150
147
|
function isRequestBodySchema(schema) {
|
|
151
148
|
return 'content' in schema;
|
|
152
149
|
}
|
|
@@ -180,8 +177,8 @@ function isRequestBodySchema(schema) {
|
|
|
180
177
|
* it shouldn't raise immediate cause for alarm.
|
|
181
178
|
*
|
|
182
179
|
* @see {@link https://tools.ietf.org/html/rfc6901}
|
|
183
|
-
* @param pointer
|
|
184
|
-
* @param examples
|
|
180
|
+
* @param pointer JSON pointer to search for an example for.
|
|
181
|
+
* @param examples Array of previous schemas we've found relating to this pointer.
|
|
185
182
|
*/
|
|
186
183
|
function searchForExampleByPointer(pointer, examples) {
|
|
187
184
|
if (examples === void 0) { examples = []; }
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { OASDocument } from 'rmoas.types';
|
|
2
|
+
export declare type ReducerOptions = {
|
|
3
|
+
/** A key-value object of path + method combinations to reduce by. */
|
|
4
|
+
paths?: Record<string, string[] | '*'>;
|
|
5
|
+
/** An array of tags in the OpenAPI definition to reduce by. */
|
|
6
|
+
tags?: string[];
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* With an array of tags or object of paths+method combinations, reduce an OpenAPI definition to a
|
|
10
|
+
* new definition that just contains those tags or path + methods.
|
|
11
|
+
*
|
|
12
|
+
* @example <caption>Reduce by an array of tags only.</caption>
|
|
13
|
+
* { APIDEFINITION, { tags: ['pet] } }
|
|
14
|
+
*
|
|
15
|
+
* @example <caption>Reduce by a specific path and methods.</caption>
|
|
16
|
+
* { APIDEFINITION, { paths: { '/pet': ['get', 'post'] } } }
|
|
17
|
+
*
|
|
18
|
+
* @example <caption>Reduce by a specific path and all methods it has.</caption>
|
|
19
|
+
* { APIDEFINITION, { paths: { '/pet': '*' } } }
|
|
20
|
+
*
|
|
21
|
+
* @param definition A valid OpenAPI 3.x definition
|
|
22
|
+
* @param opts Option configuration to reduce by.
|
|
23
|
+
*/
|
|
24
|
+
export default function reducer(definition: OASDocument, opts?: ReducerOptions): OASDocument;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
exports.__esModule = true;
|
|
6
|
+
var jsonpath_1 = __importDefault(require("jsonpath"));
|
|
7
|
+
var jsonpointer_1 = __importDefault(require("jsonpointer"));
|
|
8
|
+
var utils_1 = require("oas-normalize/dist/lib/utils");
|
|
9
|
+
/**
|
|
10
|
+
* Query a JSON Schema object for any `$ref` pointers. Return any pointers that were found.
|
|
11
|
+
*
|
|
12
|
+
* @param schema JSON Schema object to look for any `$ref` pointers within it.
|
|
13
|
+
*/
|
|
14
|
+
function getUsedRefs(schema) {
|
|
15
|
+
return jsonpath_1["default"].query(schema, "$..['$ref']");
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Recursively process a `$ref` pointer and accumulate any other `$ref` pointers that it or its
|
|
19
|
+
* children use.
|
|
20
|
+
*
|
|
21
|
+
* @param schema JSON Schema object to look for and accumulate any `$ref` pointers that it may have.
|
|
22
|
+
* @param $refs Known set of `$ref` pointers.
|
|
23
|
+
* @param $ref `$ref` pointer to fetch a schema from out of the supplied schema.
|
|
24
|
+
*/
|
|
25
|
+
function accumulateUsedRefs(schema, $refs, $ref) {
|
|
26
|
+
var $refSchema = jsonpointer_1["default"].get(schema, $ref.substring(1));
|
|
27
|
+
getUsedRefs($refSchema).forEach(function (currRef) {
|
|
28
|
+
// If we've already processed this $ref don't send us into an infinite loop.
|
|
29
|
+
if ($refs.has(currRef)) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
$refs.add(currRef);
|
|
33
|
+
accumulateUsedRefs(schema, $refs, currRef);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* With an array of tags or object of paths+method combinations, reduce an OpenAPI definition to a
|
|
38
|
+
* new definition that just contains those tags or path + methods.
|
|
39
|
+
*
|
|
40
|
+
* @example <caption>Reduce by an array of tags only.</caption>
|
|
41
|
+
* { APIDEFINITION, { tags: ['pet] } }
|
|
42
|
+
*
|
|
43
|
+
* @example <caption>Reduce by a specific path and methods.</caption>
|
|
44
|
+
* { APIDEFINITION, { paths: { '/pet': ['get', 'post'] } } }
|
|
45
|
+
*
|
|
46
|
+
* @example <caption>Reduce by a specific path and all methods it has.</caption>
|
|
47
|
+
* { APIDEFINITION, { paths: { '/pet': '*' } } }
|
|
48
|
+
*
|
|
49
|
+
* @param definition A valid OpenAPI 3.x definition
|
|
50
|
+
* @param opts Option configuration to reduce by.
|
|
51
|
+
*/
|
|
52
|
+
function reducer(definition, opts) {
|
|
53
|
+
if (opts === void 0) { opts = {}; }
|
|
54
|
+
var reduceTags = 'tags' in opts ? opts.tags : [];
|
|
55
|
+
var reducePaths = 'paths' in opts ? opts.paths : {};
|
|
56
|
+
var $refs = new Set();
|
|
57
|
+
var usedTags = new Set();
|
|
58
|
+
var baseVersion = parseInt((0, utils_1.version)(definition), 10);
|
|
59
|
+
if (baseVersion !== 3) {
|
|
60
|
+
throw new Error('Sorry, only OpenAPI 3.x definitions are supported.');
|
|
61
|
+
}
|
|
62
|
+
// Stringify and parse so we get a full non-reference clone of the API definition to work with.
|
|
63
|
+
var reduced = JSON.parse(JSON.stringify(definition));
|
|
64
|
+
if ('paths' in reduced) {
|
|
65
|
+
Object.keys(reduced.paths).forEach(function (path) {
|
|
66
|
+
if (Object.keys(reducePaths).length) {
|
|
67
|
+
if (!(path in reducePaths)) {
|
|
68
|
+
delete reduced.paths[path];
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
Object.keys(reduced.paths[path]).forEach(function (method) {
|
|
73
|
+
// If this method is `parameters` we should always retain it.
|
|
74
|
+
if (method !== 'parameters') {
|
|
75
|
+
if (Object.keys(reducePaths).length) {
|
|
76
|
+
if (reducePaths[path] !== '*' && Array.isArray(reducePaths[path]) && !reducePaths[path].includes(method)) {
|
|
77
|
+
delete reduced.paths[path][method];
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
var operation = reduced.paths[path][method];
|
|
83
|
+
// If we're reducing by tags and this operation doesn't live in one of those, remove it.
|
|
84
|
+
if (reduceTags.length) {
|
|
85
|
+
if (!('tags' in operation)) {
|
|
86
|
+
delete reduced.paths[path][method];
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
else if (!reduceTags.filter(function (value) { return operation.tags.includes(value); }).length) {
|
|
90
|
+
delete reduced.paths[path][method];
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Accumulate a list of used tags so we can filter out any ones that we don't need later.
|
|
95
|
+
if ('tags' in operation) {
|
|
96
|
+
operation.tags.forEach(function (tag) {
|
|
97
|
+
usedTags.add(tag);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// Accumulate a list of $ref pointers that are used within this operation.
|
|
101
|
+
getUsedRefs(operation).forEach(function (ref) {
|
|
102
|
+
$refs.add(ref);
|
|
103
|
+
});
|
|
104
|
+
// Accumulate any used security schemas that we need to retain.
|
|
105
|
+
if ('security' in operation) {
|
|
106
|
+
Object.values(operation.security).forEach(function (sec) {
|
|
107
|
+
Object.keys(sec).forEach(function (scheme) {
|
|
108
|
+
$refs.add("#/components/securitySchemes/".concat(scheme));
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
// If this path no longer has any methods, delete it.
|
|
114
|
+
if (!Object.keys(reduced.paths[path]).length) {
|
|
115
|
+
delete reduced.paths[path];
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
// If we don't have any more paths after cleanup, throw an error because an OpenAPI file must
|
|
119
|
+
// have at least one path.
|
|
120
|
+
if (!Object.keys(reduced.paths).length) {
|
|
121
|
+
throw new Error('All paths in the API definition were removed. Did you supply the right path name to reduce by?');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Recursively accumulate any components that are in use.
|
|
125
|
+
$refs.forEach(function ($ref) { return accumulateUsedRefs(reduced, $refs, $ref); });
|
|
126
|
+
// Remove any unused components.
|
|
127
|
+
if ('components' in reduced) {
|
|
128
|
+
Object.keys(reduced.components).forEach(function (componentType) {
|
|
129
|
+
Object.keys(reduced.components[componentType]).forEach(function (component) {
|
|
130
|
+
if (!$refs.has("#/components/".concat(componentType, "/").concat(component))) {
|
|
131
|
+
delete reduced.components[componentType][component];
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
// If this component group is now empty, delete it.
|
|
135
|
+
if (!Object.keys(reduced.components[componentType]).length) {
|
|
136
|
+
delete reduced.components[componentType];
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
// If this path no longer has any components, delete it.
|
|
140
|
+
if (!Object.keys(reduced.components).length) {
|
|
141
|
+
delete reduced.components;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Remove any unused tags.
|
|
145
|
+
if ('tags' in reduced) {
|
|
146
|
+
reduced.tags.forEach(function (tag, k) {
|
|
147
|
+
if (!usedTags.has(tag.name)) {
|
|
148
|
+
delete reduced.tags[k];
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
// Remove any now empty items from the tags array.
|
|
152
|
+
reduced.tags = reduced.tags.filter(Boolean);
|
|
153
|
+
if (!reduced.tags.length) {
|
|
154
|
+
delete reduced.tags;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return reduced;
|
|
158
|
+
}
|
|
159
|
+
exports["default"] = reducer;
|
|
@@ -38,9 +38,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
};
|
|
39
39
|
exports.__esModule = true;
|
|
40
40
|
exports.types = void 0;
|
|
41
|
+
var clone_object_1 = __importDefault(require("../lib/clone-object"));
|
|
41
42
|
var matches_mimetype_1 = __importDefault(require("../lib/matches-mimetype"));
|
|
42
43
|
var openapi_to_json_schema_1 = __importStar(require("../lib/openapi-to-json-schema"));
|
|
43
|
-
var clone_object_1 = __importDefault(require("../lib/clone-object"));
|
|
44
44
|
var isJSON = matches_mimetype_1["default"].json;
|
|
45
45
|
/**
|
|
46
46
|
* The order of this object determines how they will be sorted in the compiled JSON Schema
|
|
@@ -161,7 +161,8 @@ function getParametersAsJsonSchema(operation, api, opts) {
|
|
|
161
161
|
* Typescript is INCREDIBLY SLOW parsing this one line. I think it's because of the large
|
|
162
162
|
* variety of types that that object could represent but I can't yet think of a way to get
|
|
163
163
|
* around that.
|
|
164
|
-
*
|
|
164
|
+
*
|
|
165
|
+
* @todo
|
|
165
166
|
*/
|
|
166
167
|
components[componentType] = {};
|
|
167
168
|
Object.keys(api.components[componentType]).forEach(function (schemaName) {
|
|
@@ -326,6 +327,7 @@ function getParametersAsJsonSchema(operation, api, opts) {
|
|
|
326
327
|
* Since this library assumes that the schema has already been dereferenced, adding every
|
|
327
328
|
* component here that **isn't** circular adds a ton of bloat so it'd be cool if `components`
|
|
328
329
|
* was just the remaining `$ref` pointers that are still being referenced.
|
|
330
|
+
*
|
|
329
331
|
* @todo
|
|
330
332
|
*/
|
|
331
333
|
if (hasCircularRefs && components) {
|
|
@@ -37,9 +37,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
39
|
exports.__esModule = true;
|
|
40
|
-
var openapi_to_json_schema_1 = __importStar(require("../lib/openapi-to-json-schema"));
|
|
41
|
-
var matches_mimetype_1 = __importDefault(require("../lib/matches-mimetype"));
|
|
42
40
|
var clone_object_1 = __importDefault(require("../lib/clone-object"));
|
|
41
|
+
var matches_mimetype_1 = __importDefault(require("../lib/matches-mimetype"));
|
|
42
|
+
var openapi_to_json_schema_1 = __importStar(require("../lib/openapi-to-json-schema"));
|
|
43
43
|
var isJSON = matches_mimetype_1["default"].json;
|
|
44
44
|
/**
|
|
45
45
|
* Turn a header map from OpenAPI 3.0.3 (and some earlier versions too) into a schema.
|
|
@@ -138,6 +138,7 @@ function getResponseAsJsonSchema(operation, api, statusCode) {
|
|
|
138
138
|
* Since this library assumes that the schema has already been dereferenced, adding every
|
|
139
139
|
* component here that **isn't** circular adds a ton of bloat so it'd be cool if `components`
|
|
140
140
|
* was just the remaining `$ref` pointers that are still being referenced.
|
|
141
|
+
*
|
|
141
142
|
* @todo
|
|
142
143
|
*/
|
|
143
144
|
if (hasCircularRefs && api.components && schemaWrapper.schema) {
|
|
@@ -14,8 +14,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
16
|
exports.__esModule = true;
|
|
17
|
-
var rmoas_types_1 = require("../rmoas.types");
|
|
18
17
|
var get_mediatype_examples_1 = __importDefault(require("../lib/get-mediatype-examples"));
|
|
18
|
+
var rmoas_types_1 = require("../rmoas.types");
|
|
19
19
|
/**
|
|
20
20
|
* Retrieve a collection of response examples keyed, by their media type.
|
|
21
21
|
*
|
package/dist/operation.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { RequestBodyExamples } from './operation/get-requestbody-examples';
|
|
2
1
|
import type { CallbackExamples } from './operation/get-callback-examples';
|
|
2
|
+
import type { RequestBodyExamples } from './operation/get-requestbody-examples';
|
|
3
3
|
import type { ResponseExamples } from './operation/get-response-examples';
|
|
4
4
|
import * as RMOAS from './rmoas.types';
|
|
5
5
|
declare type SecurityType = 'Basic' | 'Bearer' | 'Query' | 'Header' | 'Cookie' | 'OAuth2' | 'http' | 'apiKey';
|
|
@@ -89,7 +89,7 @@ export default class Operation {
|
|
|
89
89
|
* Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
|
|
90
90
|
* a hash of the path and method will be returned instead.
|
|
91
91
|
*
|
|
92
|
-
* @param opts
|
|
92
|
+
* @param opts Options
|
|
93
93
|
* @param opts.camelCase Generate a JS method-friendly operation ID when one isn't present.
|
|
94
94
|
*/
|
|
95
95
|
getOperationId(opts?: {
|
|
@@ -124,7 +124,7 @@ export default class Operation {
|
|
|
124
124
|
* Convert the operation into an array of JSON Schema schemas for each available type of
|
|
125
125
|
* parameter available on the operation.
|
|
126
126
|
*
|
|
127
|
-
* @param opts
|
|
127
|
+
* @param opts Options
|
|
128
128
|
* @param opts.globalDefaults Contains an object of user defined schema defaults.
|
|
129
129
|
* @param opts.mergeIntoBodyAndMetadata If you want the output to be two objects: body (contains
|
|
130
130
|
* `body` and `formData` JSON Schema) and metadata (contains `path`, `query`, `cookie`, and
|
|
@@ -140,7 +140,7 @@ export default class Operation {
|
|
|
140
140
|
/**
|
|
141
141
|
* Get a single response for this status code, formatted as JSON schema.
|
|
142
142
|
*
|
|
143
|
-
* @param statusCode
|
|
143
|
+
* @param statusCode Status code to pull a JSON Schema response for.
|
|
144
144
|
*/
|
|
145
145
|
getResponseAsJsonSchema(statusCode: string | number): {
|
|
146
146
|
type: string | string[];
|
|
@@ -191,7 +191,7 @@ export default class Operation {
|
|
|
191
191
|
/**
|
|
192
192
|
* Return a specific response out of the operation by a given HTTP status code.
|
|
193
193
|
*
|
|
194
|
-
* @param statusCode
|
|
194
|
+
* @param statusCode Status code to pull a response object for.
|
|
195
195
|
*/
|
|
196
196
|
getResponseByStatusCode(statusCode: string | number): boolean | RMOAS.ResponseObject;
|
|
197
197
|
/**
|
package/dist/operation.js
CHANGED
|
@@ -53,15 +53,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
53
53
|
};
|
|
54
54
|
exports.__esModule = true;
|
|
55
55
|
exports.Webhook = exports.Callback = void 0;
|
|
56
|
-
var RMOAS = __importStar(require("./rmoas.types"));
|
|
57
56
|
var dedupe_common_parameters_1 = __importDefault(require("./lib/dedupe-common-parameters"));
|
|
58
57
|
var find_schema_definition_1 = __importDefault(require("./lib/find-schema-definition"));
|
|
58
|
+
var matches_mimetype_1 = __importDefault(require("./lib/matches-mimetype"));
|
|
59
|
+
var get_callback_examples_1 = __importDefault(require("./operation/get-callback-examples"));
|
|
59
60
|
var get_parameters_as_json_schema_1 = __importDefault(require("./operation/get-parameters-as-json-schema"));
|
|
60
|
-
var get_response_as_json_schema_1 = __importDefault(require("./operation/get-response-as-json-schema"));
|
|
61
61
|
var get_requestbody_examples_1 = __importDefault(require("./operation/get-requestbody-examples"));
|
|
62
|
-
var
|
|
62
|
+
var get_response_as_json_schema_1 = __importDefault(require("./operation/get-response-as-json-schema"));
|
|
63
63
|
var get_response_examples_1 = __importDefault(require("./operation/get-response-examples"));
|
|
64
|
-
var
|
|
64
|
+
var RMOAS = __importStar(require("./rmoas.types"));
|
|
65
65
|
var utils_1 = require("./utils");
|
|
66
66
|
var Operation = /** @class */ (function () {
|
|
67
67
|
function Operation(api, path, method, operation) {
|
|
@@ -304,7 +304,7 @@ var Operation = /** @class */ (function () {
|
|
|
304
304
|
* Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
|
|
305
305
|
* a hash of the path and method will be returned instead.
|
|
306
306
|
*
|
|
307
|
-
* @param opts
|
|
307
|
+
* @param opts Options
|
|
308
308
|
* @param opts.camelCase Generate a JS method-friendly operation ID when one isn't present.
|
|
309
309
|
*/
|
|
310
310
|
Operation.prototype.getOperationId = function (opts) {
|
|
@@ -408,7 +408,7 @@ var Operation = /** @class */ (function () {
|
|
|
408
408
|
* Convert the operation into an array of JSON Schema schemas for each available type of
|
|
409
409
|
* parameter available on the operation.
|
|
410
410
|
*
|
|
411
|
-
* @param opts
|
|
411
|
+
* @param opts Options
|
|
412
412
|
* @param opts.globalDefaults Contains an object of user defined schema defaults.
|
|
413
413
|
* @param opts.mergeIntoBodyAndMetadata If you want the output to be two objects: body (contains
|
|
414
414
|
* `body` and `formData` JSON Schema) and metadata (contains `path`, `query`, `cookie`, and
|
|
@@ -423,7 +423,7 @@ var Operation = /** @class */ (function () {
|
|
|
423
423
|
/**
|
|
424
424
|
* Get a single response for this status code, formatted as JSON schema.
|
|
425
425
|
*
|
|
426
|
-
* @param statusCode
|
|
426
|
+
* @param statusCode Status code to pull a JSON Schema response for.
|
|
427
427
|
*/
|
|
428
428
|
Operation.prototype.getResponseAsJsonSchema = function (statusCode) {
|
|
429
429
|
return (0, get_response_as_json_schema_1["default"])(this, this.api, statusCode);
|
|
@@ -550,7 +550,7 @@ var Operation = /** @class */ (function () {
|
|
|
550
550
|
/**
|
|
551
551
|
* Return a specific response out of the operation by a given HTTP status code.
|
|
552
552
|
*
|
|
553
|
-
* @param statusCode
|
|
553
|
+
* @param statusCode Status code to pull a response object for.
|
|
554
554
|
*/
|
|
555
555
|
Operation.prototype.getResponseByStatusCode = function (statusCode) {
|
|
556
556
|
if (!this.schema.responses) {
|
package/dist/rmoas.types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
|
|
2
1
|
import type { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema';
|
|
2
|
+
import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
|
|
3
3
|
export declare type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
|
|
4
4
|
/**
|
|
5
5
|
* @param check Data to determine if it contains a ReferenceObject (`$ref` pointer`).
|
package/dist/samples/index.js
CHANGED
|
@@ -3,9 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
exports.__esModule = true;
|
|
6
|
-
var utils_1 = require("./utils");
|
|
7
|
-
var memoizee_1 = __importDefault(require("memoizee"));
|
|
8
6
|
var json_schema_merge_allof_1 = __importDefault(require("json-schema-merge-allof"));
|
|
7
|
+
var memoizee_1 = __importDefault(require("memoizee"));
|
|
8
|
+
var utils_1 = require("./utils");
|
|
9
9
|
var sampleDefaults = function (genericSample) {
|
|
10
10
|
return function (schema) {
|
|
11
11
|
return typeof schema["default"] === typeof genericSample ? schema["default"] : genericSample;
|
package/dist/samples/utils.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @see {@link https://github.com/swagger-api/swagger-ui/blob/master/src/core/utils.js}
|
|
6
6
|
*/
|
|
7
7
|
import type * as RMOAS from '../rmoas.types';
|
|
8
|
-
export declare function usesPolymorphism(schema: RMOAS.SchemaObject): false | "
|
|
8
|
+
export declare function usesPolymorphism(schema: RMOAS.SchemaObject): false | "anyOf" | "oneOf" | "allOf";
|
|
9
9
|
export declare function objectify(thing: unknown | Record<string, unknown>): Record<string, any>;
|
|
10
10
|
export declare function normalizeArray(arr: string | number | (string | number)[]): (string | number)[];
|
|
11
11
|
export declare function isFunc(thing: unknown): thing is Function;
|
package/dist/samples/utils.js
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Portions of this file have been extracted and modified from Swagger UI.
|
|
4
|
-
*
|
|
5
|
-
* @license Apache-2.0
|
|
6
|
-
* @see {@link https://github.com/swagger-api/swagger-ui/blob/master/src/core/utils.js}
|
|
7
|
-
*/
|
|
8
2
|
var __assign = (this && this.__assign) || function () {
|
|
9
3
|
__assign = Object.assign || function(t) {
|
|
10
4
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oas",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.4.0",
|
|
4
4
|
"description": "Working with OpenAPI definitions is hard. This makes it easier.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ReadMe <support@readme.io> (https://readme.com)",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "tsc",
|
|
39
39
|
"lint": "eslint . --ext .js,.ts",
|
|
40
|
-
"prebuild": "rm -rf dist/
|
|
40
|
+
"prebuild": "rm -rf dist/",
|
|
41
41
|
"prepack": "npm run build",
|
|
42
42
|
"prepare": "husky install",
|
|
43
43
|
"pretest": "npm run lint",
|
|
@@ -56,10 +56,11 @@
|
|
|
56
56
|
"inquirer": "^8.1.2",
|
|
57
57
|
"json-schema-merge-allof": "^0.8.1",
|
|
58
58
|
"json2yaml": "^1.1.0",
|
|
59
|
+
"jsonpath": "^1.1.1",
|
|
59
60
|
"jsonpointer": "^5.0.0",
|
|
60
61
|
"memoizee": "^0.4.14",
|
|
61
62
|
"minimist": "^1.2.0",
|
|
62
|
-
"oas-normalize": "^
|
|
63
|
+
"oas-normalize": "^7.0.0",
|
|
63
64
|
"openapi-types": "^12.0.0",
|
|
64
65
|
"path-to-regexp": "^6.2.0",
|
|
65
66
|
"swagger-inline": "^6.0.0"
|
|
@@ -67,11 +68,12 @@
|
|
|
67
68
|
"devDependencies": {
|
|
68
69
|
"@commitlint/cli": "^17.0.2",
|
|
69
70
|
"@commitlint/config-conventional": "^17.0.2",
|
|
70
|
-
"@readme/eslint-config": "^
|
|
71
|
+
"@readme/eslint-config": "^10.0.0",
|
|
71
72
|
"@readme/oas-examples": "^5.4.1",
|
|
72
73
|
"@readme/openapi-parser": "^2.2.0",
|
|
73
74
|
"@types/jest": "^28.1.6",
|
|
74
75
|
"@types/json-schema-merge-allof": "^0.6.1",
|
|
76
|
+
"@types/jsonpath": "^0.2.0",
|
|
75
77
|
"@types/memoizee": "^0.4.6",
|
|
76
78
|
"eslint": "^8.20.0",
|
|
77
79
|
"husky": "^8.0.1",
|
package/src/cli/commands/help.js
CHANGED
package/src/cli/commands/init.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
const
|
|
1
|
+
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const chalk = require('chalk');
|
|
3
5
|
const inquirer = require('inquirer');
|
|
4
|
-
const fs = require('fs');
|
|
5
6
|
const YAML = require('json2yaml');
|
|
7
|
+
|
|
6
8
|
const utils = require('../lib/utils');
|
|
7
9
|
|
|
8
10
|
exports.swagger = false;
|
package/src/cli/index.js
CHANGED
package/src/cli/lib/utils.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
1
|
const fs = require('fs');
|
|
2
|
+
|
|
3
3
|
const cardinal = require('cardinal');
|
|
4
|
+
const chalk = require('chalk');
|
|
4
5
|
const glob = require('glob');
|
|
5
|
-
const swaggerInline = require('swagger-inline');
|
|
6
6
|
const OASNormalize = require('oas-normalize');
|
|
7
|
+
const swaggerInline = require('swagger-inline');
|
|
7
8
|
|
|
8
9
|
exports.findSwagger = async function (info, cb) {
|
|
9
10
|
const file = info.args[info.args.length - 1];
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { MatchResult } from 'path-to-regexp';
|
|
|
4
4
|
|
|
5
5
|
import $RefParser from '@readme/json-schema-ref-parser';
|
|
6
6
|
import { pathToRegexp, match } from 'path-to-regexp';
|
|
7
|
+
|
|
7
8
|
import getAuth from './lib/get-auth';
|
|
8
9
|
import getUserVariable from './lib/get-user-variable';
|
|
9
10
|
import Operation, { Callback, Webhook } from './operation';
|
|
@@ -757,7 +758,8 @@ export default class Oas {
|
|
|
757
758
|
* Dereference the current OAS definition so it can be parsed free of worries of `$ref` schemas
|
|
758
759
|
* and circular structures.
|
|
759
760
|
*
|
|
760
|
-
* @param opts
|
|
761
|
+
* @param opts Options
|
|
762
|
+
* @param opts.preserveRefAsJSONSchemaTitle Preserve component schema names within themselves as a `title`.
|
|
761
763
|
*/
|
|
762
764
|
async dereference(opts = { preserveRefAsJSONSchemaTitle: false }) {
|
|
763
765
|
if (this.dereferencing.complete) {
|
|
@@ -4,8 +4,8 @@ import * as RMOAS from '../rmoas.types';
|
|
|
4
4
|
* With an array of common parameters filter down them to what isn't already present in a list of
|
|
5
5
|
* non-common parameters.
|
|
6
6
|
*
|
|
7
|
-
* @param parameters
|
|
8
|
-
* @param commonParameters
|
|
7
|
+
* @param parameters Array of parameters defined at the operation level.
|
|
8
|
+
* @param commonParameters Array of **common** parameters defined at the path item level.
|
|
9
9
|
*/
|
|
10
10
|
export default function dedupeCommonParameters(
|
|
11
11
|
parameters: RMOAS.ParameterObject[],
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/* eslint-disable no-continue */
|
|
2
2
|
import type { OpenAPIV3_1 } from 'openapi-types';
|
|
3
|
-
|
|
4
|
-
import jsonpointer from 'jsonpointer';
|
|
3
|
+
|
|
5
4
|
import mergeJSONSchemaAllOf from 'json-schema-merge-allof';
|
|
5
|
+
import jsonpointer from 'jsonpointer';
|
|
6
|
+
|
|
7
|
+
import * as RMOAS from '../rmoas.types';
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* This list has been pulled from `openapi-schema-to-json-schema` but been slightly modified to fit
|
|
@@ -72,23 +74,25 @@ const FORMAT_OPTIONS: {
|
|
|
72
74
|
* Encode a string to be used as a JSON pointer.
|
|
73
75
|
*
|
|
74
76
|
* @see {@link https://tools.ietf.org/html/rfc6901}
|
|
75
|
-
* @param str
|
|
77
|
+
* @param str String to encode into string that can be used as a JSON pointer.
|
|
76
78
|
*/
|
|
77
79
|
function encodePointer(str: string) {
|
|
78
80
|
return str.replace('~', '~0').replace('/', '~1');
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
export function getSchemaVersionString(schema: RMOAS.SchemaObject, api: RMOAS.OASDocument): string {
|
|
82
|
-
// If we're not on version 3.1.0, we always fall back to the default schema version for pre
|
|
84
|
+
// If we're not on version 3.1.0, we always fall back to the default schema version for pre-3.1.0.
|
|
83
85
|
if (!RMOAS.isOAS31(api)) {
|
|
84
86
|
// This should remain as an HTTP url, not HTTPS.
|
|
85
87
|
return 'http://json-schema.org/draft-04/schema#';
|
|
86
88
|
}
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
/**
|
|
91
|
+
* If the schema indicates the version, prefer that.
|
|
92
|
+
*
|
|
93
|
+
* We use `as` here because the schema *should* be an OAS 3.1 schema due to the `isOAS31` check
|
|
94
|
+
* above.
|
|
95
|
+
*/
|
|
92
96
|
if ((schema as OpenAPIV3_1.SchemaObject).$schema) {
|
|
93
97
|
return (schema as OpenAPIV3_1.SchemaObject).$schema;
|
|
94
98
|
}
|
|
@@ -109,11 +113,6 @@ function isPolymorphicSchema(schema: RMOAS.SchemaObject): boolean {
|
|
|
109
113
|
return 'allOf' in schema || 'anyOf' in schema || 'oneOf' in schema;
|
|
110
114
|
}
|
|
111
115
|
|
|
112
|
-
/**
|
|
113
|
-
* Determine if a given schema looks like a `requestBody` schema and contains the `content` object.
|
|
114
|
-
*
|
|
115
|
-
* @param schema
|
|
116
|
-
*/
|
|
117
116
|
function isRequestBodySchema(schema: unknown): schema is RMOAS.RequestBodyObject {
|
|
118
117
|
return 'content' in (schema as RMOAS.RequestBodyObject);
|
|
119
118
|
}
|
|
@@ -148,8 +147,8 @@ function isRequestBodySchema(schema: unknown): schema is RMOAS.RequestBodyObject
|
|
|
148
147
|
* it shouldn't raise immediate cause for alarm.
|
|
149
148
|
*
|
|
150
149
|
* @see {@link https://tools.ietf.org/html/rfc6901}
|
|
151
|
-
* @param pointer
|
|
152
|
-
* @param examples
|
|
150
|
+
* @param pointer JSON pointer to search for an example for.
|
|
151
|
+
* @param examples Array of previous schemas we've found relating to this pointer.
|
|
153
152
|
*/
|
|
154
153
|
function searchForExampleByPointer(pointer: string, examples: PrevSchemasType = []) {
|
|
155
154
|
if (!examples.length || !pointer.length) {
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import type { ComponentsObject, HttpMethods, OASDocument, TagObject } from 'rmoas.types';
|
|
2
|
+
|
|
3
|
+
import jsonPath from 'jsonpath';
|
|
4
|
+
import jsonPointer from 'jsonpointer';
|
|
5
|
+
import { version as getAPIDefinitionVersion } from 'oas-normalize/dist/lib/utils';
|
|
6
|
+
|
|
7
|
+
export type ReducerOptions = {
|
|
8
|
+
/** A key-value object of path + method combinations to reduce by. */
|
|
9
|
+
paths?: Record<string, string[] | '*'>;
|
|
10
|
+
/** An array of tags in the OpenAPI definition to reduce by. */
|
|
11
|
+
tags?: string[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Query a JSON Schema object for any `$ref` pointers. Return any pointers that were found.
|
|
16
|
+
*
|
|
17
|
+
* @param schema JSON Schema object to look for any `$ref` pointers within it.
|
|
18
|
+
*/
|
|
19
|
+
function getUsedRefs(schema: any) {
|
|
20
|
+
return jsonPath.query(schema, "$..['$ref']");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Recursively process a `$ref` pointer and accumulate any other `$ref` pointers that it or its
|
|
25
|
+
* children use.
|
|
26
|
+
*
|
|
27
|
+
* @param schema JSON Schema object to look for and accumulate any `$ref` pointers that it may have.
|
|
28
|
+
* @param $refs Known set of `$ref` pointers.
|
|
29
|
+
* @param $ref `$ref` pointer to fetch a schema from out of the supplied schema.
|
|
30
|
+
*/
|
|
31
|
+
function accumulateUsedRefs(schema: Record<string, unknown>, $refs: Set<string>, $ref: string): void {
|
|
32
|
+
const $refSchema = jsonPointer.get(schema, $ref.substring(1));
|
|
33
|
+
getUsedRefs($refSchema).forEach(currRef => {
|
|
34
|
+
// If we've already processed this $ref don't send us into an infinite loop.
|
|
35
|
+
if ($refs.has(currRef)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
$refs.add(currRef);
|
|
40
|
+
accumulateUsedRefs(schema, $refs, currRef);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* With an array of tags or object of paths+method combinations, reduce an OpenAPI definition to a
|
|
46
|
+
* new definition that just contains those tags or path + methods.
|
|
47
|
+
*
|
|
48
|
+
* @example <caption>Reduce by an array of tags only.</caption>
|
|
49
|
+
* { APIDEFINITION, { tags: ['pet] } }
|
|
50
|
+
*
|
|
51
|
+
* @example <caption>Reduce by a specific path and methods.</caption>
|
|
52
|
+
* { APIDEFINITION, { paths: { '/pet': ['get', 'post'] } } }
|
|
53
|
+
*
|
|
54
|
+
* @example <caption>Reduce by a specific path and all methods it has.</caption>
|
|
55
|
+
* { APIDEFINITION, { paths: { '/pet': '*' } } }
|
|
56
|
+
*
|
|
57
|
+
* @param definition A valid OpenAPI 3.x definition
|
|
58
|
+
* @param opts Option configuration to reduce by.
|
|
59
|
+
*/
|
|
60
|
+
export default function reducer(definition: OASDocument, opts: ReducerOptions = {}) {
|
|
61
|
+
const reduceTags = 'tags' in opts ? opts.tags : [];
|
|
62
|
+
const reducePaths = 'paths' in opts ? opts.paths : {};
|
|
63
|
+
|
|
64
|
+
const $refs: Set<string> = new Set();
|
|
65
|
+
const usedTags: Set<string> = new Set();
|
|
66
|
+
|
|
67
|
+
const baseVersion = parseInt(getAPIDefinitionVersion(definition as any), 10);
|
|
68
|
+
if (baseVersion !== 3) {
|
|
69
|
+
throw new Error('Sorry, only OpenAPI 3.x definitions are supported.');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Stringify and parse so we get a full non-reference clone of the API definition to work with.
|
|
73
|
+
const reduced = JSON.parse(JSON.stringify(definition)) as OASDocument;
|
|
74
|
+
|
|
75
|
+
if ('paths' in reduced) {
|
|
76
|
+
Object.keys(reduced.paths).forEach(path => {
|
|
77
|
+
if (Object.keys(reducePaths).length) {
|
|
78
|
+
if (!(path in reducePaths)) {
|
|
79
|
+
delete reduced.paths[path];
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
Object.keys(reduced.paths[path]).forEach((method: 'parameters' | HttpMethods) => {
|
|
85
|
+
// If this method is `parameters` we should always retain it.
|
|
86
|
+
if (method !== 'parameters') {
|
|
87
|
+
if (Object.keys(reducePaths).length) {
|
|
88
|
+
if (reducePaths[path] !== '*' && Array.isArray(reducePaths[path]) && !reducePaths[path].includes(method)) {
|
|
89
|
+
delete reduced.paths[path][method];
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const operation = reduced.paths[path][method];
|
|
96
|
+
|
|
97
|
+
// If we're reducing by tags and this operation doesn't live in one of those, remove it.
|
|
98
|
+
if (reduceTags.length) {
|
|
99
|
+
if (!('tags' in operation)) {
|
|
100
|
+
delete reduced.paths[path][method];
|
|
101
|
+
return;
|
|
102
|
+
} else if (!reduceTags.filter(value => operation.tags.includes(value)).length) {
|
|
103
|
+
delete reduced.paths[path][method];
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Accumulate a list of used tags so we can filter out any ones that we don't need later.
|
|
109
|
+
if ('tags' in operation) {
|
|
110
|
+
operation.tags.forEach((tag: string) => {
|
|
111
|
+
usedTags.add(tag);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Accumulate a list of $ref pointers that are used within this operation.
|
|
116
|
+
getUsedRefs(operation).forEach(ref => {
|
|
117
|
+
$refs.add(ref);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Accumulate any used security schemas that we need to retain.
|
|
121
|
+
if ('security' in operation) {
|
|
122
|
+
Object.values(operation.security).forEach(sec => {
|
|
123
|
+
Object.keys(sec).forEach(scheme => {
|
|
124
|
+
$refs.add(`#/components/securitySchemes/${scheme}`);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// If this path no longer has any methods, delete it.
|
|
131
|
+
if (!Object.keys(reduced.paths[path]).length) {
|
|
132
|
+
delete reduced.paths[path];
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// If we don't have any more paths after cleanup, throw an error because an OpenAPI file must
|
|
137
|
+
// have at least one path.
|
|
138
|
+
if (!Object.keys(reduced.paths).length) {
|
|
139
|
+
throw new Error('All paths in the API definition were removed. Did you supply the right path name to reduce by?');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Recursively accumulate any components that are in use.
|
|
144
|
+
$refs.forEach($ref => accumulateUsedRefs(reduced, $refs, $ref));
|
|
145
|
+
|
|
146
|
+
// Remove any unused components.
|
|
147
|
+
if ('components' in reduced) {
|
|
148
|
+
Object.keys(reduced.components).forEach((componentType: keyof ComponentsObject) => {
|
|
149
|
+
Object.keys(reduced.components[componentType]).forEach(component => {
|
|
150
|
+
if (!$refs.has(`#/components/${componentType}/${component}`)) {
|
|
151
|
+
delete reduced.components[componentType][component];
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// If this component group is now empty, delete it.
|
|
156
|
+
if (!Object.keys(reduced.components[componentType]).length) {
|
|
157
|
+
delete reduced.components[componentType];
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// If this path no longer has any components, delete it.
|
|
162
|
+
if (!Object.keys(reduced.components).length) {
|
|
163
|
+
delete reduced.components;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Remove any unused tags.
|
|
168
|
+
if ('tags' in reduced) {
|
|
169
|
+
reduced.tags.forEach((tag: TagObject, k: number) => {
|
|
170
|
+
if (!usedTags.has(tag.name)) {
|
|
171
|
+
delete reduced.tags[k];
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Remove any now empty items from the tags array.
|
|
176
|
+
reduced.tags = reduced.tags.filter(Boolean);
|
|
177
|
+
|
|
178
|
+
if (!reduced.tags.length) {
|
|
179
|
+
delete reduced.tags;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return reduced;
|
|
184
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import type Operation from '../operation';
|
|
1
2
|
import type { ComponentsObject, ExampleObject, OASDocument, ParameterObject, SchemaObject } from '../rmoas.types';
|
|
2
3
|
import type { OpenAPIV3_1 } from 'openapi-types';
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
import cloneObject from '../lib/clone-object';
|
|
4
6
|
import matchesMimetype from '../lib/matches-mimetype';
|
|
5
7
|
import toJSONSchema, { getSchemaVersionString } from '../lib/openapi-to-json-schema';
|
|
6
|
-
import cloneObject from '../lib/clone-object';
|
|
7
8
|
|
|
8
9
|
const isJSON = matchesMimetype.json;
|
|
9
10
|
|
|
@@ -166,7 +167,8 @@ export default function getParametersAsJsonSchema(
|
|
|
166
167
|
* Typescript is INCREDIBLY SLOW parsing this one line. I think it's because of the large
|
|
167
168
|
* variety of types that that object could represent but I can't yet think of a way to get
|
|
168
169
|
* around that.
|
|
169
|
-
*
|
|
170
|
+
*
|
|
171
|
+
* @todo
|
|
170
172
|
*/
|
|
171
173
|
components[componentType] = {};
|
|
172
174
|
|
|
@@ -354,6 +356,7 @@ export default function getParametersAsJsonSchema(
|
|
|
354
356
|
* Since this library assumes that the schema has already been dereferenced, adding every
|
|
355
357
|
* component here that **isn't** circular adds a ton of bloat so it'd be cool if `components`
|
|
356
358
|
* was just the remaining `$ref` pointers that are still being referenced.
|
|
359
|
+
*
|
|
357
360
|
* @todo
|
|
358
361
|
*/
|
|
359
362
|
if (hasCircularRefs && components) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type Operation from 'operation';
|
|
1
2
|
import type {
|
|
2
3
|
ComponentsObject,
|
|
3
4
|
MediaTypeObject,
|
|
@@ -6,10 +7,10 @@ import type {
|
|
|
6
7
|
SchemaObject,
|
|
7
8
|
HeaderObject,
|
|
8
9
|
} from 'rmoas.types';
|
|
9
|
-
|
|
10
|
-
import toJSONSchema, { getSchemaVersionString } from '../lib/openapi-to-json-schema';
|
|
11
|
-
import matches from '../lib/matches-mimetype';
|
|
10
|
+
|
|
12
11
|
import cloneObject from '../lib/clone-object';
|
|
12
|
+
import matches from '../lib/matches-mimetype';
|
|
13
|
+
import toJSONSchema, { getSchemaVersionString } from '../lib/openapi-to-json-schema';
|
|
13
14
|
|
|
14
15
|
const isJSON = matches.json;
|
|
15
16
|
|
|
@@ -141,6 +142,7 @@ export default function getResponseAsJsonSchema(operation: Operation, api: OASDo
|
|
|
141
142
|
* Since this library assumes that the schema has already been dereferenced, adding every
|
|
142
143
|
* component here that **isn't** circular adds a ton of bloat so it'd be cool if `components`
|
|
143
144
|
* was just the remaining `$ref` pointers that are still being referenced.
|
|
145
|
+
*
|
|
144
146
|
* @todo
|
|
145
147
|
*/
|
|
146
148
|
if (hasCircularRefs && api.components && schemaWrapper.schema) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type * as RMOAS from '../rmoas.types';
|
|
2
1
|
import type { MediaTypeExample } from '../lib/get-mediatype-examples';
|
|
2
|
+
import type * as RMOAS from '../rmoas.types';
|
|
3
3
|
|
|
4
|
-
import { isRef } from '../rmoas.types';
|
|
5
4
|
import getMediaTypeExamples from '../lib/get-mediatype-examples';
|
|
5
|
+
import { isRef } from '../rmoas.types';
|
|
6
6
|
|
|
7
7
|
export type ResponseExamples = {
|
|
8
8
|
status: string;
|
package/src/operation.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
|
|
2
|
-
import type { RequestBodyExamples } from './operation/get-requestbody-examples';
|
|
3
1
|
import type { CallbackExamples } from './operation/get-callback-examples';
|
|
2
|
+
import type { RequestBodyExamples } from './operation/get-requestbody-examples';
|
|
4
3
|
import type { ResponseExamples } from './operation/get-response-examples';
|
|
4
|
+
import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
|
|
5
5
|
|
|
6
|
-
import * as RMOAS from './rmoas.types';
|
|
7
6
|
import dedupeCommonParameters from './lib/dedupe-common-parameters';
|
|
8
7
|
import findSchemaDefinition from './lib/find-schema-definition';
|
|
8
|
+
import matchesMimeType from './lib/matches-mimetype';
|
|
9
|
+
import getCallbackExamples from './operation/get-callback-examples';
|
|
9
10
|
import getParametersAsJsonSchema from './operation/get-parameters-as-json-schema';
|
|
10
|
-
import getResponseAsJsonSchema from './operation/get-response-as-json-schema';
|
|
11
11
|
import getRequestBodyExamples from './operation/get-requestbody-examples';
|
|
12
|
-
import
|
|
12
|
+
import getResponseAsJsonSchema from './operation/get-response-as-json-schema';
|
|
13
13
|
import getResponseExamples from './operation/get-response-examples';
|
|
14
|
-
import
|
|
14
|
+
import * as RMOAS from './rmoas.types';
|
|
15
15
|
import { supportedMethods } from './utils';
|
|
16
16
|
|
|
17
17
|
type SecurityType = 'Basic' | 'Bearer' | 'Query' | 'Header' | 'Cookie' | 'OAuth2' | 'http' | 'apiKey';
|
|
@@ -332,7 +332,7 @@ export default class Operation {
|
|
|
332
332
|
* Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
|
|
333
333
|
* a hash of the path and method will be returned instead.
|
|
334
334
|
*
|
|
335
|
-
* @param opts
|
|
335
|
+
* @param opts Options
|
|
336
336
|
* @param opts.camelCase Generate a JS method-friendly operation ID when one isn't present.
|
|
337
337
|
*/
|
|
338
338
|
getOperationId(opts?: { camelCase: boolean }): string {
|
|
@@ -448,7 +448,7 @@ export default class Operation {
|
|
|
448
448
|
* Convert the operation into an array of JSON Schema schemas for each available type of
|
|
449
449
|
* parameter available on the operation.
|
|
450
450
|
*
|
|
451
|
-
* @param opts
|
|
451
|
+
* @param opts Options
|
|
452
452
|
* @param opts.globalDefaults Contains an object of user defined schema defaults.
|
|
453
453
|
* @param opts.mergeIntoBodyAndMetadata If you want the output to be two objects: body (contains
|
|
454
454
|
* `body` and `formData` JSON Schema) and metadata (contains `path`, `query`, `cookie`, and
|
|
@@ -469,7 +469,7 @@ export default class Operation {
|
|
|
469
469
|
/**
|
|
470
470
|
* Get a single response for this status code, formatted as JSON schema.
|
|
471
471
|
*
|
|
472
|
-
* @param statusCode
|
|
472
|
+
* @param statusCode Status code to pull a JSON Schema response for.
|
|
473
473
|
*/
|
|
474
474
|
getResponseAsJsonSchema(statusCode: string | number) {
|
|
475
475
|
return getResponseAsJsonSchema(this, this.api, statusCode);
|
|
@@ -616,7 +616,7 @@ export default class Operation {
|
|
|
616
616
|
/**
|
|
617
617
|
* Return a specific response out of the operation by a given HTTP status code.
|
|
618
618
|
*
|
|
619
|
-
* @param statusCode
|
|
619
|
+
* @param statusCode Status code to pull a response object for.
|
|
620
620
|
*/
|
|
621
621
|
getResponseByStatusCode(statusCode: string | number): boolean | RMOAS.ResponseObject {
|
|
622
622
|
if (!this.schema.responses) {
|
package/src/rmoas.types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
|
|
2
1
|
import type { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema';
|
|
2
|
+
import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
|
|
3
3
|
|
|
4
4
|
export type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
|
|
5
5
|
|
package/src/samples/index.ts
CHANGED
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
* @see {@link https://github.com/swagger-api/swagger-ui/blob/master/src/core/plugins/samples/fn.js}
|
|
6
6
|
*/
|
|
7
7
|
import type * as RMOAS from '../rmoas.types';
|
|
8
|
-
|
|
9
|
-
import memoize from 'memoizee';
|
|
8
|
+
|
|
10
9
|
import mergeAllOf from 'json-schema-merge-allof';
|
|
10
|
+
import memoize from 'memoizee';
|
|
11
|
+
|
|
12
|
+
import { objectify, usesPolymorphism, isFunc, normalizeArray, deeplyStripKey } from './utils';
|
|
11
13
|
|
|
12
14
|
const sampleDefaults = (genericSample: string | number | boolean) => {
|
|
13
15
|
return (schema: RMOAS.SchemaObject): typeof genericSample =>
|