@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.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
- * Injects discriminator enum values into child schemas so they know which value identifies them.
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
- * Returns a new `InputNode` the original is never mutated.
139
- *
140
- * @example
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 applyDiscriminatorInheritance(root) {
139
+ function buildDiscriminatorChildMap(schemas) {
147
140
  const childMap = /* @__PURE__ */ new Map();
148
- for (const schema of root.schemas) {
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
- const objectNode = ast.narrowSchema(node, "object");
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
- * @note Not exported; called internally by `parseOas()` and `parseSchema()`.
1197
+ * @internal
1178
1198
  */
1179
1199
  function createSchemaParser(ctx) {
1180
1200
  const document = ctx.document;
@@ -1192,7 +1212,7 @@ function createSchemaParser(ctx) {
1192
1212
  * blowup — `customer` alone may be referenced from dozens of top-level schemas,
1193
1213
  * each triggering a fresh recursive expansion of its entire sub-tree.
1194
1214
  *
1195
- * Memoising by `$ref` path reduces the overall work from O(2^depth) to O(N)
1215
+ * Memoizing by `$ref` path reduces the overall work from O(2^depth) to O(N)
1196
1216
  * where N is the number of unique schema names.
1197
1217
  */
1198
1218
  const resolvedRefCache = /* @__PURE__ */ new Map();
@@ -1303,7 +1323,7 @@ function createSchemaParser(ctx) {
1303
1323
  }));
1304
1324
  return ast.createSchema({
1305
1325
  type: "intersection",
1306
- members: [...ast.mergeAdjacentObjects(allOfMembers.slice(0, syntheticStart)), ...ast.mergeAdjacentObjects(allOfMembers.slice(syntheticStart))],
1326
+ members: [...ast.mergeAdjacentObjectsLazy(allOfMembers.slice(0, syntheticStart)), ...ast.mergeAdjacentObjectsLazy(allOfMembers.slice(syntheticStart))],
1307
1327
  ...buildSchemaNode(schema, name, nullable, defaultValue)
1308
1328
  });
1309
1329
  }
@@ -1881,7 +1901,7 @@ function parseOas(document, options = {}) {
1881
1901
  name
1882
1902
  }, mergedOptions));
1883
1903
  const paths = new BaseOas(document).getPaths();
1884
- const operations = Object.entries(paths).flatMap(([_path, methods]) => Object.entries(methods).map(([, operation]) => operation ? _parseOperation(mergedOptions, operation) : null).filter((op) => op !== null));
1904
+ const operations = Object.entries(paths).flatMap(([, methods]) => Object.entries(methods).map(([, operation]) => operation ? _parseOperation(mergedOptions, operation) : null).filter((op) => op !== null));
1885
1905
  return {
1886
1906
  root: ast.createInput({
1887
1907
  schemas,
@@ -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 parseFromConfig(source);
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
  });