@kubb/adapter-oas 5.0.0-beta.57 → 5.0.0-beta.59

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
@@ -114,7 +114,7 @@ const structuralKeys = new Set([
114
114
  *
115
115
  * Only formats whose AST type differs from the OAS `type` field appear here.
116
116
  * Formats that depend on runtime options (`int64`, `date-time`, `date`, `time`) are handled separately
117
- * in the parser. `ipv4` and `ipv6` map to their own dedicated schema types; `hostname` and
117
+ * in the parser. `ipv4` and `ipv6` map to their own dedicated schema types. `hostname` and
118
118
  * `idn-hostname` map to `'url'` as the closest generic string-format type.
119
119
  *
120
120
  * @example
@@ -167,8 +167,8 @@ const formatMap = {
167
167
  */
168
168
  const enumExtensionKeys = ["x-enumNames", "x-enum-varnames"];
169
169
  /**
170
- * Maps `'any' | 'unknown' | 'void'` option strings to their `ScalarSchemaType` constant.
171
- * Replaces a plain object lookup with a `Map` for explicit key membership testing via `.has()`.
170
+ * Maps the `unknownType`/`emptySchemaType` option string to its `ScalarSchemaType` constant.
171
+ * A `Map` (over a plain object) lets callers test key membership with `.has()`.
172
172
  */
173
173
  const typeOptionMap = new Map([
174
174
  ["any", _kubb_core.ast.schemaTypes.any],
@@ -863,6 +863,120 @@ const oasDialect = _kubb_core.ast.defineSchemaDialect({
863
863
  resolveRef
864
864
  });
865
865
  //#endregion
866
+ //#region src/discriminator.ts
867
+ /**
868
+ * Builds a map of child schema names → discriminator patch data by scanning the given
869
+ * top-level AST schema nodes for union schemas that carry a `discriminatorPropertyName`.
870
+ *
871
+ * The streaming path calls this on a small pre-parsed subset of schemas (only the
872
+ * discriminator parents) rather than on all schemas at once.
873
+ */
874
+ function buildDiscriminatorChildMap(schemas) {
875
+ const childMap = /* @__PURE__ */ new Map();
876
+ for (const schema of schemas) {
877
+ let unionNode = _kubb_core.ast.narrowSchema(schema, "union");
878
+ if (!unionNode) {
879
+ const intersectionMembers = _kubb_core.ast.narrowSchema(schema, "intersection")?.members;
880
+ if (intersectionMembers) for (const m of intersectionMembers) {
881
+ const u = _kubb_core.ast.narrowSchema(m, "union");
882
+ if (u) {
883
+ unionNode = u;
884
+ break;
885
+ }
886
+ }
887
+ }
888
+ if (!unionNode?.discriminatorPropertyName || !unionNode.members) continue;
889
+ const { discriminatorPropertyName, members } = unionNode;
890
+ for (const member of members) {
891
+ const intersectionNode = _kubb_core.ast.narrowSchema(member, "intersection");
892
+ if (!intersectionNode?.members) continue;
893
+ let refNode = null;
894
+ let objNode = null;
895
+ for (const m of intersectionNode.members) {
896
+ refNode ??= _kubb_core.ast.narrowSchema(m, "ref");
897
+ objNode ??= _kubb_core.ast.narrowSchema(m, "object");
898
+ }
899
+ if (!refNode?.name || !objNode) continue;
900
+ const prop = objNode.properties.find((p) => p.name === discriminatorPropertyName);
901
+ const enumNode = prop ? _kubb_core.ast.narrowSchema(prop.schema, "enum") : null;
902
+ if (!enumNode?.enumValues?.length) continue;
903
+ const enumValues = enumNode.enumValues.filter((v) => v !== null);
904
+ if (!enumValues.length) continue;
905
+ const existing = childMap.get(refNode.name);
906
+ if (!existing) {
907
+ childMap.set(refNode.name, {
908
+ propertyName: discriminatorPropertyName,
909
+ enumValues: [...enumValues]
910
+ });
911
+ continue;
912
+ }
913
+ existing.enumValues.push(...enumValues);
914
+ }
915
+ }
916
+ return childMap;
917
+ }
918
+ /**
919
+ * Patches a single top-level `SchemaNode` with its discriminator entry (adds or replaces
920
+ * the discriminant property). Used by the streaming path to apply patches inline per yield
921
+ * without buffering all schemas.
922
+ */
923
+ function patchDiscriminatorNode(node, entry) {
924
+ const objectNode = _kubb_core.ast.narrowSchema(node, "object");
925
+ if (!objectNode) return node;
926
+ const { propertyName, enumValues } = entry;
927
+ const enumSchema = _kubb_core.ast.factory.createSchema({
928
+ type: "enum",
929
+ enumValues
930
+ });
931
+ const newProp = _kubb_core.ast.factory.createProperty({
932
+ name: propertyName,
933
+ required: true,
934
+ schema: enumSchema
935
+ });
936
+ const existingIdx = objectNode.properties.findIndex((p) => p.name === propertyName);
937
+ const newProperties = existingIdx >= 0 ? objectNode.properties.map((p, i) => i === existingIdx ? newProp : p) : [...objectNode.properties, newProp];
938
+ return {
939
+ ...objectNode,
940
+ properties: newProperties
941
+ };
942
+ }
943
+ /**
944
+ * Creates a single-property object schema used as a discriminator literal.
945
+ *
946
+ * @example
947
+ * ```ts
948
+ * createDiscriminantNode({ propertyName: 'type', value: 'dog' })
949
+ * // -> { type: 'object', properties: [{ name: 'type', required: true, schema: enum('dog') }] }
950
+ * ```
951
+ */
952
+ function createDiscriminantNode({ propertyName, value }) {
953
+ return _kubb_core.ast.factory.createSchema({
954
+ type: "object",
955
+ primitive: "object",
956
+ properties: [_kubb_core.ast.factory.createProperty({
957
+ name: propertyName,
958
+ schema: _kubb_core.ast.factory.createSchema({
959
+ type: "enum",
960
+ primitive: "string",
961
+ enumValues: [value]
962
+ }),
963
+ required: true
964
+ })]
965
+ });
966
+ }
967
+ /**
968
+ * Returns the discriminator key whose mapping value matches `ref`, or `null` when there is no match.
969
+ *
970
+ * @example
971
+ * ```ts
972
+ * findDiscriminator({ dog: '#/components/schemas/Dog' }, '#/components/schemas/Dog') // 'dog'
973
+ * ```
974
+ */
975
+ function findDiscriminator(mapping, ref) {
976
+ if (!mapping || !ref) return null;
977
+ return Object.entries(mapping).find(([, value]) => value === ref)?.[0] ?? null;
978
+ }
979
+ //#endregion
866
980
  //#region src/mime.ts
867
981
  /**
868
982
  * MIME type fragments that mark a media type as JSON-like.
@@ -1351,7 +1465,7 @@ function getSchemas(document, { contentType }) {
1351
1465
  }
1352
1466
  /**
1353
1467
  * Resolves the AST type descriptor for a date/time format, honoring the `dateType` option.
1354
- * Returns `null` when `dateType: false`, signalling the format should fall through to `string`.
1468
+ * Returns `null` when `dateType: false`, so the format falls through to `string`.
1355
1469
  */
1356
1470
  function getDateType(options, format) {
1357
1471
  if (!options.dateType) return null;
@@ -1453,9 +1567,9 @@ function getResponseBodyContentTypes(document, operation, statusCode) {
1453
1567
  * Normalizes malformed `{ type: 'array', enum: [...] }` schemas by moving enum values into items.
1454
1568
  *
1455
1569
  * This pattern violates the OpenAPI spec but appears in real specs. The fix moves enum values
1456
- * from the array to its items sub-schema, making them valid for downstream processing.
1570
+ * from the array to its items sub-schema, so they are valid for downstream processing.
1457
1571
  *
1458
- * @note This is a defensive measure for robustness with non-compliant specs.
1572
+ * @note A defensive measure for non-compliant specs.
1459
1573
  */
1460
1574
  function normalizeArrayEnum(schema) {
1461
1575
  const normalizedItems = {
@@ -1473,7 +1587,7 @@ function normalizeArrayEnum(schema) {
1473
1587
  *
1474
1588
  * Returns closures that share mutable state (`resolvingRefs` set for cycle detection).
1475
1589
  * Each converter branch (`convertRef`, `convertAllOf`, etc.) mutually recursively calls `parseSchema`,
1476
- * made possible by hoisting of function declarations.
1590
+ * which works because function declarations hoist.
1477
1591
  *
1478
1592
  * @internal
1479
1593
  */
@@ -1518,7 +1632,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1518
1632
  }
1519
1633
  resolvedSchema = resolvedRefCache.get(refPath) ?? null;
1520
1634
  }
1521
- return _kubb_core.ast.createSchema({
1635
+ return _kubb_core.ast.factory.createSchema({
1522
1636
  ...buildSchemaNode(schema, name, nullable, defaultValue),
1523
1637
  type: "ref",
1524
1638
  name: (0, _kubb_ast_utils.extractRefName)(schema.$ref),
@@ -1539,7 +1653,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1539
1653
  const { kind: _kind, ...memberNodeProps } = memberNode;
1540
1654
  const mergedNullable = nullable || memberNode.nullable || void 0;
1541
1655
  const mergedDefault = schema.default === null && mergedNullable ? void 0 : schema.default ?? memberNode.default;
1542
- return _kubb_core.ast.createSchema({
1656
+ return _kubb_core.ast.factory.createSchema({
1543
1657
  ...memberNodeProps,
1544
1658
  name,
1545
1659
  title: schema.title ?? memberNode.title,
@@ -1565,7 +1679,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1565
1679
  const inOneOf = parentUnion.some((oneOfItem) => dialect.isReference(oneOfItem) && oneOfItem.$ref === childRef);
1566
1680
  const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
1567
1681
  if (inOneOf || inMapping) {
1568
- const discriminatorValue = (0, _kubb_ast_utils.findDiscriminator)(deref.discriminator.mapping, childRef);
1682
+ const discriminatorValue = findDiscriminator(deref.discriminator.mapping, childRef);
1569
1683
  if (discriminatorValue) filteredDiscriminantValues.push({
1570
1684
  propertyName: deref.discriminator.propertyName,
1571
1685
  value: discriminatorValue
@@ -1603,11 +1717,11 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1603
1717
  const { allOf: _allOf, ...schemaWithoutAllOf } = schema;
1604
1718
  allOfMembers.push(parseSchema({ schema: schemaWithoutAllOf }, rawOptions));
1605
1719
  }
1606
- for (const { propertyName, value } of filteredDiscriminantValues) allOfMembers.push(_kubb_core.ast.createDiscriminantNode({
1720
+ for (const { propertyName, value } of filteredDiscriminantValues) allOfMembers.push(createDiscriminantNode({
1607
1721
  propertyName,
1608
1722
  value
1609
1723
  }));
1610
- return _kubb_core.ast.createSchema({
1724
+ return _kubb_core.ast.factory.createSchema({
1611
1725
  type: "intersection",
1612
1726
  members: [..._kubb_core.ast.mergeAdjacentObjectsLazy(allOfMembers.slice(0, syntheticStart)), ..._kubb_core.ast.mergeAdjacentObjectsLazy(allOfMembers.slice(syntheticStart))],
1613
1727
  ...buildSchemaNode(schema, name, nullable, defaultValue)
@@ -1620,7 +1734,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1620
1734
  function pickDiscriminatorPropertyNode(node, propertyName) {
1621
1735
  const discriminatorProperty = _kubb_core.ast.narrowSchema(node, "object")?.properties?.find((property) => property.name === propertyName);
1622
1736
  if (!discriminatorProperty) return null;
1623
- return _kubb_core.ast.createSchema({
1737
+ return _kubb_core.ast.factory.createSchema({
1624
1738
  type: "object",
1625
1739
  primitive: "object",
1626
1740
  properties: [discriminatorProperty]
@@ -1644,7 +1758,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1644
1758
  if (sharedPropertiesNode || discriminator?.mapping) {
1645
1759
  const members = unionMembers.map((s) => {
1646
1760
  const ref = dialect.isReference(s) ? s.$ref : void 0;
1647
- const discriminatorValue = (0, _kubb_ast_utils.findDiscriminator)(discriminator?.mapping, ref);
1761
+ const discriminatorValue = findDiscriminator(discriminator?.mapping, ref);
1648
1762
  const memberNode = parseSchema({
1649
1763
  schema: s,
1650
1764
  name
@@ -1655,27 +1769,27 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1655
1769
  propertyName: discriminator.propertyName,
1656
1770
  values: [discriminatorValue]
1657
1771
  }), discriminator.propertyName) : void 0;
1658
- return _kubb_core.ast.createSchema({
1772
+ return _kubb_core.ast.factory.createSchema({
1659
1773
  type: "intersection",
1660
- members: [memberNode, narrowedDiscriminatorNode ?? _kubb_core.ast.createDiscriminantNode({
1774
+ members: [memberNode, narrowedDiscriminatorNode ?? createDiscriminantNode({
1661
1775
  propertyName: discriminator.propertyName,
1662
1776
  value: discriminatorValue
1663
1777
  })]
1664
1778
  });
1665
1779
  });
1666
- const unionNode = _kubb_core.ast.createSchema({
1780
+ const unionNode = _kubb_core.ast.factory.createSchema({
1667
1781
  type: "union",
1668
1782
  ...unionBase,
1669
1783
  members
1670
1784
  });
1671
1785
  if (!sharedPropertiesNode) return unionNode;
1672
- return _kubb_core.ast.createSchema({
1786
+ return _kubb_core.ast.factory.createSchema({
1673
1787
  type: "intersection",
1674
1788
  ...buildSchemaNode(schema, name, nullable, defaultValue),
1675
1789
  members: [unionNode, sharedPropertiesNode]
1676
1790
  });
1677
1791
  }
1678
- return _kubb_core.ast.createSchema({
1792
+ return _kubb_core.ast.factory.createSchema({
1679
1793
  type: "union",
1680
1794
  ...unionBase,
1681
1795
  members: _kubb_core.ast.simplifyUnion(unionMembers.map((s) => parseSchema({
@@ -1689,7 +1803,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1689
1803
  */
1690
1804
  function convertConst({ schema, name, nullable, defaultValue }) {
1691
1805
  const constValue = schema.const;
1692
- if (constValue === null) return _kubb_core.ast.createSchema({
1806
+ if (constValue === null) return _kubb_core.ast.factory.createSchema({
1693
1807
  type: "null",
1694
1808
  primitive: "null",
1695
1809
  name,
@@ -1699,7 +1813,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1699
1813
  format: schema.format
1700
1814
  });
1701
1815
  const constPrimitive = getPrimitiveType(typeof constValue === "number" ? "number" : typeof constValue === "boolean" ? "boolean" : "string");
1702
- return _kubb_core.ast.createSchema({
1816
+ return _kubb_core.ast.factory.createSchema({
1703
1817
  type: "enum",
1704
1818
  primitive: constPrimitive,
1705
1819
  enumValues: [constValue],
@@ -1712,7 +1826,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1712
1826
  */
1713
1827
  function convertFormat({ schema, name, nullable, defaultValue, options }) {
1714
1828
  const base = buildSchemaNode(schema, name, nullable, defaultValue);
1715
- if (schema.format === "int64") return _kubb_core.ast.createSchema({
1829
+ if (schema.format === "int64") return _kubb_core.ast.factory.createSchema({
1716
1830
  type: options.integerType === "bigint" ? "bigint" : "integer",
1717
1831
  primitive: "integer",
1718
1832
  ...base,
@@ -1724,14 +1838,14 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1724
1838
  if (schema.format === "date-time" || schema.format === "date" || schema.format === "time") {
1725
1839
  const dateType = getDateType(options, schema.format);
1726
1840
  if (!dateType) return null;
1727
- if (dateType.type === "datetime") return _kubb_core.ast.createSchema({
1841
+ if (dateType.type === "datetime") return _kubb_core.ast.factory.createSchema({
1728
1842
  ...base,
1729
1843
  primitive: "string",
1730
1844
  type: "datetime",
1731
1845
  offset: dateType.offset,
1732
1846
  local: dateType.local
1733
1847
  });
1734
- return _kubb_core.ast.createSchema({
1848
+ return _kubb_core.ast.factory.createSchema({
1735
1849
  ...base,
1736
1850
  primitive: "string",
1737
1851
  type: dateType.type,
@@ -1741,36 +1855,36 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1741
1855
  const specialType = getSchemaType(schema.format);
1742
1856
  if (!specialType) return null;
1743
1857
  const specialPrimitive = specialType === "number" || specialType === "integer" || specialType === "bigint" ? specialType : "string";
1744
- if (specialType === "number" || specialType === "integer" || specialType === "bigint") return _kubb_core.ast.createSchema({
1858
+ if (specialType === "number" || specialType === "integer" || specialType === "bigint") return _kubb_core.ast.factory.createSchema({
1745
1859
  ...base,
1746
1860
  primitive: specialPrimitive,
1747
1861
  type: specialType
1748
1862
  });
1749
- if (specialType === "url") return _kubb_core.ast.createSchema({
1863
+ if (specialType === "url") return _kubb_core.ast.factory.createSchema({
1750
1864
  ...base,
1751
1865
  primitive: "string",
1752
1866
  type: "url",
1753
1867
  min: schema.minLength,
1754
1868
  max: schema.maxLength
1755
1869
  });
1756
- if (specialType === "ipv4") return _kubb_core.ast.createSchema({
1870
+ if (specialType === "ipv4") return _kubb_core.ast.factory.createSchema({
1757
1871
  ...base,
1758
1872
  primitive: "string",
1759
1873
  type: "ipv4"
1760
1874
  });
1761
- if (specialType === "ipv6") return _kubb_core.ast.createSchema({
1875
+ if (specialType === "ipv6") return _kubb_core.ast.factory.createSchema({
1762
1876
  ...base,
1763
1877
  primitive: "string",
1764
1878
  type: "ipv6"
1765
1879
  });
1766
- if (specialType === "uuid" || specialType === "email") return _kubb_core.ast.createSchema({
1880
+ if (specialType === "uuid" || specialType === "email") return _kubb_core.ast.factory.createSchema({
1767
1881
  ...base,
1768
1882
  primitive: "string",
1769
1883
  type: specialType,
1770
1884
  min: schema.minLength,
1771
1885
  max: schema.maxLength
1772
1886
  });
1773
- return _kubb_core.ast.createSchema({
1887
+ return _kubb_core.ast.factory.createSchema({
1774
1888
  ...base,
1775
1889
  primitive: specialPrimitive,
1776
1890
  type: specialType
@@ -1786,7 +1900,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1786
1900
  }, rawOptions);
1787
1901
  const nullInEnum = schema.enum.includes(null);
1788
1902
  const filteredValues = nullInEnum ? schema.enum.filter((v) => v !== null) : schema.enum;
1789
- if (nullInEnum && filteredValues.length === 0) return _kubb_core.ast.createSchema({
1903
+ if (nullInEnum && filteredValues.length === 0) return _kubb_core.ast.factory.createSchema({
1790
1904
  type: "null",
1791
1905
  primitive: "null",
1792
1906
  name,
@@ -1818,7 +1932,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1818
1932
  const rawEnumNames = extensionKey ? schema[extensionKey] : void 0;
1819
1933
  const uniqueValues = [...new Set(filteredValues)];
1820
1934
  const seenNames = /* @__PURE__ */ new Set();
1821
- return _kubb_core.ast.createSchema({
1935
+ return _kubb_core.ast.factory.createSchema({
1822
1936
  ...enumBase,
1823
1937
  primitive: enumPrimitiveType,
1824
1938
  namedEnumValues: uniqueValues.map((value, index) => ({
@@ -1832,7 +1946,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1832
1946
  })
1833
1947
  });
1834
1948
  }
1835
- return _kubb_core.ast.createSchema({
1949
+ return _kubb_core.ast.factory.createSchema({
1836
1950
  ...enumBase,
1837
1951
  enumValues: [...new Set(filteredValues)]
1838
1952
  });
@@ -1861,7 +1975,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1861
1975
  }
1862
1976
  return node;
1863
1977
  })();
1864
- return _kubb_core.ast.createProperty({
1978
+ return _kubb_core.ast.factory.createProperty({
1865
1979
  name: propName,
1866
1980
  schema: {
1867
1981
  ...schemaNode,
@@ -1875,11 +1989,11 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1875
1989
  if (additionalProperties === true) return true;
1876
1990
  if (additionalProperties === false) return false;
1877
1991
  if (additionalProperties && Object.keys(additionalProperties).length > 0) return parseSchema({ schema: additionalProperties }, rawOptions);
1878
- if (additionalProperties) return _kubb_core.ast.createSchema({ type: typeOptionMap.get(options.unknownType) });
1992
+ if (additionalProperties) return _kubb_core.ast.factory.createSchema({ type: typeOptionMap.get(options.unknownType) });
1879
1993
  })();
1880
1994
  const rawPatternProperties = "patternProperties" in schema ? schema.patternProperties : void 0;
1881
- const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || typeof patternSchema === "object" && Object.keys(patternSchema).length === 0 ? _kubb_core.ast.createSchema({ type: typeOptionMap.get(options.unknownType) }) : parseSchema({ schema: patternSchema }, rawOptions)])) : void 0;
1882
- const objectNode = _kubb_core.ast.createSchema({
1995
+ const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || typeof patternSchema === "object" && Object.keys(patternSchema).length === 0 ? _kubb_core.ast.factory.createSchema({ type: typeOptionMap.get(options.unknownType) }) : parseSchema({ schema: patternSchema }, rawOptions)])) : void 0;
1996
+ const objectNode = _kubb_core.ast.factory.createSchema({
1883
1997
  type: "object",
1884
1998
  primitive: "object",
1885
1999
  properties,
@@ -1907,8 +2021,8 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1907
2021
  */
1908
2022
  function convertTuple({ schema, name, nullable, defaultValue, rawOptions }) {
1909
2023
  const tupleItems = (schema.prefixItems ?? []).map((item) => parseSchema({ schema: item }, rawOptions));
1910
- const rest = schema.items ? parseSchema({ schema: schema.items }, rawOptions) : _kubb_core.ast.createSchema({ type: "any" });
1911
- return _kubb_core.ast.createSchema({
2024
+ const rest = schema.items ? parseSchema({ schema: schema.items }, rawOptions) : _kubb_core.ast.factory.createSchema({ type: "any" });
2025
+ return _kubb_core.ast.factory.createSchema({
1912
2026
  type: "tuple",
1913
2027
  primitive: "array",
1914
2028
  items: tupleItems,
@@ -1928,7 +2042,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1928
2042
  schema: rawItems,
1929
2043
  name: itemName
1930
2044
  }, rawOptions)] : [];
1931
- return _kubb_core.ast.createSchema({
2045
+ return _kubb_core.ast.factory.createSchema({
1932
2046
  type: "array",
1933
2047
  primitive: "array",
1934
2048
  items,
@@ -1942,7 +2056,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1942
2056
  * Converts a `type: 'string'` schema into a `StringSchemaNode`.
1943
2057
  */
1944
2058
  function convertString({ schema, name, nullable, defaultValue }) {
1945
- return _kubb_core.ast.createSchema({
2059
+ return _kubb_core.ast.factory.createSchema({
1946
2060
  type: "string",
1947
2061
  primitive: "string",
1948
2062
  min: schema.minLength,
@@ -1955,7 +2069,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1955
2069
  * Converts a `type: 'number'` or `type: 'integer'` schema.
1956
2070
  */
1957
2071
  function convertNumeric({ schema, name, nullable, defaultValue }, type) {
1958
- return _kubb_core.ast.createSchema({
2072
+ return _kubb_core.ast.factory.createSchema({
1959
2073
  type,
1960
2074
  primitive: type,
1961
2075
  min: schema.minimum,
@@ -1970,7 +2084,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1970
2084
  * Converts a `type: 'boolean'` schema.
1971
2085
  */
1972
2086
  function convertBoolean({ schema, name, nullable, defaultValue }) {
1973
- return _kubb_core.ast.createSchema({
2087
+ return _kubb_core.ast.factory.createSchema({
1974
2088
  type: "boolean",
1975
2089
  primitive: "boolean",
1976
2090
  ...buildSchemaNode(schema, name, nullable, defaultValue)
@@ -1980,7 +2094,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1980
2094
  * Converts an explicit `type: 'null'` schema.
1981
2095
  */
1982
2096
  function convertNull({ schema, name, nullable }) {
1983
- return _kubb_core.ast.createSchema({
2097
+ return _kubb_core.ast.factory.createSchema({
1984
2098
  type: "null",
1985
2099
  primitive: "null",
1986
2100
  name,
@@ -1996,7 +2110,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1996
2110
  * into a `blob` node.
1997
2111
  */
1998
2112
  function convertBlob({ schema, name, nullable, defaultValue }) {
1999
- return _kubb_core.ast.createSchema({
2113
+ return _kubb_core.ast.factory.createSchema({
2000
2114
  type: "blob",
2001
2115
  primitive: "string",
2002
2116
  ...buildSchemaNode(schema, name, nullable, defaultValue)
@@ -2013,7 +2127,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2013
2127
  const nonNullTypes = types.filter((t) => t !== "null");
2014
2128
  if (nonNullTypes.length <= 1) return null;
2015
2129
  const arrayNullable = types.includes("null") || nullable || void 0;
2016
- return _kubb_core.ast.createSchema({
2130
+ return _kubb_core.ast.factory.createSchema({
2017
2131
  type: "union",
2018
2132
  members: nonNullTypes.map((t) => parseSchema({
2019
2133
  schema: {
@@ -2156,7 +2270,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2156
2270
  if (node) return node;
2157
2271
  }
2158
2272
  const emptyType = typeOptionMap.get(options.emptySchemaType);
2159
- return _kubb_core.ast.createSchema({
2273
+ return _kubb_core.ast.factory.createSchema({
2160
2274
  type: emptyType,
2161
2275
  name,
2162
2276
  title: schema.title,
@@ -2174,8 +2288,8 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2174
2288
  const schema = param["schema"] ? parseSchema({
2175
2289
  schema: param["schema"],
2176
2290
  name: schemaName
2177
- }, options) : _kubb_core.ast.createSchema({ type: typeOptionMap.get(options.unknownType) });
2178
- return _kubb_core.ast.createParameter({
2291
+ }, options) : _kubb_core.ast.factory.createSchema({ type: typeOptionMap.get(options.unknownType) });
2292
+ return _kubb_core.ast.factory.createParameter({
2179
2293
  name: paramName,
2180
2294
  in: param["in"],
2181
2295
  schema: {
@@ -2262,7 +2376,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2262
2376
  schema: raw && Object.keys(raw).length > 0 ? parseSchema({
2263
2377
  schema: raw,
2264
2378
  name: responseName
2265
- }, options) : _kubb_core.ast.createSchema({ type: typeOptionMap.get(options.emptySchemaType) }),
2379
+ }, options) : _kubb_core.ast.factory.createSchema({ type: typeOptionMap.get(options.emptySchemaType) }),
2266
2380
  keysToOmit: collectPropertyKeysByFlag(raw, "writeOnly")
2267
2381
  };
2268
2382
  };
@@ -2277,7 +2391,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2277
2391
  }) || "application/json",
2278
2392
  ...parseEntrySchema(ctx.contentType)
2279
2393
  });
2280
- return _kubb_core.ast.createResponse({
2394
+ return _kubb_core.ast.factory.createResponse({
2281
2395
  statusCode,
2282
2396
  description,
2283
2397
  content
@@ -2291,7 +2405,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2291
2405
  const fallback = pathItemDoc?.[key];
2292
2406
  return typeof fallback === "string" ? fallback : void 0;
2293
2407
  };
2294
- return _kubb_core.ast.createOperation({
2408
+ return _kubb_core.ast.factory.createOperation({
2295
2409
  operationId,
2296
2410
  protocol: "http",
2297
2411
  method: operation.method.toUpperCase(),
@@ -2312,84 +2426,6 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2312
2426
  };
2313
2427
  }
2314
2428
  //#endregion
2315
- //#region src/discriminator.ts
2316
- /**
2317
- * Builds a map of child schema names → discriminator patch data by scanning the given
2318
- * top-level AST schema nodes for union schemas that carry a `discriminatorPropertyName`.
2319
- *
2320
- * The streaming path calls this on a small pre-parsed subset of schemas (only the
2321
- * discriminator parents) rather than on all schemas at once.
2322
- */
2323
- function buildDiscriminatorChildMap(schemas) {
2324
- const childMap = /* @__PURE__ */ new Map();
2325
- for (const schema of schemas) {
2326
- let unionNode = _kubb_core.ast.narrowSchema(schema, "union");
2327
- if (!unionNode) {
2328
- const intersectionMembers = _kubb_core.ast.narrowSchema(schema, "intersection")?.members;
2329
- if (intersectionMembers) for (const m of intersectionMembers) {
2330
- const u = _kubb_core.ast.narrowSchema(m, "union");
2331
- if (u) {
2332
- unionNode = u;
2333
- break;
2334
- }
2335
- }
2336
- }
2337
- if (!unionNode?.discriminatorPropertyName || !unionNode.members) continue;
2338
- const { discriminatorPropertyName, members } = unionNode;
2339
- for (const member of members) {
2340
- const intersectionNode = _kubb_core.ast.narrowSchema(member, "intersection");
2341
- if (!intersectionNode?.members) continue;
2342
- let refNode = null;
2343
- let objNode = null;
2344
- for (const m of intersectionNode.members) {
2345
- refNode ??= _kubb_core.ast.narrowSchema(m, "ref");
2346
- objNode ??= _kubb_core.ast.narrowSchema(m, "object");
2347
- }
2348
- if (!refNode?.name || !objNode) continue;
2349
- const prop = objNode.properties.find((p) => p.name === discriminatorPropertyName);
2350
- const enumNode = prop ? _kubb_core.ast.narrowSchema(prop.schema, "enum") : null;
2351
- if (!enumNode?.enumValues?.length) continue;
2352
- const enumValues = enumNode.enumValues.filter((v) => v !== null);
2353
- if (!enumValues.length) continue;
2354
- const existing = childMap.get(refNode.name);
2355
- if (!existing) {
2356
- childMap.set(refNode.name, {
2357
- propertyName: discriminatorPropertyName,
2358
- enumValues: [...enumValues]
2359
- });
2360
- continue;
2361
- }
2362
- existing.enumValues.push(...enumValues);
2363
- }
2364
- }
2365
- return childMap;
2366
- }
2367
- /**
2368
- * Patches a single top-level `SchemaNode` with its discriminator entry (adds or replaces
2369
- * the discriminant property). Used by the streaming path to apply patches inline per yield
2370
- * without buffering all schemas.
2371
- */
2372
- function patchDiscriminatorNode(node, entry) {
2373
- const objectNode = _kubb_core.ast.narrowSchema(node, "object");
2374
- if (!objectNode) return node;
2375
- const { propertyName, enumValues } = entry;
2376
- const enumSchema = _kubb_core.ast.createSchema({
2377
- type: "enum",
2378
- enumValues
2379
- });
2380
- const newProp = _kubb_core.ast.createProperty({
2381
- name: propertyName,
2382
- required: true,
2383
- schema: enumSchema
2384
- });
2385
- const existingIdx = objectNode.properties.findIndex((p) => p.name === propertyName);
2386
- const newProperties = existingIdx >= 0 ? objectNode.properties.map((p, i) => i === existingIdx ? newProp : p) : [...objectNode.properties, newProp];
2387
- return {
2388
- ...objectNode,
2389
- properties: newProperties
2390
- };
2391
- }
2392
- //#endregion
2393
2429
  //#region src/schemaDiagnostics.ts
2394
2430
  /**
2395
2431
  * Reports the advisory diagnostics (`KUBB_UNSUPPORTED_FORMAT`, `KUBB_DEPRECATED`) for one
@@ -2452,7 +2488,7 @@ function visit(node, pointer) {
2452
2488
  *
2453
2489
  * Only enums and objects are candidates, and object shapes that reference a circular schema are
2454
2490
  * rejected to avoid hoisting recursive structures. Inline shapes reuse their context-derived
2455
- * name (collision-resolved against existing component names); shapes without a name stay inline.
2491
+ * name (collision-resolved against existing component names). Shapes without a name stay inline.
2456
2492
  */
2457
2493
  function createDedupePlan({ schemaNodes, operationNodes, schemaNames, circularNames }) {
2458
2494
  const circularSchemas = new Set(circularNames);
@@ -2462,7 +2498,7 @@ function createDedupePlan({ schemaNodes, operationNodes, schemaNames, circularNa
2462
2498
  if (node.type === "enum") return true;
2463
2499
  if (node.type !== "object") return false;
2464
2500
  if (node.name && circularSchemas.has(node.name)) return false;
2465
- return !_kubb_core.ast.containsCircularRef(node, { circularSchemas });
2501
+ return !(0, _kubb_ast_utils.containsCircularRef)(node, { circularSchemas });
2466
2502
  },
2467
2503
  nameFor: (node) => {
2468
2504
  const base = node.name;
@@ -2536,7 +2572,7 @@ function preScan({ schemas, parseSchema, parseOperation, document, parserOptions
2536
2572
  if (_kubb_core.ast.narrowSchema(node, _kubb_core.ast.schemaTypes.enum) && node.name) enumNames.push(node.name);
2537
2573
  if (discriminator === "inherit" && (schema.oneOf ?? schema.anyOf) && schema.discriminator?.propertyName) discriminatorParentNodes.push(node);
2538
2574
  }
2539
- const circularNames = [..._kubb_core.ast.findCircularSchemas(allNodes)];
2575
+ const circularNames = [...(0, _kubb_ast_utils.findCircularSchemas)(allNodes)];
2540
2576
  const discriminatorChildMap = discriminatorParentNodes.length > 0 ? buildDiscriminatorChildMap(discriminatorParentNodes) : null;
2541
2577
  let dedupePlan = null;
2542
2578
  if (dedupe) {
@@ -2584,7 +2620,7 @@ function createInputStream({ schemas, parseSchema, parseOperation, document, par
2584
2620
  const rewriteTopLevelSchema = (node) => {
2585
2621
  if (!dedupePlan) return node;
2586
2622
  const canonical = dedupePlan.canonicalBySignature.get(_kubb_core.ast.signatureOf(node));
2587
- if (canonical && canonical.name !== node.name) return _kubb_core.ast.createSchema({
2623
+ if (canonical && canonical.name !== node.name) return _kubb_core.ast.factory.createSchema({
2588
2624
  type: "ref",
2589
2625
  name: node.name ?? null,
2590
2626
  ref: canonical.ref,
@@ -2625,7 +2661,12 @@ function createInputStream({ schemas, parseSchema, parseOperation, document, par
2625
2661
  }
2626
2662
  })();
2627
2663
  } };
2628
- return _kubb_core.ast.createStreamInput(schemasIterable, operationsIterable, meta);
2664
+ return _kubb_core.ast.factory.createInput({
2665
+ stream: true,
2666
+ schemas: schemasIterable,
2667
+ operations: operationsIterable,
2668
+ meta
2669
+ });
2629
2670
  }
2630
2671
  //#endregion
2631
2672
  //#region src/adapter.ts
@@ -2784,7 +2825,7 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
2784
2825
  const rawName = (0, _kubb_ast_utils.extractRefName)(schemaRef.ref);
2785
2826
  const result = resolve(nameMapping.get(rawName) ?? rawName);
2786
2827
  if (!result) return null;
2787
- return _kubb_core.ast.createImport({
2828
+ return _kubb_core.ast.factory.createImport({
2788
2829
  name: [result.name],
2789
2830
  path: result.path
2790
2831
  });
@@ -2793,7 +2834,7 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
2793
2834
  async parse(source) {
2794
2835
  const streamNode = await createStream(source);
2795
2836
  const [schemas, operations] = await Promise.all([Array.fromAsync(streamNode.schemas), Array.fromAsync(streamNode.operations)]);
2796
- return _kubb_core.ast.createInput({
2837
+ return _kubb_core.ast.factory.createInput({
2797
2838
  schemas,
2798
2839
  operations,
2799
2840
  meta: streamNode.meta