@kubb/agent 5.0.0-alpha.34 → 5.0.0-alpha.36
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/.output/nitro.json +1 -1
- package/.output/server/chunks/nitro/nitro.mjs +1790 -20812
- package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
- package/.output/server/chunks/routes/api/health.get.mjs +16 -14
- package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
- package/.output/server/index.mjs +16 -14
- package/.output/server/index.mjs.map +1 -1
- package/.output/server/node_modules/.nitro/ws@8.18.0/lib/constants.js +18 -0
- package/.output/server/node_modules/.nitro/ws@8.18.0/lib/permessage-deflate.js +514 -0
- package/.output/server/node_modules/.nitro/ws@8.18.0/lib/sender.js +602 -0
- package/.output/server/node_modules/.nitro/ws@8.18.0/lib/stream.js +159 -0
- package/.output/server/node_modules/.nitro/ws@8.18.0/lib/websocket-server.js +540 -0
- package/.output/server/node_modules/.nitro/ws@8.18.0/lib/websocket.js +1388 -0
- package/.output/server/node_modules/.nitro/ws@8.18.0/package.json +69 -0
- package/.output/server/node_modules/.nitro/ws@8.18.0/wrapper.mjs +8 -0
- package/.output/server/node_modules/.nitro/ws@8.20.0/lib/buffer-util.js +131 -0
- package/.output/server/node_modules/.nitro/ws@8.20.0/lib/event-target.js +292 -0
- package/.output/server/node_modules/.nitro/ws@8.20.0/lib/extension.js +203 -0
- package/.output/server/node_modules/.nitro/ws@8.20.0/lib/limiter.js +55 -0
- package/.output/server/node_modules/.nitro/ws@8.20.0/lib/receiver.js +706 -0
- package/.output/server/node_modules/.nitro/ws@8.20.0/lib/subprotocol.js +62 -0
- package/.output/server/node_modules/.nitro/ws@8.20.0/lib/validation.js +152 -0
- package/.output/server/node_modules/@clack/core/dist/index.mjs +11 -0
- package/.output/server/node_modules/@clack/core/package.json +60 -0
- package/.output/server/node_modules/@clack/prompts/dist/index.mjs +137 -0
- package/.output/server/node_modules/@clack/prompts/package.json +65 -0
- package/.output/server/node_modules/@kubb/ast/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/ast/dist/index.js +423 -0
- package/.output/server/node_modules/@kubb/ast/package.json +70 -0
- package/.output/server/node_modules/@kubb/core/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/core/dist/hooks.js +23 -0
- package/.output/server/node_modules/@kubb/core/dist/index.js +2311 -0
- package/.output/server/node_modules/@kubb/core/package.json +109 -0
- package/.output/server/node_modules/@kubb/fabric-core/dist/chunk-O_arW02_.js +17 -0
- package/.output/server/node_modules/@kubb/fabric-core/dist/defaultParser-iCpMSYCp.js +15 -0
- package/.output/server/node_modules/@kubb/fabric-core/dist/getRelativePath-NAm_Y-vp.js +55 -0
- package/.output/server/node_modules/@kubb/fabric-core/dist/index.js +653 -0
- package/.output/server/node_modules/@kubb/fabric-core/dist/onProcessExit-Cput7j2c.js +742 -0
- package/.output/server/node_modules/@kubb/fabric-core/dist/parsers/typescript.js +101 -0
- package/.output/server/node_modules/@kubb/fabric-core/dist/parsers.js +17 -0
- package/.output/server/node_modules/@kubb/fabric-core/dist/plugins.js +375 -0
- package/.output/server/node_modules/@kubb/fabric-core/package.json +111 -0
- package/.output/server/node_modules/@kubb/oas/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/oas/dist/index.js +918 -0
- package/.output/server/node_modules/@kubb/oas/package.json +94 -0
- package/.output/server/node_modules/@kubb/plugin-client/dist/StaticClassClient-bCe7RG_w.js +636 -0
- package/.output/server/node_modules/@kubb/plugin-client/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-client/dist/components.js +2 -0
- package/.output/server/node_modules/@kubb/plugin-client/dist/generators-BffddRNu.js +723 -0
- package/.output/server/node_modules/@kubb/plugin-client/dist/index.js +124 -0
- package/.output/server/node_modules/@kubb/plugin-client/dist/templates/clients/axios.source.js +6 -0
- package/.output/server/node_modules/@kubb/plugin-client/dist/templates/clients/fetch.source.js +6 -0
- package/.output/server/node_modules/@kubb/plugin-client/dist/templates/config.source.js +6 -0
- package/.output/server/node_modules/@kubb/plugin-client/package.json +153 -0
- package/.output/server/node_modules/@kubb/plugin-cypress/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-cypress/dist/components-BK_6GU4v.js +257 -0
- package/.output/server/node_modules/@kubb/plugin-cypress/dist/generators-D5YFtyyC.js +71 -0
- package/.output/server/node_modules/@kubb/plugin-cypress/dist/index.js +79 -0
- package/.output/server/node_modules/@kubb/plugin-cypress/package.json +108 -0
- package/.output/server/node_modules/@kubb/plugin-faker/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-faker/dist/components-BkBIov4R.js +419 -0
- package/.output/server/node_modules/@kubb/plugin-faker/dist/fakerGenerator-BztogaeO.js +200 -0
- package/.output/server/node_modules/@kubb/plugin-faker/dist/index.js +141 -0
- package/.output/server/node_modules/@kubb/plugin-faker/package.json +103 -0
- package/.output/server/node_modules/@kubb/plugin-mcp/dist/Server-H3SwqhwF.js +178 -0
- package/.output/server/node_modules/@kubb/plugin-mcp/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-mcp/dist/generators-BqkMrcs9.js +274 -0
- package/.output/server/node_modules/@kubb/plugin-mcp/dist/index.js +122 -0
- package/.output/server/node_modules/@kubb/plugin-mcp/package.json +107 -0
- package/.output/server/node_modules/@kubb/plugin-msw/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-msw/dist/components-DgtTZkWX.js +277 -0
- package/.output/server/node_modules/@kubb/plugin-msw/dist/generators-C34kqa1L.js +161 -0
- package/.output/server/node_modules/@kubb/plugin-msw/dist/index.js +84 -0
- package/.output/server/node_modules/@kubb/plugin-msw/package.json +109 -0
- package/.output/server/node_modules/@kubb/plugin-oas/dist/SchemaMapper-CqMkO2T1.js +58 -0
- package/.output/server/node_modules/@kubb/plugin-oas/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-oas/dist/generators-D7C3CXsN.js +79 -0
- package/.output/server/node_modules/@kubb/plugin-oas/dist/generators.js +2 -0
- package/.output/server/node_modules/@kubb/plugin-oas/dist/getFooter-Pw3tLCiV.js +112 -0
- package/.output/server/node_modules/@kubb/plugin-oas/dist/hooks.js +200 -0
- package/.output/server/node_modules/@kubb/plugin-oas/dist/index.js +408 -0
- package/.output/server/node_modules/@kubb/plugin-oas/dist/requestBody-pRavthCw.js +1336 -0
- package/.output/server/node_modules/@kubb/plugin-oas/dist/utils.js +268 -0
- package/.output/server/node_modules/@kubb/plugin-oas/package.json +122 -0
- package/.output/server/node_modules/@kubb/plugin-react-query/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-react-query/dist/components-CpyHYGOw.js +1520 -0
- package/.output/server/node_modules/@kubb/plugin-react-query/dist/generators-CpiBv5eE.js +1427 -0
- package/.output/server/node_modules/@kubb/plugin-react-query/dist/index.js +166 -0
- package/.output/server/node_modules/@kubb/plugin-react-query/package.json +112 -0
- package/.output/server/node_modules/@kubb/plugin-redoc/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-redoc/dist/index.js +65 -0
- package/.output/server/node_modules/@kubb/plugin-redoc/package.json +85 -0
- package/.output/server/node_modules/@kubb/plugin-redoc/static/redoc.hbs +22 -0
- package/.output/server/node_modules/@kubb/plugin-solid-query/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-solid-query/dist/components-BhStIi1M.js +665 -0
- package/.output/server/node_modules/@kubb/plugin-solid-query/dist/generators-CQClzsST.js +415 -0
- package/.output/server/node_modules/@kubb/plugin-solid-query/dist/index.js +145 -0
- package/.output/server/node_modules/@kubb/plugin-solid-query/package.json +113 -0
- package/.output/server/node_modules/@kubb/plugin-svelte-query/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-svelte-query/dist/components-DntKBsnB.js +666 -0
- package/.output/server/node_modules/@kubb/plugin-svelte-query/dist/generators-BtTsGGrM.js +414 -0
- package/.output/server/node_modules/@kubb/plugin-svelte-query/dist/index.js +145 -0
- package/.output/server/node_modules/@kubb/plugin-svelte-query/package.json +113 -0
- package/.output/server/node_modules/@kubb/plugin-swr/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-swr/dist/components-DRDGvgXG.js +702 -0
- package/.output/server/node_modules/@kubb/plugin-swr/dist/generators-ClWZJ-YG.js +399 -0
- package/.output/server/node_modules/@kubb/plugin-swr/dist/index.js +144 -0
- package/.output/server/node_modules/@kubb/plugin-swr/package.json +115 -0
- package/.output/server/node_modules/@kubb/plugin-ts/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-ts/dist/components-C7fu-sK1.js +723 -0
- package/.output/server/node_modules/@kubb/plugin-ts/dist/index.js +2 -0
- package/.output/server/node_modules/@kubb/plugin-ts/dist/plugin-CYC-FGXe.js +479 -0
- package/.output/server/node_modules/@kubb/plugin-ts/package.json +105 -0
- package/.output/server/node_modules/@kubb/plugin-vue-query/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-vue-query/dist/components-_AMBl0g-.js +1029 -0
- package/.output/server/node_modules/@kubb/plugin-vue-query/dist/generators-Zb1s5Wmb.js +661 -0
- package/.output/server/node_modules/@kubb/plugin-vue-query/dist/index.js +157 -0
- package/.output/server/node_modules/@kubb/plugin-vue-query/package.json +114 -0
- package/.output/server/node_modules/@kubb/plugin-zod/dist/chunk--u3MIqq1.js +8 -0
- package/.output/server/node_modules/@kubb/plugin-zod/dist/components-eECfXVou.js +842 -0
- package/.output/server/node_modules/@kubb/plugin-zod/dist/generators-D1R6NNf2.js +290 -0
- package/.output/server/node_modules/@kubb/plugin-zod/dist/index.js +175 -0
- package/.output/server/node_modules/@kubb/plugin-zod/dist/templates/ToZod.source.js +6 -0
- package/.output/server/node_modules/@kubb/plugin-zod/package.json +112 -0
- package/.output/server/node_modules/@kubb/react-fabric/dist/chunk-BGCRLu6H.js +38 -0
- package/.output/server/node_modules/@kubb/react-fabric/dist/index.js +525 -0
- package/.output/server/node_modules/@kubb/react-fabric/dist/jsx-runtime-Bl0DfUmV.js +1448 -0
- package/.output/server/node_modules/@kubb/react-fabric/dist/jsx-runtime.js +12 -0
- package/.output/server/node_modules/@kubb/react-fabric/dist/parsers.js +2 -0
- package/.output/server/node_modules/@kubb/react-fabric/dist/plugins.js +4 -0
- package/.output/server/node_modules/@kubb/react-fabric/dist/reactPlugin-QQPrjNuQ.js +17813 -0
- package/.output/server/node_modules/@kubb/react-fabric/package.json +143 -0
- package/.output/server/node_modules/@redocly/config/lib/root-config-schema.js +11 -1
- package/.output/server/node_modules/@redocly/config/package.json +1 -1
- package/.output/server/node_modules/@redocly/openapi-core/lib/bundle/bundle-document.js +25 -10
- package/.output/server/node_modules/@redocly/openapi-core/lib/bundle/bundle-visitor.js +32 -29
- package/.output/server/node_modules/@redocly/openapi-core/lib/config/config.js +5 -0
- package/.output/server/node_modules/@redocly/openapi-core/lib/decorators/oas2/index.js +1 -1
- package/.output/server/node_modules/@redocly/openapi-core/lib/decorators/oas2/remove-unused-components.js +47 -38
- package/.output/server/node_modules/@redocly/openapi-core/lib/decorators/oas3/index.js +1 -1
- package/.output/server/node_modules/@redocly/openapi-core/lib/decorators/oas3/remove-unused-components.js +45 -41
- package/.output/server/node_modules/@redocly/openapi-core/lib/rules/common/no-http-verbs-in-paths.js +3 -1
- package/.output/server/node_modules/@redocly/openapi-core/lib/rules/common/no-required-schema-properties-undefined.js +41 -55
- package/.output/server/node_modules/@redocly/openapi-core/lib/walk.js +28 -16
- package/.output/server/node_modules/@redocly/openapi-core/package.json +2 -2
- package/.output/server/node_modules/buffer-from/index.js +72 -0
- package/.output/server/node_modules/buffer-from/package.json +19 -0
- package/.output/server/node_modules/fast-string-truncated-width/dist/index.js +171 -0
- package/.output/server/node_modules/fast-string-truncated-width/dist/utils.js +15 -0
- package/.output/server/node_modules/fast-string-truncated-width/package.json +35 -0
- package/.output/server/node_modules/fast-string-width/dist/index.js +14 -0
- package/.output/server/node_modules/fast-string-width/package.json +34 -0
- package/.output/server/node_modules/fast-wrap-ansi/lib/main.js +216 -0
- package/.output/server/node_modules/fast-wrap-ansi/package.json +51 -0
- package/.output/server/node_modules/p-limit/index.js +127 -0
- package/.output/server/node_modules/p-limit/package.json +58 -0
- package/.output/server/node_modules/react-devtools-core/dist/backend.js +18302 -0
- package/.output/server/node_modules/react-devtools-core/package.json +38 -0
- package/.output/server/node_modules/sisteransi/package.json +34 -0
- package/.output/server/node_modules/sisteransi/src/index.js +58 -0
- package/.output/server/node_modules/source-map-support/package.json +31 -0
- package/.output/server/node_modules/source-map-support/source-map-support.js +625 -0
- package/.output/server/node_modules/typescript/lib/typescript.js +200276 -0
- package/.output/server/node_modules/typescript/package.json +120 -0
- package/.output/server/node_modules/yocto-queue/index.js +90 -0
- package/.output/server/node_modules/yocto-queue/package.json +48 -0
- package/.output/server/package.json +35 -4
- package/package.json +20 -20
- /package/.output/server/node_modules/{ws → .nitro/ws@8.18.0}/lib/buffer-util.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.18.0}/lib/event-target.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.18.0}/lib/extension.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.18.0}/lib/limiter.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.18.0}/lib/receiver.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.18.0}/lib/subprotocol.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.18.0}/lib/validation.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.20.0}/lib/constants.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.20.0}/lib/permessage-deflate.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.20.0}/lib/sender.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.20.0}/lib/stream.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.20.0}/lib/websocket-server.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.20.0}/lib/websocket.js +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.20.0}/package.json +0 -0
- /package/.output/server/node_modules/{ws → .nitro/ws@8.20.0}/wrapper.mjs +0 -0
|
@@ -0,0 +1,918 @@
|
|
|
1
|
+
import "./chunk--u3MIqq1.js";
|
|
2
|
+
import jsonpointer from "jsonpointer";
|
|
3
|
+
import BaseOas from "oas";
|
|
4
|
+
import { matchesMimeType } from "oas/utils";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { bundle, loadConfig } from "@redocly/openapi-core";
|
|
7
|
+
import yaml from "@stoplight/yaml";
|
|
8
|
+
import { isRef } from "oas/types";
|
|
9
|
+
import OASNormalize from "oas-normalize";
|
|
10
|
+
import { isPlainObject, mergeDeep } from "remeda";
|
|
11
|
+
import swagger2openapi from "swagger2openapi";
|
|
12
|
+
//#region src/constants.ts
|
|
13
|
+
/**
|
|
14
|
+
* JSON Schema keywords that indicate structural composition.
|
|
15
|
+
* Used when deciding whether an inline `allOf` fragment can be safely flattened
|
|
16
|
+
* into its parent (fragments containing any of these keys must not be inlined).
|
|
17
|
+
*/
|
|
18
|
+
const STRUCTURAL_KEYS = new Set([
|
|
19
|
+
"properties",
|
|
20
|
+
"items",
|
|
21
|
+
"additionalProperties",
|
|
22
|
+
"oneOf",
|
|
23
|
+
"anyOf",
|
|
24
|
+
"allOf",
|
|
25
|
+
"not"
|
|
26
|
+
]);
|
|
27
|
+
/**
|
|
28
|
+
* Maps OAS/JSON Schema `format` strings to their Kubb `SchemaType` equivalents.
|
|
29
|
+
*
|
|
30
|
+
* Only formats that require a type different from the raw OAS `type` are listed here.
|
|
31
|
+
* `int64`, `date-time`, `date`, and `time` are handled separately because their
|
|
32
|
+
* output depends on runtime parser options and cannot live in a static map.
|
|
33
|
+
*
|
|
34
|
+
* Note: `ipv4`, `ipv6`, and `hostname` map to `'url'` — not semantically accurate,
|
|
35
|
+
* but `'url'` is the closest supported scalar type in the Kubb AST.
|
|
36
|
+
*/
|
|
37
|
+
const FORMAT_MAP = {
|
|
38
|
+
uuid: "uuid",
|
|
39
|
+
email: "email",
|
|
40
|
+
"idn-email": "email",
|
|
41
|
+
uri: "url",
|
|
42
|
+
"uri-reference": "url",
|
|
43
|
+
url: "url",
|
|
44
|
+
ipv4: "url",
|
|
45
|
+
ipv6: "url",
|
|
46
|
+
hostname: "url",
|
|
47
|
+
"idn-hostname": "url",
|
|
48
|
+
binary: "blob",
|
|
49
|
+
byte: "blob",
|
|
50
|
+
int32: "integer",
|
|
51
|
+
float: "number",
|
|
52
|
+
double: "number"
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Exhaustive list of media types that Kubb recognizes.
|
|
56
|
+
* Kept as a module-level constant to avoid re-allocating the array on every call.
|
|
57
|
+
*/
|
|
58
|
+
const KNOWN_MEDIA_TYPES = [
|
|
59
|
+
"application/json",
|
|
60
|
+
"application/xml",
|
|
61
|
+
"application/x-www-form-urlencoded",
|
|
62
|
+
"application/octet-stream",
|
|
63
|
+
"application/pdf",
|
|
64
|
+
"application/zip",
|
|
65
|
+
"application/graphql",
|
|
66
|
+
"multipart/form-data",
|
|
67
|
+
"text/plain",
|
|
68
|
+
"text/html",
|
|
69
|
+
"text/csv",
|
|
70
|
+
"text/xml",
|
|
71
|
+
"image/png",
|
|
72
|
+
"image/jpeg",
|
|
73
|
+
"image/gif",
|
|
74
|
+
"image/webp",
|
|
75
|
+
"image/svg+xml",
|
|
76
|
+
"audio/mpeg",
|
|
77
|
+
"video/mp4"
|
|
78
|
+
];
|
|
79
|
+
/**
|
|
80
|
+
* Vendor extension keys used by various spec generators to attach human-readable
|
|
81
|
+
* labels to enum values. Checked in priority order: the first key found wins.
|
|
82
|
+
*/
|
|
83
|
+
const ENUM_EXTENSION_KEYS = ["x-enumNames", "x-enum-varnames"];
|
|
84
|
+
/**
|
|
85
|
+
* Canonical HTTP method names used throughout the Kubb OAS layer.
|
|
86
|
+
* Keys are uppercase (as used in generated code); values are the lowercase
|
|
87
|
+
* strings that the `oas` library uses internally.
|
|
88
|
+
* @deprecated use httpMethods from @kubb/ast
|
|
89
|
+
*/
|
|
90
|
+
const httpMethods = {
|
|
91
|
+
GET: "get",
|
|
92
|
+
POST: "post",
|
|
93
|
+
PUT: "put",
|
|
94
|
+
PATCH: "patch",
|
|
95
|
+
DELETE: "delete",
|
|
96
|
+
HEAD: "head",
|
|
97
|
+
OPTIONS: "options",
|
|
98
|
+
TRACE: "trace"
|
|
99
|
+
};
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region ../../internals/utils/src/casing.ts
|
|
102
|
+
/**
|
|
103
|
+
* Shared implementation for camelCase and PascalCase conversion.
|
|
104
|
+
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
105
|
+
* and capitalizes each word according to `pascal`.
|
|
106
|
+
*
|
|
107
|
+
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
108
|
+
*/
|
|
109
|
+
function toCamelOrPascal(text, pascal) {
|
|
110
|
+
return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
|
|
111
|
+
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
112
|
+
if (i === 0 && !pascal) return word.charAt(0).toLowerCase() + word.slice(1);
|
|
113
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
114
|
+
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Splits `text` on `.` and applies `transformPart` to each segment.
|
|
118
|
+
* The last segment receives `isLast = true`, all earlier segments receive `false`.
|
|
119
|
+
* Segments are joined with `/` to form a file path.
|
|
120
|
+
*/
|
|
121
|
+
function applyToFileParts(text, transformPart) {
|
|
122
|
+
const parts = text.split(".");
|
|
123
|
+
return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Converts `text` to camelCase.
|
|
127
|
+
* When `isFile` is `true`, dot-separated segments are each cased independently and joined with `/`.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* camelCase('hello-world') // 'helloWorld'
|
|
131
|
+
* camelCase('pet.petId', { isFile: true }) // 'pet/petId'
|
|
132
|
+
*/
|
|
133
|
+
function camelCase(text, { isFile, prefix = "", suffix = "" } = {}) {
|
|
134
|
+
if (isFile) return applyToFileParts(text, (part, isLast) => camelCase(part, isLast ? {
|
|
135
|
+
prefix,
|
|
136
|
+
suffix
|
|
137
|
+
} : {}));
|
|
138
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Converts `text` to PascalCase.
|
|
142
|
+
* When `isFile` is `true`, the last dot-separated segment is PascalCased and earlier segments are camelCased.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* pascalCase('hello-world') // 'HelloWorld'
|
|
146
|
+
* pascalCase('pet.petId', { isFile: true }) // 'pet/PetId'
|
|
147
|
+
*/
|
|
148
|
+
function pascalCase(text, { isFile, prefix = "", suffix = "" } = {}) {
|
|
149
|
+
if (isFile) return applyToFileParts(text, (part, isLast) => isLast ? pascalCase(part, {
|
|
150
|
+
prefix,
|
|
151
|
+
suffix
|
|
152
|
+
}) : camelCase(part));
|
|
153
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
|
|
154
|
+
}
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region ../../internals/utils/src/reserved.ts
|
|
157
|
+
/**
|
|
158
|
+
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
159
|
+
*/
|
|
160
|
+
function isValidVarName(name) {
|
|
161
|
+
try {
|
|
162
|
+
new Function(`var ${name}`);
|
|
163
|
+
} catch {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region ../../internals/utils/src/urlPath.ts
|
|
170
|
+
/**
|
|
171
|
+
* Parses and transforms an OpenAPI/Swagger path string into various URL formats.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* const p = new URLPath('/pet/{petId}')
|
|
175
|
+
* p.URL // '/pet/:petId'
|
|
176
|
+
* p.template // '`/pet/${petId}`'
|
|
177
|
+
*/
|
|
178
|
+
var URLPath = class {
|
|
179
|
+
/** The raw OpenAPI/Swagger path string, e.g. `/pet/{petId}`. */
|
|
180
|
+
path;
|
|
181
|
+
#options;
|
|
182
|
+
constructor(path, options = {}) {
|
|
183
|
+
this.path = path;
|
|
184
|
+
this.#options = options;
|
|
185
|
+
}
|
|
186
|
+
/** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`. */
|
|
187
|
+
get URL() {
|
|
188
|
+
return this.toURLPath();
|
|
189
|
+
}
|
|
190
|
+
/** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`). */
|
|
191
|
+
get isURL() {
|
|
192
|
+
try {
|
|
193
|
+
return !!new URL(this.path).href;
|
|
194
|
+
} catch {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* new URLPath('/pet/{petId}').template // '`/pet/${petId}`'
|
|
203
|
+
* new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'
|
|
204
|
+
*/
|
|
205
|
+
get template() {
|
|
206
|
+
return this.toTemplateString();
|
|
207
|
+
}
|
|
208
|
+
/** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set. */
|
|
209
|
+
get object() {
|
|
210
|
+
return this.toObject();
|
|
211
|
+
}
|
|
212
|
+
/** Returns a map of path parameter names, or `undefined` when the path has no parameters. */
|
|
213
|
+
get params() {
|
|
214
|
+
return this.getParams();
|
|
215
|
+
}
|
|
216
|
+
#transformParam(raw) {
|
|
217
|
+
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
218
|
+
return this.#options.casing === "camelcase" ? camelCase(param) : param;
|
|
219
|
+
}
|
|
220
|
+
/** Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name. */
|
|
221
|
+
#eachParam(fn) {
|
|
222
|
+
for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
|
|
223
|
+
const raw = match[1];
|
|
224
|
+
fn(raw, this.#transformParam(raw));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
toObject({ type = "path", replacer, stringify } = {}) {
|
|
228
|
+
const object = {
|
|
229
|
+
url: type === "path" ? this.toURLPath() : this.toTemplateString({ replacer }),
|
|
230
|
+
params: this.getParams()
|
|
231
|
+
};
|
|
232
|
+
if (stringify) {
|
|
233
|
+
if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
|
|
234
|
+
if (object.params) return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll("'", "").replaceAll(`"`, "")} }`;
|
|
235
|
+
return `{ url: '${object.url}' }`;
|
|
236
|
+
}
|
|
237
|
+
return object;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
241
|
+
* An optional `replacer` can transform each extracted parameter name before interpolation.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
|
|
245
|
+
*/
|
|
246
|
+
toTemplateString({ prefix = "", replacer } = {}) {
|
|
247
|
+
return `\`${prefix}${this.path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
248
|
+
if (i % 2 === 0) return part;
|
|
249
|
+
const param = this.#transformParam(part);
|
|
250
|
+
return `\${${replacer ? replacer(param) : param}}`;
|
|
251
|
+
}).join("")}\``;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
255
|
+
* An optional `replacer` transforms each parameter name in both key and value positions.
|
|
256
|
+
* Returns `undefined` when no path parameters are found.
|
|
257
|
+
*/
|
|
258
|
+
getParams(replacer) {
|
|
259
|
+
const params = {};
|
|
260
|
+
this.#eachParam((_raw, param) => {
|
|
261
|
+
const key = replacer ? replacer(param) : param;
|
|
262
|
+
params[key] = key;
|
|
263
|
+
});
|
|
264
|
+
return Object.keys(params).length > 0 ? params : void 0;
|
|
265
|
+
}
|
|
266
|
+
/** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`. */
|
|
267
|
+
toURLPath() {
|
|
268
|
+
return this.path.replace(/\{([^}]+)\}/g, ":$1");
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region src/utils.ts
|
|
273
|
+
/**
|
|
274
|
+
* Returns `true` when `doc` looks like a Swagger 2.0 document (no `openapi` key).
|
|
275
|
+
*/
|
|
276
|
+
function isOpenApiV2Document(doc) {
|
|
277
|
+
return !!doc && isPlainObject(doc) && !("openapi" in doc);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Returns `true` when `doc` is an OpenAPI 3.1 document.
|
|
281
|
+
*/
|
|
282
|
+
function isOpenApiV3_1Document(doc) {
|
|
283
|
+
return !!doc && isPlainObject(doc) && "openapi" in doc && doc.openapi.startsWith("3.1");
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Returns `true` when `obj` is a parameter object (has an `in` field distinguishing it from a schema).
|
|
287
|
+
*/
|
|
288
|
+
function isParameterObject(obj) {
|
|
289
|
+
return !!obj && "in" in obj;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Determines if a schema is nullable, considering:
|
|
293
|
+
* - OpenAPI 3.0 `nullable` / `x-nullable`
|
|
294
|
+
* - OpenAPI 3.1 JSON Schema `type: ['null', ...]` or `type: 'null'`
|
|
295
|
+
*/
|
|
296
|
+
function isNullable(schema) {
|
|
297
|
+
if ((schema?.nullable ?? schema?.["x-nullable"]) === true) return true;
|
|
298
|
+
const schemaType = schema?.type;
|
|
299
|
+
if (schemaType === "null") return true;
|
|
300
|
+
if (Array.isArray(schemaType)) return schemaType.includes("null");
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Returns `true` when `obj` is an OpenAPI `$ref` pointer object.
|
|
305
|
+
*/
|
|
306
|
+
function isReference(obj) {
|
|
307
|
+
return !!obj && isRef(obj);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Returns `true` when `obj` is a schema that carries a structured `discriminator` object
|
|
311
|
+
* (as opposed to a plain string discriminator used in some older specs).
|
|
312
|
+
*/
|
|
313
|
+
function isDiscriminator(obj) {
|
|
314
|
+
const record = obj;
|
|
315
|
+
return !!obj && !!record["discriminator"] && typeof record["discriminator"] !== "string";
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Determines whether a schema is required.
|
|
319
|
+
*
|
|
320
|
+
* Returns true if the schema has a non-empty {@link SchemaObject.required} array or a truthy {@link SchemaObject.required} property.
|
|
321
|
+
*/
|
|
322
|
+
function isRequired(schema) {
|
|
323
|
+
if (!schema) return false;
|
|
324
|
+
return Array.isArray(schema.required) ? !!schema.required?.length : !!schema.required;
|
|
325
|
+
}
|
|
326
|
+
function isAllOptional(schema) {
|
|
327
|
+
if (!schema) return true;
|
|
328
|
+
if (isOptional(schema)) return true;
|
|
329
|
+
const s = schema;
|
|
330
|
+
if (Array.isArray(s?.required) && s?.required.length > 0) return false;
|
|
331
|
+
const groups = [
|
|
332
|
+
s?.allOf,
|
|
333
|
+
s?.anyOf,
|
|
334
|
+
s?.oneOf
|
|
335
|
+
].filter((g) => Array.isArray(g));
|
|
336
|
+
if (groups.length === 0) return true;
|
|
337
|
+
return groups.every((arr) => arr.every((child) => isAllOptional(child)));
|
|
338
|
+
}
|
|
339
|
+
function isOptional(schema) {
|
|
340
|
+
return !isRequired(schema);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Determines the appropriate default value for a schema parameter.
|
|
344
|
+
* - For array types: returns '[]'
|
|
345
|
+
* - For union types (anyOf/oneOf):
|
|
346
|
+
* - If at least one variant has all-optional fields: returns '{}'
|
|
347
|
+
* - Otherwise: returns undefined (no default)
|
|
348
|
+
* - For object types with optional fields: returns '{}'
|
|
349
|
+
* - For primitive types (string, number, boolean): returns undefined (no default)
|
|
350
|
+
* - For required types: returns undefined (no default)
|
|
351
|
+
*/
|
|
352
|
+
function getDefaultValue(schema) {
|
|
353
|
+
if (!schema || !isOptional(schema)) return;
|
|
354
|
+
if (schema.type === "array") return "[]";
|
|
355
|
+
if (schema.anyOf || schema.oneOf) {
|
|
356
|
+
const variants = schema.anyOf || schema.oneOf;
|
|
357
|
+
if (!Array.isArray(variants)) return;
|
|
358
|
+
if (!variants.some((variant) => isAllOptional(variant))) return;
|
|
359
|
+
return "{}";
|
|
360
|
+
}
|
|
361
|
+
if (schema.type === "object" || schema.properties) return "{}";
|
|
362
|
+
}
|
|
363
|
+
async function parse(pathOrApi, { oasClass = Oas, canBundle = true, enablePaths = true } = {}) {
|
|
364
|
+
if (typeof pathOrApi === "string" && canBundle) return parse((await bundle({
|
|
365
|
+
ref: pathOrApi,
|
|
366
|
+
config: await loadConfig(),
|
|
367
|
+
base: pathOrApi
|
|
368
|
+
})).bundle.parsed, {
|
|
369
|
+
oasClass,
|
|
370
|
+
canBundle,
|
|
371
|
+
enablePaths
|
|
372
|
+
});
|
|
373
|
+
const document = await new OASNormalize(pathOrApi, {
|
|
374
|
+
enablePaths,
|
|
375
|
+
colorizeErrors: true
|
|
376
|
+
}).load();
|
|
377
|
+
if (isOpenApiV2Document(document)) {
|
|
378
|
+
const { openapi } = await swagger2openapi.convertObj(document, { anchors: true });
|
|
379
|
+
return new oasClass(openapi);
|
|
380
|
+
}
|
|
381
|
+
return new oasClass(document);
|
|
382
|
+
}
|
|
383
|
+
async function merge(pathOrApi, { oasClass = Oas } = {}) {
|
|
384
|
+
const instances = await Promise.all(pathOrApi.map((p) => parse(p, {
|
|
385
|
+
oasClass,
|
|
386
|
+
enablePaths: false,
|
|
387
|
+
canBundle: false
|
|
388
|
+
})));
|
|
389
|
+
if (instances.length === 0) throw new Error("No OAS instances provided for merging.");
|
|
390
|
+
return parse(instances.reduce((acc, current) => {
|
|
391
|
+
return mergeDeep(acc, current.document);
|
|
392
|
+
}, {
|
|
393
|
+
openapi: "3.0.0",
|
|
394
|
+
info: {
|
|
395
|
+
title: "Merged API",
|
|
396
|
+
version: "1.0.0"
|
|
397
|
+
},
|
|
398
|
+
paths: {},
|
|
399
|
+
components: { schemas: {} }
|
|
400
|
+
}), { oasClass });
|
|
401
|
+
}
|
|
402
|
+
function parseFromConfig(config, oasClass = Oas) {
|
|
403
|
+
if ("data" in config.input) {
|
|
404
|
+
if (typeof config.input.data === "object") return parse(structuredClone(config.input.data), { oasClass });
|
|
405
|
+
try {
|
|
406
|
+
return parse(yaml.parse(config.input.data), { oasClass });
|
|
407
|
+
} catch (_e) {
|
|
408
|
+
return parse(config.input.data, { oasClass });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (Array.isArray(config.input)) return merge(config.input.map((input) => path.resolve(config.root, input.path)), { oasClass });
|
|
412
|
+
if (new URLPath(config.input.path).isURL) return parse(config.input.path, { oasClass });
|
|
413
|
+
return parse(path.resolve(config.root, config.input.path), { oasClass });
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Flatten allOf schemas by merging keyword-only fragments.
|
|
417
|
+
* Only flattens schemas where allOf items don't contain structural keys or $refs.
|
|
418
|
+
*/
|
|
419
|
+
function flattenSchema(schema) {
|
|
420
|
+
if (!schema?.allOf || schema.allOf.length === 0) return schema || null;
|
|
421
|
+
if (schema.allOf.some((item) => isRef(item))) return schema;
|
|
422
|
+
const isPlainFragment = (item) => !Object.keys(item).some((key) => STRUCTURAL_KEYS.has(key));
|
|
423
|
+
if (!schema.allOf.every((item) => isPlainFragment(item))) return schema;
|
|
424
|
+
const merged = { ...schema };
|
|
425
|
+
delete merged.allOf;
|
|
426
|
+
for (const fragment of schema.allOf) for (const [key, value] of Object.entries(fragment)) if (merged[key] === void 0) merged[key] = value;
|
|
427
|
+
return merged;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Validate an OpenAPI document using oas-normalize.
|
|
431
|
+
*/
|
|
432
|
+
async function validate(document) {
|
|
433
|
+
return new OASNormalize(document, {
|
|
434
|
+
enablePaths: true,
|
|
435
|
+
colorizeErrors: true
|
|
436
|
+
}).validate({ parser: { validate: { errors: { colorize: true } } } });
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Collect all schema $ref dependencies recursively.
|
|
440
|
+
*/
|
|
441
|
+
function collectRefs(schema, refs = /* @__PURE__ */ new Set()) {
|
|
442
|
+
if (Array.isArray(schema)) {
|
|
443
|
+
for (const item of schema) collectRefs(item, refs);
|
|
444
|
+
return refs;
|
|
445
|
+
}
|
|
446
|
+
if (schema && typeof schema === "object") for (const [key, value] of Object.entries(schema)) if (key === "$ref" && typeof value === "string") {
|
|
447
|
+
const match = value.match(/^#\/components\/schemas\/(.+)$/);
|
|
448
|
+
if (match) refs.add(match[1]);
|
|
449
|
+
} else collectRefs(value, refs);
|
|
450
|
+
return refs;
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Sort schemas topologically so referenced schemas appear first.
|
|
454
|
+
*/
|
|
455
|
+
function sortSchemas(schemas) {
|
|
456
|
+
const deps = /* @__PURE__ */ new Map();
|
|
457
|
+
for (const [name, schema] of Object.entries(schemas)) deps.set(name, Array.from(collectRefs(schema)));
|
|
458
|
+
const sorted = [];
|
|
459
|
+
const visited = /* @__PURE__ */ new Set();
|
|
460
|
+
function visit(name, stack = /* @__PURE__ */ new Set()) {
|
|
461
|
+
if (visited.has(name)) return;
|
|
462
|
+
if (stack.has(name)) return;
|
|
463
|
+
stack.add(name);
|
|
464
|
+
const children = deps.get(name) || [];
|
|
465
|
+
for (const child of children) if (deps.has(child)) visit(child, stack);
|
|
466
|
+
stack.delete(name);
|
|
467
|
+
visited.add(name);
|
|
468
|
+
sorted.push(name);
|
|
469
|
+
}
|
|
470
|
+
for (const name of Object.keys(schemas)) visit(name);
|
|
471
|
+
const sortedSchemas = {};
|
|
472
|
+
for (const name of sorted) sortedSchemas[name] = schemas[name];
|
|
473
|
+
return sortedSchemas;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Extract schema from content object (used by responses and requestBodies).
|
|
477
|
+
* Returns null if the schema is just a $ref (not a unique type definition).
|
|
478
|
+
*/
|
|
479
|
+
function extractSchemaFromContent(content, preferredContentType) {
|
|
480
|
+
if (!content) return null;
|
|
481
|
+
const firstContentType = Object.keys(content)[0] || "application/json";
|
|
482
|
+
const schema = content[preferredContentType || firstContentType]?.schema;
|
|
483
|
+
if (schema && "$ref" in schema) return null;
|
|
484
|
+
return schema || null;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Get semantic suffix for a schema source.
|
|
488
|
+
*/
|
|
489
|
+
function getSemanticSuffix(source) {
|
|
490
|
+
switch (source) {
|
|
491
|
+
case "schemas": return "Schema";
|
|
492
|
+
case "responses": return "Response";
|
|
493
|
+
case "requestBodies": return "Request";
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Legacy resolution strategy - no collision detection, just use original names.
|
|
498
|
+
* This preserves backward compatibility when collisionDetection is false.
|
|
499
|
+
* @deprecated
|
|
500
|
+
*/
|
|
501
|
+
function legacyResolve(schemasWithMeta) {
|
|
502
|
+
const schemas = {};
|
|
503
|
+
const nameMapping = /* @__PURE__ */ new Map();
|
|
504
|
+
for (const item of schemasWithMeta) {
|
|
505
|
+
schemas[item.originalName] = item.schema;
|
|
506
|
+
const refPath = `#/components/${item.source}/${item.originalName}`;
|
|
507
|
+
nameMapping.set(refPath, item.originalName);
|
|
508
|
+
}
|
|
509
|
+
return {
|
|
510
|
+
schemas,
|
|
511
|
+
nameMapping
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Resolve name collisions by applying suffixes based on collision type.
|
|
516
|
+
*
|
|
517
|
+
* Strategy:
|
|
518
|
+
* - Same-component collisions (e.g., "Variant" + "variant" both in schemas): numeric suffixes (Variant, Variant2)
|
|
519
|
+
* - Cross-component collisions (e.g., "Pet" in schemas + "Pet" in requestBodies): semantic suffixes (PetSchema, PetRequest)
|
|
520
|
+
*/
|
|
521
|
+
function resolveCollisions(schemasWithMeta) {
|
|
522
|
+
const schemas = {};
|
|
523
|
+
const nameMapping = /* @__PURE__ */ new Map();
|
|
524
|
+
const normalizedNames = /* @__PURE__ */ new Map();
|
|
525
|
+
for (const item of schemasWithMeta) {
|
|
526
|
+
const normalized = pascalCase(item.originalName);
|
|
527
|
+
if (!normalizedNames.has(normalized)) normalizedNames.set(normalized, []);
|
|
528
|
+
normalizedNames.get(normalized).push(item);
|
|
529
|
+
}
|
|
530
|
+
for (const [, items] of normalizedNames) {
|
|
531
|
+
if (items.length === 1) {
|
|
532
|
+
const item = items[0];
|
|
533
|
+
schemas[item.originalName] = item.schema;
|
|
534
|
+
const refPath = `#/components/${item.source}/${item.originalName}`;
|
|
535
|
+
nameMapping.set(refPath, item.originalName);
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
if (new Set(items.map((item) => item.source)).size === 1) items.forEach((item, index) => {
|
|
539
|
+
const suffix = index === 0 ? "" : (index + 1).toString();
|
|
540
|
+
const uniqueName = item.originalName + suffix;
|
|
541
|
+
schemas[uniqueName] = item.schema;
|
|
542
|
+
const refPath = `#/components/${item.source}/${item.originalName}`;
|
|
543
|
+
nameMapping.set(refPath, uniqueName);
|
|
544
|
+
});
|
|
545
|
+
else items.forEach((item) => {
|
|
546
|
+
const suffix = getSemanticSuffix(item.source);
|
|
547
|
+
const uniqueName = item.originalName + suffix;
|
|
548
|
+
schemas[uniqueName] = item.schema;
|
|
549
|
+
const refPath = `#/components/${item.source}/${item.originalName}`;
|
|
550
|
+
nameMapping.set(refPath, uniqueName);
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
return {
|
|
554
|
+
schemas,
|
|
555
|
+
nameMapping
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
//#endregion
|
|
559
|
+
//#region src/Oas.ts
|
|
560
|
+
/**
|
|
561
|
+
* Prefix used to create synthetic `$ref` values for anonymous (inline) discriminator schemas.
|
|
562
|
+
* The suffix is the schema index within the discriminator's `oneOf`/`anyOf` array.
|
|
563
|
+
* @example `#kubb-inline-0`
|
|
564
|
+
*/
|
|
565
|
+
const KUBB_INLINE_REF_PREFIX = "#kubb-inline-";
|
|
566
|
+
var Oas = class extends BaseOas {
|
|
567
|
+
#options = { discriminator: "strict" };
|
|
568
|
+
document;
|
|
569
|
+
constructor(document) {
|
|
570
|
+
super(document, void 0);
|
|
571
|
+
this.document = document;
|
|
572
|
+
}
|
|
573
|
+
setOptions(options) {
|
|
574
|
+
this.#options = {
|
|
575
|
+
...this.#options,
|
|
576
|
+
...options
|
|
577
|
+
};
|
|
578
|
+
if (this.#options.discriminator === "inherit") this.#applyDiscriminatorInheritance();
|
|
579
|
+
}
|
|
580
|
+
get options() {
|
|
581
|
+
return this.#options;
|
|
582
|
+
}
|
|
583
|
+
get($ref) {
|
|
584
|
+
const origRef = $ref;
|
|
585
|
+
$ref = $ref.trim();
|
|
586
|
+
if ($ref === "") return null;
|
|
587
|
+
if ($ref.startsWith("#")) $ref = globalThis.decodeURIComponent($ref.substring(1));
|
|
588
|
+
else return null;
|
|
589
|
+
const current = jsonpointer.get(this.api, $ref);
|
|
590
|
+
if (!current) throw new Error(`Could not find a definition for ${origRef}.`);
|
|
591
|
+
return current;
|
|
592
|
+
}
|
|
593
|
+
getKey($ref) {
|
|
594
|
+
const key = $ref.split("/").pop();
|
|
595
|
+
return key === "" ? void 0 : key;
|
|
596
|
+
}
|
|
597
|
+
set($ref, value) {
|
|
598
|
+
$ref = $ref.trim();
|
|
599
|
+
if ($ref === "") return false;
|
|
600
|
+
if ($ref.startsWith("#")) {
|
|
601
|
+
$ref = globalThis.decodeURIComponent($ref.substring(1));
|
|
602
|
+
jsonpointer.set(this.api, $ref, value);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
#setDiscriminator(schema) {
|
|
606
|
+
const { mapping = {}, propertyName } = schema.discriminator;
|
|
607
|
+
if (this.#options.discriminator === "inherit") Object.entries(mapping).forEach(([mappingKey, mappingValue]) => {
|
|
608
|
+
if (mappingValue) {
|
|
609
|
+
const childSchema = this.get(mappingValue);
|
|
610
|
+
if (!childSchema) return;
|
|
611
|
+
if (!childSchema.properties) childSchema.properties = {};
|
|
612
|
+
const property = childSchema.properties[propertyName];
|
|
613
|
+
if (childSchema.properties) {
|
|
614
|
+
childSchema.properties[propertyName] = {
|
|
615
|
+
...childSchema.properties ? childSchema.properties[propertyName] : {},
|
|
616
|
+
enum: [...property?.enum?.filter((value) => value !== mappingKey) ?? [], mappingKey]
|
|
617
|
+
};
|
|
618
|
+
childSchema.required = typeof childSchema.required === "boolean" ? childSchema.required : [...new Set([...childSchema.required ?? [], propertyName])];
|
|
619
|
+
this.set(mappingValue, childSchema);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
getDiscriminator(schema) {
|
|
625
|
+
if (!isDiscriminator(schema) || !schema) return null;
|
|
626
|
+
const { mapping = {}, propertyName } = schema.discriminator;
|
|
627
|
+
/**
|
|
628
|
+
* Helper to extract discriminator value from a schema.
|
|
629
|
+
* Checks in order:
|
|
630
|
+
* 1. Extension property matching propertyName (e.g., x-linode-ref-name)
|
|
631
|
+
* 2. Property with const value
|
|
632
|
+
* 3. Property with single enum value
|
|
633
|
+
* 4. Title as fallback
|
|
634
|
+
*/
|
|
635
|
+
const getDiscriminatorValue = (schema) => {
|
|
636
|
+
if (!schema) return null;
|
|
637
|
+
if (propertyName.startsWith("x-")) {
|
|
638
|
+
const extensionValue = schema[propertyName];
|
|
639
|
+
if (extensionValue && typeof extensionValue === "string") return extensionValue;
|
|
640
|
+
}
|
|
641
|
+
const propertySchema = schema.properties?.[propertyName];
|
|
642
|
+
if (propertySchema && "const" in propertySchema && propertySchema.const !== void 0) return String(propertySchema.const);
|
|
643
|
+
if (propertySchema && propertySchema.enum?.length === 1) return String(propertySchema.enum[0]);
|
|
644
|
+
return schema.title || null;
|
|
645
|
+
};
|
|
646
|
+
/**
|
|
647
|
+
* Process oneOf/anyOf items to build mapping.
|
|
648
|
+
* Handles both $ref and inline schemas.
|
|
649
|
+
*/
|
|
650
|
+
const processSchemas = (schemas, existingMapping) => {
|
|
651
|
+
schemas.forEach((schemaItem, index) => {
|
|
652
|
+
if (isReference(schemaItem)) {
|
|
653
|
+
const key = this.getKey(schemaItem.$ref);
|
|
654
|
+
try {
|
|
655
|
+
const discriminatorValue = getDiscriminatorValue(this.get(schemaItem.$ref));
|
|
656
|
+
const canAdd = key && !Object.values(existingMapping).includes(schemaItem.$ref);
|
|
657
|
+
if (canAdd && discriminatorValue) existingMapping[discriminatorValue] = schemaItem.$ref;
|
|
658
|
+
else if (canAdd) existingMapping[key] = schemaItem.$ref;
|
|
659
|
+
} catch (_error) {
|
|
660
|
+
if (key && !Object.values(existingMapping).includes(schemaItem.$ref)) existingMapping[key] = schemaItem.$ref;
|
|
661
|
+
}
|
|
662
|
+
} else {
|
|
663
|
+
const discriminatorValue = getDiscriminatorValue(schemaItem);
|
|
664
|
+
if (discriminatorValue) existingMapping[discriminatorValue] = `${KUBB_INLINE_REF_PREFIX}${index}`;
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
};
|
|
668
|
+
if (schema.oneOf) processSchemas(schema.oneOf, mapping);
|
|
669
|
+
if (schema.anyOf) processSchemas(schema.anyOf, mapping);
|
|
670
|
+
return {
|
|
671
|
+
...schema.discriminator,
|
|
672
|
+
mapping
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
dereferenceWithRef(schema) {
|
|
676
|
+
if (isReference(schema)) return {
|
|
677
|
+
...schema,
|
|
678
|
+
...this.get(schema.$ref),
|
|
679
|
+
$ref: schema.$ref
|
|
680
|
+
};
|
|
681
|
+
return schema;
|
|
682
|
+
}
|
|
683
|
+
#applyDiscriminatorInheritance() {
|
|
684
|
+
const components = this.api.components;
|
|
685
|
+
if (!components?.schemas) return;
|
|
686
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
687
|
+
const enqueue = (value) => {
|
|
688
|
+
if (!value) return;
|
|
689
|
+
if (Array.isArray(value)) {
|
|
690
|
+
for (const item of value) enqueue(item);
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
if (typeof value === "object") visit(value);
|
|
694
|
+
};
|
|
695
|
+
const visit = (schema) => {
|
|
696
|
+
if (!schema || typeof schema !== "object") return;
|
|
697
|
+
if (isReference(schema)) {
|
|
698
|
+
visit(this.get(schema.$ref));
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
const schemaObject = schema;
|
|
702
|
+
if (visited.has(schemaObject)) return;
|
|
703
|
+
visited.add(schemaObject);
|
|
704
|
+
if (isDiscriminator(schemaObject)) this.#setDiscriminator(schemaObject);
|
|
705
|
+
if ("allOf" in schemaObject) enqueue(schemaObject.allOf);
|
|
706
|
+
if ("oneOf" in schemaObject) enqueue(schemaObject.oneOf);
|
|
707
|
+
if ("anyOf" in schemaObject) enqueue(schemaObject.anyOf);
|
|
708
|
+
if ("not" in schemaObject) enqueue(schemaObject.not);
|
|
709
|
+
if ("items" in schemaObject) enqueue(schemaObject.items);
|
|
710
|
+
if ("prefixItems" in schemaObject) enqueue(schemaObject.prefixItems);
|
|
711
|
+
if (schemaObject.properties) enqueue(Object.values(schemaObject.properties));
|
|
712
|
+
if (schemaObject.additionalProperties && typeof schemaObject.additionalProperties === "object") enqueue(schemaObject.additionalProperties);
|
|
713
|
+
};
|
|
714
|
+
for (const schema of Object.values(components.schemas)) visit(schema);
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Oas does not have a getResponseBody(contentType)
|
|
718
|
+
*/
|
|
719
|
+
#getResponseBodyFactory(responseBody) {
|
|
720
|
+
function hasResponseBody(res = responseBody) {
|
|
721
|
+
return !!res;
|
|
722
|
+
}
|
|
723
|
+
return (contentType) => {
|
|
724
|
+
if (!hasResponseBody(responseBody)) return false;
|
|
725
|
+
if (isReference(responseBody)) return false;
|
|
726
|
+
if (!responseBody.content) return false;
|
|
727
|
+
if (contentType) {
|
|
728
|
+
if (!(contentType in responseBody.content)) return false;
|
|
729
|
+
return responseBody.content[contentType];
|
|
730
|
+
}
|
|
731
|
+
let availableContentType;
|
|
732
|
+
const contentTypes = Object.keys(responseBody.content);
|
|
733
|
+
contentTypes.forEach((mt) => {
|
|
734
|
+
if (!availableContentType && matchesMimeType.json(mt)) availableContentType = mt;
|
|
735
|
+
});
|
|
736
|
+
if (!availableContentType) contentTypes.forEach((mt) => {
|
|
737
|
+
if (!availableContentType) availableContentType = mt;
|
|
738
|
+
});
|
|
739
|
+
if (availableContentType) return [
|
|
740
|
+
availableContentType,
|
|
741
|
+
responseBody.content[availableContentType],
|
|
742
|
+
...responseBody.description ? [responseBody.description] : []
|
|
743
|
+
];
|
|
744
|
+
return false;
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
getResponseSchema(operation, statusCode) {
|
|
748
|
+
if (operation.schema.responses) Object.keys(operation.schema.responses).forEach((key) => {
|
|
749
|
+
const schema = operation.schema.responses[key];
|
|
750
|
+
const $ref = isReference(schema) ? schema.$ref : void 0;
|
|
751
|
+
if (schema && $ref) operation.schema.responses[key] = this.get($ref);
|
|
752
|
+
});
|
|
753
|
+
const getResponseBody = this.#getResponseBodyFactory(operation.getResponseByStatusCode(statusCode));
|
|
754
|
+
const { contentType } = this.#options;
|
|
755
|
+
const responseBody = getResponseBody(contentType);
|
|
756
|
+
if (responseBody === false) return {};
|
|
757
|
+
const schema = Array.isArray(responseBody) ? responseBody[1].schema : responseBody.schema;
|
|
758
|
+
if (!schema) return {};
|
|
759
|
+
return this.dereferenceWithRef(schema);
|
|
760
|
+
}
|
|
761
|
+
getRequestSchema(operation) {
|
|
762
|
+
const { contentType } = this.#options;
|
|
763
|
+
if (operation.schema.requestBody) operation.schema.requestBody = this.dereferenceWithRef(operation.schema.requestBody);
|
|
764
|
+
const requestBody = operation.getRequestBody(contentType);
|
|
765
|
+
if (requestBody === false) return;
|
|
766
|
+
const schema = Array.isArray(requestBody) ? requestBody[1].schema : requestBody.schema;
|
|
767
|
+
if (!schema) return;
|
|
768
|
+
return this.dereferenceWithRef(schema);
|
|
769
|
+
}
|
|
770
|
+
getParametersSchema(operation, inKey) {
|
|
771
|
+
const { contentType = operation.getContentType() } = this.#options;
|
|
772
|
+
const resolveParams = (params) => params.map((p) => this.dereferenceWithRef(p)).filter((p) => !!p && typeof p === "object" && "in" in p && "name" in p);
|
|
773
|
+
const operationParams = resolveParams(operation.schema?.parameters || []);
|
|
774
|
+
const pathItem = this.api?.paths?.[operation.path];
|
|
775
|
+
const pathLevelParams = resolveParams(pathItem && !isReference(pathItem) && pathItem.parameters ? pathItem.parameters : []);
|
|
776
|
+
const paramMap = /* @__PURE__ */ new Map();
|
|
777
|
+
for (const p of pathLevelParams) if (p.name && p.in) paramMap.set(`${p.in}:${p.name}`, p);
|
|
778
|
+
for (const p of operationParams) if (p.name && p.in) paramMap.set(`${p.in}:${p.name}`, p);
|
|
779
|
+
const params = Array.from(paramMap.values()).filter((v) => v.in === inKey);
|
|
780
|
+
if (!params.length) return null;
|
|
781
|
+
return params.reduce((schema, pathParameters) => {
|
|
782
|
+
const property = pathParameters.content?.[contentType]?.schema ?? pathParameters.schema;
|
|
783
|
+
const required = typeof schema.required === "boolean" ? schema.required : [...schema.required || [], pathParameters.required ? pathParameters.name : void 0].filter(Boolean);
|
|
784
|
+
const getDefaultStyle = (location) => {
|
|
785
|
+
if (location === "query") return "form";
|
|
786
|
+
if (location === "path") return "simple";
|
|
787
|
+
return "simple";
|
|
788
|
+
};
|
|
789
|
+
const style = pathParameters.style || getDefaultStyle(inKey);
|
|
790
|
+
const explode = pathParameters.explode !== void 0 ? pathParameters.explode : style === "form";
|
|
791
|
+
if (inKey === "query" && style === "form" && explode === true && property?.type === "object" && property?.additionalProperties && !property?.properties) return {
|
|
792
|
+
...schema,
|
|
793
|
+
description: pathParameters.description || schema.description,
|
|
794
|
+
deprecated: schema.deprecated,
|
|
795
|
+
example: property.example || schema.example,
|
|
796
|
+
additionalProperties: property.additionalProperties
|
|
797
|
+
};
|
|
798
|
+
return {
|
|
799
|
+
...schema,
|
|
800
|
+
description: schema.description,
|
|
801
|
+
deprecated: schema.deprecated,
|
|
802
|
+
example: schema.example,
|
|
803
|
+
required,
|
|
804
|
+
properties: {
|
|
805
|
+
...schema.properties,
|
|
806
|
+
[pathParameters.name]: {
|
|
807
|
+
description: pathParameters.description,
|
|
808
|
+
...property
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
};
|
|
812
|
+
}, {
|
|
813
|
+
type: "object",
|
|
814
|
+
required: [],
|
|
815
|
+
properties: {}
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
async validate() {
|
|
819
|
+
return validate(this.api);
|
|
820
|
+
}
|
|
821
|
+
flattenSchema(schema) {
|
|
822
|
+
return flattenSchema(schema);
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Get schemas from OpenAPI components (schemas, responses, requestBodies).
|
|
826
|
+
* Returns schemas in dependency order along with name mapping for collision resolution.
|
|
827
|
+
*/
|
|
828
|
+
getSchemas(options = {}) {
|
|
829
|
+
const contentType = options.contentType ?? this.#options.contentType;
|
|
830
|
+
const includes = options.includes ?? [
|
|
831
|
+
"schemas",
|
|
832
|
+
"requestBodies",
|
|
833
|
+
"responses"
|
|
834
|
+
];
|
|
835
|
+
const shouldResolveCollisions = options.collisionDetection ?? this.#options.collisionDetection ?? false;
|
|
836
|
+
const components = this.getDefinition().components;
|
|
837
|
+
const schemasWithMeta = [];
|
|
838
|
+
if (includes.includes("schemas")) {
|
|
839
|
+
const componentSchemas = components?.schemas || {};
|
|
840
|
+
for (const [name, schemaObject] of Object.entries(componentSchemas)) {
|
|
841
|
+
let schema = schemaObject;
|
|
842
|
+
if (isReference(schemaObject)) {
|
|
843
|
+
const resolved = this.get(schemaObject.$ref);
|
|
844
|
+
if (resolved && !isReference(resolved)) schema = resolved;
|
|
845
|
+
}
|
|
846
|
+
schemasWithMeta.push({
|
|
847
|
+
schema,
|
|
848
|
+
source: "schemas",
|
|
849
|
+
originalName: name
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
if (includes.includes("responses")) {
|
|
854
|
+
const responses = components?.responses || {};
|
|
855
|
+
for (const [name, response] of Object.entries(responses)) {
|
|
856
|
+
const schema = extractSchemaFromContent(response.content, contentType);
|
|
857
|
+
if (schema) {
|
|
858
|
+
let resolvedSchema = schema;
|
|
859
|
+
if (isReference(schema)) {
|
|
860
|
+
const resolved = this.get(schema.$ref);
|
|
861
|
+
if (resolved && !isReference(resolved)) resolvedSchema = resolved;
|
|
862
|
+
}
|
|
863
|
+
schemasWithMeta.push({
|
|
864
|
+
schema: resolvedSchema,
|
|
865
|
+
source: "responses",
|
|
866
|
+
originalName: name
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
if (includes.includes("requestBodies")) {
|
|
872
|
+
const requestBodies = components?.requestBodies || {};
|
|
873
|
+
for (const [name, request] of Object.entries(requestBodies)) {
|
|
874
|
+
const schema = extractSchemaFromContent(request.content, contentType);
|
|
875
|
+
if (schema) {
|
|
876
|
+
let resolvedSchema = schema;
|
|
877
|
+
if (isReference(schema)) {
|
|
878
|
+
const resolved = this.get(schema.$ref);
|
|
879
|
+
if (resolved && !isReference(resolved)) resolvedSchema = resolved;
|
|
880
|
+
}
|
|
881
|
+
schemasWithMeta.push({
|
|
882
|
+
schema: resolvedSchema,
|
|
883
|
+
source: "requestBodies",
|
|
884
|
+
originalName: name
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
const { schemas, nameMapping } = shouldResolveCollisions ? resolveCollisions(schemasWithMeta) : legacyResolve(schemasWithMeta);
|
|
890
|
+
return {
|
|
891
|
+
schemas: sortSchemas(schemas),
|
|
892
|
+
nameMapping
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
//#endregion
|
|
897
|
+
//#region src/resolveServerUrl.ts
|
|
898
|
+
/**
|
|
899
|
+
* Resolves an OpenAPI server URL by substituting `{variable}` placeholders
|
|
900
|
+
* with values from `overrides` (user-provided) or the spec-defined defaults.
|
|
901
|
+
*
|
|
902
|
+
* Throws if an override value is not in the variable's `enum` list.
|
|
903
|
+
*/
|
|
904
|
+
function resolveServerUrl(server, overrides) {
|
|
905
|
+
if (!server.variables) return server.url;
|
|
906
|
+
let url = server.url;
|
|
907
|
+
for (const [key, variable] of Object.entries(server.variables)) {
|
|
908
|
+
const value = overrides?.[key] ?? (variable.default != null ? String(variable.default) : void 0);
|
|
909
|
+
if (value === void 0) continue;
|
|
910
|
+
if (variable.enum?.length && !variable.enum.some((e) => String(e) === value)) throw new Error(`Invalid server variable value '${value}' for '${key}' when resolving ${server.url}. Valid values are: ${variable.enum.join(", ")}.`);
|
|
911
|
+
url = url.replaceAll(`{${key}}`, value);
|
|
912
|
+
}
|
|
913
|
+
return url;
|
|
914
|
+
}
|
|
915
|
+
//#endregion
|
|
916
|
+
export { ENUM_EXTENSION_KEYS, FORMAT_MAP, httpMethods as HttpMethods, httpMethods, KNOWN_MEDIA_TYPES, KUBB_INLINE_REF_PREFIX, Oas, STRUCTURAL_KEYS, flattenSchema, getDefaultValue, isAllOptional, isDiscriminator, isNullable, isOpenApiV3_1Document, isOptional, isParameterObject, isReference, isRequired, merge, parse, parseFromConfig, resolveServerUrl, validate };
|
|
917
|
+
|
|
918
|
+
//# sourceMappingURL=index.js.map
|