@kubb/adapter-oas 5.4.3 → 5.5.0

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
@@ -1251,6 +1251,73 @@ function extractDiscriminatedAllOfMembers({ allOfMembers, name, refs }) {
1251
1251
  };
1252
1252
  }
1253
1253
  //#endregion
1254
+ //#region src/emit/converters/annotatedEnum.ts
1255
+ const ANNOTATIONS = /* @__PURE__ */ new Set([
1256
+ "title",
1257
+ "description",
1258
+ "default",
1259
+ "deprecated",
1260
+ "readOnly",
1261
+ "writeOnly",
1262
+ "example",
1263
+ "examples",
1264
+ "xml",
1265
+ "externalDocs"
1266
+ ]);
1267
+ const UNION_KEYS = /* @__PURE__ */ new Set([
1268
+ ...ANNOTATIONS,
1269
+ "type",
1270
+ "nullable",
1271
+ "oneOf",
1272
+ "anyOf"
1273
+ ]);
1274
+ const MEMBER_KEYS = /* @__PURE__ */ new Set([
1275
+ ...ANNOTATIONS,
1276
+ "type",
1277
+ "const"
1278
+ ]);
1279
+ function hasOnlyKeys(schema, keys) {
1280
+ return typeof schema === "object" && schema !== null && !Array.isArray(schema) && Object.keys(schema).every((key) => keys.has(key) || key.startsWith("x-"));
1281
+ }
1282
+ function matchesType(type, value) {
1283
+ return type === void 0 || type === typeof value || type === "integer" && typeof value === "number" && Number.isInteger(value);
1284
+ }
1285
+ /** Recognizes annotated const unions only when replacing them cannot discard validation constraints. */
1286
+ function convertAnnotatedEnum(context) {
1287
+ const { schema, document } = context;
1288
+ if (!document.openapi?.startsWith("3.1.")) return void 0;
1289
+ if (!hasOnlyKeys(schema, UNION_KEYS) || schema.oneOf !== void 0 && schema.anyOf !== void 0) return void 0;
1290
+ const members = schema.oneOf ?? schema.anyOf;
1291
+ if (!members?.length) return void 0;
1292
+ const names = /* @__PURE__ */ new Set();
1293
+ const values = /* @__PURE__ */ new Set();
1294
+ const namedEnumValues = [];
1295
+ let primitive;
1296
+ for (const member of members) {
1297
+ if (!hasOnlyKeys(member, MEMBER_KEYS)) return void 0;
1298
+ const value = member.const;
1299
+ if (typeof value !== "string" && (typeof value !== "number" || !Number.isFinite(value))) return void 0;
1300
+ if (typeof member.title !== "string" || !member.title.trim() || names.has(member.title) || values.has(value)) return void 0;
1301
+ if (!matchesType(schema.type, value) || !matchesType(member.type, value)) return void 0;
1302
+ const valueType = typeof value === "number" ? "number" : "string";
1303
+ if (primitive !== void 0 && primitive !== valueType) return void 0;
1304
+ primitive = valueType;
1305
+ names.add(member.title);
1306
+ values.add(value);
1307
+ namedEnumValues.push({
1308
+ name: member.title,
1309
+ value,
1310
+ primitive: valueType,
1311
+ description: member.description
1312
+ });
1313
+ }
1314
+ return createNode(context, {
1315
+ type: "enum",
1316
+ primitive,
1317
+ namedEnumValues
1318
+ });
1319
+ }
1320
+ //#endregion
1254
1321
  //#region src/emit/converters/composition.ts
1255
1322
  /**
1256
1323
  * Converts a `$ref` schema into a `RefSchemaNode`.
@@ -1363,7 +1430,10 @@ function convertAllOf({ schema, name, nullable, defaultValue, rawOptions, parse,
1363
1430
  /**
1364
1431
  * Converts a `oneOf` / `anyOf` schema into a `UnionSchemaNode`.
1365
1432
  */
1366
- function convertUnion({ schema, name, nullable, defaultValue, rawOptions, parse, refs }) {
1433
+ function convertUnion(context) {
1434
+ const annotatedEnum = convertAnnotatedEnum(context);
1435
+ if (annotatedEnum) return annotatedEnum;
1436
+ const { schema, name, nullable, defaultValue, rawOptions, parse, refs } = context;
1367
1437
  const ctx = {
1368
1438
  schema,
1369
1439
  name,
@@ -1516,9 +1586,7 @@ function convertFormat(context) {
1516
1586
  if (schema.format === "int64" || schema.format === "uint64") return createNode(ctx, {
1517
1587
  type: options.integerType === "bigint" ? "bigint" : "integer",
1518
1588
  primitive: "integer",
1519
- min: schema.minimum,
1520
- max: schema.maximum,
1521
- ...getExclusiveBounds(schema)
1589
+ ...getNumericConstraints(schema)
1522
1590
  });
1523
1591
  if (schema.format === "date-time" || schema.format === "date" || schema.format === "time") {
1524
1592
  const dateType = getDateType(options, schema.format);
@@ -1535,13 +1603,15 @@ function convertFormat(context) {
1535
1603
  });
1536
1604
  }
1537
1605
  const specialType = getSchemaType(schema.format);
1606
+ const isNumeric = specialType === "number" || specialType === "integer" || specialType === "bigint";
1538
1607
  return createNode(ctx, {
1539
- primitive: specialType === "number" || specialType === "integer" || specialType === "bigint" ? specialType : "string",
1608
+ primitive: isNumeric ? specialType : "string",
1540
1609
  type: specialType,
1541
1610
  ...specialType === "url" || specialType === "uuid" || specialType === "email" ? {
1542
1611
  min: schema.minLength,
1543
1612
  max: schema.maxLength
1544
- } : {}
1613
+ } : {},
1614
+ ...isNumeric ? getNumericConstraints(schema) : {}
1545
1615
  });
1546
1616
  }
1547
1617
  /**
@@ -1618,6 +1688,18 @@ function convertString({ schema, name, nullable, defaultValue }) {
1618
1688
  });
1619
1689
  }
1620
1690
  /**
1691
+ * Reads the numeric constraints shared by every `number`, `integer` and `bigint` node. A `format`
1692
+ * such as `double` or `int32` only narrows the type, so formatted numbers keep these too.
1693
+ */
1694
+ function getNumericConstraints(schema) {
1695
+ return {
1696
+ min: schema.minimum,
1697
+ max: schema.maximum,
1698
+ ...getExclusiveBounds(schema),
1699
+ multipleOf: schema.multipleOf
1700
+ };
1701
+ }
1702
+ /**
1621
1703
  * Converts a `type: 'number'` or `type: 'integer'` schema.
1622
1704
  */
1623
1705
  function convertNumeric({ schema, name, nullable, defaultValue }, type) {
@@ -1629,10 +1711,7 @@ function convertNumeric({ schema, name, nullable, defaultValue }, type) {
1629
1711
  }, {
1630
1712
  type,
1631
1713
  primitive: type,
1632
- min: schema.minimum,
1633
- max: schema.maximum,
1634
- ...getExclusiveBounds(schema),
1635
- multipleOf: schema.multipleOf
1714
+ ...getNumericConstraints(schema)
1636
1715
  });
1637
1716
  }
1638
1717
  /**