@kubb/adapter-oas 5.0.0-beta.30 → 5.0.0-beta.32
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 +92 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +15 -3
- package/dist/index.js +93 -17
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter.ts +13 -4
- package/src/discriminator.ts +2 -35
- package/src/parser.ts +16 -0
- package/src/resolvers.ts +1 -8
- package/src/stream.ts +105 -4
- package/src/types.ts +13 -0
- /package/dist/{chunk--u3MIqq1.js → chunk-C0LytTxp.js} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { t as __name } from "./chunk
|
|
2
|
-
import * as _$_kubb_core0 from "@kubb/core";
|
|
1
|
+
import { t as __name } from "./chunk-C0LytTxp.js";
|
|
3
2
|
import { AdapterFactoryOptions, ast } from "@kubb/core";
|
|
4
3
|
import { DiscriminatorObject as DiscriminatorObject$2, MediaTypeObject as MediaTypeObject$2, OASDocument, ResponseObject as ResponseObject$2, SchemaObject as SchemaObject$2 } from "oas/types";
|
|
5
4
|
import { Operation as Operation$1 } from "oas/operation";
|
|
@@ -476,6 +475,18 @@ type AdapterOasOptions = {
|
|
|
476
475
|
* @default 'strict'
|
|
477
476
|
*/
|
|
478
477
|
discriminator?: 'strict' | 'inherit';
|
|
478
|
+
/**
|
|
479
|
+
* Collapse structurally identical schemas and enums into a single shared definition.
|
|
480
|
+
*
|
|
481
|
+
* Duplicated inline shapes (especially enums repeated across many properties) are hoisted
|
|
482
|
+
* into one named schema; every other occurrence — and any structurally identical top-level
|
|
483
|
+
* component — becomes a `ref` to it. Equality is shape-only: documentation such as
|
|
484
|
+
* `description` and `example` is ignored. Enabled by default; set to `false` to keep every
|
|
485
|
+
* occurrence inline and produce byte-for-byte identical output to earlier versions.
|
|
486
|
+
*
|
|
487
|
+
* @default true
|
|
488
|
+
*/
|
|
489
|
+
dedupe?: boolean;
|
|
479
490
|
} & Partial<ast.ParserOptions>;
|
|
480
491
|
/**
|
|
481
492
|
* Adapter options after defaults have been applied and schema name collisions resolved.
|
|
@@ -486,6 +497,7 @@ type AdapterOasResolvedOptions = {
|
|
|
486
497
|
serverIndex: AdapterOasOptions['serverIndex'];
|
|
487
498
|
serverVariables: AdapterOasOptions['serverVariables'];
|
|
488
499
|
discriminator: NonNullable<AdapterOasOptions['discriminator']>;
|
|
500
|
+
dedupe: NonNullable<AdapterOasOptions['dedupe']>;
|
|
489
501
|
dateType: NonNullable<AdapterOasOptions['dateType']>;
|
|
490
502
|
integerType: NonNullable<AdapterOasOptions['integerType']>;
|
|
491
503
|
unknownType: NonNullable<AdapterOasOptions['unknownType']>;
|
|
@@ -540,7 +552,7 @@ declare const adapterOasName = "oas";
|
|
|
540
552
|
* })
|
|
541
553
|
* ```
|
|
542
554
|
*/
|
|
543
|
-
declare const adapterOas: (options?: AdapterOasOptions | undefined) =>
|
|
555
|
+
declare const adapterOas: (options?: AdapterOasOptions | undefined) => import("@kubb/core").Adapter<AdapterOas>;
|
|
544
556
|
//#endregion
|
|
545
557
|
//#region src/factory.d.ts
|
|
546
558
|
type ValidateDocumentOptions = {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./chunk
|
|
1
|
+
import "./chunk-C0LytTxp.js";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { ast, createAdapter } from "@kubb/core";
|
|
4
4
|
import BaseOas from "oas";
|
|
@@ -1484,6 +1484,15 @@ function createSchemaParser(ctx, dialect = oasDialect) {
|
|
|
1484
1484
|
}, rawOptions);
|
|
1485
1485
|
const nullInEnum = schema.enum.includes(null);
|
|
1486
1486
|
const filteredValues = nullInEnum ? schema.enum.filter((v) => v !== null) : schema.enum;
|
|
1487
|
+
if (nullInEnum && filteredValues.length === 0) return ast.createSchema({
|
|
1488
|
+
type: "null",
|
|
1489
|
+
primitive: "null",
|
|
1490
|
+
name,
|
|
1491
|
+
title: schema.title,
|
|
1492
|
+
description: schema.description,
|
|
1493
|
+
deprecated: schema.deprecated,
|
|
1494
|
+
format: schema.format
|
|
1495
|
+
});
|
|
1487
1496
|
const enumNullable = nullable || nullInEnum || void 0;
|
|
1488
1497
|
const enumDefault = schema.default === null && enumNullable ? void 0 : schema.default;
|
|
1489
1498
|
const enumPrimitive = getPrimitiveType(type);
|
|
@@ -1989,9 +1998,8 @@ function createSchemaParser(ctx, dialect = oasDialect) {
|
|
|
1989
1998
|
* Builds a map of child schema names → discriminator patch data by scanning the given
|
|
1990
1999
|
* top-level AST schema nodes for union schemas that carry a `discriminatorPropertyName`.
|
|
1991
2000
|
*
|
|
1992
|
-
*
|
|
1993
|
-
*
|
|
1994
|
-
* schemas at once.
|
|
2001
|
+
* The streaming path calls this on a small pre-parsed subset of schemas (only the
|
|
2002
|
+
* discriminator parents) rather than on all schemas at once.
|
|
1995
2003
|
*/
|
|
1996
2004
|
function buildDiscriminatorChildMap(schemas) {
|
|
1997
2005
|
const childMap = /* @__PURE__ */ new Map();
|
|
@@ -2065,6 +2073,36 @@ function patchDiscriminatorNode(node, entry) {
|
|
|
2065
2073
|
//#endregion
|
|
2066
2074
|
//#region src/stream.ts
|
|
2067
2075
|
/**
|
|
2076
|
+
* Builds the deduplication plan from the already-parsed top-level schema nodes plus a
|
|
2077
|
+
* single extra parse pass over operations (so duplicates in request/response bodies are seen).
|
|
2078
|
+
*
|
|
2079
|
+
* Only enums and objects are candidates, and object shapes that reference a circular schema are
|
|
2080
|
+
* rejected to avoid hoisting recursive structures. Inline shapes reuse their context-derived
|
|
2081
|
+
* name (collision-resolved against existing component names); shapes without a name stay inline.
|
|
2082
|
+
*/
|
|
2083
|
+
function createDedupePlan({ schemaNodes, operationNodes, schemaNames, circularNames }) {
|
|
2084
|
+
const circularSchemas = new Set(circularNames);
|
|
2085
|
+
const usedNames = new Set(schemaNames);
|
|
2086
|
+
return ast.buildDedupePlan([...schemaNodes, ...operationNodes], {
|
|
2087
|
+
isCandidate: (node) => {
|
|
2088
|
+
if (node.type === "enum") return true;
|
|
2089
|
+
if (node.type !== "object") return false;
|
|
2090
|
+
if (node.name && circularSchemas.has(node.name)) return false;
|
|
2091
|
+
return !ast.containsCircularRef(node, { circularSchemas });
|
|
2092
|
+
},
|
|
2093
|
+
nameFor: (node) => {
|
|
2094
|
+
const base = node.name;
|
|
2095
|
+
if (!base) return null;
|
|
2096
|
+
let name = base;
|
|
2097
|
+
let counter = 2;
|
|
2098
|
+
while (usedNames.has(name)) name = `${base}${counter++}`;
|
|
2099
|
+
usedNames.add(name);
|
|
2100
|
+
return name;
|
|
2101
|
+
},
|
|
2102
|
+
refFor: (name) => `${SCHEMA_REF_PREFIX}${name}`
|
|
2103
|
+
});
|
|
2104
|
+
}
|
|
2105
|
+
/**
|
|
2068
2106
|
* Reads the server URL from the document's `servers` array at `serverIndex`,
|
|
2069
2107
|
* interpolating any `serverVariables` into the URL template.
|
|
2070
2108
|
*
|
|
@@ -2105,7 +2143,7 @@ function resolveBaseUrl({ document, serverIndex, serverVariables }) {
|
|
|
2105
2143
|
* })
|
|
2106
2144
|
* ```
|
|
2107
2145
|
*/
|
|
2108
|
-
function preScan({ schemas, parseSchema, parserOptions, discriminator }) {
|
|
2146
|
+
function preScan({ schemas, parseSchema, parseOperation, baseOas, parserOptions, discriminator, dedupe }) {
|
|
2109
2147
|
const allNodes = [];
|
|
2110
2148
|
const refAliasMap = /* @__PURE__ */ new Map();
|
|
2111
2149
|
const enumNames = [];
|
|
@@ -2120,11 +2158,30 @@ function preScan({ schemas, parseSchema, parserOptions, discriminator }) {
|
|
|
2120
2158
|
if (ast.narrowSchema(node, ast.schemaTypes.enum) && node.name) enumNames.push(node.name);
|
|
2121
2159
|
if (discriminator === "inherit" && (schema.oneOf ?? schema.anyOf) && schema.discriminator?.propertyName) discriminatorParentNodes.push(node);
|
|
2122
2160
|
}
|
|
2161
|
+
const circularNames = [...ast.findCircularSchemas(allNodes)];
|
|
2162
|
+
const discriminatorChildMap = discriminatorParentNodes.length > 0 ? buildDiscriminatorChildMap(discriminatorParentNodes) : null;
|
|
2163
|
+
let dedupePlan = null;
|
|
2164
|
+
if (dedupe) {
|
|
2165
|
+
const operationNodes = [];
|
|
2166
|
+
for (const methods of Object.values(baseOas.getPaths())) for (const operation of Object.values(methods)) {
|
|
2167
|
+
if (!operation) continue;
|
|
2168
|
+
const operationNode = parseOperation(parserOptions, operation);
|
|
2169
|
+
if (operationNode) operationNodes.push(operationNode);
|
|
2170
|
+
}
|
|
2171
|
+
dedupePlan = createDedupePlan({
|
|
2172
|
+
schemaNodes: allNodes,
|
|
2173
|
+
operationNodes,
|
|
2174
|
+
schemaNames: Object.keys(schemas),
|
|
2175
|
+
circularNames
|
|
2176
|
+
});
|
|
2177
|
+
for (const definition of dedupePlan.hoisted) if (definition.type === "enum" && definition.name) enumNames.push(definition.name);
|
|
2178
|
+
}
|
|
2123
2179
|
return {
|
|
2124
2180
|
refAliasMap,
|
|
2125
2181
|
enumNames,
|
|
2126
|
-
circularNames
|
|
2127
|
-
discriminatorChildMap
|
|
2182
|
+
circularNames,
|
|
2183
|
+
discriminatorChildMap,
|
|
2184
|
+
dedupePlan
|
|
2128
2185
|
};
|
|
2129
2186
|
}
|
|
2130
2187
|
/**
|
|
@@ -2145,26 +2202,39 @@ function preScan({ schemas, parseSchema, parserOptions, discriminator }) {
|
|
|
2145
2202
|
* }
|
|
2146
2203
|
* ```
|
|
2147
2204
|
*/
|
|
2148
|
-
function createInputStream({ schemas, parseSchema, parseOperation, baseOas, parserOptions, refAliasMap, discriminatorChildMap, meta }) {
|
|
2205
|
+
function createInputStream({ schemas, parseSchema, parseOperation, baseOas, parserOptions, refAliasMap, discriminatorChildMap, dedupePlan, meta }) {
|
|
2206
|
+
const rewriteTopLevelSchema = (node) => {
|
|
2207
|
+
if (!dedupePlan) return node;
|
|
2208
|
+
const canonical = dedupePlan.canonicalBySignature.get(ast.schemaSignature(node));
|
|
2209
|
+
if (canonical && canonical.name !== node.name) return ast.createSchema({
|
|
2210
|
+
type: "ref",
|
|
2211
|
+
name: node.name ?? null,
|
|
2212
|
+
ref: canonical.ref,
|
|
2213
|
+
description: node.description,
|
|
2214
|
+
deprecated: node.deprecated
|
|
2215
|
+
});
|
|
2216
|
+
return ast.applyDedupe(node, dedupePlan.canonicalBySignature, true);
|
|
2217
|
+
};
|
|
2149
2218
|
const schemasIterable = { [Symbol.asyncIterator]() {
|
|
2150
2219
|
return (async function* () {
|
|
2220
|
+
if (dedupePlan) for (const definition of dedupePlan.hoisted) yield definition;
|
|
2151
2221
|
for (const [name, schema] of Object.entries(schemas)) {
|
|
2152
2222
|
const alias = refAliasMap.get(name);
|
|
2153
2223
|
if (alias?.name && schemas[alias.name]) {
|
|
2154
|
-
yield {
|
|
2224
|
+
yield rewriteTopLevelSchema({
|
|
2155
2225
|
...parseSchema({
|
|
2156
2226
|
schema: schemas[alias.name],
|
|
2157
2227
|
name: alias.name
|
|
2158
2228
|
}, parserOptions),
|
|
2159
2229
|
name
|
|
2160
|
-
};
|
|
2230
|
+
});
|
|
2161
2231
|
continue;
|
|
2162
2232
|
}
|
|
2163
2233
|
const parsed = parseSchema({
|
|
2164
2234
|
schema,
|
|
2165
2235
|
name
|
|
2166
2236
|
}, parserOptions);
|
|
2167
|
-
yield discriminatorChildMap?.get(name) ? patchDiscriminatorNode(parsed, discriminatorChildMap.get(name)) : parsed;
|
|
2237
|
+
yield rewriteTopLevelSchema(discriminatorChildMap?.get(name) ? patchDiscriminatorNode(parsed, discriminatorChildMap.get(name)) : parsed);
|
|
2168
2238
|
}
|
|
2169
2239
|
})();
|
|
2170
2240
|
} };
|
|
@@ -2173,7 +2243,7 @@ function createInputStream({ schemas, parseSchema, parseOperation, baseOas, pars
|
|
|
2173
2243
|
for (const methods of Object.values(baseOas.getPaths())) for (const operation of Object.values(methods)) {
|
|
2174
2244
|
if (!operation) continue;
|
|
2175
2245
|
const node = parseOperation(parserOptions, operation);
|
|
2176
|
-
if (node) yield node;
|
|
2246
|
+
if (node) yield dedupePlan ? ast.applyDedupe(node, dedupePlan.canonicalBySignature) : node;
|
|
2177
2247
|
}
|
|
2178
2248
|
})();
|
|
2179
2249
|
} };
|
|
@@ -2213,7 +2283,7 @@ const adapterOasName = "oas";
|
|
|
2213
2283
|
* ```
|
|
2214
2284
|
*/
|
|
2215
2285
|
const adapterOas = createAdapter((options) => {
|
|
2216
|
-
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;
|
|
2286
|
+
const { validate = true, contentType, serverIndex, serverVariables, discriminator = "strict", dedupe = true, 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;
|
|
2217
2287
|
const parserOptions = {
|
|
2218
2288
|
...DEFAULT_PARSER_OPTIONS,
|
|
2219
2289
|
dateType,
|
|
@@ -2240,25 +2310,30 @@ const adapterOas = createAdapter((options) => {
|
|
|
2240
2310
|
document,
|
|
2241
2311
|
contentType
|
|
2242
2312
|
}));
|
|
2243
|
-
const ensurePreScan = once((schemas, parseSchema) => preScan({
|
|
2313
|
+
const ensurePreScan = once((schemas, parseSchema, parseOperation, baseOas) => preScan({
|
|
2244
2314
|
schemas,
|
|
2245
2315
|
parseSchema,
|
|
2316
|
+
parseOperation,
|
|
2317
|
+
baseOas,
|
|
2246
2318
|
parserOptions,
|
|
2247
|
-
discriminator
|
|
2319
|
+
discriminator,
|
|
2320
|
+
dedupe
|
|
2248
2321
|
}));
|
|
2249
2322
|
async function createStream(source) {
|
|
2250
2323
|
const document = await ensureDocument(source);
|
|
2251
2324
|
const schemas = await ensureSchemas(document);
|
|
2252
2325
|
const { parseSchema, parseOperation } = ensureSchemaParser(document);
|
|
2253
|
-
const
|
|
2326
|
+
const baseOas = ensureBaseOas(document);
|
|
2327
|
+
const { refAliasMap, enumNames, circularNames, discriminatorChildMap, dedupePlan } = ensurePreScan(schemas, parseSchema, parseOperation, baseOas);
|
|
2254
2328
|
return createInputStream({
|
|
2255
2329
|
schemas,
|
|
2256
2330
|
parseSchema,
|
|
2257
2331
|
parseOperation,
|
|
2258
|
-
baseOas
|
|
2332
|
+
baseOas,
|
|
2259
2333
|
parserOptions,
|
|
2260
2334
|
refAliasMap,
|
|
2261
2335
|
discriminatorChildMap,
|
|
2336
|
+
dedupePlan,
|
|
2262
2337
|
meta: {
|
|
2263
2338
|
title: document.info?.title,
|
|
2264
2339
|
description: document.info?.description,
|
|
@@ -2282,6 +2357,7 @@ const adapterOas = createAdapter((options) => {
|
|
|
2282
2357
|
serverIndex,
|
|
2283
2358
|
serverVariables,
|
|
2284
2359
|
discriminator,
|
|
2360
|
+
dedupe,
|
|
2285
2361
|
dateType,
|
|
2286
2362
|
integerType,
|
|
2287
2363
|
unknownType,
|