@kubb/adapter-oas 5.0.0-beta.14 → 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 CHANGED
@@ -22,6 +22,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  }) : target, mod));
23
23
  //#endregion
24
24
  let _kubb_core = require("@kubb/core");
25
+ let oas = require("oas");
26
+ oas = __toESM(oas, 1);
25
27
  let node_path = require("node:path");
26
28
  node_path = __toESM(node_path, 1);
27
29
  let _redocly_openapi_core = require("@redocly/openapi-core");
@@ -29,8 +31,6 @@ let oas_normalize = require("oas-normalize");
29
31
  oas_normalize = __toESM(oas_normalize, 1);
30
32
  let swagger2openapi = require("swagger2openapi");
31
33
  swagger2openapi = __toESM(swagger2openapi, 1);
32
- let oas = require("oas");
33
- oas = __toESM(oas, 1);
34
34
  let oas_types = require("oas/types");
35
35
  let oas_utils = require("oas/utils");
36
36
  //#region src/constants.ts
@@ -155,23 +155,16 @@ const typeOptionMap = new Map([
155
155
  //#endregion
156
156
  //#region src/discriminator.ts
157
157
  /**
158
- * Injects discriminator enum values into child schemas so they know which value identifies them.
159
- *
160
- * Finds every union schema in `input.schemas` that has a `discriminatorPropertyName`, collects the
161
- * enum value each union member is mapped to, then adds (or replaces) that property on the matching
162
- * child object schema.
163
- *
164
- * Returns a new `InputNode` — the original is never mutated.
158
+ * Builds a map of child schema names discriminator patch data by scanning the given
159
+ * top-level AST schema nodes for union schemas that carry a `discriminatorPropertyName`.
165
160
  *
166
- * @example
167
- * ```ts
168
- * const { root } = parseOas(document, options)
169
- * const next = applyDiscriminatorInheritance(root)
170
- * ```
161
+ * Extracted from `applyDiscriminatorInheritance` so the streaming path can call it on a
162
+ * small pre-parsed subset of schemas (only the discriminator parents) rather than on all
163
+ * schemas at once.
171
164
  */
172
- function applyDiscriminatorInheritance(root) {
165
+ function buildDiscriminatorChildMap(schemas) {
173
166
  const childMap = /* @__PURE__ */ new Map();
174
- for (const schema of root.schemas) {
167
+ for (const schema of schemas) {
175
168
  let unionNode = _kubb_core.ast.narrowSchema(schema, "union");
176
169
  if (!unionNode) {
177
170
  const intersectionMembers = _kubb_core.ast.narrowSchema(schema, "intersection")?.members;
@@ -208,29 +201,56 @@ function applyDiscriminatorInheritance(root) {
208
201
  });
209
202
  }
210
203
  }
204
+ return childMap;
205
+ }
206
+ /**
207
+ * Patches a single top-level `SchemaNode` with its discriminator entry (adds or replaces
208
+ * the discriminant property). Used by the streaming path to apply patches inline per yield
209
+ * without buffering all schemas.
210
+ */
211
+ function patchDiscriminatorNode(node, entry) {
212
+ const objectNode = _kubb_core.ast.narrowSchema(node, "object");
213
+ if (!objectNode) return node;
214
+ const { propertyName, enumValues } = entry;
215
+ const enumSchema = _kubb_core.ast.createSchema({
216
+ type: "enum",
217
+ enumValues
218
+ });
219
+ const newProp = _kubb_core.ast.createProperty({
220
+ name: propertyName,
221
+ required: true,
222
+ schema: enumSchema
223
+ });
224
+ const existingIdx = objectNode.properties.findIndex((p) => p.name === propertyName);
225
+ const newProperties = existingIdx >= 0 ? objectNode.properties.map((p, i) => i === existingIdx ? newProp : p) : [...objectNode.properties, newProp];
226
+ return {
227
+ ...objectNode,
228
+ properties: newProperties
229
+ };
230
+ }
231
+ /**
232
+ * Injects discriminator enum values into child schemas so they know which value identifies them.
233
+ *
234
+ * Finds every union schema in `input.schemas` that has a `discriminatorPropertyName`, collects the
235
+ * enum value each union member is mapped to, then adds (or replaces) that property on the matching
236
+ * child object schema.
237
+ *
238
+ * Returns a new `InputNode` — the original is never mutated.
239
+ *
240
+ * @example
241
+ * ```ts
242
+ * const { root } = parseOas(document, options)
243
+ * const next = applyDiscriminatorInheritance(root)
244
+ * ```
245
+ */
246
+ function applyDiscriminatorInheritance(root) {
247
+ const childMap = buildDiscriminatorChildMap(root.schemas);
211
248
  if (childMap.size === 0) return root;
212
249
  return _kubb_core.ast.transform(root, { schema(node, { parent }) {
213
250
  if (parent?.kind !== "Input" || !node.name) return;
214
251
  const entry = childMap.get(node.name);
215
252
  if (!entry) return;
216
- const objectNode = _kubb_core.ast.narrowSchema(node, "object");
217
- if (!objectNode) return;
218
- const { propertyName, enumValues } = entry;
219
- const enumSchema = _kubb_core.ast.createSchema({
220
- type: "enum",
221
- enumValues
222
- });
223
- const newProp = _kubb_core.ast.createProperty({
224
- name: propertyName,
225
- required: true,
226
- schema: enumSchema
227
- });
228
- const existingIdx = objectNode.properties.findIndex((p) => p.name === propertyName);
229
- const newProperties = existingIdx >= 0 ? objectNode.properties.map((p, i) => i === existingIdx ? newProp : p) : [...objectNode.properties, newProp];
230
- return {
231
- ...objectNode,
232
- properties: newProperties
233
- };
253
+ return patchDiscriminatorNode(node, entry);
234
254
  } });
235
255
  }
236
256
  //#endregion
@@ -1200,7 +1220,7 @@ function normalizeArrayEnum(schema) {
1200
1220
  * Each converter branch (`convertRef`, `convertAllOf`, etc.) mutually recursively calls `parseSchema`,
1201
1221
  * made possible by hoisting of function declarations.
1202
1222
  *
1203
- * @note Not exported; called internally by `parseOas()` and `parseSchema()`.
1223
+ * @internal
1204
1224
  */
1205
1225
  function createSchemaParser(ctx) {
1206
1226
  const document = ctx.document;
@@ -1218,7 +1238,7 @@ function createSchemaParser(ctx) {
1218
1238
  * blowup — `customer` alone may be referenced from dozens of top-level schemas,
1219
1239
  * each triggering a fresh recursive expansion of its entire sub-tree.
1220
1240
  *
1221
- * Memoising by `$ref` path reduces the overall work from O(2^depth) to O(N)
1241
+ * Memoizing by `$ref` path reduces the overall work from O(2^depth) to O(N)
1222
1242
  * where N is the number of unique schema names.
1223
1243
  */
1224
1244
  const resolvedRefCache = /* @__PURE__ */ new Map();
@@ -1329,7 +1349,7 @@ function createSchemaParser(ctx) {
1329
1349
  }));
1330
1350
  return _kubb_core.ast.createSchema({
1331
1351
  type: "intersection",
1332
- members: [..._kubb_core.ast.mergeAdjacentObjects(allOfMembers.slice(0, syntheticStart)), ..._kubb_core.ast.mergeAdjacentObjects(allOfMembers.slice(syntheticStart))],
1352
+ members: [..._kubb_core.ast.mergeAdjacentObjectsLazy(allOfMembers.slice(0, syntheticStart)), ..._kubb_core.ast.mergeAdjacentObjectsLazy(allOfMembers.slice(syntheticStart))],
1333
1353
  ...buildSchemaNode(schema, name, nullable, defaultValue)
1334
1354
  });
1335
1355
  }
@@ -1907,7 +1927,7 @@ function parseOas(document, options = {}) {
1907
1927
  name
1908
1928
  }, mergedOptions));
1909
1929
  const paths = new oas.default(document).getPaths();
1910
- const operations = Object.entries(paths).flatMap(([_path, methods]) => Object.entries(methods).map(([, operation]) => operation ? _parseOperation(mergedOptions, operation) : null).filter((op) => op !== null));
1930
+ const operations = Object.entries(paths).flatMap(([, methods]) => Object.entries(methods).map(([, operation]) => operation ? _parseOperation(mergedOptions, operation) : null).filter((op) => op !== null));
1911
1931
  return {
1912
1932
  root: _kubb_core.ast.createInput({
1913
1933
  schemas,
@@ -1943,8 +1963,36 @@ const adapterOasName = "oas";
1943
1963
  */
1944
1964
  const adapterOas = (0, _kubb_core.createAdapter)((options) => {
1945
1965
  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;
1966
+ const parserOptions = {
1967
+ ...DEFAULT_PARSER_OPTIONS,
1968
+ dateType,
1969
+ integerType,
1970
+ unknownType,
1971
+ emptySchemaType,
1972
+ enumSuffix
1973
+ };
1946
1974
  let nameMapping = /* @__PURE__ */ new Map();
1947
- let parsedDocument;
1975
+ let parsedDocument = null;
1976
+ let schemaObjects = null;
1977
+ function resolveBaseURL(document) {
1978
+ const server = serverIndex !== void 0 ? document.servers?.at(serverIndex) : void 0;
1979
+ return server?.url ? resolveServerUrl(server, serverVariables) : void 0;
1980
+ }
1981
+ async function ensureDocument(source) {
1982
+ if (parsedDocument) return parsedDocument;
1983
+ const fresh = await parseFromConfig(source);
1984
+ if (validate) await validateDocument(fresh);
1985
+ parsedDocument = fresh;
1986
+ return fresh;
1987
+ }
1988
+ async function ensureSchemas(document) {
1989
+ if (!schemaObjects) {
1990
+ const result = getSchemas(document, { contentType });
1991
+ schemaObjects = result.schemas;
1992
+ nameMapping = result.nameMapping;
1993
+ }
1994
+ return schemaObjects;
1995
+ }
1948
1996
  return {
1949
1997
  name: "oas",
1950
1998
  get options() {
@@ -1983,10 +2031,7 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
1983
2031
  });
1984
2032
  },
1985
2033
  async parse(source) {
1986
- const document = await parseFromConfig(source);
1987
- if (validate) await validateDocument(document);
1988
- const server = serverIndex !== void 0 ? document.servers?.at(serverIndex) : void 0;
1989
- const baseURL = server?.url ? resolveServerUrl(server, serverVariables) : void 0;
2034
+ const document = await ensureDocument(source);
1990
2035
  const { root: parsedRoot, nameMapping: parsedNameMapping } = parseOas(document, {
1991
2036
  contentType,
1992
2037
  dateType,
@@ -1997,16 +2042,79 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
1997
2042
  });
1998
2043
  const node = discriminator === "inherit" ? applyDiscriminatorInheritance(parsedRoot) : parsedRoot;
1999
2044
  nameMapping = parsedNameMapping;
2000
- parsedDocument = document;
2001
2045
  return _kubb_core.ast.createInput({
2002
2046
  ...node,
2003
2047
  meta: {
2004
2048
  title: document.info?.title,
2005
2049
  description: document.info?.description,
2006
2050
  version: document.info?.version,
2007
- baseURL
2051
+ baseURL: resolveBaseURL(document)
2008
2052
  }
2009
2053
  });
2054
+ },
2055
+ async count(source) {
2056
+ const document = await ensureDocument(source);
2057
+ const schemas = await ensureSchemas(document);
2058
+ const baseOas = new oas.default(document);
2059
+ const operationCount = Object.values(baseOas.getPaths()).flatMap(Object.values).filter(Boolean).length;
2060
+ return {
2061
+ schemas: Object.keys(schemas).length,
2062
+ operations: operationCount
2063
+ };
2064
+ },
2065
+ async stream(source) {
2066
+ const document = await ensureDocument(source);
2067
+ const schemas = await ensureSchemas(document);
2068
+ let discriminatorChildMap = null;
2069
+ if (discriminator === "inherit") {
2070
+ const { parseSchema: _preParser } = createSchemaParser({
2071
+ document,
2072
+ contentType
2073
+ });
2074
+ const parentNodes = [];
2075
+ for (const [name, schema] of Object.entries(schemas)) if ((schema.oneOf ?? schema.anyOf) && schema.discriminator?.propertyName) parentNodes.push(_preParser({
2076
+ schema,
2077
+ name
2078
+ }, parserOptions));
2079
+ if (parentNodes.length > 0) discriminatorChildMap = buildDiscriminatorChildMap(parentNodes);
2080
+ }
2081
+ const schemasIterable = { [Symbol.asyncIterator]() {
2082
+ return (async function* () {
2083
+ const { parseSchema: _parseSchema } = createSchemaParser({
2084
+ document,
2085
+ contentType
2086
+ });
2087
+ for (const [name, schema] of Object.entries(schemas)) {
2088
+ let node = _parseSchema({
2089
+ schema,
2090
+ name
2091
+ }, parserOptions);
2092
+ const entry = discriminatorChildMap?.get(name);
2093
+ if (entry) node = patchDiscriminatorNode(node, entry);
2094
+ yield node;
2095
+ }
2096
+ })();
2097
+ } };
2098
+ const operationsIterable = { [Symbol.asyncIterator]() {
2099
+ return (async function* () {
2100
+ const { parseOperation: _parseOperation } = createSchemaParser({
2101
+ document,
2102
+ contentType
2103
+ });
2104
+ const paths = new oas.default(document).getPaths();
2105
+ for (const methods of Object.values(paths)) for (const operation of Object.values(methods)) {
2106
+ if (!operation) continue;
2107
+ const node = _parseOperation(parserOptions, operation);
2108
+ if (node) yield node;
2109
+ }
2110
+ })();
2111
+ } };
2112
+ return _kubb_core.ast.createStreamInput(schemasIterable, operationsIterable, {
2113
+ title: document.info?.title,
2114
+ description: document.info?.description,
2115
+ version: document.info?.version,
2116
+ baseURL: resolveBaseURL(document)
2117
+ });
2010
2118
  }
2011
2119
  };
2012
2120
  });