@kubb/adapter-oas 5.5.5 → 5.6.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/dist/index.cjs +530 -831
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +12 -18
- package/dist/index.js +480 -759
- package/dist/index.js.map +1 -1
- package/package.json +4 -6
package/dist/index.cjs
CHANGED
|
@@ -1,35 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
//#region \0rolldown/runtime.js
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
-
key = keys[i];
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
-
get: ((k) => from[k]).bind(null, key),
|
|
14
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
20
|
-
value: mod,
|
|
21
|
-
enumerable: true
|
|
22
|
-
}) : target, mod));
|
|
23
2
|
//#endregion
|
|
24
|
-
let
|
|
25
|
-
let _kubb_core = require("@kubb/core");
|
|
3
|
+
let _kubb_kit = require("@kubb/kit");
|
|
26
4
|
let node_fs_promises = require("node:fs/promises");
|
|
27
|
-
let node_path = require("node:path");
|
|
28
|
-
node_path = __toESM(node_path, 1);
|
|
29
5
|
let yaml = require("yaml");
|
|
30
6
|
let _scalar_openapi_upgrader = require("@scalar/openapi-upgrader");
|
|
31
7
|
let api_ref_bundler = require("api-ref-bundler");
|
|
32
|
-
let _kubb_kit = require("@kubb/kit");
|
|
33
8
|
//#region src/constants.ts
|
|
34
9
|
/**
|
|
35
10
|
* Default parser options applied when no explicit options are provided.
|
|
@@ -153,11 +128,11 @@ const enumDescriptionKeys = ["x-enumDescriptions", "x-enum-descriptions"];
|
|
|
153
128
|
function buildDiscriminatorChildMap(schemas) {
|
|
154
129
|
const childMap = /* @__PURE__ */ new Map();
|
|
155
130
|
for (const schema of schemas) {
|
|
156
|
-
let unionNode =
|
|
131
|
+
let unionNode = _kubb_kit.ast.narrowSchema(schema, "union");
|
|
157
132
|
if (!unionNode) {
|
|
158
|
-
const intersectionMembers =
|
|
133
|
+
const intersectionMembers = _kubb_kit.ast.narrowSchema(schema, "intersection")?.members;
|
|
159
134
|
if (intersectionMembers) for (const m of intersectionMembers) {
|
|
160
|
-
const u =
|
|
135
|
+
const u = _kubb_kit.ast.narrowSchema(m, "union");
|
|
161
136
|
if (u) {
|
|
162
137
|
unionNode = u;
|
|
163
138
|
break;
|
|
@@ -167,17 +142,17 @@ function buildDiscriminatorChildMap(schemas) {
|
|
|
167
142
|
if (!unionNode?.discriminatorPropertyName || !unionNode.members) continue;
|
|
168
143
|
const { discriminatorPropertyName, members } = unionNode;
|
|
169
144
|
for (const member of members) {
|
|
170
|
-
const intersectionNode =
|
|
145
|
+
const intersectionNode = _kubb_kit.ast.narrowSchema(member, "intersection");
|
|
171
146
|
if (!intersectionNode?.members) continue;
|
|
172
147
|
let refNode = null;
|
|
173
148
|
let objNode = null;
|
|
174
149
|
for (const m of intersectionNode.members) {
|
|
175
|
-
refNode ??=
|
|
176
|
-
objNode ??=
|
|
150
|
+
refNode ??= _kubb_kit.ast.narrowSchema(m, "ref");
|
|
151
|
+
objNode ??= _kubb_kit.ast.narrowSchema(m, "object");
|
|
177
152
|
}
|
|
178
153
|
if (!refNode?.name || !objNode) continue;
|
|
179
154
|
const prop = objNode.properties.find((p) => p.name === discriminatorPropertyName);
|
|
180
|
-
const enumNode = prop ?
|
|
155
|
+
const enumNode = prop ? _kubb_kit.ast.narrowSchema(prop.schema, "enum") : null;
|
|
181
156
|
if (!enumNode?.enumValues?.length) continue;
|
|
182
157
|
const enumValues = enumNode.enumValues.filter((v) => v !== null);
|
|
183
158
|
if (!enumValues.length) continue;
|
|
@@ -203,16 +178,16 @@ function buildDiscriminatorChildMap(schemas) {
|
|
|
203
178
|
*/
|
|
204
179
|
function patchDiscriminatorNode(node, entry) {
|
|
205
180
|
const { propertyName, enumValues } = entry;
|
|
206
|
-
const enumSchema =
|
|
181
|
+
const enumSchema = _kubb_kit.ast.factory.createSchema({
|
|
207
182
|
type: "enum",
|
|
208
183
|
enumValues
|
|
209
184
|
});
|
|
210
|
-
const newProp =
|
|
185
|
+
const newProp = _kubb_kit.ast.factory.createProperty({
|
|
211
186
|
name: propertyName,
|
|
212
187
|
required: true,
|
|
213
188
|
schema: enumSchema
|
|
214
189
|
});
|
|
215
|
-
const objectNode =
|
|
190
|
+
const objectNode = _kubb_kit.ast.narrowSchema(node, "object");
|
|
216
191
|
if (objectNode) {
|
|
217
192
|
const existingIdx = objectNode.properties.findIndex((p) => p.name === propertyName);
|
|
218
193
|
const newProperties = existingIdx >= 0 ? objectNode.properties.map((p, i) => i === existingIdx ? newProp : p) : [...objectNode.properties, newProp];
|
|
@@ -221,14 +196,14 @@ function patchDiscriminatorNode(node, entry) {
|
|
|
221
196
|
properties: newProperties
|
|
222
197
|
};
|
|
223
198
|
}
|
|
224
|
-
const intersectionNode =
|
|
199
|
+
const intersectionNode = _kubb_kit.ast.narrowSchema(node, "intersection");
|
|
225
200
|
if (!intersectionNode?.members) return node;
|
|
226
|
-
const discriminantNode =
|
|
201
|
+
const discriminantNode = _kubb_kit.ast.factory.createSchema({
|
|
227
202
|
type: "object",
|
|
228
203
|
primitive: "object",
|
|
229
204
|
properties: [newProp]
|
|
230
205
|
});
|
|
231
|
-
const patchedIdx = intersectionNode.members.findIndex((member) =>
|
|
206
|
+
const patchedIdx = intersectionNode.members.findIndex((member) => _kubb_kit.ast.narrowSchema(member, "object")?.properties.some((p) => p.name === propertyName));
|
|
232
207
|
const newMembers = patchedIdx >= 0 ? intersectionNode.members.map((member, i) => i === patchedIdx ? patchDiscriminatorNode(member, entry) : member) : [...intersectionNode.members, discriminantNode];
|
|
233
208
|
return {
|
|
234
209
|
...intersectionNode,
|
|
@@ -399,8 +374,8 @@ async function fetchSource(url) {
|
|
|
399
374
|
try {
|
|
400
375
|
return await fetch(url);
|
|
401
376
|
} catch (error) {
|
|
402
|
-
throw new
|
|
403
|
-
code:
|
|
377
|
+
throw new _kubb_kit.Diagnostics.Error({
|
|
378
|
+
code: _kubb_kit.Diagnostics.code.inputUnreachable,
|
|
404
379
|
severity: "error",
|
|
405
380
|
message: `Cannot reach ${url.href}: ${describeFetchFailure(error)}`,
|
|
406
381
|
help: "Check that the host is running and reachable from this machine. For a local server, start it and confirm the port matches the one in `input`.",
|
|
@@ -415,8 +390,8 @@ async function readSource(sourcePath) {
|
|
|
415
390
|
const response = await fetchSource(url);
|
|
416
391
|
if (!response.ok) {
|
|
417
392
|
const status = response.statusText ? `${response.status} ${response.statusText}` : String(response.status);
|
|
418
|
-
throw new
|
|
419
|
-
code:
|
|
393
|
+
throw new _kubb_kit.Diagnostics.Error({
|
|
394
|
+
code: _kubb_kit.Diagnostics.code.inputRequestFailed,
|
|
420
395
|
severity: "error",
|
|
421
396
|
message: `The server at ${url.href} answered with HTTP ${status} instead of the OpenAPI document.`,
|
|
422
397
|
help: helpForStatus(response.status),
|
|
@@ -453,8 +428,8 @@ async function resolveSource(sourcePath) {
|
|
|
453
428
|
*/
|
|
454
429
|
async function assertInputExists(input) {
|
|
455
430
|
if (urlRegExp.test(input)) return;
|
|
456
|
-
if (!await exists(input)) throw new
|
|
457
|
-
code:
|
|
431
|
+
if (!await exists(input)) throw new _kubb_kit.Diagnostics.Error({
|
|
432
|
+
code: _kubb_kit.Diagnostics.code.inputNotFound,
|
|
458
433
|
severity: "error",
|
|
459
434
|
message: `Cannot read the file set as \`input\` (or via \`kubb generate PATH\`): ${input}`,
|
|
460
435
|
help: "Check that the path exists and is readable, then set it as `input` or pass it as `kubb generate PATH`.",
|
|
@@ -530,7 +505,7 @@ async function parseDocument(pathOrApi) {
|
|
|
530
505
|
/**
|
|
531
506
|
* Creates a `Document` from an `AdapterSource`.
|
|
532
507
|
*
|
|
533
|
-
* - `{ type: 'path' }`
|
|
508
|
+
* - `{ type: 'path' }` bundles an absolute file path (core resolves `input`) or remote URL.
|
|
534
509
|
* - `{ type: 'data' }` parses an inline string (YAML/JSON) or raw object.
|
|
535
510
|
*
|
|
536
511
|
* @example
|
|
@@ -541,10 +516,8 @@ async function parseDocument(pathOrApi) {
|
|
|
541
516
|
*/
|
|
542
517
|
async function parseFromConfig(source) {
|
|
543
518
|
if (source.type === "data") return parseDocument(typeof source.data === "string" ? (0, yaml.parse)(source.data) : structuredClone(source.data));
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
await assertInputExists(resolved);
|
|
547
|
-
return parseDocument(resolved);
|
|
519
|
+
await assertInputExists(source.path);
|
|
520
|
+
return parseDocument(source.path);
|
|
548
521
|
}
|
|
549
522
|
/**
|
|
550
523
|
* Asserts the parsed input is an OpenAPI or Swagger document.
|
|
@@ -556,8 +529,8 @@ async function parseFromConfig(source) {
|
|
|
556
529
|
*/
|
|
557
530
|
function assertDocument(document) {
|
|
558
531
|
if (document && ("openapi" in document || "swagger" in document)) return;
|
|
559
|
-
throw new
|
|
560
|
-
code:
|
|
532
|
+
throw new _kubb_kit.Diagnostics.Error({
|
|
533
|
+
code: _kubb_kit.Diagnostics.code.invalidDocument,
|
|
561
534
|
severity: "error",
|
|
562
535
|
message: "The resolved `input` is not an OpenAPI or Swagger document: it declares no `openapi` or `swagger` version.",
|
|
563
536
|
help: "Point `input` at a document that declares `openapi` or `swagger`. If you pass an object, pass the spec itself rather than a wrapper such as `{ path }` or `{ data }`.",
|
|
@@ -566,8 +539,8 @@ function assertDocument(document) {
|
|
|
566
539
|
}
|
|
567
540
|
/** Reports a validation problem as a `KUBB_INVALID_SPEC` warning, a no-op outside a build. */
|
|
568
541
|
function reportInvalidSpec(message) {
|
|
569
|
-
|
|
570
|
-
code:
|
|
542
|
+
_kubb_kit.Diagnostics.report({
|
|
543
|
+
code: _kubb_kit.Diagnostics.code.invalidSpec,
|
|
571
544
|
severity: "warning",
|
|
572
545
|
message,
|
|
573
546
|
help: "Fix the spec, or run `kubb validate` to list every error. Set `validate: false` on the adapter to skip this check."
|
|
@@ -673,21 +646,6 @@ const jsonMimeFragments = [
|
|
|
673
646
|
function isJsonMimeType(mimeType) {
|
|
674
647
|
return jsonMimeFragments.some((fragment) => mimeType.includes(fragment));
|
|
675
648
|
}
|
|
676
|
-
/**
|
|
677
|
-
* Picks a media-type entry from a `content` map: the first JSON-like media type, falling back to
|
|
678
|
-
* the first declared one. Returns `false` when `content` has no entries.
|
|
679
|
-
*
|
|
680
|
-
* @example
|
|
681
|
-
* ```ts
|
|
682
|
-
* pickContentEntry({ 'application/xml': xmlEntry, 'application/json': jsonEntry })
|
|
683
|
-
* // ['application/json', jsonEntry]
|
|
684
|
-
* ```
|
|
685
|
-
*/
|
|
686
|
-
function pickContentEntry(content) {
|
|
687
|
-
const mediaTypes = Object.keys(content);
|
|
688
|
-
const available = mediaTypes.find(isJsonMimeType) ?? mediaTypes[0];
|
|
689
|
-
return available ? [available, content[available]] : false;
|
|
690
|
-
}
|
|
691
649
|
//#endregion
|
|
692
650
|
//#region src/model/components.ts
|
|
693
651
|
/**
|
|
@@ -877,8 +835,8 @@ function resolveServerUrl(server, overrides) {
|
|
|
877
835
|
for (const [key, variable] of Object.entries(server.variables)) {
|
|
878
836
|
const value = overrides?.[key] ?? (variable.default != null ? String(variable.default) : void 0);
|
|
879
837
|
if (value === void 0) continue;
|
|
880
|
-
if (variable.enum?.length && !variable.enum.some((e) => String(e) === value)) throw new
|
|
881
|
-
code:
|
|
838
|
+
if (variable.enum?.length && !variable.enum.some((e) => String(e) === value)) throw new _kubb_kit.Diagnostics.Error({
|
|
839
|
+
code: _kubb_kit.Diagnostics.code.invalidServerVariable,
|
|
882
840
|
severity: "error",
|
|
883
841
|
message: `Invalid server variable value '${value}' for '${key}' when resolving ${server.url}. Valid values are: ${variable.enum.join(", ")}.`,
|
|
884
842
|
help: `Use one of the allowed enum values, or drop the enum on the '${key}' server variable.`,
|
|
@@ -893,10 +851,6 @@ function resolveServerUrl(server, overrides) {
|
|
|
893
851
|
}
|
|
894
852
|
//#endregion
|
|
895
853
|
//#region src/operation.ts
|
|
896
|
-
/**
|
|
897
|
-
* Slugifies a path for the `operationId` fallback: non-alphanumerics collapse to single dashes,
|
|
898
|
-
* with no leading or trailing dash.
|
|
899
|
-
*/
|
|
900
854
|
function slugify(value) {
|
|
901
855
|
return value.replace(/[^a-zA-Z0-9]/g, "-").replace(/-{2,}/g, "-").replace(/^-|-$/g, "");
|
|
902
856
|
}
|
|
@@ -917,12 +871,12 @@ function getResponseStatusCodes({ schema }) {
|
|
|
917
871
|
return Object.keys(responses).filter((key) => !key.startsWith("x-") && !!responses[key] && typeof responses[key] === "object");
|
|
918
872
|
}
|
|
919
873
|
/**
|
|
920
|
-
* Returns the response object for a status code, resolving a `$ref` through `refs`. `
|
|
874
|
+
* Returns the response object for a status code, resolving a `$ref` through `refs`. `null` when absent.
|
|
921
875
|
*/
|
|
922
876
|
function getResponseByStatusCode({ operation, refs, statusCode }) {
|
|
923
877
|
const responses = operation.schema.responses;
|
|
924
|
-
if (!responses || isReference(responses)) return
|
|
925
|
-
return refs.deref(responses[statusCode])
|
|
878
|
+
if (!responses || isReference(responses)) return null;
|
|
879
|
+
return refs.deref(responses[statusCode]);
|
|
926
880
|
}
|
|
927
881
|
/**
|
|
928
882
|
* Resolves the operation's request body, dereferencing a `$ref` through `refs`. Returns `null`
|
|
@@ -932,51 +886,37 @@ function getRequestBody({ operation, refs }) {
|
|
|
932
886
|
return refs.deref(operation.schema.requestBody);
|
|
933
887
|
}
|
|
934
888
|
/**
|
|
935
|
-
* Resolves the request body (a `$ref` through `refs`) and returns its content map, or
|
|
936
|
-
* `undefined` when the operation has no request body.
|
|
937
|
-
*/
|
|
938
|
-
function getRequestBodyContent({ operation, refs }) {
|
|
939
|
-
return getRequestBody({
|
|
940
|
-
operation,
|
|
941
|
-
refs
|
|
942
|
-
})?.content;
|
|
943
|
-
}
|
|
944
|
-
/**
|
|
945
|
-
* Returns the request body media type. With `mediaType` set, returns that entry or `false`.
|
|
946
|
-
* Otherwise picks the first JSON-like media type, then the first declared one, as a
|
|
947
|
-
* `[mediaType, object]` tuple.
|
|
948
|
-
*/
|
|
949
|
-
function getRequestContent({ operation, refs, mediaType }) {
|
|
950
|
-
const content = getRequestBodyContent({
|
|
951
|
-
operation,
|
|
952
|
-
refs
|
|
953
|
-
});
|
|
954
|
-
if (!content) return false;
|
|
955
|
-
if (mediaType) return mediaType in content ? content[mediaType] : false;
|
|
956
|
-
return pickContentEntry(content);
|
|
957
|
-
}
|
|
958
|
-
/**
|
|
959
889
|
* Returns the primary request content type. Prefers a JSON-like media type (the last one wins
|
|
960
890
|
* when several are declared), then the first declared one, defaulting to `'application/json'`.
|
|
961
891
|
*/
|
|
962
892
|
function getRequestContentType({ operation, refs }) {
|
|
963
|
-
const content =
|
|
893
|
+
const content = getRequestBody({
|
|
964
894
|
operation,
|
|
965
895
|
refs
|
|
966
|
-
});
|
|
896
|
+
})?.content;
|
|
967
897
|
const mediaTypes = content ? Object.keys(content) : [];
|
|
968
898
|
return mediaTypes.findLast(isJsonMimeType) ?? mediaTypes[0] ?? "application/json";
|
|
969
899
|
}
|
|
900
|
+
/** Merges path-level and operation-level parameters; operation-level wins per `in:name`. */
|
|
901
|
+
function getParameters({ operation, refs }) {
|
|
902
|
+
const resolveParams = (params) => params.map((p) => refs.derefKeepingRef(p)).filter((p) => !!p && typeof p === "object" && "in" in p && "name" in p);
|
|
903
|
+
const operationParams = resolveParams(operation.schema?.parameters || []);
|
|
904
|
+
const pathLevelParams = resolveParams(operation.pathItem.parameters ?? []);
|
|
905
|
+
const paramMap = /* @__PURE__ */ new Map();
|
|
906
|
+
for (const p of [...pathLevelParams, ...operationParams]) if (p.name && p.in) paramMap.set(`${p.in}:${p.name}`, p);
|
|
907
|
+
return Array.from(paramMap.values());
|
|
908
|
+
}
|
|
909
|
+
/** Schema for one media type of a `content` map, with the binary fallback for an emptied non-JSON entry. */
|
|
910
|
+
function getBodySchema({ content, contentType, refs }) {
|
|
911
|
+
const entry = contentType ? content?.[contentType] : void 0;
|
|
912
|
+
if (!entry) return null;
|
|
913
|
+
const binary = getBinaryFallbackSchema(contentType, entry.schema);
|
|
914
|
+
if (binary) return binary;
|
|
915
|
+
return entry.schema ? refs.derefKeepingRef(entry.schema) : null;
|
|
916
|
+
}
|
|
970
917
|
/**
|
|
971
918
|
* Builds an `Operation` for every supported HTTP method on every path, in document order.
|
|
972
919
|
* `x-` path keys and unresolvable path-item `$ref`s are skipped.
|
|
973
|
-
*
|
|
974
|
-
* @example
|
|
975
|
-
* ```ts
|
|
976
|
-
* for (const operation of getOperations(document, refs)) {
|
|
977
|
-
* parseOperation(options, operation)
|
|
978
|
-
* }
|
|
979
|
-
* ```
|
|
980
920
|
*/
|
|
981
921
|
function getOperations(document, refs) {
|
|
982
922
|
const operations = [];
|
|
@@ -1001,32 +941,144 @@ function getOperations(document, refs) {
|
|
|
1001
941
|
}
|
|
1002
942
|
return operations;
|
|
1003
943
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
944
|
+
/** Property names whose schema has a truthy `readOnly` or `writeOnly` flag; `$ref` entries are skipped. */
|
|
945
|
+
function collectPropertyKeysByFlag(schema, flag) {
|
|
946
|
+
if (!schema?.properties) return null;
|
|
947
|
+
const keys = [];
|
|
948
|
+
for (const key in schema.properties) {
|
|
949
|
+
const prop = schema.properties[key];
|
|
950
|
+
if (prop && !isReference(prop) && prop[flag]) keys.push(key);
|
|
951
|
+
}
|
|
952
|
+
return keys.length ? keys : null;
|
|
953
|
+
}
|
|
954
|
+
function parseParameter({ param, parentName, options, parseSchema }) {
|
|
955
|
+
const schemaName = parentName && param.name ? pascalCase(`${parentName} ${param.name}`) : void 0;
|
|
956
|
+
const schema = param.schema ? parseSchema({
|
|
957
|
+
schema: param.schema,
|
|
958
|
+
name: schemaName
|
|
959
|
+
}) : _kubb_kit.ast.factory.createSchema({ type: options.unknownType });
|
|
960
|
+
const style = param.style;
|
|
961
|
+
const explode = param.explode;
|
|
962
|
+
return _kubb_kit.ast.factory.createParameter({
|
|
963
|
+
name: param.name,
|
|
964
|
+
in: param.in,
|
|
965
|
+
schema: {
|
|
966
|
+
...schema,
|
|
967
|
+
description: param.description ?? schema.description
|
|
968
|
+
},
|
|
969
|
+
required: param.required ?? false,
|
|
970
|
+
...style !== void 0 ? { style } : {},
|
|
971
|
+
...explode !== void 0 ? { explode } : {}
|
|
972
|
+
});
|
|
1012
973
|
}
|
|
1013
974
|
/**
|
|
1014
|
-
*
|
|
1015
|
-
* `specialCasedFormats` that `convertFormat` handles directly (int64, uint64, date-time, date, time). False means the format falls back to
|
|
1016
|
-
* the base type, which is what `KUBB_UNSUPPORTED_FORMAT` flags. Reading both sources keeps the
|
|
1017
|
-
* diagnostic in step with the parser as `formatMap` grows.
|
|
975
|
+
* Converts an OAS `Operation` into an `OperationNode`.
|
|
1018
976
|
*/
|
|
1019
|
-
function
|
|
1020
|
-
|
|
977
|
+
function parseOperation({ operation, ...ctx }) {
|
|
978
|
+
const { refs, contentType, options, parseSchema } = ctx;
|
|
979
|
+
const operationId = getOperationId(operation);
|
|
980
|
+
const operationName = operationId ? pascalCase(operationId) : void 0;
|
|
981
|
+
const parameters = getParameters({
|
|
982
|
+
operation,
|
|
983
|
+
refs
|
|
984
|
+
}).map((param) => parseParameter({
|
|
985
|
+
options,
|
|
986
|
+
parseSchema,
|
|
987
|
+
param,
|
|
988
|
+
parentName: operationName
|
|
989
|
+
}));
|
|
990
|
+
const body = getRequestBody({
|
|
991
|
+
operation,
|
|
992
|
+
refs
|
|
993
|
+
});
|
|
994
|
+
const bodyRequired = body?.required === true;
|
|
995
|
+
const requestBodyName = operationName ? `${operationName}Request` : void 0;
|
|
996
|
+
const content = (contentType ? [contentType] : Object.keys(body?.content ?? {})).flatMap((ct) => {
|
|
997
|
+
const schema = getBodySchema({
|
|
998
|
+
content: body?.content,
|
|
999
|
+
contentType: ct,
|
|
1000
|
+
refs
|
|
1001
|
+
});
|
|
1002
|
+
if (!schema) return [];
|
|
1003
|
+
return [_kubb_kit.ast.factory.createContent({
|
|
1004
|
+
contentType: ct,
|
|
1005
|
+
schema: _kubb_kit.ast.optionality(parseSchema({
|
|
1006
|
+
schema,
|
|
1007
|
+
name: requestBodyName
|
|
1008
|
+
}), bodyRequired),
|
|
1009
|
+
keysToOmit: collectPropertyKeysByFlag(schema, "readOnly")
|
|
1010
|
+
})];
|
|
1011
|
+
});
|
|
1012
|
+
const requestBody = content.length > 0 || body?.description ? {
|
|
1013
|
+
description: body?.description,
|
|
1014
|
+
required: bodyRequired || void 0,
|
|
1015
|
+
content: content.length > 0 ? content : void 0
|
|
1016
|
+
} : void 0;
|
|
1017
|
+
const responses = getResponseStatusCodes(operation).map((statusCode) => {
|
|
1018
|
+
const response = getResponseByStatusCode({
|
|
1019
|
+
operation,
|
|
1020
|
+
refs,
|
|
1021
|
+
statusCode
|
|
1022
|
+
});
|
|
1023
|
+
const responseName = operationName ? `${operationName}Status${statusCode}` : void 0;
|
|
1024
|
+
const parseEntrySchema = (ct) => {
|
|
1025
|
+
const raw = getBodySchema({
|
|
1026
|
+
content: response?.content,
|
|
1027
|
+
contentType: ct,
|
|
1028
|
+
refs
|
|
1029
|
+
});
|
|
1030
|
+
return {
|
|
1031
|
+
schema: raw && Object.keys(raw).length > 0 ? parseSchema({
|
|
1032
|
+
schema: raw,
|
|
1033
|
+
name: responseName
|
|
1034
|
+
}) : _kubb_kit.ast.factory.createSchema({ type: options.emptySchemaType }),
|
|
1035
|
+
keysToOmit: collectPropertyKeysByFlag(raw, "writeOnly")
|
|
1036
|
+
};
|
|
1037
|
+
};
|
|
1038
|
+
const responseContent = (contentType ? [contentType] : Object.keys(response?.content ?? {})).map((ct) => _kubb_kit.ast.factory.createContent({
|
|
1039
|
+
contentType: ct,
|
|
1040
|
+
...parseEntrySchema(ct)
|
|
1041
|
+
}));
|
|
1042
|
+
if (responseContent.length === 0) responseContent.push(_kubb_kit.ast.factory.createContent({
|
|
1043
|
+
contentType: getRequestContentType({
|
|
1044
|
+
operation,
|
|
1045
|
+
refs
|
|
1046
|
+
}),
|
|
1047
|
+
...parseEntrySchema(contentType)
|
|
1048
|
+
}));
|
|
1049
|
+
return _kubb_kit.ast.factory.createResponse({
|
|
1050
|
+
statusCode,
|
|
1051
|
+
description: response?.description,
|
|
1052
|
+
content: responseContent
|
|
1053
|
+
});
|
|
1054
|
+
});
|
|
1055
|
+
const pickDoc = (key) => {
|
|
1056
|
+
const own = operation.schema[key];
|
|
1057
|
+
if (typeof own === "string") return own;
|
|
1058
|
+
const fallback = operation.pathItem[key];
|
|
1059
|
+
return typeof fallback === "string" ? fallback : void 0;
|
|
1060
|
+
};
|
|
1061
|
+
return _kubb_kit.ast.factory.createOperation({
|
|
1062
|
+
operationId,
|
|
1063
|
+
protocol: "http",
|
|
1064
|
+
method: operation.method.toUpperCase(),
|
|
1065
|
+
path: operation.path,
|
|
1066
|
+
tags: Array.isArray(operation.schema.tags) ? operation.schema.tags.map(String) : [],
|
|
1067
|
+
summary: pickDoc("summary") || void 0,
|
|
1068
|
+
description: pickDoc("description") || void 0,
|
|
1069
|
+
deprecated: operation.schema.deprecated || void 0,
|
|
1070
|
+
parameters,
|
|
1071
|
+
requestBody,
|
|
1072
|
+
responses
|
|
1073
|
+
});
|
|
1021
1074
|
}
|
|
1075
|
+
//#endregion
|
|
1076
|
+
//#region src/emit/schemaShape.ts
|
|
1022
1077
|
/**
|
|
1023
|
-
*
|
|
1024
|
-
* Numeric types (`number`, `integer`, `bigint`) pass through unchanged. `boolean` maps to `'boolean'`. Everything else becomes `'string'`.
|
|
1078
|
+
* Whether `format` maps to a dedicated type; `false` is what `KUBB_UNSUPPORTED_FORMAT` flags.
|
|
1025
1079
|
*/
|
|
1026
|
-
function
|
|
1027
|
-
|
|
1028
|
-
if (type === "boolean") return "boolean";
|
|
1029
|
-
return "string";
|
|
1080
|
+
function isHandledFormat(format) {
|
|
1081
|
+
return formatMap[format] !== void 0 || specialCasedFormats.has(format);
|
|
1030
1082
|
}
|
|
1031
1083
|
/**
|
|
1032
1084
|
* Resolves the `dateType` option down to the value for one format. The scalar form of
|
|
@@ -1038,51 +1090,6 @@ function resolveDateTypeValue(dateType, format) {
|
|
|
1038
1090
|
return dateType[format === "date-time" ? "dateTime" : format] ?? "string";
|
|
1039
1091
|
}
|
|
1040
1092
|
/**
|
|
1041
|
-
* Resolves the AST type descriptor for a date/time format, honoring the `dateType` option.
|
|
1042
|
-
* Returns `null` when the resolved value is `false`, so the format falls through to `string`.
|
|
1043
|
-
*/
|
|
1044
|
-
function getDateType(options, format) {
|
|
1045
|
-
const value = resolveDateTypeValue(options.dateType, format);
|
|
1046
|
-
if (!value) return null;
|
|
1047
|
-
if (format === "date-time") {
|
|
1048
|
-
if (value === "date") return {
|
|
1049
|
-
type: "date",
|
|
1050
|
-
representation: "date"
|
|
1051
|
-
};
|
|
1052
|
-
if (value === "stringOffset") return {
|
|
1053
|
-
type: "datetime",
|
|
1054
|
-
offset: true
|
|
1055
|
-
};
|
|
1056
|
-
if (value === "stringLocal") return {
|
|
1057
|
-
type: "datetime",
|
|
1058
|
-
local: true
|
|
1059
|
-
};
|
|
1060
|
-
return {
|
|
1061
|
-
type: "datetime",
|
|
1062
|
-
offset: false
|
|
1063
|
-
};
|
|
1064
|
-
}
|
|
1065
|
-
if (format === "date") return {
|
|
1066
|
-
type: "date",
|
|
1067
|
-
representation: value === "date" ? "date" : "string"
|
|
1068
|
-
};
|
|
1069
|
-
return {
|
|
1070
|
-
type: "time",
|
|
1071
|
-
representation: value === "date" ? "date" : "string"
|
|
1072
|
-
};
|
|
1073
|
-
}
|
|
1074
|
-
/**
|
|
1075
|
-
* Reads a schema's numeric `exclusiveMinimum`/`exclusiveMaximum` bounds (the OAS 3.1 numeric
|
|
1076
|
-
* form). Either key is `undefined` when absent or, for the legacy OAS 3.0 boolean form, not a
|
|
1077
|
-
* number.
|
|
1078
|
-
*/
|
|
1079
|
-
function getExclusiveBounds(schema) {
|
|
1080
|
-
return {
|
|
1081
|
-
exclusiveMinimum: typeof schema.exclusiveMinimum === "number" ? schema.exclusiveMinimum : void 0,
|
|
1082
|
-
exclusiveMaximum: typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : void 0
|
|
1083
|
-
};
|
|
1084
|
-
}
|
|
1085
|
-
/**
|
|
1086
1093
|
* Reads schema examples as an array. OAS 3.1 uses an `examples` array, but specs (including ones
|
|
1087
1094
|
* labeled 3.1) still use the singular OAS 3.0 `example`, which the upgrader only converts on the
|
|
1088
1095
|
* 3.0 -> 3.1 hop. Normalize both into one array so the AST node exposes only `examples`.
|
|
@@ -1091,12 +1098,6 @@ function extractExamples(schema) {
|
|
|
1091
1098
|
if (Array.isArray(schema.examples)) return schema.examples;
|
|
1092
1099
|
return schema.example !== void 0 ? [schema.example] : void 0;
|
|
1093
1100
|
}
|
|
1094
|
-
/**
|
|
1095
|
-
* Returns `true` when `fragment` carries any JSON Schema keyword that makes it
|
|
1096
|
-
* structurally significant on its own (see `structuralKeys`).
|
|
1097
|
-
*
|
|
1098
|
-
* A fragment with a structural keyword can't be safely merged into a parent schema.
|
|
1099
|
-
*/
|
|
1100
1101
|
function hasStructuralKeywords(fragment) {
|
|
1101
1102
|
return Object.keys(fragment).some((key) => structuralKeys.has(key));
|
|
1102
1103
|
}
|
|
@@ -1104,23 +1105,19 @@ function hasStructuralKeywords(fragment) {
|
|
|
1104
1105
|
* Flattens a keyword-only `allOf` into its parent schema.
|
|
1105
1106
|
*
|
|
1106
1107
|
* Only flattens when every member is a plain fragment, with no `$ref` and no structural keywords
|
|
1107
|
-
* (see `structuralKeys`). Outer schema values take precedence over fragment values.
|
|
1108
|
-
*
|
|
1108
|
+
* (see `structuralKeys`). Outer schema values take precedence over fragment values. Returns the
|
|
1109
|
+
* original schema unchanged when flattening is unsafe.
|
|
1109
1110
|
*
|
|
1110
1111
|
* @example
|
|
1111
1112
|
* ```ts
|
|
1112
1113
|
* flattenSchema({ allOf: [{ description: 'A pet' }], type: 'object', properties: {} })
|
|
1113
1114
|
* // { type: 'object', properties: {}, description: 'A pet' }
|
|
1114
|
-
* ```
|
|
1115
|
-
*
|
|
1116
|
-
* @example
|
|
1117
|
-
* ```ts
|
|
1118
1115
|
* flattenSchema({ allOf: [{ $ref: '#/components/schemas/Pet' }] })
|
|
1119
1116
|
* // returned unchanged, contains a $ref
|
|
1120
1117
|
* ```
|
|
1121
1118
|
*/
|
|
1122
1119
|
function flattenSchema(schema) {
|
|
1123
|
-
if (!schema
|
|
1120
|
+
if (!schema.allOf?.length) return schema;
|
|
1124
1121
|
const allOfFragments = schema.allOf;
|
|
1125
1122
|
if (allOfFragments.some((item) => isReference(item))) return schema;
|
|
1126
1123
|
if (allOfFragments.some(hasStructuralKeywords)) return schema;
|
|
@@ -1137,7 +1134,7 @@ function flattenSchema(schema) {
|
|
|
1137
1134
|
* whatever makes its node distinct; this folds both into one call.
|
|
1138
1135
|
*/
|
|
1139
1136
|
function createNode({ schema, name, nullable, defaultValue }, extras) {
|
|
1140
|
-
return
|
|
1137
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
1141
1138
|
name,
|
|
1142
1139
|
nullable,
|
|
1143
1140
|
title: schema.title,
|
|
@@ -1163,12 +1160,12 @@ function createNode({ schema, name, nullable, defaultValue }, extras) {
|
|
|
1163
1160
|
* ```
|
|
1164
1161
|
*/
|
|
1165
1162
|
function createDiscriminantNode({ propertyName, values }) {
|
|
1166
|
-
return
|
|
1163
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
1167
1164
|
type: "object",
|
|
1168
1165
|
primitive: "object",
|
|
1169
|
-
properties: [
|
|
1166
|
+
properties: [_kubb_kit.ast.factory.createProperty({
|
|
1170
1167
|
name: propertyName,
|
|
1171
|
-
schema:
|
|
1168
|
+
schema: _kubb_kit.ast.factory.createSchema({
|
|
1172
1169
|
type: "enum",
|
|
1173
1170
|
primitive: "string",
|
|
1174
1171
|
enumValues: values
|
|
@@ -1199,11 +1196,11 @@ function findDiscriminators(mapping, ref) {
|
|
|
1199
1196
|
* at this union usage site, which is what makes this mode "preserve" (as opposed to `propagate`,
|
|
1200
1197
|
* which additionally patches the child schema's own definition in a post-pass).
|
|
1201
1198
|
*/
|
|
1202
|
-
function narrowUnionMembers({ unionMembers, discriminator, sharedPropertiesNode, parse,
|
|
1199
|
+
function narrowUnionMembers({ unionMembers, discriminator, sharedPropertiesNode, parse, name, refs }) {
|
|
1203
1200
|
function pickDiscriminatorPropertyNode(node, propertyName) {
|
|
1204
|
-
const discriminatorProperty =
|
|
1201
|
+
const discriminatorProperty = _kubb_kit.ast.narrowSchema(node, "object")?.properties?.find((property) => property.name === propertyName);
|
|
1205
1202
|
if (!discriminatorProperty) return null;
|
|
1206
|
-
return
|
|
1203
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
1207
1204
|
type: "object",
|
|
1208
1205
|
primitive: "object",
|
|
1209
1206
|
properties: [discriminatorProperty]
|
|
@@ -1241,13 +1238,13 @@ function narrowUnionMembers({ unionMembers, discriminator, sharedPropertiesNode,
|
|
|
1241
1238
|
const memberNode = parse({
|
|
1242
1239
|
schema: s,
|
|
1243
1240
|
name
|
|
1244
|
-
}
|
|
1241
|
+
});
|
|
1245
1242
|
if (!discriminatorValues.length || !discriminator) return memberNode;
|
|
1246
|
-
const narrowedDiscriminatorNode = sharedPropertiesNode ? pickDiscriminatorPropertyNode(
|
|
1243
|
+
const narrowedDiscriminatorNode = sharedPropertiesNode ? pickDiscriminatorPropertyNode(_kubb_kit.ast.applyMacros(sharedPropertiesNode, [(0, _kubb_kit.macroDiscriminatorEnum)({
|
|
1247
1244
|
propertyName: discriminator.propertyName,
|
|
1248
1245
|
values: discriminatorValues
|
|
1249
1246
|
})], { depth: "shallow" }), discriminator.propertyName) : void 0;
|
|
1250
|
-
return
|
|
1247
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
1251
1248
|
type: "intersection",
|
|
1252
1249
|
members: [memberNode, narrowedDiscriminatorNode ?? createDiscriminantNode({
|
|
1253
1250
|
propertyName: discriminator.propertyName,
|
|
@@ -1358,6 +1355,68 @@ function convertAnnotatedEnum(context) {
|
|
|
1358
1355
|
//#endregion
|
|
1359
1356
|
//#region src/emit/converters/composition.ts
|
|
1360
1357
|
/**
|
|
1358
|
+
* Collects property schemas from all `allOf` members and outer schema properties,
|
|
1359
|
+
* recursively resolving `$ref` pointers.
|
|
1360
|
+
*/
|
|
1361
|
+
function collectSiblingProperties(allOfMembers, refs, outerProperties) {
|
|
1362
|
+
const properties = { ...outerProperties };
|
|
1363
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1364
|
+
function collectFrom(item) {
|
|
1365
|
+
if (!item) return;
|
|
1366
|
+
if (isReference(item)) {
|
|
1367
|
+
if (visited.has(item.$ref)) return;
|
|
1368
|
+
visited.add(item.$ref);
|
|
1369
|
+
const resolved = refs.resolve(item.$ref, { report: false });
|
|
1370
|
+
if (resolved && !isReference(resolved)) collectFrom(resolved);
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
if (item.properties) Object.assign(properties, item.properties);
|
|
1374
|
+
if (Array.isArray(item.allOf)) for (const member of item.allOf) collectFrom(member);
|
|
1375
|
+
}
|
|
1376
|
+
for (const item of allOfMembers) collectFrom(item);
|
|
1377
|
+
return properties;
|
|
1378
|
+
}
|
|
1379
|
+
/**
|
|
1380
|
+
* Enriches union members that declare `required` properties without declaring corresponding
|
|
1381
|
+
* property schemas, populating the missing property definitions from available sibling schemas
|
|
1382
|
+
* (or an empty schema falling back to the configured emptySchemaType).
|
|
1383
|
+
*/
|
|
1384
|
+
function resolveUnionMembers(members, siblingProperties) {
|
|
1385
|
+
return members.map((member) => {
|
|
1386
|
+
if (!member || typeof member !== "object" || isReference(member)) return member;
|
|
1387
|
+
const obj = member;
|
|
1388
|
+
if (!Array.isArray(obj.required) || obj.required.length === 0) return member;
|
|
1389
|
+
const existingProps = obj.properties ?? {};
|
|
1390
|
+
const missingKeys = obj.required.filter((key) => !Object.prototype.hasOwnProperty.call(existingProps, key));
|
|
1391
|
+
if (missingKeys.length === 0) return member;
|
|
1392
|
+
const newProperties = { ...existingProps };
|
|
1393
|
+
for (const key of missingKeys) {
|
|
1394
|
+
const value = Object.prototype.hasOwnProperty.call(siblingProperties, key) ? siblingProperties[key] : {};
|
|
1395
|
+
Object.defineProperty(newProperties, key, {
|
|
1396
|
+
value,
|
|
1397
|
+
enumerable: true,
|
|
1398
|
+
writable: true,
|
|
1399
|
+
configurable: true
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1402
|
+
return {
|
|
1403
|
+
type: obj.type ?? "object",
|
|
1404
|
+
...obj,
|
|
1405
|
+
properties: newProperties
|
|
1406
|
+
};
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* Enriches any `oneOf` or `anyOf` branches on a schema object with properties from sibling schemas.
|
|
1411
|
+
*/
|
|
1412
|
+
function resolveUnionSchema(schema, siblingProperties) {
|
|
1413
|
+
if (!schema.oneOf && !schema.anyOf) return schema;
|
|
1414
|
+
const next = { ...resolveUnionMembers([schema], siblingProperties)[0] ?? schema };
|
|
1415
|
+
if (schema.oneOf) next.oneOf = resolveUnionMembers(schema.oneOf, siblingProperties);
|
|
1416
|
+
if (schema.anyOf) next.anyOf = resolveUnionMembers(schema.anyOf, siblingProperties);
|
|
1417
|
+
return next;
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1361
1420
|
* Converts a `$ref` schema into a `RefSchemaNode`.
|
|
1362
1421
|
*
|
|
1363
1422
|
* The resolved schema is stored in `node.schema`. Usage-site sibling fields
|
|
@@ -1365,9 +1424,9 @@ function convertAnnotatedEnum(context) {
|
|
|
1365
1424
|
* Use `syncSchemaRef(node)` in printers to get a merged view of both.
|
|
1366
1425
|
* Circular refs are detected in `refs.resolveNode` and leave `schema` as `null`.
|
|
1367
1426
|
*/
|
|
1368
|
-
function convertRef({ schema, name, nullable, defaultValue,
|
|
1427
|
+
function convertRef({ schema, name, nullable, defaultValue, document, parse, refs, renames }) {
|
|
1369
1428
|
const refPath = schema.$ref;
|
|
1370
|
-
const resolvedSchema = refPath ? refs.resolveNode(refPath, parse
|
|
1429
|
+
const resolvedSchema = refPath ? refs.resolveNode(refPath, parse) : null;
|
|
1371
1430
|
const ctx = {
|
|
1372
1431
|
schema,
|
|
1373
1432
|
name,
|
|
@@ -1387,17 +1446,17 @@ function convertRef({ schema, name, nullable, defaultValue, rawOptions, document
|
|
|
1387
1446
|
/**
|
|
1388
1447
|
* Converts an `allOf` schema into a flattened node or an `IntersectionSchemaNode`.
|
|
1389
1448
|
*/
|
|
1390
|
-
function convertAllOf({ schema, name, nullable, defaultValue,
|
|
1449
|
+
function convertAllOf({ schema, name, nullable, defaultValue, parse, refs }) {
|
|
1391
1450
|
if (schema.allOf.length === 1 && !schema.properties && !(Array.isArray(schema.required) && schema.required.length) && schema.additionalProperties === void 0) {
|
|
1392
1451
|
const [memberSchema] = schema.allOf;
|
|
1393
1452
|
const memberNode = parse({
|
|
1394
1453
|
schema: memberSchema,
|
|
1395
1454
|
name
|
|
1396
|
-
}
|
|
1455
|
+
});
|
|
1397
1456
|
const { kind: _kind, ...memberNodeProps } = memberNode;
|
|
1398
1457
|
const mergedNullable = nullable || memberNode.nullable || void 0;
|
|
1399
1458
|
const mergedDefault = schema.default === null && mergedNullable ? void 0 : schema.default ?? memberNode.default;
|
|
1400
|
-
return
|
|
1459
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
1401
1460
|
...memberNodeProps,
|
|
1402
1461
|
name,
|
|
1403
1462
|
title: schema.title ?? memberNode.title,
|
|
@@ -1417,10 +1476,11 @@ function convertAllOf({ schema, name, nullable, defaultValue, rawOptions, parse,
|
|
|
1417
1476
|
name,
|
|
1418
1477
|
refs
|
|
1419
1478
|
});
|
|
1420
|
-
const
|
|
1479
|
+
const siblingProperties = collectSiblingProperties(schema.allOf, refs, schema.properties);
|
|
1480
|
+
const allOfMembers = discriminatedAllOf.map((s) => isReference(s) ? s : resolveUnionSchema(s, siblingProperties)).map((s) => parse({
|
|
1421
1481
|
schema: s,
|
|
1422
1482
|
name
|
|
1423
|
-
}
|
|
1483
|
+
}));
|
|
1424
1484
|
const syntheticStart = allOfMembers.length;
|
|
1425
1485
|
if (Array.isArray(schema.required) && schema.required.length) {
|
|
1426
1486
|
const outerKeys = schema.properties ? new Set(Object.keys(schema.properties)) : /* @__PURE__ */ new Set();
|
|
@@ -1441,7 +1501,7 @@ function convertAllOf({ schema, name, nullable, defaultValue, rawOptions, parse,
|
|
|
1441
1501
|
allOfMembers.push(parse({
|
|
1442
1502
|
schema: memberSchema,
|
|
1443
1503
|
name
|
|
1444
|
-
}
|
|
1504
|
+
}));
|
|
1445
1505
|
break;
|
|
1446
1506
|
}
|
|
1447
1507
|
}
|
|
@@ -1449,7 +1509,7 @@ function convertAllOf({ schema, name, nullable, defaultValue, rawOptions, parse,
|
|
|
1449
1509
|
}
|
|
1450
1510
|
if (schema.properties) {
|
|
1451
1511
|
const { allOf: _allOf, ...schemaWithoutAllOf } = schema;
|
|
1452
|
-
allOfMembers.push(parse({ schema: schemaWithoutAllOf }
|
|
1512
|
+
allOfMembers.push(parse({ schema: schemaWithoutAllOf }));
|
|
1453
1513
|
}
|
|
1454
1514
|
for (const { propertyName, values } of discriminantValues) allOfMembers.push(createDiscriminantNode({
|
|
1455
1515
|
propertyName,
|
|
@@ -1471,14 +1531,14 @@ function convertAllOf({ schema, name, nullable, defaultValue, rawOptions, parse,
|
|
|
1471
1531
|
function convertUnion(context) {
|
|
1472
1532
|
const annotatedEnum = convertAnnotatedEnum(context);
|
|
1473
1533
|
if (annotatedEnum) return annotatedEnum;
|
|
1474
|
-
const { schema, name, nullable, defaultValue,
|
|
1534
|
+
const { schema, name, nullable, defaultValue, parse, refs } = context;
|
|
1475
1535
|
const ctx = {
|
|
1476
1536
|
schema,
|
|
1477
1537
|
name,
|
|
1478
1538
|
nullable,
|
|
1479
1539
|
defaultValue
|
|
1480
1540
|
};
|
|
1481
|
-
const unionMembers = [...schema.oneOf ?? [], ...schema.anyOf ?? []];
|
|
1541
|
+
const unionMembers = resolveUnionMembers([...schema.oneOf ?? [], ...schema.anyOf ?? []], schema.properties ?? {});
|
|
1482
1542
|
const strategy = schema.oneOf ? "one" : "any";
|
|
1483
1543
|
const explicitDiscriminatorPropertyName = isDiscriminator(schema) ? schema.discriminator.propertyName : void 0;
|
|
1484
1544
|
const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
|
|
@@ -1486,14 +1546,13 @@ function convertUnion(context) {
|
|
|
1486
1546
|
const sharedPropertiesNode = schema.properties ? parse({
|
|
1487
1547
|
schema: memberBaseSchema,
|
|
1488
1548
|
name
|
|
1489
|
-
}
|
|
1549
|
+
}) : void 0;
|
|
1490
1550
|
if (sharedPropertiesNode || discriminator) {
|
|
1491
1551
|
const members = narrowUnionMembers({
|
|
1492
1552
|
unionMembers,
|
|
1493
1553
|
discriminator,
|
|
1494
1554
|
sharedPropertiesNode,
|
|
1495
1555
|
parse,
|
|
1496
|
-
rawOptions,
|
|
1497
1556
|
name,
|
|
1498
1557
|
refs
|
|
1499
1558
|
});
|
|
@@ -1501,7 +1560,7 @@ function convertUnion(context) {
|
|
|
1501
1560
|
type: "union",
|
|
1502
1561
|
strategy,
|
|
1503
1562
|
members,
|
|
1504
|
-
discriminatorPropertyName: explicitDiscriminatorPropertyName ??
|
|
1563
|
+
discriminatorPropertyName: explicitDiscriminatorPropertyName ?? _kubb_kit.ast.inferDiscriminatorPropertyName(members)
|
|
1505
1564
|
});
|
|
1506
1565
|
if (!sharedPropertiesNode) return unionNode;
|
|
1507
1566
|
return createNode(ctx, {
|
|
@@ -1512,14 +1571,14 @@ function convertUnion(context) {
|
|
|
1512
1571
|
const members = unionMembers.map((s) => parse({
|
|
1513
1572
|
schema: s,
|
|
1514
1573
|
name
|
|
1515
|
-
}
|
|
1574
|
+
}));
|
|
1516
1575
|
const unionNode = createNode(ctx, {
|
|
1517
1576
|
type: "union",
|
|
1518
1577
|
strategy,
|
|
1519
1578
|
members,
|
|
1520
|
-
discriminatorPropertyName: explicitDiscriminatorPropertyName ??
|
|
1579
|
+
discriminatorPropertyName: explicitDiscriminatorPropertyName ?? _kubb_kit.ast.inferDiscriminatorPropertyName(members)
|
|
1521
1580
|
});
|
|
1522
|
-
return
|
|
1581
|
+
return _kubb_kit.ast.applyMacros(unionNode, [_kubb_kit.macroSimplifyUnion], { depth: "shallow" });
|
|
1523
1582
|
}
|
|
1524
1583
|
/**
|
|
1525
1584
|
* Converts an OAS 3.1 multi-type array (e.g. `type: ['string', 'number']`) into a `UnionSchemaNode`.
|
|
@@ -1527,7 +1586,7 @@ function convertUnion(context) {
|
|
|
1527
1586
|
* remains; a single remaining type (e.g. `['string', 'null']`) is handled as that type instead,
|
|
1528
1587
|
* with nullability already folded in.
|
|
1529
1588
|
*/
|
|
1530
|
-
function convertMultiType({ schema, name, nullable, defaultValue,
|
|
1589
|
+
function convertMultiType({ schema, name, nullable, defaultValue, parse }) {
|
|
1531
1590
|
const types = schema.type;
|
|
1532
1591
|
const nonNullTypes = types.filter((t) => t !== "null");
|
|
1533
1592
|
return createNode({
|
|
@@ -1544,7 +1603,7 @@ function convertMultiType({ schema, name, nullable, defaultValue, rawOptions, pa
|
|
|
1544
1603
|
type: t
|
|
1545
1604
|
},
|
|
1546
1605
|
name
|
|
1547
|
-
}
|
|
1606
|
+
});
|
|
1548
1607
|
})
|
|
1549
1608
|
});
|
|
1550
1609
|
}
|
|
@@ -1569,12 +1628,50 @@ function normalizeArrayEnum(schema) {
|
|
|
1569
1628
|
items: normalizedItems
|
|
1570
1629
|
};
|
|
1571
1630
|
}
|
|
1631
|
+
function getPrimitiveType(type) {
|
|
1632
|
+
if (type === "number" || type === "integer" || type === "bigint") return type;
|
|
1633
|
+
if (type === "boolean") return "boolean";
|
|
1634
|
+
return "string";
|
|
1635
|
+
}
|
|
1636
|
+
/** Shared by number, integer and bigint nodes; the exclusive bounds keep only the OAS 3.1 numeric form. */
|
|
1637
|
+
function getNumericConstraints(schema) {
|
|
1638
|
+
return {
|
|
1639
|
+
min: schema.minimum,
|
|
1640
|
+
max: schema.maximum,
|
|
1641
|
+
exclusiveMinimum: typeof schema.exclusiveMinimum === "number" ? schema.exclusiveMinimum : void 0,
|
|
1642
|
+
exclusiveMaximum: typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : void 0,
|
|
1643
|
+
multipleOf: schema.multipleOf
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
function getDateType(options, format) {
|
|
1647
|
+
const value = resolveDateTypeValue(options.dateType, format);
|
|
1648
|
+
if (format !== "date-time") return {
|
|
1649
|
+
type: format,
|
|
1650
|
+
representation: value === "date" ? "date" : "string"
|
|
1651
|
+
};
|
|
1652
|
+
if (value === "date") return {
|
|
1653
|
+
type: "date",
|
|
1654
|
+
representation: "date"
|
|
1655
|
+
};
|
|
1656
|
+
if (value === "stringOffset") return {
|
|
1657
|
+
type: "datetime",
|
|
1658
|
+
offset: true
|
|
1659
|
+
};
|
|
1660
|
+
if (value === "stringLocal") return {
|
|
1661
|
+
type: "datetime",
|
|
1662
|
+
local: true
|
|
1663
|
+
};
|
|
1664
|
+
return {
|
|
1665
|
+
type: "datetime",
|
|
1666
|
+
offset: false
|
|
1667
|
+
};
|
|
1668
|
+
}
|
|
1572
1669
|
/**
|
|
1573
1670
|
* Builds a `null` scalar node carrying the schema's documentation. Shared by the `const: null`
|
|
1574
1671
|
* and the drf-spectacular `NullEnum` (`{ enum: [null] }`) branches, which render identically.
|
|
1575
1672
|
*/
|
|
1576
1673
|
function createNullNode(schema, name, nullable) {
|
|
1577
|
-
return
|
|
1674
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
1578
1675
|
type: "null",
|
|
1579
1676
|
primitive: "null",
|
|
1580
1677
|
name,
|
|
@@ -1588,22 +1685,13 @@ function createNullNode(schema, name, nullable) {
|
|
|
1588
1685
|
/**
|
|
1589
1686
|
* Converts an OAS 3.1 `const` schema into a null scalar or a single-value `EnumSchemaNode`.
|
|
1590
1687
|
*/
|
|
1591
|
-
function convertConst(
|
|
1688
|
+
function convertConst(context) {
|
|
1689
|
+
const { schema, name } = context;
|
|
1592
1690
|
const constValue = schema.const;
|
|
1593
1691
|
if (constValue === null) return createNullNode(schema, name);
|
|
1594
|
-
|
|
1595
|
-
if (typeof constValue === "number") return "number";
|
|
1596
|
-
if (typeof constValue === "boolean") return "boolean";
|
|
1597
|
-
return "string";
|
|
1598
|
-
})());
|
|
1599
|
-
return createNode({
|
|
1600
|
-
schema,
|
|
1601
|
-
name,
|
|
1602
|
-
nullable,
|
|
1603
|
-
defaultValue
|
|
1604
|
-
}, {
|
|
1692
|
+
return createNode(context, {
|
|
1605
1693
|
type: "enum",
|
|
1606
|
-
primitive:
|
|
1694
|
+
primitive: getPrimitiveType(typeof constValue),
|
|
1607
1695
|
enumValues: [constValue]
|
|
1608
1696
|
});
|
|
1609
1697
|
}
|
|
@@ -1613,36 +1701,30 @@ function convertConst({ schema, name, nullable, defaultValue }) {
|
|
|
1613
1701
|
* a date-ish format, that `dateType` is not `false`.
|
|
1614
1702
|
*/
|
|
1615
1703
|
function convertFormat(context) {
|
|
1616
|
-
const { schema,
|
|
1617
|
-
const ctx = {
|
|
1618
|
-
schema,
|
|
1619
|
-
name,
|
|
1620
|
-
nullable,
|
|
1621
|
-
defaultValue
|
|
1622
|
-
};
|
|
1704
|
+
const { schema, options, type } = context;
|
|
1623
1705
|
if (type === "string" && numericFormats.has(schema.format)) return convertString(context);
|
|
1624
|
-
if (schema.format === "int64" || schema.format === "uint64") return createNode(
|
|
1706
|
+
if (schema.format === "int64" || schema.format === "uint64") return createNode(context, {
|
|
1625
1707
|
type: options.integerType === "bigint" ? "bigint" : "integer",
|
|
1626
1708
|
primitive: "integer",
|
|
1627
1709
|
...getNumericConstraints(schema)
|
|
1628
1710
|
});
|
|
1629
1711
|
if (schema.format === "date-time" || schema.format === "date" || schema.format === "time") {
|
|
1630
1712
|
const dateType = getDateType(options, schema.format);
|
|
1631
|
-
if (dateType.type === "datetime") return createNode(
|
|
1713
|
+
if (dateType.type === "datetime") return createNode(context, {
|
|
1632
1714
|
primitive: "string",
|
|
1633
1715
|
type: "datetime",
|
|
1634
1716
|
offset: dateType.offset,
|
|
1635
1717
|
local: dateType.local
|
|
1636
1718
|
});
|
|
1637
|
-
return createNode(
|
|
1719
|
+
return createNode(context, {
|
|
1638
1720
|
primitive: "string",
|
|
1639
1721
|
type: dateType.type,
|
|
1640
1722
|
representation: dateType.representation
|
|
1641
1723
|
});
|
|
1642
1724
|
}
|
|
1643
|
-
const specialType =
|
|
1644
|
-
const isNumeric = specialType === "number" || specialType === "integer"
|
|
1645
|
-
return createNode(
|
|
1725
|
+
const specialType = formatMap[schema.format];
|
|
1726
|
+
const isNumeric = specialType === "number" || specialType === "integer";
|
|
1727
|
+
return createNode(context, {
|
|
1646
1728
|
primitive: isNumeric ? specialType : "string",
|
|
1647
1729
|
type: specialType,
|
|
1648
1730
|
...specialType === "url" || specialType === "uuid" || specialType === "email" ? {
|
|
@@ -1655,11 +1737,11 @@ function convertFormat(context) {
|
|
|
1655
1737
|
/**
|
|
1656
1738
|
* Converts an `enum` schema into an `EnumSchemaNode`.
|
|
1657
1739
|
*/
|
|
1658
|
-
function convertEnum({ schema, name, nullable, type,
|
|
1740
|
+
function convertEnum({ schema, name, nullable, type, parse }) {
|
|
1659
1741
|
if (type === "array") return parse({
|
|
1660
1742
|
schema: normalizeArrayEnum(schema),
|
|
1661
1743
|
name
|
|
1662
|
-
}
|
|
1744
|
+
});
|
|
1663
1745
|
const nullInEnum = schema.enum.includes(null);
|
|
1664
1746
|
const filteredValues = nullInEnum ? schema.enum.filter((v) => v !== null) : schema.enum;
|
|
1665
1747
|
if (nullInEnum && filteredValues.length === 0) return createNullNode(schema, name);
|
|
@@ -1711,13 +1793,9 @@ function convertEnum({ schema, name, nullable, type, rawOptions, parse }) {
|
|
|
1711
1793
|
/**
|
|
1712
1794
|
* Converts a `type: 'string'` schema into a `StringSchemaNode`.
|
|
1713
1795
|
*/
|
|
1714
|
-
function convertString(
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
name,
|
|
1718
|
-
nullable,
|
|
1719
|
-
defaultValue
|
|
1720
|
-
}, {
|
|
1796
|
+
function convertString(context) {
|
|
1797
|
+
const { schema } = context;
|
|
1798
|
+
return createNode(context, {
|
|
1721
1799
|
type: "string",
|
|
1722
1800
|
primitive: "string",
|
|
1723
1801
|
min: schema.minLength,
|
|
@@ -1726,58 +1804,13 @@ function convertString({ schema, name, nullable, defaultValue }) {
|
|
|
1726
1804
|
});
|
|
1727
1805
|
}
|
|
1728
1806
|
/**
|
|
1729
|
-
* Reads the numeric constraints shared by every `number`, `integer` and `bigint` node. A `format`
|
|
1730
|
-
* such as `double` or `int32` only narrows the type, so formatted numbers keep these too.
|
|
1731
|
-
*/
|
|
1732
|
-
function getNumericConstraints(schema) {
|
|
1733
|
-
return {
|
|
1734
|
-
min: schema.minimum,
|
|
1735
|
-
max: schema.maximum,
|
|
1736
|
-
...getExclusiveBounds(schema),
|
|
1737
|
-
multipleOf: schema.multipleOf
|
|
1738
|
-
};
|
|
1739
|
-
}
|
|
1740
|
-
/**
|
|
1741
1807
|
* Converts a `type: 'number'` or `type: 'integer'` schema.
|
|
1742
1808
|
*/
|
|
1743
|
-
function convertNumeric(
|
|
1744
|
-
return createNode({
|
|
1745
|
-
schema,
|
|
1746
|
-
name,
|
|
1747
|
-
nullable,
|
|
1748
|
-
defaultValue
|
|
1749
|
-
}, {
|
|
1809
|
+
function convertNumeric(context, type) {
|
|
1810
|
+
return createNode(context, {
|
|
1750
1811
|
type,
|
|
1751
1812
|
primitive: type,
|
|
1752
|
-
...getNumericConstraints(schema)
|
|
1753
|
-
});
|
|
1754
|
-
}
|
|
1755
|
-
/**
|
|
1756
|
-
* Converts a `type: 'boolean'` schema.
|
|
1757
|
-
*/
|
|
1758
|
-
function convertBoolean({ schema, name, nullable, defaultValue }) {
|
|
1759
|
-
return createNode({
|
|
1760
|
-
schema,
|
|
1761
|
-
name,
|
|
1762
|
-
nullable,
|
|
1763
|
-
defaultValue
|
|
1764
|
-
}, {
|
|
1765
|
-
type: "boolean",
|
|
1766
|
-
primitive: "boolean"
|
|
1767
|
-
});
|
|
1768
|
-
}
|
|
1769
|
-
/**
|
|
1770
|
-
* Converts a raw binary schema into a `blob` node.
|
|
1771
|
-
*/
|
|
1772
|
-
function convertBinary({ schema, name, nullable, defaultValue }) {
|
|
1773
|
-
return createNode({
|
|
1774
|
-
schema,
|
|
1775
|
-
name,
|
|
1776
|
-
nullable,
|
|
1777
|
-
defaultValue
|
|
1778
|
-
}, {
|
|
1779
|
-
type: "blob",
|
|
1780
|
-
primitive: "string"
|
|
1813
|
+
...getNumericConstraints(context.schema)
|
|
1781
1814
|
});
|
|
1782
1815
|
}
|
|
1783
1816
|
//#endregion
|
|
@@ -1786,9 +1819,9 @@ function convertBinary({ schema, name, nullable, defaultValue }) {
|
|
|
1786
1819
|
* Resolves a `true` or empty-object map schema (`additionalProperties`/`patternProperties`) to
|
|
1787
1820
|
* `options.unknownType`, otherwise parses it as a regular schema.
|
|
1788
1821
|
*/
|
|
1789
|
-
function resolveMapSchema(mapSchema, options, parse
|
|
1790
|
-
if (mapSchema === true || typeof mapSchema === "object" && Object.keys(mapSchema).length === 0) return
|
|
1791
|
-
return parse({ schema: mapSchema }
|
|
1822
|
+
function resolveMapSchema(mapSchema, { options, parse }) {
|
|
1823
|
+
if (mapSchema === true || typeof mapSchema === "object" && Object.keys(mapSchema).length === 0) return _kubb_kit.ast.factory.createSchema({ type: options.unknownType });
|
|
1824
|
+
return parse({ schema: mapSchema });
|
|
1792
1825
|
}
|
|
1793
1826
|
/**
|
|
1794
1827
|
* Names the inline enums on a property's schema, and on each item when the property is a tuple, from
|
|
@@ -1796,10 +1829,10 @@ function resolveMapSchema(mapSchema, options, parse, rawOptions) {
|
|
|
1796
1829
|
*/
|
|
1797
1830
|
function nameEnums(node, options) {
|
|
1798
1831
|
const macro = (0, _kubb_kit.macroEnumName)(options);
|
|
1799
|
-
const named =
|
|
1800
|
-
const tupleNode =
|
|
1832
|
+
const named = _kubb_kit.ast.applyMacros(node, [macro], { depth: "shallow" });
|
|
1833
|
+
const tupleNode = _kubb_kit.ast.narrowSchema(named, "tuple");
|
|
1801
1834
|
if (tupleNode?.items) {
|
|
1802
|
-
const namedItems = tupleNode.items.map((item) =>
|
|
1835
|
+
const namedItems = tupleNode.items.map((item) => _kubb_kit.ast.applyMacros(item, [macro], { depth: "shallow" }));
|
|
1803
1836
|
if (namedItems.some((item, i) => item !== tupleNode.items[i])) return {
|
|
1804
1837
|
...tupleNode,
|
|
1805
1838
|
items: namedItems
|
|
@@ -1810,7 +1843,7 @@ function nameEnums(node, options) {
|
|
|
1810
1843
|
/**
|
|
1811
1844
|
* Converts an object-like schema into an `ObjectSchemaNode`.
|
|
1812
1845
|
*/
|
|
1813
|
-
function convertObject({ schema, name, nullable, defaultValue,
|
|
1846
|
+
function convertObject({ schema, name, nullable, defaultValue, options, parse }) {
|
|
1814
1847
|
const properties = schema.properties ? Object.entries(schema.properties).map(([propName, propSchema]) => {
|
|
1815
1848
|
const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
|
|
1816
1849
|
const resolvedPropSchema = propSchema;
|
|
@@ -1818,12 +1851,12 @@ function convertObject({ schema, name, nullable, defaultValue, rawOptions, optio
|
|
|
1818
1851
|
const schemaNode = nameEnums(parse({
|
|
1819
1852
|
schema: resolvedPropSchema,
|
|
1820
1853
|
name: (0, _kubb_kit.childName)(name, propName)
|
|
1821
|
-
}
|
|
1854
|
+
}), {
|
|
1822
1855
|
parentName: name,
|
|
1823
1856
|
propName,
|
|
1824
1857
|
enumSuffix: options.enumSuffix
|
|
1825
1858
|
});
|
|
1826
|
-
return
|
|
1859
|
+
return _kubb_kit.ast.factory.createProperty({
|
|
1827
1860
|
name: propName,
|
|
1828
1861
|
schema: {
|
|
1829
1862
|
...schemaNode,
|
|
@@ -1835,11 +1868,17 @@ function convertObject({ schema, name, nullable, defaultValue, rawOptions, optio
|
|
|
1835
1868
|
const additionalProperties = schema.additionalProperties;
|
|
1836
1869
|
const additionalPropertiesNode = (() => {
|
|
1837
1870
|
if (additionalProperties === true) return true;
|
|
1838
|
-
if (additionalProperties) return resolveMapSchema(additionalProperties,
|
|
1871
|
+
if (additionalProperties) return resolveMapSchema(additionalProperties, {
|
|
1872
|
+
options,
|
|
1873
|
+
parse
|
|
1874
|
+
});
|
|
1839
1875
|
return additionalProperties;
|
|
1840
1876
|
})();
|
|
1841
1877
|
const rawPatternProperties = "patternProperties" in schema ? schema.patternProperties : void 0;
|
|
1842
|
-
const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, resolveMapSchema(patternSchema,
|
|
1878
|
+
const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, resolveMapSchema(patternSchema, {
|
|
1879
|
+
options,
|
|
1880
|
+
parse
|
|
1881
|
+
})])) : void 0;
|
|
1843
1882
|
const objectNode = createNode({
|
|
1844
1883
|
schema,
|
|
1845
1884
|
name,
|
|
@@ -1858,7 +1897,7 @@ function convertObject({ schema, name, nullable, defaultValue, rawOptions, optio
|
|
|
1858
1897
|
const discPropName = schema.discriminator.propertyName;
|
|
1859
1898
|
const values = Object.keys(schema.discriminator.mapping);
|
|
1860
1899
|
const enumName = name ? (0, _kubb_kit.enumPropName)(name, discPropName, options.enumSuffix) : void 0;
|
|
1861
|
-
return
|
|
1900
|
+
return _kubb_kit.ast.applyMacros(objectNode, [(0, _kubb_kit.macroDiscriminatorEnum)({
|
|
1862
1901
|
propertyName: discPropName,
|
|
1863
1902
|
values,
|
|
1864
1903
|
enumName
|
|
@@ -1869,9 +1908,9 @@ function convertObject({ schema, name, nullable, defaultValue, rawOptions, optio
|
|
|
1869
1908
|
/**
|
|
1870
1909
|
* Converts an OAS 3.1 `prefixItems` tuple into a `TupleSchemaNode`.
|
|
1871
1910
|
*/
|
|
1872
|
-
function convertTuple({ schema, name, nullable, defaultValue,
|
|
1873
|
-
const tupleItems = (schema.prefixItems ?? []).map((item) => parse({ schema: item }
|
|
1874
|
-
const rest = schema.items === false ? void 0 : !schema.items || schema.items === true ?
|
|
1911
|
+
function convertTuple({ schema, name, nullable, defaultValue, options, parse }) {
|
|
1912
|
+
const tupleItems = (schema.prefixItems ?? []).map((item) => parse({ schema: item }));
|
|
1913
|
+
const rest = schema.items === false ? void 0 : !schema.items || schema.items === true ? _kubb_kit.ast.factory.createSchema({ type: options.unknownType }) : parse({ schema: schema.items });
|
|
1875
1914
|
return createNode({
|
|
1876
1915
|
schema,
|
|
1877
1916
|
name,
|
|
@@ -1889,13 +1928,13 @@ function convertTuple({ schema, name, nullable, defaultValue, rawOptions, option
|
|
|
1889
1928
|
/**
|
|
1890
1929
|
* Converts a `type: 'array'` schema into an `ArraySchemaNode`.
|
|
1891
1930
|
*/
|
|
1892
|
-
function convertArray({ schema, name, nullable, defaultValue,
|
|
1931
|
+
function convertArray({ schema, name, nullable, defaultValue, options, parse }) {
|
|
1893
1932
|
const rawItems = schema.items;
|
|
1894
1933
|
const itemName = rawItems?.enum?.length && name ? (0, _kubb_kit.enumPropName)(null, name, options.enumSuffix) : name;
|
|
1895
1934
|
const items = rawItems ? [parse({
|
|
1896
1935
|
schema: rawItems,
|
|
1897
1936
|
name: itemName
|
|
1898
|
-
}
|
|
1937
|
+
})] : [];
|
|
1899
1938
|
return createNode({
|
|
1900
1939
|
schema,
|
|
1901
1940
|
name,
|
|
@@ -1954,7 +1993,10 @@ const schemaRules = [
|
|
|
1954
1993
|
},
|
|
1955
1994
|
{
|
|
1956
1995
|
match: ({ schema }) => isBinary(schema),
|
|
1957
|
-
convert:
|
|
1996
|
+
convert: (ctx) => createNode(ctx, {
|
|
1997
|
+
type: "blob",
|
|
1998
|
+
primitive: "string"
|
|
1999
|
+
})
|
|
1958
2000
|
},
|
|
1959
2001
|
{
|
|
1960
2002
|
match: ({ schema, type }) => !type && (schema.minLength !== void 0 || schema.maxLength !== void 0 || schema.pattern !== void 0),
|
|
@@ -1994,7 +2036,10 @@ const schemaRules = [
|
|
|
1994
2036
|
},
|
|
1995
2037
|
{
|
|
1996
2038
|
match: ({ type }) => type === "boolean",
|
|
1997
|
-
convert:
|
|
2039
|
+
convert: (ctx) => createNode(ctx, {
|
|
2040
|
+
type: "boolean",
|
|
2041
|
+
primitive: "boolean"
|
|
2042
|
+
})
|
|
1998
2043
|
},
|
|
1999
2044
|
{
|
|
2000
2045
|
match: ({ type }) => type === "null",
|
|
@@ -2002,95 +2047,94 @@ const schemaRules = [
|
|
|
2002
2047
|
}
|
|
2003
2048
|
];
|
|
2004
2049
|
//#endregion
|
|
2005
|
-
//#region src/
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
*
|
|
2009
|
-
*
|
|
2010
|
-
*
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
const
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
value: null
|
|
2050
|
+
//#region src/parser.ts
|
|
2051
|
+
/**
|
|
2052
|
+
* Creates the schema converter bound to one OpenAPI document: `parseSchema` dispatches each
|
|
2053
|
+
* schema through the ordered `schemaRules` table, with the parser options merged once.
|
|
2054
|
+
*
|
|
2055
|
+
* @internal
|
|
2056
|
+
*/
|
|
2057
|
+
function createSchemaParser(ctx) {
|
|
2058
|
+
const { document, refs, renames } = ctx;
|
|
2059
|
+
const options = {
|
|
2060
|
+
...DEFAULT_PARSER_OPTIONS,
|
|
2061
|
+
...ctx.options
|
|
2018
2062
|
};
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2063
|
+
function parseSchema({ schema, name }) {
|
|
2064
|
+
const flattenedSchema = flattenSchema(schema);
|
|
2065
|
+
if (flattenedSchema !== schema) return parseSchema({
|
|
2066
|
+
schema: flattenedSchema,
|
|
2067
|
+
name
|
|
2068
|
+
});
|
|
2069
|
+
const nullable = isNullable(schema) || void 0;
|
|
2070
|
+
const context = {
|
|
2071
|
+
schema,
|
|
2072
|
+
name,
|
|
2073
|
+
nullable,
|
|
2074
|
+
defaultValue: schema.default === null && nullable ? void 0 : schema.default,
|
|
2075
|
+
type: Array.isArray(schema.type) ? schema.type.find((t) => t !== "null") ?? schema.type[0] : schema.type,
|
|
2076
|
+
options,
|
|
2077
|
+
parse: parseSchema,
|
|
2078
|
+
document,
|
|
2079
|
+
refs,
|
|
2080
|
+
renames
|
|
2081
|
+
};
|
|
2082
|
+
for (const rule of schemaRules) if (rule.match(context)) return rule.convert(context);
|
|
2083
|
+
return createNode(context, { type: options.emptySchemaType });
|
|
2024
2084
|
}
|
|
2025
|
-
|
|
2026
|
-
applicable: true,
|
|
2027
|
-
value: docCache.get(pointer)
|
|
2028
|
-
};
|
|
2029
|
-
const current = pointer.split("/").filter(Boolean).map((token) => globalThis.decodeURIComponent(token).replaceAll("~1", "/").replaceAll("~0", "~")).reduce((obj, key) => obj?.[key], document);
|
|
2030
|
-
if (current) docCache.set(pointer, current);
|
|
2031
|
-
return {
|
|
2032
|
-
applicable: true,
|
|
2033
|
-
value: current ?? null
|
|
2034
|
-
};
|
|
2085
|
+
return { parseSchema };
|
|
2035
2086
|
}
|
|
2087
|
+
//#endregion
|
|
2088
|
+
//#region src/promoteEnums.ts
|
|
2036
2089
|
/**
|
|
2037
|
-
*
|
|
2038
|
-
*
|
|
2039
|
-
*
|
|
2040
|
-
* resolved, reports a `refNotFound` diagnostic into the active build and returns `null`. Outside a
|
|
2041
|
-
* build there is no sink to collect it, so it throws instead.
|
|
2042
|
-
*
|
|
2043
|
-
* @example
|
|
2044
|
-
* ```ts
|
|
2045
|
-
* resolveRef<SchemaObject>(document, '#/components/schemas/Pet')
|
|
2046
|
-
* ```
|
|
2090
|
+
* Collects inline enums to lift to the top level, keyed by the name the parser derived for them
|
|
2091
|
+
* (e.g. `PetStatusEnum`). An enum already defined as a top-level component is left as-is, and a
|
|
2092
|
+
* name that recurs maps to the first definition so each name yields one shared type.
|
|
2047
2093
|
*/
|
|
2048
|
-
function
|
|
2049
|
-
const
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2094
|
+
function collectInlineEnums(roots, topLevelNames) {
|
|
2095
|
+
const promoted = /* @__PURE__ */ new Map();
|
|
2096
|
+
for (const root of roots) {
|
|
2097
|
+
const isSchemaRoot = root.kind === "Schema";
|
|
2098
|
+
for (const node of _kubb_kit.ast.collect(root, { schema: (schemaNode) => schemaNode })) {
|
|
2099
|
+
if (node.type !== "enum" || !node.name) continue;
|
|
2100
|
+
if (isSchemaRoot && node === root) continue;
|
|
2101
|
+
if (topLevelNames.has(node.name)) continue;
|
|
2102
|
+
if (!promoted.has(node.name)) promoted.set(node.name, {
|
|
2103
|
+
...node,
|
|
2104
|
+
optional: void 0,
|
|
2105
|
+
nullish: void 0
|
|
2106
|
+
});
|
|
2061
2107
|
}
|
|
2062
|
-
}
|
|
2063
|
-
|
|
2064
|
-
return null;
|
|
2108
|
+
}
|
|
2109
|
+
return promoted;
|
|
2065
2110
|
}
|
|
2066
2111
|
/**
|
|
2067
|
-
*
|
|
2068
|
-
*
|
|
2069
|
-
* Useful for parser flows that need both dereferenced fields and pointer
|
|
2070
|
-
* identity (for naming/import purposes). Non-reference values are returned as-is.
|
|
2071
|
-
*
|
|
2072
|
-
* @example
|
|
2073
|
-
* ```ts
|
|
2074
|
-
* dereferenceWithRef(document, { $ref: '#/components/schemas/Pet' })
|
|
2075
|
-
* // { $ref: '#/components/schemas/Pet', type: 'object', properties: { ... } }
|
|
2076
|
-
* ```
|
|
2112
|
+
* Replaces every promoted inline enum in `node` with a `ref` to its lifted definition, keeping the
|
|
2113
|
+
* occurrence's usage-slot and documentation fields.
|
|
2077
2114
|
*/
|
|
2078
|
-
function
|
|
2079
|
-
if (
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2115
|
+
function refPromotedEnums(node, promoted) {
|
|
2116
|
+
if (promoted.size === 0) return node;
|
|
2117
|
+
return _kubb_kit.ast.transform(node, { schema(schemaNode) {
|
|
2118
|
+
if (schemaNode.type !== "enum" || !schemaNode.name || !promoted.has(schemaNode.name)) return void 0;
|
|
2119
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
2120
|
+
type: "ref",
|
|
2121
|
+
name: schemaNode.name,
|
|
2122
|
+
ref: `${SCHEMA_REF_PREFIX}${schemaNode.name}`,
|
|
2123
|
+
optional: schemaNode.optional,
|
|
2124
|
+
nullish: schemaNode.nullish,
|
|
2125
|
+
readOnly: schemaNode.readOnly,
|
|
2126
|
+
writeOnly: schemaNode.writeOnly,
|
|
2127
|
+
deprecated: schemaNode.deprecated,
|
|
2128
|
+
description: schemaNode.description,
|
|
2129
|
+
default: schemaNode.default,
|
|
2130
|
+
examples: schemaNode.examples
|
|
2131
|
+
});
|
|
2132
|
+
} });
|
|
2085
2133
|
}
|
|
2134
|
+
//#endregion
|
|
2135
|
+
//#region src/refs.ts
|
|
2086
2136
|
/**
|
|
2087
|
-
* Creates the `$ref` resolution service for one document.
|
|
2088
|
-
*
|
|
2089
|
-
* Replaces what used to be six overlapping resolvers (a reporting walk, a silent walk, an
|
|
2090
|
-
* existence check, and a resolve-then-parse-into-a-node step, each with its own cache) with one
|
|
2091
|
-
* pointer walk and one explicit `report` contract for a missing ref: `report: true` (the default)
|
|
2092
|
-
* reports a `refNotFound` diagnostic (or throws outside a build), `report: false` resolves to
|
|
2093
|
-
* `null` silently for a speculative lookup.
|
|
2137
|
+
* Creates the `$ref` resolution service for one document. One pointer walk backs every method.
|
|
2094
2138
|
*
|
|
2095
2139
|
* @example
|
|
2096
2140
|
* ```ts
|
|
@@ -2100,12 +2144,31 @@ function dereferenceWithRef(document, schema) {
|
|
|
2100
2144
|
* refs.exists('#/components/schemas/Pet')
|
|
2101
2145
|
* refs.resolveNode('#/components/schemas/Pet', parseSchema)
|
|
2102
2146
|
* refs.deref<ResponseObject>(operation.schema.responses?.['200'])
|
|
2147
|
+
* refs.derefKeepingRef(parameter)
|
|
2103
2148
|
* ```
|
|
2104
2149
|
*/
|
|
2105
2150
|
function createRefs(document) {
|
|
2151
|
+
const pointerCache = /* @__PURE__ */ new Map();
|
|
2106
2152
|
const resolvedNodeCache = /* @__PURE__ */ new Map();
|
|
2107
|
-
const existenceCache = /* @__PURE__ */ new Map();
|
|
2108
2153
|
const resolvingRefs = /* @__PURE__ */ new Set();
|
|
2154
|
+
function walkPointer($ref) {
|
|
2155
|
+
const trimmed = $ref.trim();
|
|
2156
|
+
if (trimmed === "" || !trimmed.startsWith("#")) return {
|
|
2157
|
+
applicable: false,
|
|
2158
|
+
value: null
|
|
2159
|
+
};
|
|
2160
|
+
const pointer = trimmed.substring(1);
|
|
2161
|
+
if (pointerCache.has(pointer)) return {
|
|
2162
|
+
applicable: true,
|
|
2163
|
+
value: pointerCache.get(pointer)
|
|
2164
|
+
};
|
|
2165
|
+
const current = pointer.split("/").filter(Boolean).map((token) => globalThis.decodeURIComponent(token).replaceAll("~1", "/").replaceAll("~0", "~")).reduce((obj, key) => obj?.[key], document);
|
|
2166
|
+
if (current) pointerCache.set(pointer, current);
|
|
2167
|
+
return {
|
|
2168
|
+
applicable: true,
|
|
2169
|
+
value: current ?? null
|
|
2170
|
+
};
|
|
2171
|
+
}
|
|
2109
2172
|
/**
|
|
2110
2173
|
* Resolves a local `#/...` JSON pointer. Returns `null` for an empty or non-local ref.
|
|
2111
2174
|
* `report: true` (default) reports a `refNotFound` diagnostic into the active build (or throws
|
|
@@ -2113,27 +2176,36 @@ function createRefs(document) {
|
|
|
2113
2176
|
* for a speculative lookup where a missing ref is not an error.
|
|
2114
2177
|
*/
|
|
2115
2178
|
function resolve(refPath, options) {
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2179
|
+
const { applicable, value } = walkPointer(refPath);
|
|
2180
|
+
if (!applicable || value || options?.report === false) return value;
|
|
2181
|
+
const diagnostic = {
|
|
2182
|
+
code: _kubb_kit.Diagnostics.code.refNotFound,
|
|
2183
|
+
severity: "error",
|
|
2184
|
+
message: `Could not find a definition for ${refPath}.`,
|
|
2185
|
+
help: "Add the schema under `components.schemas`, or fix the `$ref`. Run `kubb validate` to check the spec.",
|
|
2186
|
+
location: {
|
|
2187
|
+
kind: "schema",
|
|
2188
|
+
pointer: refPath,
|
|
2189
|
+
ref: refPath
|
|
2190
|
+
}
|
|
2191
|
+
};
|
|
2192
|
+
if (!_kubb_kit.Diagnostics.report(diagnostic)) throw new _kubb_kit.Diagnostics.Error(diagnostic);
|
|
2193
|
+
return null;
|
|
2121
2194
|
}
|
|
2122
2195
|
/**
|
|
2123
2196
|
* Returns `true` when a `$ref` path resolves to a component the document actually defines.
|
|
2124
2197
|
* A circular ref still resolves to an existing target, so this stays `true` for cycles and only
|
|
2125
|
-
* goes `false` for a `$ref` that points at a component the spec never declares.
|
|
2198
|
+
* goes `false` for a `$ref` that points at a component the spec never declares.
|
|
2126
2199
|
*/
|
|
2127
2200
|
function exists(refPath) {
|
|
2128
|
-
|
|
2129
|
-
return existenceCache.get(refPath) ?? false;
|
|
2201
|
+
return !!resolve(refPath, { report: false });
|
|
2130
2202
|
}
|
|
2131
2203
|
/**
|
|
2132
2204
|
* Resolves a `$ref` to its parsed node via `parse`, guarding against cycles and memoizing per
|
|
2133
2205
|
* instance. Returns `null` when the ref is currently being resolved (a cycle) or cannot be
|
|
2134
2206
|
* resolved (e.g. a minimal document in a unit test).
|
|
2135
2207
|
*/
|
|
2136
|
-
function resolveNode(refPath, parse
|
|
2208
|
+
function resolveNode(refPath, parse) {
|
|
2137
2209
|
if (resolvingRefs.has(refPath)) return null;
|
|
2138
2210
|
if (!resolvedNodeCache.has(refPath)) {
|
|
2139
2211
|
let resolved = null;
|
|
@@ -2141,7 +2213,7 @@ function createRefs(document) {
|
|
|
2141
2213
|
const referenced = resolve(refPath);
|
|
2142
2214
|
if (referenced) {
|
|
2143
2215
|
resolvingRefs.add(refPath);
|
|
2144
|
-
resolved = parse({ schema: referenced }
|
|
2216
|
+
resolved = parse({ schema: referenced });
|
|
2145
2217
|
resolvingRefs.delete(refPath);
|
|
2146
2218
|
}
|
|
2147
2219
|
} catch {}
|
|
@@ -2154,399 +2226,30 @@ function createRefs(document) {
|
|
|
2154
2226
|
* resolved target. Returns `null` when the value is empty, cannot be resolved, or is still a
|
|
2155
2227
|
* `$ref` after resolving (e.g. a document with no component registry). A non-`$ref` value is
|
|
2156
2228
|
* returned as-is.
|
|
2157
|
-
*
|
|
2158
|
-
* @example
|
|
2159
|
-
* ```ts
|
|
2160
|
-
* refs.deref<ResponseObject>(operation.schema.responses?.['200'])
|
|
2161
|
-
* ```
|
|
2162
2229
|
*/
|
|
2163
2230
|
function deref(value) {
|
|
2164
2231
|
if (!isReference(value)) return value ? value : null;
|
|
2165
2232
|
const resolved = resolve(value.$ref);
|
|
2166
2233
|
return resolved && !isReference(resolved) ? resolved : null;
|
|
2167
2234
|
}
|
|
2235
|
+
/** Resolves a `$ref` object but keeps the `$ref` field on the result; other values pass through. */
|
|
2236
|
+
function derefKeepingRef(value) {
|
|
2237
|
+
if (isReference(value)) return {
|
|
2238
|
+
...value,
|
|
2239
|
+
...resolve(value.$ref),
|
|
2240
|
+
$ref: value.$ref
|
|
2241
|
+
};
|
|
2242
|
+
return value;
|
|
2243
|
+
}
|
|
2168
2244
|
return {
|
|
2169
2245
|
resolve,
|
|
2170
2246
|
exists,
|
|
2171
2247
|
resolveNode,
|
|
2172
|
-
deref
|
|
2173
|
-
|
|
2174
|
-
}
|
|
2175
|
-
//#endregion
|
|
2176
|
-
//#region src/model/operations.ts
|
|
2177
|
-
/**
|
|
2178
|
-
* Returns all parameters for an operation, merging path-level and operation-level entries.
|
|
2179
|
-
* Operation-level parameters override path-level ones with the same `in:name` key.
|
|
2180
|
-
* Each `$ref` parameter is dereferenced via `dereferenceWithRef` before merging.
|
|
2181
|
-
*
|
|
2182
|
-
* @example
|
|
2183
|
-
* ```ts
|
|
2184
|
-
* getParameters({ document, operation })
|
|
2185
|
-
* // [{ name: 'petId', in: 'path', required: true, schema: { type: 'integer' } }]
|
|
2186
|
-
* ```
|
|
2187
|
-
*/
|
|
2188
|
-
function getParameters({ document, operation }) {
|
|
2189
|
-
const resolveParams = (params) => params.map((p) => dereferenceWithRef(document, p)).filter((p) => !!p && typeof p === "object" && "in" in p && "name" in p);
|
|
2190
|
-
const operationParams = resolveParams(operation.schema?.parameters || []);
|
|
2191
|
-
const pathLevelParams = resolveParams(operation.pathItem.parameters ?? []);
|
|
2192
|
-
const paramMap = /* @__PURE__ */ new Map();
|
|
2193
|
-
for (const p of pathLevelParams) if (p.name && p.in) paramMap.set(`${p.in}:${p.name}`, p);
|
|
2194
|
-
for (const p of operationParams) if (p.name && p.in) paramMap.set(`${p.in}:${p.name}`, p);
|
|
2195
|
-
return Array.from(paramMap.values());
|
|
2196
|
-
}
|
|
2197
|
-
function getResponseBody(responseBody, contentType) {
|
|
2198
|
-
if (!responseBody) return false;
|
|
2199
|
-
if (isReference(responseBody)) return false;
|
|
2200
|
-
const body = responseBody;
|
|
2201
|
-
if (!body.content) return false;
|
|
2202
|
-
if (contentType) return contentType in body.content ? [contentType, body.content[contentType]] : false;
|
|
2203
|
-
return pickContentEntry(body.content);
|
|
2204
|
-
}
|
|
2205
|
-
/**
|
|
2206
|
-
* Returns the response schema for a given operation and HTTP status code.
|
|
2207
|
-
*
|
|
2208
|
-
* Returns an empty object `{}` when no response body schema is available.
|
|
2209
|
-
*
|
|
2210
|
-
* @example
|
|
2211
|
-
* ```ts
|
|
2212
|
-
* getResponseSchema({ document, operation, refs, statusCode: 200 }) // SchemaObject
|
|
2213
|
-
* getResponseSchema({ document, operation, refs, statusCode: '4XX' }) // {}
|
|
2214
|
-
* ```
|
|
2215
|
-
*/
|
|
2216
|
-
function getResponseSchema({ document, operation, refs, statusCode, options = {} }) {
|
|
2217
|
-
const responseBody = getResponseBody(getResponseByStatusCode({
|
|
2218
|
-
operation,
|
|
2219
|
-
refs,
|
|
2220
|
-
statusCode
|
|
2221
|
-
}), options.contentType);
|
|
2222
|
-
if (responseBody === false) return {};
|
|
2223
|
-
const [mediaType, entry] = responseBody;
|
|
2224
|
-
const schema = entry.schema;
|
|
2225
|
-
const binary = getBinaryFallbackSchema(mediaType, schema);
|
|
2226
|
-
if (binary) return binary;
|
|
2227
|
-
if (!schema) return {};
|
|
2228
|
-
return dereferenceWithRef(document, schema);
|
|
2229
|
-
}
|
|
2230
|
-
/**
|
|
2231
|
-
* Returns the request body schema for an operation, or `null` when absent.
|
|
2232
|
-
*
|
|
2233
|
-
* @example
|
|
2234
|
-
* ```ts
|
|
2235
|
-
* getRequestSchema({ document, operation, refs }) // SchemaObject | null
|
|
2236
|
-
* ```
|
|
2237
|
-
*/
|
|
2238
|
-
function getRequestSchema({ document, operation, refs, options = {} }) {
|
|
2239
|
-
const requestBody = getRequestContent({
|
|
2240
|
-
operation,
|
|
2241
|
-
refs,
|
|
2242
|
-
mediaType: options.contentType
|
|
2243
|
-
});
|
|
2244
|
-
if (requestBody === false) return null;
|
|
2245
|
-
const mediaType = Array.isArray(requestBody) ? requestBody[0] : options.contentType;
|
|
2246
|
-
const schema = Array.isArray(requestBody) ? requestBody[1].schema : requestBody.schema;
|
|
2247
|
-
const binary = getBinaryFallbackSchema(mediaType, schema);
|
|
2248
|
-
if (binary) return binary;
|
|
2249
|
-
if (!schema) return null;
|
|
2250
|
-
return dereferenceWithRef(document, schema);
|
|
2251
|
-
}
|
|
2252
|
-
/**
|
|
2253
|
-
* Returns all request body content type keys for an operation, resolving a `$ref` requestBody
|
|
2254
|
-
* through `refs`.
|
|
2255
|
-
*
|
|
2256
|
-
* @example
|
|
2257
|
-
* ```ts
|
|
2258
|
-
* getRequestBodyContentTypes(operation, refs)
|
|
2259
|
-
* // ['application/json', 'multipart/form-data']
|
|
2260
|
-
* ```
|
|
2261
|
-
*/
|
|
2262
|
-
function getRequestBodyContentTypes(operation, refs) {
|
|
2263
|
-
const body = getRequestBody({
|
|
2264
|
-
operation,
|
|
2265
|
-
refs
|
|
2266
|
-
});
|
|
2267
|
-
return body?.content ? Object.keys(body.content) : [];
|
|
2268
|
-
}
|
|
2269
|
-
/**
|
|
2270
|
-
* Returns all response content type keys for an operation at a given status code, resolving the
|
|
2271
|
-
* response `$ref` through `refs`.
|
|
2272
|
-
*
|
|
2273
|
-
* @example
|
|
2274
|
-
* ```ts
|
|
2275
|
-
* getResponseBodyContentTypes(operation, refs, 200)
|
|
2276
|
-
* // ['application/json', 'application/xml']
|
|
2277
|
-
* ```
|
|
2278
|
-
*/
|
|
2279
|
-
function getResponseBodyContentTypes(operation, refs, statusCode) {
|
|
2280
|
-
const responseObj = getResponseByStatusCode({
|
|
2281
|
-
operation,
|
|
2282
|
-
refs,
|
|
2283
|
-
statusCode
|
|
2284
|
-
});
|
|
2285
|
-
if (!responseObj || typeof responseObj !== "object" || isReference(responseObj)) return [];
|
|
2286
|
-
const body = responseObj;
|
|
2287
|
-
return body.content ? Object.keys(body.content) : [];
|
|
2288
|
-
}
|
|
2289
|
-
//#endregion
|
|
2290
|
-
//#region src/parser.ts
|
|
2291
|
-
/**
|
|
2292
|
-
* Creates the schema and operation converters bound to one OpenAPI document.
|
|
2293
|
-
*
|
|
2294
|
-
* Takes the `$ref` service for this document (shared with the rest of the pipeline, see
|
|
2295
|
-
* `adapter.ts`) and owns the `parseSchema` recursion seam, then dispatches each schema through
|
|
2296
|
-
* the ordered `schemaRules` table from `emit/parseSchema.ts`. Every converter is a standalone
|
|
2297
|
-
* function that recurses through the `parse` function passed to it, so this file only wires
|
|
2298
|
-
* state to the converters.
|
|
2299
|
-
*
|
|
2300
|
-
* @internal
|
|
2301
|
-
*/
|
|
2302
|
-
function createSchemaParser(ctx) {
|
|
2303
|
-
const document = ctx.document;
|
|
2304
|
-
const refs = ctx.refs;
|
|
2305
|
-
/**
|
|
2306
|
-
* Converts an OAS `SchemaObject` into a `SchemaNode`.
|
|
2307
|
-
*
|
|
2308
|
-
* Builds the per-schema context, then walks the ordered {@link schemaRules} table and returns
|
|
2309
|
-
* the first converter that produces a node. When none match, falls back to the configured
|
|
2310
|
-
* `emptySchemaType`.
|
|
2311
|
-
*/
|
|
2312
|
-
function parseSchema({ schema, name }, rawOptions) {
|
|
2313
|
-
const options = {
|
|
2314
|
-
...DEFAULT_PARSER_OPTIONS,
|
|
2315
|
-
...rawOptions
|
|
2316
|
-
};
|
|
2317
|
-
const flattenedSchema = flattenSchema(schema);
|
|
2318
|
-
if (flattenedSchema && flattenedSchema !== schema) return parseSchema({
|
|
2319
|
-
schema: flattenedSchema,
|
|
2320
|
-
name
|
|
2321
|
-
}, rawOptions);
|
|
2322
|
-
const nullable = isNullable(schema) || void 0;
|
|
2323
|
-
const context = {
|
|
2324
|
-
schema,
|
|
2325
|
-
name,
|
|
2326
|
-
nullable,
|
|
2327
|
-
defaultValue: schema.default === null && nullable ? void 0 : schema.default,
|
|
2328
|
-
type: Array.isArray(schema.type) ? schema.type.find((t) => t !== "null") ?? schema.type[0] : schema.type,
|
|
2329
|
-
rawOptions,
|
|
2330
|
-
options,
|
|
2331
|
-
parse: parseSchema,
|
|
2332
|
-
document,
|
|
2333
|
-
refs,
|
|
2334
|
-
renames: ctx.renames
|
|
2335
|
-
};
|
|
2336
|
-
for (const rule of schemaRules) if (rule.match(context)) return rule.convert(context);
|
|
2337
|
-
const emptyType = options.emptySchemaType;
|
|
2338
|
-
return _kubb_ast.ast.factory.createSchema({
|
|
2339
|
-
type: emptyType,
|
|
2340
|
-
name,
|
|
2341
|
-
title: schema.title,
|
|
2342
|
-
description: schema.description,
|
|
2343
|
-
format: schema.format
|
|
2344
|
-
});
|
|
2345
|
-
}
|
|
2346
|
-
/**
|
|
2347
|
-
* Converts a dereferenced OAS parameter object into a `ParameterNode`.
|
|
2348
|
-
*/
|
|
2349
|
-
function parseParameter(options, param, parentName) {
|
|
2350
|
-
const required = param["required"] ?? false;
|
|
2351
|
-
const paramName = param["name"];
|
|
2352
|
-
const schemaName = parentName && paramName ? pascalCase(`${parentName} ${paramName}`) : void 0;
|
|
2353
|
-
const schema = param["schema"] ? parseSchema({
|
|
2354
|
-
schema: param["schema"],
|
|
2355
|
-
name: schemaName
|
|
2356
|
-
}, options) : _kubb_ast.ast.factory.createSchema({ type: options.unknownType });
|
|
2357
|
-
const style = param["style"];
|
|
2358
|
-
const explode = param["explode"];
|
|
2359
|
-
return _kubb_ast.ast.factory.createParameter({
|
|
2360
|
-
name: paramName,
|
|
2361
|
-
in: param["in"],
|
|
2362
|
-
schema: {
|
|
2363
|
-
...schema,
|
|
2364
|
-
description: param["description"] ?? schema.description
|
|
2365
|
-
},
|
|
2366
|
-
required,
|
|
2367
|
-
...style !== void 0 ? { style } : {},
|
|
2368
|
-
...explode !== void 0 ? { explode } : {}
|
|
2369
|
-
});
|
|
2370
|
-
}
|
|
2371
|
-
/**
|
|
2372
|
-
* Reads the inline `requestBody` metadata (description / required) that OAS exposes
|
|
2373
|
-
* outside the schema itself, resolving a `$ref` requestBody through `refs`. Returns an
|
|
2374
|
-
* empty object when the request body is missing or cannot be resolved.
|
|
2375
|
-
*/
|
|
2376
|
-
function getRequestBodyMeta(operation) {
|
|
2377
|
-
const body = getRequestBody({
|
|
2378
|
-
operation,
|
|
2379
|
-
refs
|
|
2380
|
-
});
|
|
2381
|
-
if (!body) return { required: false };
|
|
2382
|
-
return {
|
|
2383
|
-
description: body.description,
|
|
2384
|
-
required: body.required === true
|
|
2385
|
-
};
|
|
2386
|
-
}
|
|
2387
|
-
/**
|
|
2388
|
-
* Collects property names whose schema has a truthy boolean flag (`readOnly` or `writeOnly`).
|
|
2389
|
-
* `$ref` entries are skipped since their flags live on the dereferenced target.
|
|
2390
|
-
*/
|
|
2391
|
-
function collectPropertyKeysByFlag(schema, flag) {
|
|
2392
|
-
if (!schema?.properties) return null;
|
|
2393
|
-
const keys = [];
|
|
2394
|
-
for (const key in schema.properties) {
|
|
2395
|
-
const prop = schema.properties[key];
|
|
2396
|
-
if (prop && !isReference(prop) && prop[flag]) keys.push(key);
|
|
2397
|
-
}
|
|
2398
|
-
return keys.length ? keys : null;
|
|
2399
|
-
}
|
|
2400
|
-
/**
|
|
2401
|
-
* Converts an OAS `Operation` into an `OperationNode`.
|
|
2402
|
-
*/
|
|
2403
|
-
function parseOperation(options, operation) {
|
|
2404
|
-
const operationId = getOperationId(operation);
|
|
2405
|
-
const operationName = operationId ? pascalCase(operationId) : void 0;
|
|
2406
|
-
const parameters = getParameters({
|
|
2407
|
-
document,
|
|
2408
|
-
operation
|
|
2409
|
-
}).map((param) => parseParameter(options, param, operationName));
|
|
2410
|
-
const allContentTypes = ctx.contentType ? [ctx.contentType] : getRequestBodyContentTypes(operation, refs);
|
|
2411
|
-
const requestBodyMeta = getRequestBodyMeta(operation);
|
|
2412
|
-
const requestBodyName = operationName ? `${operationName}Request` : void 0;
|
|
2413
|
-
const content = allContentTypes.flatMap((ct) => {
|
|
2414
|
-
const schema = getRequestSchema({
|
|
2415
|
-
document,
|
|
2416
|
-
operation,
|
|
2417
|
-
refs,
|
|
2418
|
-
options: { contentType: ct }
|
|
2419
|
-
});
|
|
2420
|
-
if (!schema) return [];
|
|
2421
|
-
return [_kubb_ast.ast.factory.createContent({
|
|
2422
|
-
contentType: ct,
|
|
2423
|
-
schema: _kubb_ast.ast.optionality(parseSchema({
|
|
2424
|
-
schema,
|
|
2425
|
-
name: requestBodyName
|
|
2426
|
-
}, options), requestBodyMeta.required),
|
|
2427
|
-
keysToOmit: collectPropertyKeysByFlag(schema, "readOnly")
|
|
2428
|
-
})];
|
|
2429
|
-
});
|
|
2430
|
-
const requestBody = content.length > 0 || requestBodyMeta.description ? {
|
|
2431
|
-
description: requestBodyMeta.description,
|
|
2432
|
-
required: requestBodyMeta.required || void 0,
|
|
2433
|
-
content: content.length > 0 ? content : void 0
|
|
2434
|
-
} : void 0;
|
|
2435
|
-
const responses = getResponseStatusCodes(operation).map((statusCode) => {
|
|
2436
|
-
const responseObj = getResponseByStatusCode({
|
|
2437
|
-
operation,
|
|
2438
|
-
refs,
|
|
2439
|
-
statusCode
|
|
2440
|
-
});
|
|
2441
|
-
const responseName = operationName ? `${operationName}Status${statusCode}` : void 0;
|
|
2442
|
-
const description = typeof responseObj === "object" && responseObj !== null ? responseObj.description : void 0;
|
|
2443
|
-
const parseEntrySchema = (contentType) => {
|
|
2444
|
-
const raw = getResponseSchema({
|
|
2445
|
-
document,
|
|
2446
|
-
operation,
|
|
2447
|
-
refs,
|
|
2448
|
-
statusCode,
|
|
2449
|
-
options: { contentType }
|
|
2450
|
-
});
|
|
2451
|
-
return {
|
|
2452
|
-
schema: raw && Object.keys(raw).length > 0 ? parseSchema({
|
|
2453
|
-
schema: raw,
|
|
2454
|
-
name: responseName
|
|
2455
|
-
}, options) : _kubb_ast.ast.factory.createSchema({ type: options.emptySchemaType }),
|
|
2456
|
-
keysToOmit: collectPropertyKeysByFlag(raw, "writeOnly")
|
|
2457
|
-
};
|
|
2458
|
-
};
|
|
2459
|
-
const content = (ctx.contentType ? [ctx.contentType] : getResponseBodyContentTypes(operation, refs, statusCode)).map((contentType) => _kubb_ast.ast.factory.createContent({
|
|
2460
|
-
contentType,
|
|
2461
|
-
...parseEntrySchema(contentType)
|
|
2462
|
-
}));
|
|
2463
|
-
if (content.length === 0) content.push(_kubb_ast.ast.factory.createContent({
|
|
2464
|
-
contentType: getRequestContentType({
|
|
2465
|
-
operation,
|
|
2466
|
-
refs
|
|
2467
|
-
}) || "application/json",
|
|
2468
|
-
...parseEntrySchema(ctx.contentType)
|
|
2469
|
-
}));
|
|
2470
|
-
return _kubb_ast.ast.factory.createResponse({
|
|
2471
|
-
statusCode,
|
|
2472
|
-
description,
|
|
2473
|
-
content
|
|
2474
|
-
});
|
|
2475
|
-
});
|
|
2476
|
-
const pickDoc = (key) => {
|
|
2477
|
-
const own = operation.schema[key];
|
|
2478
|
-
if (typeof own === "string") return own;
|
|
2479
|
-
const fallback = operation.pathItem[key];
|
|
2480
|
-
return typeof fallback === "string" ? fallback : void 0;
|
|
2481
|
-
};
|
|
2482
|
-
return _kubb_ast.ast.factory.createOperation({
|
|
2483
|
-
operationId,
|
|
2484
|
-
protocol: "http",
|
|
2485
|
-
method: operation.method.toUpperCase(),
|
|
2486
|
-
path: operation.path,
|
|
2487
|
-
tags: Array.isArray(operation.schema.tags) ? operation.schema.tags.map(String) : [],
|
|
2488
|
-
summary: pickDoc("summary") || void 0,
|
|
2489
|
-
description: pickDoc("description") || void 0,
|
|
2490
|
-
deprecated: operation.schema.deprecated || void 0,
|
|
2491
|
-
parameters,
|
|
2492
|
-
requestBody,
|
|
2493
|
-
responses
|
|
2494
|
-
});
|
|
2495
|
-
}
|
|
2496
|
-
return {
|
|
2497
|
-
parseSchema,
|
|
2498
|
-
parseOperation,
|
|
2499
|
-
parseParameter
|
|
2248
|
+
deref,
|
|
2249
|
+
derefKeepingRef
|
|
2500
2250
|
};
|
|
2501
2251
|
}
|
|
2502
2252
|
//#endregion
|
|
2503
|
-
//#region src/promoteEnums.ts
|
|
2504
|
-
/**
|
|
2505
|
-
* Collects inline enums to lift to the top level, keyed by the name the parser derived for them
|
|
2506
|
-
* (e.g. `PetStatusEnum`). An enum already defined as a top-level component is left as-is, and a
|
|
2507
|
-
* name that recurs maps to the first definition so each name yields one shared type.
|
|
2508
|
-
*/
|
|
2509
|
-
function collectInlineEnums(roots, topLevelNames) {
|
|
2510
|
-
const promoted = /* @__PURE__ */ new Map();
|
|
2511
|
-
for (const root of roots) {
|
|
2512
|
-
const isSchemaRoot = root.kind === "Schema";
|
|
2513
|
-
for (const node of _kubb_ast.ast.collect(root, { schema: (schemaNode) => schemaNode })) {
|
|
2514
|
-
if (node.type !== "enum" || !node.name) continue;
|
|
2515
|
-
if (isSchemaRoot && node === root) continue;
|
|
2516
|
-
if (topLevelNames.has(node.name)) continue;
|
|
2517
|
-
if (!promoted.has(node.name)) promoted.set(node.name, {
|
|
2518
|
-
...node,
|
|
2519
|
-
optional: void 0,
|
|
2520
|
-
nullish: void 0
|
|
2521
|
-
});
|
|
2522
|
-
}
|
|
2523
|
-
}
|
|
2524
|
-
return promoted;
|
|
2525
|
-
}
|
|
2526
|
-
/**
|
|
2527
|
-
* Replaces every promoted inline enum in `node` with a `ref` to its lifted definition, keeping the
|
|
2528
|
-
* occurrence's usage-slot and documentation fields.
|
|
2529
|
-
*/
|
|
2530
|
-
function refPromotedEnums(node, promoted) {
|
|
2531
|
-
if (promoted.size === 0) return node;
|
|
2532
|
-
return _kubb_ast.ast.transform(node, { schema(schemaNode) {
|
|
2533
|
-
if (schemaNode.type !== "enum" || !schemaNode.name || !promoted.has(schemaNode.name)) return void 0;
|
|
2534
|
-
return _kubb_ast.ast.factory.createSchema({
|
|
2535
|
-
type: "ref",
|
|
2536
|
-
name: schemaNode.name,
|
|
2537
|
-
ref: `${SCHEMA_REF_PREFIX}${schemaNode.name}`,
|
|
2538
|
-
optional: schemaNode.optional,
|
|
2539
|
-
nullish: schemaNode.nullish,
|
|
2540
|
-
readOnly: schemaNode.readOnly,
|
|
2541
|
-
writeOnly: schemaNode.writeOnly,
|
|
2542
|
-
deprecated: schemaNode.deprecated,
|
|
2543
|
-
description: schemaNode.description,
|
|
2544
|
-
default: schemaNode.default,
|
|
2545
|
-
examples: schemaNode.examples
|
|
2546
|
-
});
|
|
2547
|
-
} });
|
|
2548
|
-
}
|
|
2549
|
-
//#endregion
|
|
2550
2253
|
//#region src/schemaDiagnostics.ts
|
|
2551
2254
|
/**
|
|
2552
2255
|
* Scans one freshly converted top-level schema in a single walk, so the post-convert pass never
|
|
@@ -2573,11 +2276,11 @@ function escapePointerToken(token) {
|
|
|
2573
2276
|
}
|
|
2574
2277
|
function visit(node, pointer, refs) {
|
|
2575
2278
|
if (node.type === "ref") {
|
|
2576
|
-
const refName =
|
|
2279
|
+
const refName = _kubb_kit.ast.resolveRefName(node);
|
|
2577
2280
|
if (refName) refs.add(refName);
|
|
2578
2281
|
}
|
|
2579
|
-
if (node.deprecated)
|
|
2580
|
-
code:
|
|
2282
|
+
if (node.deprecated) _kubb_kit.Diagnostics.report({
|
|
2283
|
+
code: _kubb_kit.Diagnostics.code.deprecated,
|
|
2581
2284
|
severity: "info",
|
|
2582
2285
|
message: "This schema is marked as deprecated.",
|
|
2583
2286
|
location: {
|
|
@@ -2585,8 +2288,8 @@ function visit(node, pointer, refs) {
|
|
|
2585
2288
|
pointer
|
|
2586
2289
|
}
|
|
2587
2290
|
});
|
|
2588
|
-
if (typeof node.format === "string" && !isHandledFormat(node.format))
|
|
2589
|
-
code:
|
|
2291
|
+
if (typeof node.format === "string" && !isHandledFormat(node.format)) _kubb_kit.Diagnostics.report({
|
|
2292
|
+
code: _kubb_kit.Diagnostics.code.unsupportedFormat,
|
|
2590
2293
|
severity: "warning",
|
|
2591
2294
|
message: `Kubb does not map the format "${node.format}" to a specific type, so it falls back to the base type.`,
|
|
2592
2295
|
help: `Use a format Kubb supports, or handle "${node.format}" with a custom parser or plugin.`,
|
|
@@ -2643,20 +2346,27 @@ const adapterOasName = "oas";
|
|
|
2643
2346
|
* })
|
|
2644
2347
|
* ```
|
|
2645
2348
|
*/
|
|
2646
|
-
const adapterOas = (0,
|
|
2349
|
+
const adapterOas = (0, _kubb_kit.createAdapter)((options) => {
|
|
2647
2350
|
const { validate = true, contentType, server, discriminator = "preserve", enums = "inline", dateType = DEFAULT_PARSER_OPTIONS.dateType, integerType = DEFAULT_PARSER_OPTIONS.integerType, unknownType = DEFAULT_PARSER_OPTIONS.unknownType, enumSuffix = DEFAULT_PARSER_OPTIONS.enumSuffix, emptySchemaType = unknownType || DEFAULT_PARSER_OPTIONS.emptySchemaType } = options;
|
|
2648
2351
|
const parserOptions = {
|
|
2649
|
-
...DEFAULT_PARSER_OPTIONS,
|
|
2650
2352
|
dateType,
|
|
2651
2353
|
integerType,
|
|
2652
2354
|
unknownType,
|
|
2653
2355
|
emptySchemaType,
|
|
2654
2356
|
enumSuffix
|
|
2655
2357
|
};
|
|
2358
|
+
const resolvedOptions = {
|
|
2359
|
+
validate,
|
|
2360
|
+
contentType,
|
|
2361
|
+
server,
|
|
2362
|
+
discriminator,
|
|
2363
|
+
enums,
|
|
2364
|
+
...parserOptions
|
|
2365
|
+
};
|
|
2656
2366
|
let parsedDocument = null;
|
|
2657
2367
|
const inputCache = /* @__PURE__ */ new WeakMap();
|
|
2658
2368
|
function parseInput({ document, refs, schemas, parser }) {
|
|
2659
|
-
const { parseSchema
|
|
2369
|
+
const { parseSchema } = parser;
|
|
2660
2370
|
const parsedByName = /* @__PURE__ */ new Map();
|
|
2661
2371
|
const refAliasMap = /* @__PURE__ */ new Map();
|
|
2662
2372
|
const enumNames = [];
|
|
@@ -2666,7 +2376,7 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
|
|
|
2666
2376
|
const node = parseSchema({
|
|
2667
2377
|
schema,
|
|
2668
2378
|
name
|
|
2669
|
-
}
|
|
2379
|
+
});
|
|
2670
2380
|
parsedByName.set(name, node);
|
|
2671
2381
|
const refs = scanSchema({
|
|
2672
2382
|
node,
|
|
@@ -2674,33 +2384,35 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
|
|
|
2674
2384
|
});
|
|
2675
2385
|
if (node.name) refGraph.set(node.name, refs);
|
|
2676
2386
|
if (node.type === "ref" && node.name && node.name !== name) refAliasMap.set(name, node);
|
|
2677
|
-
if (
|
|
2387
|
+
if (_kubb_kit.ast.narrowSchema(node, "enum") && node.name) enumNames.push(node.name);
|
|
2678
2388
|
if (discriminator === "propagate" && (schema.oneOf ?? schema.anyOf) && schema.discriminator?.propertyName) discriminatorParentNodes.push(node);
|
|
2679
2389
|
}
|
|
2680
|
-
const circularNames = [...
|
|
2390
|
+
const circularNames = [..._kubb_kit.ast.findCircularSchemasFromGraph(refGraph)];
|
|
2681
2391
|
const discriminatorChildMap = discriminatorParentNodes.length > 0 ? buildDiscriminatorChildMap(discriminatorParentNodes) : null;
|
|
2682
|
-
const operationNodes =
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2392
|
+
const operationNodes = getOperations(document, refs).map((operation) => parseOperation({
|
|
2393
|
+
operation,
|
|
2394
|
+
refs,
|
|
2395
|
+
contentType,
|
|
2396
|
+
options: parserOptions,
|
|
2397
|
+
parseSchema
|
|
2398
|
+
}));
|
|
2687
2399
|
const promotedEnums = enums === "root" ? collectInlineEnums([...parsedByName.values(), ...operationNodes], new Set(Object.keys(schemas))) : null;
|
|
2688
2400
|
if (promotedEnums) for (const name of promotedEnums.keys()) enumNames.push(name);
|
|
2689
2401
|
const schemaNodes = promotedEnums ? [...promotedEnums.values()] : [];
|
|
2690
2402
|
for (const name of Object.keys(schemas)) {
|
|
2691
|
-
const
|
|
2692
|
-
const
|
|
2693
|
-
|
|
2403
|
+
const aliasTarget = refAliasMap.get(name)?.name;
|
|
2404
|
+
const aliased = aliasTarget ? parsedByName.get(aliasTarget) : void 0;
|
|
2405
|
+
const parsed = parsedByName.get(name);
|
|
2406
|
+
const child = discriminatorChildMap?.get(name);
|
|
2407
|
+
const base = child ? patchDiscriminatorNode(parsed, child) : parsed;
|
|
2408
|
+
const node = aliased ? {
|
|
2409
|
+
...aliased,
|
|
2694
2410
|
name
|
|
2695
|
-
} :
|
|
2696
|
-
const parsed = parsedByName.get(name);
|
|
2697
|
-
const child = discriminatorChildMap?.get(name);
|
|
2698
|
-
return child ? patchDiscriminatorNode(parsed, child) : parsed;
|
|
2699
|
-
})();
|
|
2411
|
+
} : base;
|
|
2700
2412
|
schemaNodes.push(promotedEnums ? refPromotedEnums(node, promotedEnums) : node);
|
|
2701
2413
|
}
|
|
2702
2414
|
const operations = promotedEnums ? operationNodes.map((node) => refPromotedEnums(node, promotedEnums)) : operationNodes;
|
|
2703
|
-
return
|
|
2415
|
+
return _kubb_kit.ast.factory.createInput({
|
|
2704
2416
|
schemas: schemaNodes,
|
|
2705
2417
|
operations,
|
|
2706
2418
|
meta: {
|
|
@@ -2718,20 +2430,7 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
|
|
|
2718
2430
|
}
|
|
2719
2431
|
return {
|
|
2720
2432
|
name: "oas",
|
|
2721
|
-
|
|
2722
|
-
return {
|
|
2723
|
-
validate,
|
|
2724
|
-
contentType,
|
|
2725
|
-
server,
|
|
2726
|
-
discriminator,
|
|
2727
|
-
enums,
|
|
2728
|
-
dateType,
|
|
2729
|
-
integerType,
|
|
2730
|
-
unknownType,
|
|
2731
|
-
emptySchemaType,
|
|
2732
|
-
enumSuffix
|
|
2733
|
-
};
|
|
2734
|
-
},
|
|
2433
|
+
options: resolvedOptions,
|
|
2735
2434
|
get document() {
|
|
2736
2435
|
return parsedDocument;
|
|
2737
2436
|
},
|
|
@@ -2760,8 +2459,8 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
|
|
|
2760
2459
|
parser: createSchemaParser({
|
|
2761
2460
|
document,
|
|
2762
2461
|
refs,
|
|
2763
|
-
|
|
2764
|
-
|
|
2462
|
+
renames,
|
|
2463
|
+
options: parserOptions
|
|
2765
2464
|
})
|
|
2766
2465
|
});
|
|
2767
2466
|
})();
|