@kubb/adapter-oas 5.0.0-alpha.10 → 5.0.0-alpha.12

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
@@ -39,6 +39,110 @@ jsonpointer = __toESM(jsonpointer);
39
39
  let oas = require("oas");
40
40
  oas = __toESM(oas);
41
41
  let oas_utils = require("oas/utils");
42
+ //#region src/constants.ts
43
+ /**
44
+ * Default values for all `Options` fields.
45
+ */
46
+ const DEFAULT_PARSER_OPTIONS = {
47
+ dateType: "string",
48
+ integerType: "number",
49
+ unknownType: "any",
50
+ emptySchemaType: "any",
51
+ enumSuffix: "enum"
52
+ };
53
+ /**
54
+ * OpenAPI version string written into merged document stubs.
55
+ */
56
+ const MERGE_OPENAPI_VERSION = "3.0.0";
57
+ /**
58
+ * Fallback `info.title` used when merging multiple API documents.
59
+ */
60
+ const MERGE_DEFAULT_TITLE = "Merged API";
61
+ /**
62
+ * Fallback `info.version` used when merging multiple API documents.
63
+ */
64
+ const MERGE_DEFAULT_VERSION = "1.0.0";
65
+ /**
66
+ * JSON Schema keywords that indicate structural composition.
67
+ * A schema fragment containing any of these keys must not be inlined into its
68
+ * parent during `allOf` flattening — it carries semantic meaning of its own.
69
+ */
70
+ const structuralKeys = new Set([
71
+ "properties",
72
+ "items",
73
+ "additionalProperties",
74
+ "oneOf",
75
+ "anyOf",
76
+ "allOf",
77
+ "not"
78
+ ]);
79
+ /**
80
+ * Maps OAS/JSON Schema `format` strings to their Kubb `SchemaType` equivalents.
81
+ *
82
+ * Only formats that need a type different from the raw OAS `type` are listed.
83
+ * `int64`, `date-time`, `date`, and `time` are handled separately because their
84
+ * mapping depends on runtime parser options.
85
+ *
86
+ * Note: `ipv4`, `ipv6`, and `hostname` map to `'url'` — the closest supported
87
+ * scalar type in the Kubb AST, even though these are not strictly URLs.
88
+ */
89
+ const formatMap = {
90
+ uuid: "uuid",
91
+ email: "email",
92
+ "idn-email": "email",
93
+ uri: "url",
94
+ "uri-reference": "url",
95
+ url: "url",
96
+ ipv4: "url",
97
+ ipv6: "url",
98
+ hostname: "url",
99
+ "idn-hostname": "url",
100
+ binary: "blob",
101
+ byte: "blob",
102
+ int32: "integer",
103
+ float: "number",
104
+ double: "number"
105
+ };
106
+ /**
107
+ * Exhaustive list of media types that Kubb recognizes.
108
+ */
109
+ const knownMediaTypes = new Set([
110
+ "application/json",
111
+ "application/xml",
112
+ "application/x-www-form-urlencoded",
113
+ "application/octet-stream",
114
+ "application/pdf",
115
+ "application/zip",
116
+ "application/graphql",
117
+ "multipart/form-data",
118
+ "text/plain",
119
+ "text/html",
120
+ "text/csv",
121
+ "text/xml",
122
+ "image/png",
123
+ "image/jpeg",
124
+ "image/gif",
125
+ "image/webp",
126
+ "image/svg+xml",
127
+ "audio/mpeg",
128
+ "video/mp4"
129
+ ]);
130
+ /**
131
+ * Vendor extension keys used to attach human-readable labels to enum values.
132
+ * Checked in priority order: the first key found wins.
133
+ */
134
+ const enumExtensionKeys = ["x-enumNames", "x-enum-varnames"];
135
+ /**
136
+ * Scalar primitive schema types used for union member simplification.
137
+ */
138
+ const SCALAR_PRIMITIVE_TYPES = new Set([
139
+ "string",
140
+ "number",
141
+ "integer",
142
+ "bigint",
143
+ "boolean"
144
+ ]);
145
+ //#endregion
42
146
  //#region src/oas/resolveServerUrl.ts
43
147
  /**
44
148
  * Resolves an OpenAPI server URL by substituting `{variable}` placeholders.
@@ -81,9 +185,12 @@ function toCamelOrPascal(text, pascal) {
81
185
  * Splits `text` on `.` and applies `transformPart` to each segment.
82
186
  * The last segment receives `isLast = true`, all earlier segments receive `false`.
83
187
  * Segments are joined with `/` to form a file path.
188
+ *
189
+ * Only splits on dots followed by a letter so that version numbers
190
+ * embedded in operationIds (e.g. `v2025.0`) are kept intact.
84
191
  */
85
192
  function applyToFileParts(text, transformPart) {
86
- const parts = text.split(".");
193
+ const parts = text.split(/\.(?=[a-zA-Z])/);
87
194
  return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
88
195
  }
89
196
  /**
@@ -117,6 +224,27 @@ function pascalCase(text, { isFile, prefix = "", suffix = "" } = {}) {
117
224
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
118
225
  }
119
226
  //#endregion
227
+ //#region ../../internals/utils/src/names.ts
228
+ /**
229
+ * Returns a unique name by appending an incrementing numeric suffix when the name has already been used.
230
+ * Mutates `data` in-place as a usage counter so subsequent calls remain consistent.
231
+ *
232
+ * @example
233
+ * const seen: Record<string, number> = {}
234
+ * getUniqueName('Foo', seen) // 'Foo'
235
+ * getUniqueName('Foo', seen) // 'Foo2'
236
+ * getUniqueName('Foo', seen) // 'Foo3'
237
+ */
238
+ function getUniqueName(originalName, data) {
239
+ let used = data[originalName] || 0;
240
+ if (used) {
241
+ data[originalName] = ++used;
242
+ originalName += used;
243
+ }
244
+ data[originalName] = 1;
245
+ return originalName;
246
+ }
247
+ //#endregion
120
248
  //#region ../../internals/utils/src/reserved.ts
121
249
  /**
122
250
  * Returns `true` when `name` is a syntactically valid JavaScript variable name.
@@ -233,100 +361,6 @@ var URLPath = class {
233
361
  }
234
362
  };
235
363
  //#endregion
236
- //#region src/constants.ts
237
- /**
238
- * OpenAPI version string written into merged document stubs.
239
- */
240
- const MERGE_OPENAPI_VERSION = "3.0.0";
241
- /**
242
- * Fallback `info.title` used when merging multiple API documents.
243
- */
244
- const MERGE_DEFAULT_TITLE = "Merged API";
245
- /**
246
- * Fallback `info.version` used when merging multiple API documents.
247
- */
248
- const MERGE_DEFAULT_VERSION = "1.0.0";
249
- /**
250
- * JSON Schema keywords that indicate structural composition.
251
- * A schema fragment containing any of these keys must not be inlined into its
252
- * parent during `allOf` flattening — it carries semantic meaning of its own.
253
- */
254
- const structuralKeys = new Set([
255
- "properties",
256
- "items",
257
- "additionalProperties",
258
- "oneOf",
259
- "anyOf",
260
- "allOf",
261
- "not"
262
- ]);
263
- /**
264
- * Maps OAS/JSON Schema `format` strings to their Kubb `SchemaType` equivalents.
265
- *
266
- * Only formats that need a type different from the raw OAS `type` are listed.
267
- * `int64`, `date-time`, `date`, and `time` are handled separately because their
268
- * mapping depends on runtime parser options.
269
- *
270
- * Note: `ipv4`, `ipv6`, and `hostname` map to `'url'` — the closest supported
271
- * scalar type in the Kubb AST, even though these are not strictly URLs.
272
- */
273
- const formatMap = {
274
- uuid: "uuid",
275
- email: "email",
276
- "idn-email": "email",
277
- uri: "url",
278
- "uri-reference": "url",
279
- url: "url",
280
- ipv4: "url",
281
- ipv6: "url",
282
- hostname: "url",
283
- "idn-hostname": "url",
284
- binary: "blob",
285
- byte: "blob",
286
- int32: "integer",
287
- float: "number",
288
- double: "number"
289
- };
290
- /**
291
- * Exhaustive list of media types that Kubb recognizes.
292
- */
293
- const knownMediaTypes = new Set([
294
- "application/json",
295
- "application/xml",
296
- "application/x-www-form-urlencoded",
297
- "application/octet-stream",
298
- "application/pdf",
299
- "application/zip",
300
- "application/graphql",
301
- "multipart/form-data",
302
- "text/plain",
303
- "text/html",
304
- "text/csv",
305
- "text/xml",
306
- "image/png",
307
- "image/jpeg",
308
- "image/gif",
309
- "image/webp",
310
- "image/svg+xml",
311
- "audio/mpeg",
312
- "video/mp4"
313
- ]);
314
- /**
315
- * Vendor extension keys used to attach human-readable labels to enum values.
316
- * Checked in priority order: the first key found wins.
317
- */
318
- const enumExtensionKeys = ["x-enumNames", "x-enum-varnames"];
319
- /**
320
- * Scalar primitive schema types used for union member simplification.
321
- */
322
- const SCALAR_PRIMITIVE_TYPES = new Set([
323
- "string",
324
- "number",
325
- "integer",
326
- "bigint",
327
- "boolean"
328
- ]);
329
- //#endregion
330
364
  //#region src/oas/Oas.ts
331
365
  /**
332
366
  * Prefix used to create synthetic `$ref` values for anonymous (inline) discriminator schemas.
@@ -1080,16 +1114,6 @@ function getImports({ node, nameMapping, resolve }) {
1080
1114
  //#endregion
1081
1115
  //#region src/parser.ts
1082
1116
  /**
1083
- * Default values for all `Options` fields.
1084
- */
1085
- const DEFAULT_OPTIONS = {
1086
- dateType: "string",
1087
- integerType: "number",
1088
- unknownType: "any",
1089
- emptySchemaType: "any",
1090
- enumSuffix: "enum"
1091
- };
1092
- /**
1093
1117
  * Looks up the Kubb `SchemaType` for a given OAS `format` string.
1094
1118
  * Returns `undefined` for formats not in `formatMap` (e.g. `int64`, `date-time`),
1095
1119
  * which are handled separately because their output depends on parser options.
@@ -1138,6 +1162,8 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1138
1162
  contentType,
1139
1163
  collisionDetection
1140
1164
  });
1165
+ const usedEnumNames = {};
1166
+ const isLegacyNaming = collisionDetection === false;
1141
1167
  /**
1142
1168
  * Maps an `'any' | 'unknown' | 'void'` option string to the corresponding `SchemaType` constant.
1143
1169
  * Used for both `unknownType` (unannotated schemas) and `emptySchemaType` (empty `{}` schemas).
@@ -1184,7 +1210,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1184
1210
  * Shared metadata fields included in every `createSchema` call.
1185
1211
  * Centralizes the common properties so sub-handlers don't repeat them.
1186
1212
  */
1187
- function buildSchemaBase(schema, name, nullable, defaultValue) {
1213
+ function renderSchemaBase(schema, name, nullable, defaultValue) {
1188
1214
  return {
1189
1215
  name,
1190
1216
  nullable,
@@ -1292,7 +1318,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1292
1318
  return (0, _kubb_ast.createSchema)({
1293
1319
  type: "intersection",
1294
1320
  members: [...allOfMembers.slice(0, syntheticStart), ...mergeAdjacentAnonymousObjects(allOfMembers.slice(syntheticStart))],
1295
- ...buildSchemaBase(schema, name, nullable, defaultValue)
1321
+ ...renderSchemaBase(schema, name, nullable, defaultValue)
1296
1322
  });
1297
1323
  }
1298
1324
  /**
@@ -1306,23 +1332,23 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1306
1332
  function convertUnion({ schema, name, nullable, defaultValue, options }) {
1307
1333
  const unionMembers = [...schema.oneOf ?? [], ...schema.anyOf ?? []];
1308
1334
  const unionBase = {
1309
- ...buildSchemaBase(schema, name, nullable, defaultValue),
1335
+ ...renderSchemaBase(schema, name, nullable, defaultValue),
1310
1336
  discriminatorPropertyName: isDiscriminator(schema) ? schema.discriminator.propertyName : void 0
1311
1337
  };
1312
1338
  if (schema.properties) {
1313
1339
  const { oneOf: _oneOf, anyOf: _anyOf, ...schemaWithoutUnion } = schema;
1314
1340
  const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
1315
- const memberBaseSchema = discriminator ? Object.fromEntries(Object.entries(schemaWithoutUnion).filter(([key]) => key !== "discriminator")) : schemaWithoutUnion;
1341
+ const sharedPropertiesNode = convertSchema({
1342
+ schema: discriminator ? Object.fromEntries(Object.entries(schemaWithoutUnion).filter(([key]) => key !== "discriminator")) : schemaWithoutUnion,
1343
+ name: isLegacyNaming ? void 0 : name
1344
+ }, options);
1316
1345
  return (0, _kubb_ast.createSchema)({
1317
1346
  type: "union",
1318
1347
  ...unionBase,
1319
1348
  members: unionMembers.map((s) => {
1320
1349
  const ref = isReference(s) ? s.$ref : void 0;
1321
1350
  const discriminatorValue = discriminator?.mapping && ref ? Object.entries(discriminator.mapping).find(([, v]) => v === ref)?.[0] : void 0;
1322
- let propertiesNode = convertSchema({
1323
- schema: memberBaseSchema,
1324
- name
1325
- }, options);
1351
+ let propertiesNode = sharedPropertiesNode;
1326
1352
  if (discriminatorValue && discriminator) propertiesNode = applyDiscriminatorEnum({
1327
1353
  node: propertiesNode,
1328
1354
  propertyName: discriminator.propertyName,
@@ -1361,7 +1387,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1361
1387
  type: "enum",
1362
1388
  primitive: getPrimitiveType(typeof constValue === "number" ? "number" : typeof constValue === "boolean" ? "boolean" : "string"),
1363
1389
  enumValues: [constValue],
1364
- ...buildSchemaBase(schema, name, nullable, defaultValue)
1390
+ ...renderSchemaBase(schema, name, nullable, defaultValue)
1365
1391
  });
1366
1392
  }
1367
1393
  /**
@@ -1370,7 +1396,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1370
1396
  * (i.e. `format: 'date-time'` with `dateType: false`).
1371
1397
  */
1372
1398
  function convertFormat({ schema, name, nullable, defaultValue, mergedOptions }) {
1373
- const base = buildSchemaBase(schema, name, nullable, defaultValue);
1399
+ const base = renderSchemaBase(schema, name, nullable, defaultValue);
1374
1400
  if (schema.format === "int64") return (0, _kubb_ast.createSchema)({
1375
1401
  type: mergedOptions.integerType === "bigint" ? "bigint" : "integer",
1376
1402
  primitive: "integer",
@@ -1508,29 +1534,62 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1508
1534
  * - not required + not nullable → `optional: true`
1509
1535
  * - not required + nullable → `nullish: true`
1510
1536
  */
1537
+ /**
1538
+ * Builds the propagation name for a child property during recursive schema conversion.
1539
+ *
1540
+ * - **Legacy naming** (`isLegacyNaming`): only the immediate property key is used
1541
+ * (e.g. `Params` for property `params`), keeping nested names short.
1542
+ * - **Default naming**: the parent name is prepended so the full path is encoded
1543
+ * (e.g. `OrderParams` when parent is `Order`).
1544
+ */
1545
+ function resolveChildName(parentName, propName) {
1546
+ if (isLegacyNaming) return pascalCase(propName);
1547
+ return parentName ? pascalCase([parentName, propName].join(" ")) : void 0;
1548
+ }
1549
+ /**
1550
+ * Derives the final name for an enum property schema node.
1551
+ *
1552
+ * The raw name always includes the enum suffix (e.g. `StatusEnum`).
1553
+ * In legacy mode an additional deduplication step appends a numeric suffix
1554
+ * when the same name has already been used (e.g. `ParamsStatusEnum2`).
1555
+ */
1556
+ function resolveEnumPropName(parentName, propName, enumSuffix) {
1557
+ const raw = pascalCase([
1558
+ parentName,
1559
+ propName,
1560
+ enumSuffix
1561
+ ].filter(Boolean).join(" "));
1562
+ return isLegacyNaming ? getUniqueName(raw, usedEnumNames) : raw;
1563
+ }
1564
+ /**
1565
+ * Given a freshly-converted property schema, returns the node with a correct
1566
+ * `name` attached — or stripped — depending on whether the node is a named
1567
+ * enum, a boolean const-enum (always inlined), or a regular schema.
1568
+ */
1569
+ function applyEnumName(propNode, parentName, propName, enumSuffix) {
1570
+ const enumNode = (0, _kubb_ast.narrowSchema)(propNode, "enum");
1571
+ if (enumNode?.primitive === "boolean") return {
1572
+ ...propNode,
1573
+ name: void 0
1574
+ };
1575
+ if (enumNode) return {
1576
+ ...propNode,
1577
+ name: resolveEnumPropName(parentName, propName, enumSuffix)
1578
+ };
1579
+ return propNode;
1580
+ }
1511
1581
  function convertObject({ schema, name, nullable, defaultValue, options, mergedOptions }) {
1512
1582
  const properties = schema.properties ? Object.entries(schema.properties).map(([propName, propSchema]) => {
1513
1583
  const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
1514
1584
  const resolvedPropSchema = propSchema;
1515
1585
  const propNullable = isNullable(resolvedPropSchema);
1516
- const basePropName = name ? pascalCase([name, propName].join(" ")) : void 0;
1517
- const propNode = convertSchema({
1518
- schema: resolvedPropSchema,
1519
- name: basePropName
1520
- }, options);
1521
- const isEnumNode = !!(0, _kubb_ast.narrowSchema)(propNode, "enum");
1522
- const derivedPropName = isEnumNode && name ? pascalCase([
1523
- name,
1524
- propName,
1525
- mergedOptions.enumSuffix
1526
- ].filter(Boolean).join(" ")) : basePropName;
1527
1586
  return (0, _kubb_ast.createProperty)({
1528
1587
  name: propName,
1529
1588
  schema: {
1530
- ...isEnumNode && derivedPropName !== basePropName ? {
1531
- ...propNode,
1532
- name: derivedPropName
1533
- } : propNode,
1589
+ ...applyEnumName(convertSchema({
1590
+ schema: resolvedPropSchema,
1591
+ name: resolveChildName(name, propName)
1592
+ }, options), name, propName, mergedOptions.enumSuffix),
1534
1593
  nullable: propNullable || void 0,
1535
1594
  optional: !required && !propNullable ? true : void 0,
1536
1595
  nullish: !required && propNullable ? true : void 0
@@ -1552,7 +1611,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1552
1611
  properties,
1553
1612
  additionalProperties: additionalPropertiesNode,
1554
1613
  patternProperties,
1555
- ...buildSchemaBase(schema, name, nullable, defaultValue)
1614
+ ...renderSchemaBase(schema, name, nullable, defaultValue)
1556
1615
  });
1557
1616
  if (isDiscriminator(schema) && schema.discriminator.mapping) {
1558
1617
  const discPropName = schema.discriminator.propertyName;
@@ -1560,11 +1619,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1560
1619
  node: objectNode,
1561
1620
  propertyName: discPropName,
1562
1621
  values: Object.keys(schema.discriminator.mapping),
1563
- enumName: name ? pascalCase([
1564
- name,
1565
- discPropName,
1566
- mergedOptions.enumSuffix
1567
- ].filter(Boolean).join(" ")) : void 0
1622
+ enumName: name ? resolveEnumPropName(name, discPropName, mergedOptions.enumSuffix) : void 0
1568
1623
  });
1569
1624
  }
1570
1625
  return objectNode;
@@ -1583,7 +1638,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1583
1638
  rest: schema.items ? convertSchema({ schema: schema.items }, options) : void 0,
1584
1639
  min: schema.minItems,
1585
1640
  max: schema.maxItems,
1586
- ...buildSchemaBase(schema, name, nullable, defaultValue)
1641
+ ...renderSchemaBase(schema, name, nullable, defaultValue)
1587
1642
  });
1588
1643
  }
1589
1644
  /**
@@ -1594,7 +1649,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1594
1649
  */
1595
1650
  function convertArray({ schema, name, nullable, defaultValue, options, mergedOptions }) {
1596
1651
  const rawItems = schema.items;
1597
- const itemName = rawItems?.enum?.length && name ? pascalCase([name, mergedOptions.enumSuffix].join(" ")) : void 0;
1652
+ const itemName = rawItems?.enum?.length && name ? resolveEnumPropName(void 0, name, mergedOptions.enumSuffix) : void 0;
1598
1653
  return (0, _kubb_ast.createSchema)({
1599
1654
  type: "array",
1600
1655
  primitive: "array",
@@ -1605,7 +1660,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1605
1660
  min: schema.minItems,
1606
1661
  max: schema.maxItems,
1607
1662
  unique: schema.uniqueItems ?? void 0,
1608
- ...buildSchemaBase(schema, name, nullable, defaultValue)
1663
+ ...renderSchemaBase(schema, name, nullable, defaultValue)
1609
1664
  });
1610
1665
  }
1611
1666
  /**
@@ -1618,7 +1673,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1618
1673
  min: schema.minLength,
1619
1674
  max: schema.maxLength,
1620
1675
  pattern: schema.pattern,
1621
- ...buildSchemaBase(schema, name, nullable, defaultValue)
1676
+ ...renderSchemaBase(schema, name, nullable, defaultValue)
1622
1677
  });
1623
1678
  }
1624
1679
  /**
@@ -1632,7 +1687,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1632
1687
  max: schema.maximum,
1633
1688
  exclusiveMinimum: typeof schema.exclusiveMinimum === "number" ? schema.exclusiveMinimum : void 0,
1634
1689
  exclusiveMaximum: typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : void 0,
1635
- ...buildSchemaBase(schema, name, nullable, defaultValue)
1690
+ ...renderSchemaBase(schema, name, nullable, defaultValue)
1636
1691
  });
1637
1692
  }
1638
1693
  /**
@@ -1642,7 +1697,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1642
1697
  return (0, _kubb_ast.createSchema)({
1643
1698
  type: "boolean",
1644
1699
  primitive: "boolean",
1645
- ...buildSchemaBase(schema, name, nullable, defaultValue)
1700
+ ...renderSchemaBase(schema, name, nullable, defaultValue)
1646
1701
  });
1647
1702
  }
1648
1703
  /**
@@ -1677,7 +1732,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1677
1732
  */
1678
1733
  function convertSchema({ schema, name }, options) {
1679
1734
  const mergedOptions = {
1680
- ...DEFAULT_OPTIONS,
1735
+ ...DEFAULT_PARSER_OPTIONS,
1681
1736
  ...options
1682
1737
  };
1683
1738
  const flattenedSchema = flattenSchema(schema);
@@ -1708,7 +1763,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1708
1763
  if (schema.type === "string" && schema.contentMediaType === "application/octet-stream") return (0, _kubb_ast.createSchema)({
1709
1764
  type: "blob",
1710
1765
  primitive: "string",
1711
- ...buildSchemaBase(schema, name, nullable, defaultValue)
1766
+ ...renderSchemaBase(schema, name, nullable, defaultValue)
1712
1767
  });
1713
1768
  if (Array.isArray(schema.type) && schema.type.length > 1) {
1714
1769
  const nonNullTypes = schema.type.filter((t) => t !== "null");
@@ -1722,7 +1777,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1722
1777
  },
1723
1778
  name
1724
1779
  }, options)),
1725
- ...buildSchemaBase(schema, name, arrayNullable, defaultValue)
1780
+ ...renderSchemaBase(schema, name, arrayNullable, defaultValue)
1726
1781
  });
1727
1782
  }
1728
1783
  if (!type) {
@@ -1770,18 +1825,26 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1770
1825
  function parseOperation(options, oas, operation) {
1771
1826
  const parameters = oas.getParameters(operation).map((param) => parseParameter(options, param));
1772
1827
  const requestBodySchema = oas.getRequestSchema(operation);
1773
- const requestBody = requestBodySchema ? convertSchema({ schema: requestBodySchema }, options) : void 0;
1828
+ const requestBodySchemaNode = requestBodySchema ? convertSchema({ schema: requestBodySchema }, options) : void 0;
1829
+ const requestBodyKeysToOmit = requestBodySchema?.properties ? Object.entries(requestBodySchema.properties).filter(([, prop]) => !isReference(prop) && prop.readOnly).map(([key]) => key) : void 0;
1830
+ const requestBody = requestBodySchemaNode ? {
1831
+ schema: requestBodySchemaNode,
1832
+ keysToOmit: requestBodyKeysToOmit?.length ? requestBodyKeysToOmit : void 0
1833
+ } : void 0;
1774
1834
  const responses = operation.getResponseStatusCodes().map((statusCode) => {
1775
1835
  const responseObj = operation.getResponseByStatusCode(statusCode);
1776
1836
  const responseSchema = oas.getResponseSchema(operation, statusCode);
1777
1837
  const schema = responseSchema && Object.keys(responseSchema).length > 0 ? convertSchema({ schema: responseSchema }, options) : (0, _kubb_ast.createSchema)({ type: resolveTypeOption(options.emptySchemaType) });
1778
1838
  const description = typeof responseObj === "object" && responseObj !== null && !Array.isArray(responseObj) ? responseObj.description : void 0;
1779
1839
  const rawContent = typeof responseObj === "object" && responseObj !== null && !Array.isArray(responseObj) ? responseObj.content : void 0;
1840
+ const mediaType = rawContent ? toMediaType(Object.keys(rawContent)[0] ?? "") : toMediaType(operation.contentType ?? "");
1841
+ const keysToOmit = responseSchema?.properties ? Object.entries(responseSchema.properties).filter(([, prop]) => !isReference(prop) && prop.writeOnly).map(([key]) => key) : void 0;
1780
1842
  return (0, _kubb_ast.createResponse)({
1781
1843
  statusCode,
1782
1844
  description,
1783
1845
  schema,
1784
- mediaType: rawContent ? toMediaType(Object.keys(rawContent)[0] ?? "") : toMediaType(operation.contentType ?? "")
1846
+ mediaType,
1847
+ keysToOmit: keysToOmit?.length ? keysToOmit : void 0
1785
1848
  });
1786
1849
  });
1787
1850
  return (0, _kubb_ast.createOperation)({
@@ -1803,7 +1866,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1803
1866
  */
1804
1867
  function parse(options) {
1805
1868
  const mergedOptions = {
1806
- ...DEFAULT_OPTIONS,
1869
+ ...DEFAULT_PARSER_OPTIONS,
1807
1870
  ...options
1808
1871
  };
1809
1872
  const schemas = Object.entries(schemaObjects).map(([name, schemaObject]) => convertSchema({
@@ -1873,7 +1936,7 @@ const adapterOasName = "oas";
1873
1936
  * ```
1874
1937
  */
1875
1938
  const adapterOas = (0, _kubb_core.createAdapter)((options) => {
1876
- const { validate = true, oasClass, contentType, serverIndex, serverVariables, discriminator = "strict", collisionDetection = false, dateType = "string", integerType = "number", unknownType = "any", emptySchemaType = unknownType } = options;
1939
+ const { validate = true, oasClass, contentType, serverIndex, serverVariables, discriminator = "strict", collisionDetection = 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;
1877
1940
  const nameMapping = /* @__PURE__ */ new Map();
1878
1941
  return {
1879
1942
  name: "oas",
@@ -1889,6 +1952,7 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
1889
1952
  integerType,
1890
1953
  unknownType,
1891
1954
  emptySchemaType,
1955
+ enumSuffix,
1892
1956
  nameMapping
1893
1957
  },
1894
1958
  getImports(node, resolve) {
@@ -1921,7 +1985,8 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
1921
1985
  dateType,
1922
1986
  integerType,
1923
1987
  unknownType,
1924
- emptySchemaType
1988
+ emptySchemaType,
1989
+ enumSuffix
1925
1990
  }),
1926
1991
  meta: {
1927
1992
  title: oas.api.info?.title,