@kubb/adapter-oas 5.0.0-beta.15 → 5.0.0-beta.16
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 +150 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +149 -41
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter.bench.ts +40 -10
- package/src/adapter.ts +108 -17
- package/src/discriminator.ts +48 -29
- package/src/parser.ts +2 -2
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./chunk--u3MIqq1.js";
|
|
2
2
|
import { ast, createAdapter } from "@kubb/core";
|
|
3
|
+
import BaseOas from "oas";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { bundle, loadConfig } from "@redocly/openapi-core";
|
|
5
6
|
import OASNormalize from "oas-normalize";
|
|
6
7
|
import swagger2openapi from "swagger2openapi";
|
|
7
|
-
import BaseOas from "oas";
|
|
8
8
|
import { isRef } from "oas/types";
|
|
9
9
|
import { matchesMimeType } from "oas/utils";
|
|
10
10
|
//#region src/constants.ts
|
|
@@ -129,23 +129,16 @@ const typeOptionMap = new Map([
|
|
|
129
129
|
//#endregion
|
|
130
130
|
//#region src/discriminator.ts
|
|
131
131
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* Finds every union schema in `input.schemas` that has a `discriminatorPropertyName`, collects the
|
|
135
|
-
* enum value each union member is mapped to, then adds (or replaces) that property on the matching
|
|
136
|
-
* child object schema.
|
|
132
|
+
* Builds a map of child schema names → discriminator patch data by scanning the given
|
|
133
|
+
* top-level AST schema nodes for union schemas that carry a `discriminatorPropertyName`.
|
|
137
134
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* ```ts
|
|
142
|
-
* const { root } = parseOas(document, options)
|
|
143
|
-
* const next = applyDiscriminatorInheritance(root)
|
|
144
|
-
* ```
|
|
135
|
+
* Extracted from `applyDiscriminatorInheritance` so the streaming path can call it on a
|
|
136
|
+
* small pre-parsed subset of schemas (only the discriminator parents) rather than on all
|
|
137
|
+
* schemas at once.
|
|
145
138
|
*/
|
|
146
|
-
function
|
|
139
|
+
function buildDiscriminatorChildMap(schemas) {
|
|
147
140
|
const childMap = /* @__PURE__ */ new Map();
|
|
148
|
-
for (const schema of
|
|
141
|
+
for (const schema of schemas) {
|
|
149
142
|
let unionNode = ast.narrowSchema(schema, "union");
|
|
150
143
|
if (!unionNode) {
|
|
151
144
|
const intersectionMembers = ast.narrowSchema(schema, "intersection")?.members;
|
|
@@ -182,29 +175,56 @@ function applyDiscriminatorInheritance(root) {
|
|
|
182
175
|
});
|
|
183
176
|
}
|
|
184
177
|
}
|
|
178
|
+
return childMap;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Patches a single top-level `SchemaNode` with its discriminator entry (adds or replaces
|
|
182
|
+
* the discriminant property). Used by the streaming path to apply patches inline per yield
|
|
183
|
+
* without buffering all schemas.
|
|
184
|
+
*/
|
|
185
|
+
function patchDiscriminatorNode(node, entry) {
|
|
186
|
+
const objectNode = ast.narrowSchema(node, "object");
|
|
187
|
+
if (!objectNode) return node;
|
|
188
|
+
const { propertyName, enumValues } = entry;
|
|
189
|
+
const enumSchema = ast.createSchema({
|
|
190
|
+
type: "enum",
|
|
191
|
+
enumValues
|
|
192
|
+
});
|
|
193
|
+
const newProp = ast.createProperty({
|
|
194
|
+
name: propertyName,
|
|
195
|
+
required: true,
|
|
196
|
+
schema: enumSchema
|
|
197
|
+
});
|
|
198
|
+
const existingIdx = objectNode.properties.findIndex((p) => p.name === propertyName);
|
|
199
|
+
const newProperties = existingIdx >= 0 ? objectNode.properties.map((p, i) => i === existingIdx ? newProp : p) : [...objectNode.properties, newProp];
|
|
200
|
+
return {
|
|
201
|
+
...objectNode,
|
|
202
|
+
properties: newProperties
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Injects discriminator enum values into child schemas so they know which value identifies them.
|
|
207
|
+
*
|
|
208
|
+
* Finds every union schema in `input.schemas` that has a `discriminatorPropertyName`, collects the
|
|
209
|
+
* enum value each union member is mapped to, then adds (or replaces) that property on the matching
|
|
210
|
+
* child object schema.
|
|
211
|
+
*
|
|
212
|
+
* Returns a new `InputNode` — the original is never mutated.
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* const { root } = parseOas(document, options)
|
|
217
|
+
* const next = applyDiscriminatorInheritance(root)
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
function applyDiscriminatorInheritance(root) {
|
|
221
|
+
const childMap = buildDiscriminatorChildMap(root.schemas);
|
|
185
222
|
if (childMap.size === 0) return root;
|
|
186
223
|
return ast.transform(root, { schema(node, { parent }) {
|
|
187
224
|
if (parent?.kind !== "Input" || !node.name) return;
|
|
188
225
|
const entry = childMap.get(node.name);
|
|
189
226
|
if (!entry) return;
|
|
190
|
-
|
|
191
|
-
if (!objectNode) return;
|
|
192
|
-
const { propertyName, enumValues } = entry;
|
|
193
|
-
const enumSchema = ast.createSchema({
|
|
194
|
-
type: "enum",
|
|
195
|
-
enumValues
|
|
196
|
-
});
|
|
197
|
-
const newProp = ast.createProperty({
|
|
198
|
-
name: propertyName,
|
|
199
|
-
required: true,
|
|
200
|
-
schema: enumSchema
|
|
201
|
-
});
|
|
202
|
-
const existingIdx = objectNode.properties.findIndex((p) => p.name === propertyName);
|
|
203
|
-
const newProperties = existingIdx >= 0 ? objectNode.properties.map((p, i) => i === existingIdx ? newProp : p) : [...objectNode.properties, newProp];
|
|
204
|
-
return {
|
|
205
|
-
...objectNode,
|
|
206
|
-
properties: newProperties
|
|
207
|
-
};
|
|
227
|
+
return patchDiscriminatorNode(node, entry);
|
|
208
228
|
} });
|
|
209
229
|
}
|
|
210
230
|
//#endregion
|
|
@@ -1174,7 +1194,7 @@ function normalizeArrayEnum(schema) {
|
|
|
1174
1194
|
* Each converter branch (`convertRef`, `convertAllOf`, etc.) mutually recursively calls `parseSchema`,
|
|
1175
1195
|
* made possible by hoisting of function declarations.
|
|
1176
1196
|
*
|
|
1177
|
-
* @
|
|
1197
|
+
* @internal
|
|
1178
1198
|
*/
|
|
1179
1199
|
function createSchemaParser(ctx) {
|
|
1180
1200
|
const document = ctx.document;
|
|
@@ -1917,8 +1937,36 @@ const adapterOasName = "oas";
|
|
|
1917
1937
|
*/
|
|
1918
1938
|
const adapterOas = createAdapter((options) => {
|
|
1919
1939
|
const { validate = true, contentType, serverIndex, serverVariables, discriminator = "strict", dateType = DEFAULT_PARSER_OPTIONS.dateType, integerType = DEFAULT_PARSER_OPTIONS.integerType, unknownType = DEFAULT_PARSER_OPTIONS.unknownType, enumSuffix = DEFAULT_PARSER_OPTIONS.enumSuffix, emptySchemaType = unknownType || DEFAULT_PARSER_OPTIONS.emptySchemaType } = options;
|
|
1940
|
+
const parserOptions = {
|
|
1941
|
+
...DEFAULT_PARSER_OPTIONS,
|
|
1942
|
+
dateType,
|
|
1943
|
+
integerType,
|
|
1944
|
+
unknownType,
|
|
1945
|
+
emptySchemaType,
|
|
1946
|
+
enumSuffix
|
|
1947
|
+
};
|
|
1920
1948
|
let nameMapping = /* @__PURE__ */ new Map();
|
|
1921
|
-
let parsedDocument;
|
|
1949
|
+
let parsedDocument = null;
|
|
1950
|
+
let schemaObjects = null;
|
|
1951
|
+
function resolveBaseURL(document) {
|
|
1952
|
+
const server = serverIndex !== void 0 ? document.servers?.at(serverIndex) : void 0;
|
|
1953
|
+
return server?.url ? resolveServerUrl(server, serverVariables) : void 0;
|
|
1954
|
+
}
|
|
1955
|
+
async function ensureDocument(source) {
|
|
1956
|
+
if (parsedDocument) return parsedDocument;
|
|
1957
|
+
const fresh = await parseFromConfig(source);
|
|
1958
|
+
if (validate) await validateDocument(fresh);
|
|
1959
|
+
parsedDocument = fresh;
|
|
1960
|
+
return fresh;
|
|
1961
|
+
}
|
|
1962
|
+
async function ensureSchemas(document) {
|
|
1963
|
+
if (!schemaObjects) {
|
|
1964
|
+
const result = getSchemas(document, { contentType });
|
|
1965
|
+
schemaObjects = result.schemas;
|
|
1966
|
+
nameMapping = result.nameMapping;
|
|
1967
|
+
}
|
|
1968
|
+
return schemaObjects;
|
|
1969
|
+
}
|
|
1922
1970
|
return {
|
|
1923
1971
|
name: "oas",
|
|
1924
1972
|
get options() {
|
|
@@ -1957,10 +2005,7 @@ const adapterOas = createAdapter((options) => {
|
|
|
1957
2005
|
});
|
|
1958
2006
|
},
|
|
1959
2007
|
async parse(source) {
|
|
1960
|
-
const document = await
|
|
1961
|
-
if (validate) await validateDocument(document);
|
|
1962
|
-
const server = serverIndex !== void 0 ? document.servers?.at(serverIndex) : void 0;
|
|
1963
|
-
const baseURL = server?.url ? resolveServerUrl(server, serverVariables) : void 0;
|
|
2008
|
+
const document = await ensureDocument(source);
|
|
1964
2009
|
const { root: parsedRoot, nameMapping: parsedNameMapping } = parseOas(document, {
|
|
1965
2010
|
contentType,
|
|
1966
2011
|
dateType,
|
|
@@ -1971,16 +2016,79 @@ const adapterOas = createAdapter((options) => {
|
|
|
1971
2016
|
});
|
|
1972
2017
|
const node = discriminator === "inherit" ? applyDiscriminatorInheritance(parsedRoot) : parsedRoot;
|
|
1973
2018
|
nameMapping = parsedNameMapping;
|
|
1974
|
-
parsedDocument = document;
|
|
1975
2019
|
return ast.createInput({
|
|
1976
2020
|
...node,
|
|
1977
2021
|
meta: {
|
|
1978
2022
|
title: document.info?.title,
|
|
1979
2023
|
description: document.info?.description,
|
|
1980
2024
|
version: document.info?.version,
|
|
1981
|
-
baseURL
|
|
2025
|
+
baseURL: resolveBaseURL(document)
|
|
1982
2026
|
}
|
|
1983
2027
|
});
|
|
2028
|
+
},
|
|
2029
|
+
async count(source) {
|
|
2030
|
+
const document = await ensureDocument(source);
|
|
2031
|
+
const schemas = await ensureSchemas(document);
|
|
2032
|
+
const baseOas = new BaseOas(document);
|
|
2033
|
+
const operationCount = Object.values(baseOas.getPaths()).flatMap(Object.values).filter(Boolean).length;
|
|
2034
|
+
return {
|
|
2035
|
+
schemas: Object.keys(schemas).length,
|
|
2036
|
+
operations: operationCount
|
|
2037
|
+
};
|
|
2038
|
+
},
|
|
2039
|
+
async stream(source) {
|
|
2040
|
+
const document = await ensureDocument(source);
|
|
2041
|
+
const schemas = await ensureSchemas(document);
|
|
2042
|
+
let discriminatorChildMap = null;
|
|
2043
|
+
if (discriminator === "inherit") {
|
|
2044
|
+
const { parseSchema: _preParser } = createSchemaParser({
|
|
2045
|
+
document,
|
|
2046
|
+
contentType
|
|
2047
|
+
});
|
|
2048
|
+
const parentNodes = [];
|
|
2049
|
+
for (const [name, schema] of Object.entries(schemas)) if ((schema.oneOf ?? schema.anyOf) && schema.discriminator?.propertyName) parentNodes.push(_preParser({
|
|
2050
|
+
schema,
|
|
2051
|
+
name
|
|
2052
|
+
}, parserOptions));
|
|
2053
|
+
if (parentNodes.length > 0) discriminatorChildMap = buildDiscriminatorChildMap(parentNodes);
|
|
2054
|
+
}
|
|
2055
|
+
const schemasIterable = { [Symbol.asyncIterator]() {
|
|
2056
|
+
return (async function* () {
|
|
2057
|
+
const { parseSchema: _parseSchema } = createSchemaParser({
|
|
2058
|
+
document,
|
|
2059
|
+
contentType
|
|
2060
|
+
});
|
|
2061
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
2062
|
+
let node = _parseSchema({
|
|
2063
|
+
schema,
|
|
2064
|
+
name
|
|
2065
|
+
}, parserOptions);
|
|
2066
|
+
const entry = discriminatorChildMap?.get(name);
|
|
2067
|
+
if (entry) node = patchDiscriminatorNode(node, entry);
|
|
2068
|
+
yield node;
|
|
2069
|
+
}
|
|
2070
|
+
})();
|
|
2071
|
+
} };
|
|
2072
|
+
const operationsIterable = { [Symbol.asyncIterator]() {
|
|
2073
|
+
return (async function* () {
|
|
2074
|
+
const { parseOperation: _parseOperation } = createSchemaParser({
|
|
2075
|
+
document,
|
|
2076
|
+
contentType
|
|
2077
|
+
});
|
|
2078
|
+
const paths = new BaseOas(document).getPaths();
|
|
2079
|
+
for (const methods of Object.values(paths)) for (const operation of Object.values(methods)) {
|
|
2080
|
+
if (!operation) continue;
|
|
2081
|
+
const node = _parseOperation(parserOptions, operation);
|
|
2082
|
+
if (node) yield node;
|
|
2083
|
+
}
|
|
2084
|
+
})();
|
|
2085
|
+
} };
|
|
2086
|
+
return ast.createStreamInput(schemasIterable, operationsIterable, {
|
|
2087
|
+
title: document.info?.title,
|
|
2088
|
+
description: document.info?.description,
|
|
2089
|
+
version: document.info?.version,
|
|
2090
|
+
baseURL: resolveBaseURL(document)
|
|
2091
|
+
});
|
|
1984
2092
|
}
|
|
1985
2093
|
};
|
|
1986
2094
|
});
|