@kubb/adapter-oas 5.17.1 → 5.18.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 +441 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -6
- package/dist/index.d.ts +22 -6
- package/dist/index.js +442 -62
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -23,6 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
let _kubb_core = require("@kubb/core");
|
|
24
24
|
let _kubb_kit = require("@kubb/kit");
|
|
25
25
|
let node_path = require("node:path");
|
|
26
|
+
let node_url = require("node:url");
|
|
26
27
|
let node_fs_promises = require("node:fs/promises");
|
|
27
28
|
let _scalar_openapi_upgrader = require("@scalar/openapi-upgrader");
|
|
28
29
|
let api_ref_bundler = require("api-ref-bundler");
|
|
@@ -35,7 +36,7 @@ var compatibility = {
|
|
|
35
36
|
"node": ">=22.22"
|
|
36
37
|
};
|
|
37
38
|
// package.json
|
|
38
|
-
var version = "5.
|
|
39
|
+
var version = "5.18.0";
|
|
39
40
|
// src/constants.ts
|
|
40
41
|
/**
|
|
41
42
|
* Default parser options applied when no explicit options are provided.
|
|
@@ -417,6 +418,21 @@ function isOpenApi32(document) {
|
|
|
417
418
|
const [major = 0, minor = 0] = String(document.openapi).split(".").map(Number);
|
|
418
419
|
return major > 3 || major === 3 && minor >= 2;
|
|
419
420
|
}
|
|
421
|
+
function pickStrings(source, keys) {
|
|
422
|
+
if (!source || typeof source !== "object") return void 0;
|
|
423
|
+
const entries = keys.flatMap((key) => {
|
|
424
|
+
const value = source[key];
|
|
425
|
+
return typeof value === "string" ? [[key, value]] : [];
|
|
426
|
+
});
|
|
427
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
428
|
+
}
|
|
429
|
+
function getExternalDocs(source) {
|
|
430
|
+
const docs = pickStrings(source, ["url", "description"]);
|
|
431
|
+
return docs?.url ? {
|
|
432
|
+
url: docs.url,
|
|
433
|
+
...docs.description !== void 0 && { description: docs.description }
|
|
434
|
+
} : void 0;
|
|
435
|
+
}
|
|
420
436
|
/**
|
|
421
437
|
* Returns the `x-*` keys of `source` as-is, or `undefined` when there are none.
|
|
422
438
|
*/
|
|
@@ -431,12 +447,12 @@ function isReference(obj) {
|
|
|
431
447
|
return !!obj && typeof obj === "object" && "$ref" in obj;
|
|
432
448
|
}
|
|
433
449
|
/**
|
|
434
|
-
* Returns `true` when `obj` is a schema with a structured OAS 3.x `discriminator` object
|
|
435
|
-
* excluding the Swagger 2 string form.
|
|
450
|
+
* Returns `true` when `obj` is a schema with a structured OAS 3.x `discriminator` object that names a
|
|
451
|
+
* `propertyName`, excluding the Swagger 2 string form and a 3.2 discriminator that only sets `defaultMapping`.
|
|
436
452
|
*/
|
|
437
453
|
function isDiscriminator(obj) {
|
|
438
|
-
const
|
|
439
|
-
return !!
|
|
454
|
+
const discriminator = obj?.["discriminator"];
|
|
455
|
+
return !!discriminator && typeof discriminator === "object" && typeof discriminator.propertyName === "string";
|
|
440
456
|
}
|
|
441
457
|
/**
|
|
442
458
|
* Returns `true` when a schema is a raw binary payload.
|
|
@@ -609,6 +625,65 @@ function createRefs(document) {
|
|
|
609
625
|
derefKeepingRef
|
|
610
626
|
};
|
|
611
627
|
}
|
|
628
|
+
// src/load/schemaIds.ts
|
|
629
|
+
const DATA_KEYS = /* @__PURE__ */ new Set([
|
|
630
|
+
"example",
|
|
631
|
+
"examples",
|
|
632
|
+
"const",
|
|
633
|
+
"enum",
|
|
634
|
+
"default"
|
|
635
|
+
]);
|
|
636
|
+
const NAMED_ENTRY_KEYS = /* @__PURE__ */ new Set([
|
|
637
|
+
"properties",
|
|
638
|
+
"patternProperties",
|
|
639
|
+
"$defs",
|
|
640
|
+
"definitions",
|
|
641
|
+
"schemas",
|
|
642
|
+
"dependentSchemas"
|
|
643
|
+
]);
|
|
644
|
+
function walk(node, pointer, visit, parentKey) {
|
|
645
|
+
if (!node || typeof node !== "object") return;
|
|
646
|
+
if (!Array.isArray(node)) visit(node, pointer);
|
|
647
|
+
const named = parentKey !== void 0 && NAMED_ENTRY_KEYS.has(parentKey);
|
|
648
|
+
for (const [key, value] of Object.entries(node)) {
|
|
649
|
+
if (!named && (DATA_KEYS.has(key) || key.startsWith("x-"))) continue;
|
|
650
|
+
walk(value, `${pointer}/${escapePointerToken(key)}`, visit, Array.isArray(node) ? parentKey : key);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* The declaration in the nearest enclosing schema, else the only one, else `undefined`.
|
|
655
|
+
*/
|
|
656
|
+
function pick(declarations, pointer) {
|
|
657
|
+
if (!declarations) return void 0;
|
|
658
|
+
const enclosing = declarations.filter((target) => pointer === target || pointer.startsWith(`${target}/`));
|
|
659
|
+
if (enclosing.length) return enclosing.reduce((a, b) => b.length > a.length ? b : a);
|
|
660
|
+
return declarations.length === 1 ? declarations[0] : void 0;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Rewrites, in place, each `$ref` to an `$id`, `$anchor` or `$dynamicAnchor`, and each `$dynamicRef`, into a
|
|
664
|
+
* `#/...` pointer, so it is not fetched. Instance data and `x-` extensions are left as written.
|
|
665
|
+
*
|
|
666
|
+
* shortcut: `$id` matches the `$ref` string exactly and `$dynamicRef` resolves statically to the nearest
|
|
667
|
+
* enclosing anchor, so a relative `$id` base or a recursively extended schema is not followed, upgrade when a spec needs that.
|
|
668
|
+
*/
|
|
669
|
+
function resolveSchemaIds(document) {
|
|
670
|
+
const targets = /* @__PURE__ */ new Map();
|
|
671
|
+
const declare = (key, pointer) => targets.set(key, [...targets.get(key) ?? [], pointer]);
|
|
672
|
+
walk(document, "#", (node, pointer) => {
|
|
673
|
+
if (typeof node["$id"] === "string") declare(node["$id"], pointer);
|
|
674
|
+
for (const key of ["$anchor", "$dynamicAnchor"]) if (typeof node[key] === "string") declare(`#${node[key]}`, pointer);
|
|
675
|
+
});
|
|
676
|
+
if (!targets.size) return;
|
|
677
|
+
walk(document, "#", (node, pointer) => {
|
|
678
|
+
const ref = typeof node["$ref"] === "string" ? pick(targets.get(node["$ref"]), pointer) : void 0;
|
|
679
|
+
if (ref) node["$ref"] = ref;
|
|
680
|
+
const dynamicRef = typeof node["$dynamicRef"] === "string" ? pick(targets.get(node["$dynamicRef"]), pointer) : void 0;
|
|
681
|
+
if (dynamicRef && node["$ref"] === void 0) {
|
|
682
|
+
node["$ref"] = dynamicRef;
|
|
683
|
+
delete node["$dynamicRef"];
|
|
684
|
+
}
|
|
685
|
+
});
|
|
686
|
+
}
|
|
612
687
|
// src/load/source.ts
|
|
613
688
|
const urlRegExp = /^https?:\/+/i;
|
|
614
689
|
/**
|
|
@@ -778,6 +853,21 @@ function isExtensionPath(path) {
|
|
|
778
853
|
return path.some((token, index) => String(token).startsWith("x-") && !namedEntryKeys.has(String(path[index - 1])));
|
|
779
854
|
}
|
|
780
855
|
/**
|
|
856
|
+
* Returns the base for relative `$ref`s: the 3.2 `$self` resolved against `pathOrUrl`, else `pathOrUrl`.
|
|
857
|
+
*/
|
|
858
|
+
function getBaseUri(pathOrUrl, root) {
|
|
859
|
+
const self = root && typeof root === "object" ? root.$self : void 0;
|
|
860
|
+
if (typeof self !== "string" || !self) return pathOrUrl;
|
|
861
|
+
try {
|
|
862
|
+
if (urlRegExp.test(self)) return new URL(self).href;
|
|
863
|
+
if (/^file:/i.test(self)) return (0, node_url.fileURLToPath)(self);
|
|
864
|
+
if (/^[a-z][a-z\d+.-]*:/i.test(self)) return pathOrUrl;
|
|
865
|
+
return urlRegExp.test(pathOrUrl) ? new URL(self, pathOrUrl).href : (0, node_path.resolve)((0, node_path.dirname)(pathOrUrl), self);
|
|
866
|
+
} catch {
|
|
867
|
+
return pathOrUrl;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
781
871
|
* Bundles a multi-file OpenAPI document into a single document via `api-ref-bundler`.
|
|
782
872
|
*
|
|
783
873
|
* External file schemas are hoisted into named `components.schemas` entries, so a property
|
|
@@ -790,8 +880,9 @@ function isExtensionPath(path) {
|
|
|
790
880
|
* all-internal document it is a no-op that still walks the whole tree to confirm that, which
|
|
791
881
|
* costs real time on a large spec.
|
|
792
882
|
*
|
|
793
|
-
* `document` stands in for the file at `pathOrUrl`, such as inline input.
|
|
794
|
-
*
|
|
883
|
+
* `document` stands in for the file at `pathOrUrl`, such as inline input. Relative `$ref`s resolve
|
|
884
|
+
* against the OpenAPI 3.2 `$self` when the document sets one. Every other file or URL read,
|
|
885
|
+
* including one that fails, lands in `sources`. A `$ref` that cannot be read reports
|
|
795
886
|
* `KUBB_REF_NOT_FOUND` at the key that holds it, as a warning when it sits inside an `x-` extension.
|
|
796
887
|
*
|
|
797
888
|
* @example Local file
|
|
@@ -803,8 +894,10 @@ function isExtensionPath(path) {
|
|
|
803
894
|
async function bundleDocument(pathOrUrl, { document, sources = [] } = {}) {
|
|
804
895
|
const cache = /* @__PURE__ */ new Map();
|
|
805
896
|
const toKey = (sourcePath) => urlRegExp.test(sourcePath) ? new URL(sourcePath).href : sourcePath;
|
|
897
|
+
let entry = pathOrUrl;
|
|
898
|
+
let entryDocument = document;
|
|
806
899
|
const resolver = (sourcePath) => {
|
|
807
|
-
if (
|
|
900
|
+
if (entryDocument !== void 0 && toKey(sourcePath) === toKey(entry)) return Promise.resolve(entryDocument);
|
|
808
901
|
const key = toKey(sourcePath);
|
|
809
902
|
const cached = cache.get(key);
|
|
810
903
|
if (cached) return cached;
|
|
@@ -814,9 +907,12 @@ async function bundleDocument(pathOrUrl, { document, sources = [] } = {}) {
|
|
|
814
907
|
return result;
|
|
815
908
|
};
|
|
816
909
|
const root = await resolver(pathOrUrl);
|
|
910
|
+
resolveSchemaIds(root);
|
|
817
911
|
if (typeof root === "object" && root !== null && !hasExternalRef(root)) return root;
|
|
818
|
-
|
|
819
|
-
|
|
912
|
+
entry = getBaseUri(pathOrUrl, root);
|
|
913
|
+
entryDocument = root;
|
|
914
|
+
return await (0, api_ref_bundler.bundle)(entry, resolver, { hooks: { onError: (message, { path, state }) => {
|
|
915
|
+
const pointer = toKey(state.baseFile) === toKey(entry) ? `#/${path.map((token) => escapePointerToken(String(token))).join("/")}` : void 0;
|
|
820
916
|
const diagnostic = {
|
|
821
917
|
code: _kubb_kit.Diagnostics.code.refNotFound,
|
|
822
918
|
severity: isExtensionPath(path) ? "warning" : "error",
|
|
@@ -855,10 +951,12 @@ async function parseFromConfig(source, sources = []) {
|
|
|
855
951
|
origin: "the inline `input` string",
|
|
856
952
|
help: "Fix the syntax at the reported line. Kubb reads `input` as an inline spec, not a file path, because it starts with `{`, `[`, `openapi:`, or `swagger:`, or spans several lines."
|
|
857
953
|
}) : structuredClone(source.data);
|
|
858
|
-
|
|
954
|
+
if (source.root && hasExternalRef(data)) return bundleDocument((0, node_path.join)(source.root, inlineInputName), {
|
|
859
955
|
document: data,
|
|
860
956
|
sources
|
|
861
|
-
})
|
|
957
|
+
});
|
|
958
|
+
resolveSchemaIds(data);
|
|
959
|
+
return data;
|
|
862
960
|
}
|
|
863
961
|
await assertInputExists(source.path);
|
|
864
962
|
return bundleDocument(source.path, { sources });
|
|
@@ -1183,6 +1281,80 @@ function getSchemas(document, { contentType }, refs) {
|
|
|
1183
1281
|
pointers
|
|
1184
1282
|
};
|
|
1185
1283
|
}
|
|
1284
|
+
// src/model/security.ts
|
|
1285
|
+
const SCHEME_POINTER = "#/components/securitySchemes/";
|
|
1286
|
+
const API_KEY_LOCATIONS = /* @__PURE__ */ new Set([
|
|
1287
|
+
"header",
|
|
1288
|
+
"query",
|
|
1289
|
+
"cookie"
|
|
1290
|
+
]);
|
|
1291
|
+
function getCredential(scheme) {
|
|
1292
|
+
if (scheme.type === "apiKey") return scheme.name && scheme.in && API_KEY_LOCATIONS.has(scheme.in) ? {
|
|
1293
|
+
type: "apiKey",
|
|
1294
|
+
in: scheme.in,
|
|
1295
|
+
name: scheme.name
|
|
1296
|
+
} : void 0;
|
|
1297
|
+
if (scheme.type === "http") return scheme.scheme ? {
|
|
1298
|
+
type: "http",
|
|
1299
|
+
scheme: scheme.scheme.toLowerCase(),
|
|
1300
|
+
...scheme.bearerFormat && { bearerFormat: scheme.bearerFormat }
|
|
1301
|
+
} : void 0;
|
|
1302
|
+
if (scheme.type === "openIdConnect") return {
|
|
1303
|
+
type: "openIdConnect",
|
|
1304
|
+
...scheme.openIdConnectUrl && { url: scheme.openIdConnectUrl }
|
|
1305
|
+
};
|
|
1306
|
+
if (scheme.type === "oauth2") {
|
|
1307
|
+
const flows = Object.entries(scheme.flows ?? {}).map(([name, flow]) => {
|
|
1308
|
+
const scopes = flow && typeof flow === "object" && flow.scopes && typeof flow.scopes === "object" ? { scopes: flow.scopes } : {};
|
|
1309
|
+
return [name, {
|
|
1310
|
+
...pickStrings(flow, [
|
|
1311
|
+
"authorizationUrl",
|
|
1312
|
+
"deviceAuthorizationUrl",
|
|
1313
|
+
"tokenUrl",
|
|
1314
|
+
"refreshUrl"
|
|
1315
|
+
]),
|
|
1316
|
+
...scopes
|
|
1317
|
+
}];
|
|
1318
|
+
});
|
|
1319
|
+
return {
|
|
1320
|
+
type: "oauth2",
|
|
1321
|
+
flows: Object.fromEntries(flows),
|
|
1322
|
+
...scheme.oauth2MetadataUrl && { metadataUrl: scheme.oauth2MetadataUrl }
|
|
1323
|
+
};
|
|
1324
|
+
}
|
|
1325
|
+
return scheme.type === "mutualTLS" ? { type: "mutualTLS" } : void 0;
|
|
1326
|
+
}
|
|
1327
|
+
/**
|
|
1328
|
+
* Maps `components.securitySchemes` to `AuthScheme` entries, leaving out a scheme a client cannot place.
|
|
1329
|
+
*/
|
|
1330
|
+
function toAuthSchemes(schemes, refs) {
|
|
1331
|
+
return Object.entries(schemes ?? {}).flatMap(([name, value]) => {
|
|
1332
|
+
const scheme = refs.deref(value);
|
|
1333
|
+
const credential = scheme && getCredential(scheme);
|
|
1334
|
+
if (!scheme || !credential) return [];
|
|
1335
|
+
return [{
|
|
1336
|
+
name,
|
|
1337
|
+
...scheme.description && { description: scheme.description },
|
|
1338
|
+
...scheme.deprecated && { deprecated: true },
|
|
1339
|
+
credential
|
|
1340
|
+
}];
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Maps security requirements to `AuthRequirement` entries. A 3.2 URI key becomes the scheme name.
|
|
1345
|
+
*/
|
|
1346
|
+
function toAuthRequirements(requirements, document) {
|
|
1347
|
+
if (!Array.isArray(requirements)) return void 0;
|
|
1348
|
+
const schemes = document.components?.securitySchemes ?? {};
|
|
1349
|
+
const toName = (key) => {
|
|
1350
|
+
const index = key.indexOf(SCHEME_POINTER);
|
|
1351
|
+
return Object.hasOwn(schemes, key) || index === -1 ? key : unescapePointerToken(key.slice(index + 29));
|
|
1352
|
+
};
|
|
1353
|
+
return requirements.filter((requirement) => !!requirement && typeof requirement === "object").map((requirement) => Object.entries(requirement).map(([key, scopes]) => ({
|
|
1354
|
+
scheme: toName(key),
|
|
1355
|
+
...Array.isArray(scopes) && scopes.length && { scopes: scopes.map(String) }
|
|
1356
|
+
})));
|
|
1357
|
+
}
|
|
1186
1358
|
// src/model/server.ts
|
|
1187
1359
|
/**
|
|
1188
1360
|
* Reads the server URL from the document's `servers` array at `server.index`,
|
|
@@ -1239,8 +1411,11 @@ function resolveServerUrl(server, overrides) {
|
|
|
1239
1411
|
* Maps OpenAPI servers to `InputServer` entries: drops entries without a `url` and fills `{variable}` defaults.
|
|
1240
1412
|
*/
|
|
1241
1413
|
function toInputServers(servers) {
|
|
1242
|
-
return servers.filter((entry) => entry.url).map(({ url, description, variables }) => {
|
|
1243
|
-
const declared =
|
|
1414
|
+
return servers.filter((entry) => entry.url).map(({ url, name, description, variables }) => {
|
|
1415
|
+
const declared = {
|
|
1416
|
+
...name !== void 0 && { name },
|
|
1417
|
+
...variables && Object.keys(variables).length > 0 && { variables }
|
|
1418
|
+
};
|
|
1244
1419
|
try {
|
|
1245
1420
|
return {
|
|
1246
1421
|
url: resolveServerUrl({
|
|
@@ -1259,6 +1434,20 @@ function toInputServers(servers) {
|
|
|
1259
1434
|
}
|
|
1260
1435
|
});
|
|
1261
1436
|
}
|
|
1437
|
+
// src/model/tag.ts
|
|
1438
|
+
function toInputTags(tags) {
|
|
1439
|
+
return tags.filter((tag) => typeof tag.name === "string").map(({ name, summary, description, parent, kind, externalDocs }) => {
|
|
1440
|
+
const docs = getExternalDocs(externalDocs);
|
|
1441
|
+
return {
|
|
1442
|
+
name,
|
|
1443
|
+
...typeof summary === "string" && { summary },
|
|
1444
|
+
...typeof description === "string" && { description },
|
|
1445
|
+
...typeof parent === "string" && { parent },
|
|
1446
|
+
...typeof kind === "string" && { kind },
|
|
1447
|
+
...docs && { externalDocs: docs }
|
|
1448
|
+
};
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1262
1451
|
// src/model/mediaType.ts
|
|
1263
1452
|
/**
|
|
1264
1453
|
* The media type without its parameters, so `text/event-stream; charset=utf-8` matches the bare name.
|
|
@@ -1616,7 +1805,8 @@ const PARAMETER_STYLES = /* @__PURE__ */ new Set([
|
|
|
1616
1805
|
"simple",
|
|
1617
1806
|
"spaceDelimited",
|
|
1618
1807
|
"pipeDelimited",
|
|
1619
|
-
"deepObject"
|
|
1808
|
+
"deepObject",
|
|
1809
|
+
"cookie"
|
|
1620
1810
|
]);
|
|
1621
1811
|
function pickStyleFields({ style, explode, allowReserved }) {
|
|
1622
1812
|
return {
|
|
@@ -1625,16 +1815,45 @@ function pickStyleFields({ style, explode, allowReserved }) {
|
|
|
1625
1815
|
...allowReserved !== void 0 ? { allowReserved } : {}
|
|
1626
1816
|
};
|
|
1627
1817
|
}
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
const node = {
|
|
1632
|
-
...contentType !== void 0 ? { contentType } : {},
|
|
1633
|
-
...pickStyleFields(rest)
|
|
1634
|
-
};
|
|
1818
|
+
function getEncodingFields({ encoding, prefixEncoding, itemEncoding }) {
|
|
1819
|
+
const entries = Object.entries(encoding ?? {}).flatMap(([property, entry]) => {
|
|
1820
|
+
const node = toEncodingNode(entry);
|
|
1635
1821
|
return Object.keys(node).length ? [[property, node]] : [];
|
|
1636
1822
|
});
|
|
1637
|
-
|
|
1823
|
+
const item = itemEncoding && toEncodingNode(itemEncoding);
|
|
1824
|
+
return {
|
|
1825
|
+
...entries.length && { encoding: Object.fromEntries(entries) },
|
|
1826
|
+
...prefixEncoding?.length && { prefixEncoding: prefixEncoding.map(toEncodingNode) },
|
|
1827
|
+
...item && Object.keys(item).length && { itemEncoding: item }
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
function toEncodingNode({ contentType, encoding, prefixEncoding, itemEncoding, ...rest }) {
|
|
1831
|
+
return {
|
|
1832
|
+
...contentType !== void 0 && { contentType },
|
|
1833
|
+
...pickStyleFields(rest),
|
|
1834
|
+
...getEncodingFields({
|
|
1835
|
+
encoding,
|
|
1836
|
+
prefixEncoding,
|
|
1837
|
+
itemEncoding
|
|
1838
|
+
})
|
|
1839
|
+
};
|
|
1840
|
+
}
|
|
1841
|
+
function getExamples({ example, examples }, refs) {
|
|
1842
|
+
const named = Object.entries(examples ?? {}).flatMap(([name, entry]) => {
|
|
1843
|
+
const resolved = refs.deref(entry);
|
|
1844
|
+
if (!resolved) return [];
|
|
1845
|
+
const { summary, description, dataValue, value, serializedValue } = resolved;
|
|
1846
|
+
const data = dataValue !== void 0 ? dataValue : value;
|
|
1847
|
+
return [{
|
|
1848
|
+
name,
|
|
1849
|
+
...typeof summary === "string" && { summary },
|
|
1850
|
+
...typeof description === "string" && { description },
|
|
1851
|
+
...data !== void 0 && { value: data },
|
|
1852
|
+
...typeof serializedValue === "string" && { serializedValue }
|
|
1853
|
+
}];
|
|
1854
|
+
});
|
|
1855
|
+
if (named.length) return { examples: named };
|
|
1856
|
+
return example !== void 0 ? { examples: [{ value: example }] } : {};
|
|
1638
1857
|
}
|
|
1639
1858
|
/**
|
|
1640
1859
|
* Returns the media type entry for `contentType`, resolving a `$ref` into `components.mediaTypes`. `null` when absent.
|
|
@@ -1663,6 +1882,24 @@ function getBodySchema({ content, contentType, refs, document }) {
|
|
|
1663
1882
|
if (binary) return binary;
|
|
1664
1883
|
return schema ? refs.derefKeepingRef(schema) : null;
|
|
1665
1884
|
}
|
|
1885
|
+
function getLinks(links, refs) {
|
|
1886
|
+
const entries = Object.entries(links ?? {}).flatMap(([name, value]) => {
|
|
1887
|
+
const link = refs.deref(value);
|
|
1888
|
+
if (!link) return [];
|
|
1889
|
+
const server = link.server ? toInputServers([link.server])[0] : void 0;
|
|
1890
|
+
return [[name, {
|
|
1891
|
+
...pickStrings(link, [
|
|
1892
|
+
"operationId",
|
|
1893
|
+
"operationRef",
|
|
1894
|
+
"description"
|
|
1895
|
+
]),
|
|
1896
|
+
...link.parameters && { parameters: link.parameters },
|
|
1897
|
+
..."requestBody" in link && { requestBody: link.requestBody },
|
|
1898
|
+
...server && { server }
|
|
1899
|
+
}]];
|
|
1900
|
+
});
|
|
1901
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
1902
|
+
}
|
|
1666
1903
|
/** The `stream` field of a content node, set when the media type is a stream. `node` is the parsed item schema. */
|
|
1667
1904
|
function getStreamField({ contentType, mediaType, refs, document, node }) {
|
|
1668
1905
|
if (!isStream(contentType, mediaType)) return {};
|
|
@@ -1733,11 +1970,12 @@ function collectPropertyKeysByFlag(schema, flag) {
|
|
|
1733
1970
|
function parseParameter({ param, pointer, parentName, options, parseSchema, refs }) {
|
|
1734
1971
|
const schemaName = parentName && param.name ? pascalCase(`${parentName} ${param.name}`) : void 0;
|
|
1735
1972
|
const contentType = param.schema ? void 0 : Object.keys(param.content ?? {})[0];
|
|
1736
|
-
const
|
|
1973
|
+
const mediaType = getMediaType({
|
|
1737
1974
|
content: param.content,
|
|
1738
1975
|
contentType,
|
|
1739
1976
|
refs
|
|
1740
|
-
})
|
|
1977
|
+
});
|
|
1978
|
+
const rawSchema = param.schema ?? mediaType?.schema;
|
|
1741
1979
|
const schema = rawSchema ? parseSchema({
|
|
1742
1980
|
schema: rawSchema,
|
|
1743
1981
|
name: schemaName
|
|
@@ -1753,7 +1991,10 @@ function parseParameter({ param, pointer, parentName, options, parseSchema, refs
|
|
|
1753
1991
|
},
|
|
1754
1992
|
required: param.required ?? false,
|
|
1755
1993
|
...pickStyleFields(param),
|
|
1756
|
-
...contentType !== void 0 ? { contentType } : {}
|
|
1994
|
+
...contentType !== void 0 ? { contentType } : {},
|
|
1995
|
+
...getExamples(mediaType ?? param, refs),
|
|
1996
|
+
...param.deprecated && { deprecated: true },
|
|
1997
|
+
...param.allowEmptyValue && { allowEmptyValue: true }
|
|
1757
1998
|
});
|
|
1758
1999
|
}
|
|
1759
2000
|
/**
|
|
@@ -1798,12 +2039,12 @@ function parseOperation({ operation, ...ctx }) {
|
|
|
1798
2039
|
name: requestBodyName
|
|
1799
2040
|
}), bodyRequired);
|
|
1800
2041
|
scanSchema(node, `${mediaTypePointer(body?.content, ct, `${pointer}/requestBody/content/${escapePointerToken(ct)}`)}/${schemaKeyword(mediaType)}`);
|
|
1801
|
-
const encoding = getEncoding(mediaType?.encoding);
|
|
1802
2042
|
return [_kubb_kit.ast.factory.createContent({
|
|
1803
2043
|
contentType: ct,
|
|
1804
2044
|
schema: node,
|
|
1805
2045
|
keysToOmit: collectPropertyKeysByFlag(schema, "readOnly"),
|
|
1806
|
-
...
|
|
2046
|
+
...mediaType && getEncodingFields(mediaType),
|
|
2047
|
+
...mediaType && getExamples(mediaType, refs),
|
|
1807
2048
|
...getStreamField({
|
|
1808
2049
|
contentType: ct,
|
|
1809
2050
|
mediaType,
|
|
@@ -1846,6 +2087,8 @@ function parseOperation({ operation, ...ctx }) {
|
|
|
1846
2087
|
return {
|
|
1847
2088
|
schema: node,
|
|
1848
2089
|
keysToOmit: collectPropertyKeysByFlag(raw, "writeOnly"),
|
|
2090
|
+
...mediaType && getEncodingFields(mediaType),
|
|
2091
|
+
...mediaType && getExamples(mediaType, refs),
|
|
1849
2092
|
...ct ? getStreamField({
|
|
1850
2093
|
contentType: ct,
|
|
1851
2094
|
mediaType,
|
|
@@ -1864,11 +2107,32 @@ function parseOperation({ operation, ...ctx }) {
|
|
|
1864
2107
|
contentType: "",
|
|
1865
2108
|
...parseEntrySchema(contentType)
|
|
1866
2109
|
}));
|
|
2110
|
+
const responsePointer = `${pointer}/responses/${statusCode}`;
|
|
2111
|
+
const headers = Object.entries(response?.headers ?? {}).flatMap(([name, value]) => {
|
|
2112
|
+
const header = name.toLowerCase() === "content-type" ? null : refs.deref(value);
|
|
2113
|
+
if (!header) return [];
|
|
2114
|
+
return [parseParameter({
|
|
2115
|
+
param: {
|
|
2116
|
+
...header,
|
|
2117
|
+
name,
|
|
2118
|
+
in: "header"
|
|
2119
|
+
},
|
|
2120
|
+
pointer: `${responsePointer}/headers/${escapePointerToken(name)}`,
|
|
2121
|
+
parentName: responseName,
|
|
2122
|
+
options,
|
|
2123
|
+
parseSchema,
|
|
2124
|
+
refs
|
|
2125
|
+
})];
|
|
2126
|
+
});
|
|
2127
|
+
const links = getLinks(response?.links, refs);
|
|
1867
2128
|
return _kubb_kit.ast.factory.createResponse({
|
|
1868
|
-
pointer:
|
|
2129
|
+
pointer: responsePointer,
|
|
1869
2130
|
statusCode,
|
|
2131
|
+
summary: response?.summary,
|
|
1870
2132
|
description: response?.description,
|
|
1871
|
-
content: responseContent
|
|
2133
|
+
content: responseContent,
|
|
2134
|
+
...headers.length && { headers },
|
|
2135
|
+
...links && { links }
|
|
1872
2136
|
});
|
|
1873
2137
|
});
|
|
1874
2138
|
const pickDoc = (key) => {
|
|
@@ -1878,6 +2142,7 @@ function parseOperation({ operation, ...ctx }) {
|
|
|
1878
2142
|
return typeof fallback === "string" ? fallback : void 0;
|
|
1879
2143
|
};
|
|
1880
2144
|
const servers = operation.schema.servers ?? operation.pathItem.servers;
|
|
2145
|
+
const auth = toAuthRequirements(operation.schema.security ?? document.security, document);
|
|
1881
2146
|
return _kubb_kit.ast.factory.createOperation({
|
|
1882
2147
|
pointer,
|
|
1883
2148
|
operationId,
|
|
@@ -1888,11 +2153,13 @@ function parseOperation({ operation, ...ctx }) {
|
|
|
1888
2153
|
summary: pickDoc("summary") || void 0,
|
|
1889
2154
|
description: pickDoc("description") || void 0,
|
|
1890
2155
|
deprecated: operation.schema.deprecated || void 0,
|
|
2156
|
+
externalDocs: getExternalDocs(operation.schema.externalDocs),
|
|
1891
2157
|
parameters,
|
|
1892
2158
|
requestBody,
|
|
1893
2159
|
responses,
|
|
1894
2160
|
extensions: pickExtensions(operation.schema),
|
|
1895
|
-
...servers && { servers: toInputServers(servers) }
|
|
2161
|
+
...servers && { servers: toInputServers(servers) },
|
|
2162
|
+
...auth && { auth }
|
|
1896
2163
|
});
|
|
1897
2164
|
}
|
|
1898
2165
|
// src/emit/createNode.ts
|
|
@@ -1913,6 +2180,7 @@ function createNode({ schema, name, nullable, defaultValue }, extras) {
|
|
|
1913
2180
|
default: defaultValue,
|
|
1914
2181
|
examples: extractExamples(schema),
|
|
1915
2182
|
format: schema.format,
|
|
2183
|
+
externalDocs: getExternalDocs(schema.externalDocs),
|
|
1916
2184
|
...extras
|
|
1917
2185
|
});
|
|
1918
2186
|
}
|
|
@@ -2377,13 +2645,15 @@ const annotationKeys = /* @__PURE__ */ new Set([
|
|
|
2377
2645
|
]);
|
|
2378
2646
|
/**
|
|
2379
2647
|
* Moves `allOf` members that hold only annotations or `if`/`then`/`else` onto the parent, so they do
|
|
2380
|
-
* not become `unknown`. The parent's own values win
|
|
2648
|
+
* not become `unknown`. The parent's own values win. The parser reads their `if`/`then`/`else` into `conditionals`.
|
|
2381
2649
|
*/
|
|
2650
|
+
function isAnnotationMember(member) {
|
|
2651
|
+
return !!member && typeof member === "object" && !isReference(member) && Object.keys(member).every((key) => annotationKeys.has(key));
|
|
2652
|
+
}
|
|
2382
2653
|
function mergeAnnotations(schema) {
|
|
2383
2654
|
const members = schema.allOf;
|
|
2384
|
-
const
|
|
2385
|
-
const
|
|
2386
|
-
const rest = members.filter((member) => !isAnnotation(member));
|
|
2655
|
+
const annotations = members.filter(isAnnotationMember);
|
|
2656
|
+
const rest = members.filter((member) => !isAnnotationMember(member));
|
|
2387
2657
|
return annotations.length && rest.length ? {
|
|
2388
2658
|
...Object.assign({}, ...annotations),
|
|
2389
2659
|
...schema,
|
|
@@ -2416,7 +2686,8 @@ function convertAllOf({ schema: original, name, nullable, defaultValue, parse, r
|
|
|
2416
2686
|
default: mergedDefault,
|
|
2417
2687
|
examples: extractExamples(schema) ?? memberNode.examples,
|
|
2418
2688
|
pattern: schema.pattern ?? ("pattern" in memberNode ? memberNode.pattern : void 0),
|
|
2419
|
-
format: schema.format ?? memberNode.format
|
|
2689
|
+
format: schema.format ?? memberNode.format,
|
|
2690
|
+
externalDocs: getExternalDocs(schema.externalDocs) ?? memberNode.externalDocs
|
|
2420
2691
|
});
|
|
2421
2692
|
}
|
|
2422
2693
|
const { members: discriminatedAllOf, discriminantValues } = extractDiscriminatedAllOfMembers({
|
|
@@ -2491,7 +2762,7 @@ function convertUnion(context) {
|
|
|
2491
2762
|
};
|
|
2492
2763
|
const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
|
|
2493
2764
|
const declaredMembers = [...schema.oneOf ?? [], ...schema.anyOf ?? []];
|
|
2494
|
-
const defaultRef = getDefaultMappingRef(discriminator);
|
|
2765
|
+
const defaultRef = getDefaultMappingRef(typeof schema.discriminator === "object" ? schema.discriminator : void 0);
|
|
2495
2766
|
const unionMembers = resolveUnionMembers(defaultRef && !declaredMembers.some((member) => isReference(member) && member.$ref === defaultRef) ? [...declaredMembers, { $ref: defaultRef }] : declaredMembers, schema.properties ?? {});
|
|
2496
2767
|
const strategy = schema.oneOf ? "one" : "any";
|
|
2497
2768
|
const explicitDiscriminatorPropertyName = discriminator?.propertyName;
|
|
@@ -2603,11 +2874,18 @@ function getPrimitiveType(type) {
|
|
|
2603
2874
|
}
|
|
2604
2875
|
/** Shared by number, integer and bigint nodes; the exclusive bounds keep only the OAS 3.1 numeric form. */
|
|
2605
2876
|
function getNumericConstraints(schema) {
|
|
2877
|
+
const exclusiveMinimum = typeof schema.exclusiveMinimum === "number" ? schema.exclusiveMinimum : void 0;
|
|
2878
|
+
const exclusiveMaximum = typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : void 0;
|
|
2879
|
+
const hasExclusive = exclusiveMinimum !== void 0 || exclusiveMaximum !== void 0;
|
|
2606
2880
|
return {
|
|
2607
2881
|
min: schema.minimum,
|
|
2608
2882
|
max: schema.maximum,
|
|
2609
|
-
|
|
2610
|
-
|
|
2883
|
+
...hasExclusive && { exclusive: {
|
|
2884
|
+
...exclusiveMinimum !== void 0 && { min: exclusiveMinimum },
|
|
2885
|
+
...exclusiveMaximum !== void 0 && { max: exclusiveMaximum }
|
|
2886
|
+
} },
|
|
2887
|
+
exclusiveMinimum,
|
|
2888
|
+
exclusiveMaximum,
|
|
2611
2889
|
multipleOf: schema.multipleOf
|
|
2612
2890
|
};
|
|
2613
2891
|
}
|
|
@@ -2616,11 +2894,11 @@ function getNumericConstraints(schema) {
|
|
|
2616
2894
|
*/
|
|
2617
2895
|
function isWithinBounds({ value, schema }) {
|
|
2618
2896
|
if (typeof value !== "number") return true;
|
|
2619
|
-
const { min, max,
|
|
2897
|
+
const { min, max, exclusive, multipleOf } = getNumericConstraints(schema);
|
|
2620
2898
|
if (min !== void 0 && value < min) return false;
|
|
2621
2899
|
if (max !== void 0 && value > max) return false;
|
|
2622
|
-
if (
|
|
2623
|
-
if (
|
|
2900
|
+
if (exclusive?.min !== void 0 && value <= exclusive.min) return false;
|
|
2901
|
+
if (exclusive?.max !== void 0 && value >= exclusive.max) return false;
|
|
2624
2902
|
if (multipleOf !== void 0 && Math.abs(value / multipleOf - Math.round(value / multipleOf)) > 1e-9) return false;
|
|
2625
2903
|
return true;
|
|
2626
2904
|
}
|
|
@@ -2778,6 +3056,15 @@ function convertFormattedEnum(context) {
|
|
|
2778
3056
|
}))
|
|
2779
3057
|
});
|
|
2780
3058
|
}
|
|
3059
|
+
function getStringContent({ schema, parse }) {
|
|
3060
|
+
const { contentMediaType: mediaType, contentEncoding: encoding, contentSchema } = schema;
|
|
3061
|
+
if (mediaType === void 0 && encoding === void 0 && !contentSchema) return {};
|
|
3062
|
+
return { content: {
|
|
3063
|
+
...mediaType !== void 0 && { mediaType },
|
|
3064
|
+
...encoding !== void 0 && { encoding },
|
|
3065
|
+
...contentSchema && { schema: parse({ schema: contentSchema }) }
|
|
3066
|
+
} };
|
|
3067
|
+
}
|
|
2781
3068
|
/**
|
|
2782
3069
|
* Converts a `type: 'string'` schema into a `StringSchemaNode`.
|
|
2783
3070
|
*/
|
|
@@ -2788,7 +3075,8 @@ function convertString(context) {
|
|
|
2788
3075
|
primitive: "string",
|
|
2789
3076
|
min: schema.minLength,
|
|
2790
3077
|
max: schema.maxLength,
|
|
2791
|
-
pattern: schema.pattern
|
|
3078
|
+
pattern: schema.pattern,
|
|
3079
|
+
...getStringContent(context)
|
|
2792
3080
|
});
|
|
2793
3081
|
}
|
|
2794
3082
|
/**
|
|
@@ -2802,6 +3090,15 @@ function convertNumeric(context, type) {
|
|
|
2802
3090
|
});
|
|
2803
3091
|
}
|
|
2804
3092
|
// src/emit/converters/structural.ts
|
|
3093
|
+
function getContains(schema, parse) {
|
|
3094
|
+
const { contains, minContains, maxContains } = schema;
|
|
3095
|
+
if (!contains || typeof contains !== "object") return {};
|
|
3096
|
+
return { contains: {
|
|
3097
|
+
schema: parse({ schema: contains }),
|
|
3098
|
+
...typeof minContains === "number" && { min: minContains },
|
|
3099
|
+
...typeof maxContains === "number" && { max: maxContains }
|
|
3100
|
+
} };
|
|
3101
|
+
}
|
|
2805
3102
|
/**
|
|
2806
3103
|
* Resolves a `true` or empty-object map schema (`additionalProperties`/`patternProperties`) to
|
|
2807
3104
|
* `options.unknownType`, otherwise parses it as a regular schema.
|
|
@@ -2854,7 +3151,7 @@ function convertObject({ schema, name, nullable, defaultValue, options, parse, r
|
|
|
2854
3151
|
required
|
|
2855
3152
|
});
|
|
2856
3153
|
}) : [];
|
|
2857
|
-
const additionalProperties = schema.additionalProperties;
|
|
3154
|
+
const additionalProperties = schema.additionalProperties ?? schema.unevaluatedProperties;
|
|
2858
3155
|
const additionalPropertiesNode = (() => {
|
|
2859
3156
|
if (additionalProperties === true) return true;
|
|
2860
3157
|
if (additionalProperties) return resolveMapSchema(additionalProperties, {
|
|
@@ -2884,6 +3181,8 @@ function convertObject({ schema, name, nullable, defaultValue, options, parse, r
|
|
|
2884
3181
|
additionalProperties: additionalPropertiesNode,
|
|
2885
3182
|
patternProperties,
|
|
2886
3183
|
propertyNames,
|
|
3184
|
+
min: schema.minProperties,
|
|
3185
|
+
max: schema.maxProperties,
|
|
2887
3186
|
minProperties: schema.minProperties,
|
|
2888
3187
|
maxProperties: schema.maxProperties
|
|
2889
3188
|
});
|
|
@@ -2914,7 +3213,8 @@ function convertObject({ schema, name, nullable, defaultValue, options, parse, r
|
|
|
2914
3213
|
*/
|
|
2915
3214
|
function convertTuple({ schema, name, nullable, defaultValue, options, parse }) {
|
|
2916
3215
|
const tupleItems = (schema.prefixItems ?? []).map((item) => parse({ schema: item }));
|
|
2917
|
-
const
|
|
3216
|
+
const tail = schema.items ?? schema.unevaluatedItems;
|
|
3217
|
+
const rest = tail === false ? void 0 : !tail || tail === true ? _kubb_kit.ast.factory.createSchema({ type: options.unknownType }) : parse({ schema: tail });
|
|
2918
3218
|
return createNode({
|
|
2919
3219
|
schema,
|
|
2920
3220
|
name,
|
|
@@ -2926,7 +3226,8 @@ function convertTuple({ schema, name, nullable, defaultValue, options, parse })
|
|
|
2926
3226
|
items: tupleItems,
|
|
2927
3227
|
rest,
|
|
2928
3228
|
min: schema.minItems,
|
|
2929
|
-
max: schema.maxItems
|
|
3229
|
+
max: schema.maxItems,
|
|
3230
|
+
...getContains(schema, parse)
|
|
2930
3231
|
});
|
|
2931
3232
|
}
|
|
2932
3233
|
/**
|
|
@@ -2950,7 +3251,8 @@ function convertArray({ schema, name, nullable, defaultValue, options, parse })
|
|
|
2950
3251
|
items,
|
|
2951
3252
|
min: schema.minItems,
|
|
2952
3253
|
max: schema.maxItems,
|
|
2953
|
-
unique: schema.uniqueItems ?? void 0
|
|
3254
|
+
unique: schema.uniqueItems ?? void 0,
|
|
3255
|
+
...getContains(schema, parse)
|
|
2954
3256
|
});
|
|
2955
3257
|
}
|
|
2956
3258
|
// src/emit/parseSchema.ts
|
|
@@ -3078,6 +3380,20 @@ const schemaRules = [
|
|
|
3078
3380
|
];
|
|
3079
3381
|
// src/parser.ts
|
|
3080
3382
|
/**
|
|
3383
|
+
* `unevaluated*` also sees what composition siblings evaluate, so with such a sibling it is dropped to keep the schema open.
|
|
3384
|
+
*/
|
|
3385
|
+
function hasUnevaluatedSiblings(schema) {
|
|
3386
|
+
if (schema.unevaluatedProperties === void 0 && schema.unevaluatedItems === void 0) return false;
|
|
3387
|
+
return [
|
|
3388
|
+
schema.allOf,
|
|
3389
|
+
schema.anyOf,
|
|
3390
|
+
schema.oneOf,
|
|
3391
|
+
schema.if,
|
|
3392
|
+
schema.dependentSchemas,
|
|
3393
|
+
schema.$ref
|
|
3394
|
+
].some((value) => value !== void 0);
|
|
3395
|
+
}
|
|
3396
|
+
/**
|
|
3081
3397
|
* Creates the schema converter bound to one OpenAPI document: `parseSchema` dispatches each
|
|
3082
3398
|
* schema through the ordered `schemaRules` table, with the parser options merged once.
|
|
3083
3399
|
*
|
|
@@ -3095,6 +3411,13 @@ function createSchemaParser(ctx) {
|
|
|
3095
3411
|
schema: flattenedSchema,
|
|
3096
3412
|
name
|
|
3097
3413
|
});
|
|
3414
|
+
if (hasUnevaluatedSiblings(schema)) {
|
|
3415
|
+
const { unevaluatedProperties: _properties, unevaluatedItems: _items, ...open } = schema;
|
|
3416
|
+
return parseSchema({
|
|
3417
|
+
schema: open,
|
|
3418
|
+
name
|
|
3419
|
+
});
|
|
3420
|
+
}
|
|
3098
3421
|
const nullable = isNullable(schema) || void 0;
|
|
3099
3422
|
const context = {
|
|
3100
3423
|
schema,
|
|
@@ -3108,8 +3431,62 @@ function createSchemaParser(ctx) {
|
|
|
3108
3431
|
refs,
|
|
3109
3432
|
renames
|
|
3110
3433
|
};
|
|
3111
|
-
|
|
3112
|
-
return createNode(context, { type: options.emptySchemaType });
|
|
3434
|
+
const rule = schemaRules.find((entry) => entry.match(context));
|
|
3435
|
+
return withConditionals(rule ? rule.convert(context) : createNode(context, { type: options.emptySchemaType }), schema);
|
|
3436
|
+
}
|
|
3437
|
+
function requireKeys(keys) {
|
|
3438
|
+
const unknown = _kubb_kit.ast.factory.createSchema({ type: _kubb_kit.ast.schemaTypes.unknown });
|
|
3439
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
3440
|
+
type: _kubb_kit.ast.schemaTypes.object,
|
|
3441
|
+
primitive: "object",
|
|
3442
|
+
properties: keys.map((name) => _kubb_kit.ast.factory.createProperty({
|
|
3443
|
+
name,
|
|
3444
|
+
required: true,
|
|
3445
|
+
schema: unknown
|
|
3446
|
+
}))
|
|
3447
|
+
});
|
|
3448
|
+
}
|
|
3449
|
+
/**
|
|
3450
|
+
* Adds `if`/`then`/`else`, `dependentRequired` and `dependentSchemas` to the node as `conditionals`.
|
|
3451
|
+
*/
|
|
3452
|
+
function withConditionals(node, schema) {
|
|
3453
|
+
const conditionals = [schema, ...Array.isArray(schema.allOf) ? schema.allOf.filter(isAnnotationMember) : []].flatMap(toConditionals);
|
|
3454
|
+
return conditionals.length ? {
|
|
3455
|
+
...node,
|
|
3456
|
+
conditionals
|
|
3457
|
+
} : node;
|
|
3458
|
+
}
|
|
3459
|
+
function toConditionals(schema) {
|
|
3460
|
+
const branch = (value) => {
|
|
3461
|
+
if (!value || typeof value !== "object") return void 0;
|
|
3462
|
+
const { required, type, ...rest } = value;
|
|
3463
|
+
if (Array.isArray(required) && required.length && (type === void 0 || type === "object") && !Object.keys(rest).length) return requireKeys(required);
|
|
3464
|
+
return parseSchema({ schema: value });
|
|
3465
|
+
};
|
|
3466
|
+
const entries = (value) => value && typeof value === "object" ? Object.entries(value) : [];
|
|
3467
|
+
const conditionals = [];
|
|
3468
|
+
const condition = branch(schema.if);
|
|
3469
|
+
if (condition) {
|
|
3470
|
+
const thenNode = branch(schema.then);
|
|
3471
|
+
const elseNode = branch(schema.else);
|
|
3472
|
+
conditionals.push({
|
|
3473
|
+
if: condition,
|
|
3474
|
+
...thenNode && { then: thenNode },
|
|
3475
|
+
...elseNode && { else: elseNode }
|
|
3476
|
+
});
|
|
3477
|
+
}
|
|
3478
|
+
for (const [key, required] of entries(schema.dependentRequired)) if (Array.isArray(required) && required.length && required.every((name) => typeof name === "string")) conditionals.push({
|
|
3479
|
+
if: requireKeys([key]),
|
|
3480
|
+
then: requireKeys(required)
|
|
3481
|
+
});
|
|
3482
|
+
for (const [key, dependent] of entries(schema.dependentSchemas)) {
|
|
3483
|
+
const thenNode = branch(dependent);
|
|
3484
|
+
if (thenNode) conditionals.push({
|
|
3485
|
+
if: requireKeys([key]),
|
|
3486
|
+
then: thenNode
|
|
3487
|
+
});
|
|
3488
|
+
}
|
|
3489
|
+
return conditionals;
|
|
3113
3490
|
}
|
|
3114
3491
|
return parseSchema;
|
|
3115
3492
|
}
|
|
@@ -3448,6 +3825,7 @@ const adapterOas = (0, _kubb_core.defineExtension)({
|
|
|
3448
3825
|
schemaNodes.push(promotedEnums ? refPromotedEnums(node, promotedEnums) : node);
|
|
3449
3826
|
}
|
|
3450
3827
|
const operations = promotedEnums ? operationNodes.map((node) => refPromotedEnums(node, promotedEnums)) : operationNodes;
|
|
3828
|
+
const authSchemes = toAuthSchemes(document.components?.securitySchemes, refs);
|
|
3451
3829
|
return _kubb_kit.ast.factory.createInput({
|
|
3452
3830
|
schemas: schemaNodes,
|
|
3453
3831
|
operations,
|
|
@@ -3455,23 +3833,25 @@ const adapterOas = (0, _kubb_core.defineExtension)({
|
|
|
3455
3833
|
title: document.info?.title,
|
|
3456
3834
|
description: document.info?.description,
|
|
3457
3835
|
version: document.info?.version,
|
|
3836
|
+
summary: document.info?.summary,
|
|
3837
|
+
termsOfService: document.info?.termsOfService,
|
|
3838
|
+
contact: pickStrings(document.info?.contact, [
|
|
3839
|
+
"name",
|
|
3840
|
+
"url",
|
|
3841
|
+
"email"
|
|
3842
|
+
]),
|
|
3843
|
+
license: typeof document.info?.license?.name === "string" ? {
|
|
3844
|
+
...pickStrings(document.info.license, ["identifier", "url"]),
|
|
3845
|
+
name: document.info.license.name
|
|
3846
|
+
} : void 0,
|
|
3847
|
+
externalDocs: getExternalDocs(document.externalDocs),
|
|
3458
3848
|
baseURL: resolveBaseUrl({
|
|
3459
3849
|
document,
|
|
3460
3850
|
server
|
|
3461
3851
|
}),
|
|
3462
3852
|
servers: toInputServers(document.servers ?? []),
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
return scheme?.type ? [{
|
|
3466
|
-
name,
|
|
3467
|
-
type: scheme.type,
|
|
3468
|
-
description: scheme.description,
|
|
3469
|
-
scheme: scheme.scheme,
|
|
3470
|
-
bearerFormat: scheme.bearerFormat,
|
|
3471
|
-
in: scheme.in,
|
|
3472
|
-
parameterName: scheme.name
|
|
3473
|
-
}] : [];
|
|
3474
|
-
}),
|
|
3853
|
+
...document.tags?.length && { tags: toInputTags(document.tags) },
|
|
3854
|
+
...authSchemes.length && { auth: authSchemes },
|
|
3475
3855
|
extensions: pickExtensions(document)
|
|
3476
3856
|
}
|
|
3477
3857
|
});
|