@kubb/adapter-oas 5.15.2 → 5.15.4
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 +90 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +90 -13
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ var compatibility = {
|
|
|
35
35
|
"node": ">=22.22"
|
|
36
36
|
};
|
|
37
37
|
// package.json
|
|
38
|
-
var version = "5.15.
|
|
38
|
+
var version = "5.15.4";
|
|
39
39
|
// src/constants.ts
|
|
40
40
|
/**
|
|
41
41
|
* Default parser options applied when no explicit options are provided.
|
|
@@ -631,8 +631,10 @@ async function readSource(sourcePath) {
|
|
|
631
631
|
async function resolveSource(sourcePath) {
|
|
632
632
|
const data = await readSource(sourcePath);
|
|
633
633
|
if (sourcePath.toLowerCase().endsWith(".md")) return data;
|
|
634
|
+
const pathname = urlRegExp.test(sourcePath) ? new URL(sourcePath).pathname : sourcePath;
|
|
634
635
|
return parseYaml(data, {
|
|
635
636
|
origin: sourcePath,
|
|
637
|
+
json: !/\.ya?ml$/i.test(pathname),
|
|
636
638
|
help: "Fix the syntax at the reported line, or check that `input` points at the spec and not an HTML page."
|
|
637
639
|
});
|
|
638
640
|
}
|
|
@@ -640,11 +642,19 @@ async function resolveSource(sourcePath) {
|
|
|
640
642
|
* Parses a YAML (or JSON) spec. A syntax error throws `KUBB_INVALID_DOCUMENT` naming `origin`,
|
|
641
643
|
* with the parser message, which keeps the line and column.
|
|
642
644
|
*
|
|
643
|
-
*
|
|
644
|
-
* `yaml
|
|
645
|
-
*
|
|
645
|
+
* With `json` (the default), a document that starts with `{` or `[` goes through `JSON.parse`
|
|
646
|
+
* first, about ten times faster than `js-yaml` on a JSON spec. A duplicate key then keeps the last
|
|
647
|
+
* value, as every JSON parser does. YAML flow syntax also starts with `{`, so a parse failure falls
|
|
648
|
+
* through to YAML. Pass `json: false` for a source known to be YAML.
|
|
649
|
+
*
|
|
650
|
+
* `js-yaml` parses about ten times faster than `yaml`, and rejects duplicate keys instead of
|
|
651
|
+
* keeping the last one. Its core schema keeps timestamps as strings and `<<` as a plain key, as
|
|
652
|
+
* `yaml` does for YAML 1.2.
|
|
646
653
|
*/
|
|
647
|
-
function parseYaml(data, { origin, help }) {
|
|
654
|
+
function parseYaml(data, { origin, help, json = true }) {
|
|
655
|
+
if (json && /^\s*[[{]/.test(data)) try {
|
|
656
|
+
return JSON.parse(data);
|
|
657
|
+
} catch {}
|
|
648
658
|
try {
|
|
649
659
|
const document = (0, js_yaml.load)(data, { schema: js_yaml.CORE_SCHEMA });
|
|
650
660
|
if (document !== void 0) return document;
|
|
@@ -2249,6 +2259,34 @@ function getNumericConstraints(schema) {
|
|
|
2249
2259
|
};
|
|
2250
2260
|
}
|
|
2251
2261
|
/**
|
|
2262
|
+
* Whether an enum value fits the schema's numeric bounds.
|
|
2263
|
+
*/
|
|
2264
|
+
function isWithinBounds({ value, schema }) {
|
|
2265
|
+
if (typeof value !== "number") return true;
|
|
2266
|
+
const { min, max, exclusiveMinimum, exclusiveMaximum, multipleOf } = getNumericConstraints(schema);
|
|
2267
|
+
if (min !== void 0 && value < min) return false;
|
|
2268
|
+
if (max !== void 0 && value > max) return false;
|
|
2269
|
+
if (exclusiveMinimum !== void 0 && value <= exclusiveMinimum) return false;
|
|
2270
|
+
if (exclusiveMaximum !== void 0 && value >= exclusiveMaximum) return false;
|
|
2271
|
+
if (multipleOf !== void 0 && Math.abs(value / multipleOf - Math.round(value / multipleOf)) > 1e-9) return false;
|
|
2272
|
+
return true;
|
|
2273
|
+
}
|
|
2274
|
+
/**
|
|
2275
|
+
* Builds the test for which `enum` entries stay: not `null`, and within the numeric bounds. `enum` and the bounds
|
|
2276
|
+
* apply together, so a value outside them is never valid. Bounds that exclude every value are a spec error, so
|
|
2277
|
+
* they are ignored rather than leaving an empty enum.
|
|
2278
|
+
*/
|
|
2279
|
+
function createEnumMemberFilter(schema) {
|
|
2280
|
+
const boundsApply = schema.enum.some((value) => value !== null && isWithinBounds({
|
|
2281
|
+
value,
|
|
2282
|
+
schema
|
|
2283
|
+
}));
|
|
2284
|
+
return (value) => value !== null && (!boundsApply || isWithinBounds({
|
|
2285
|
+
value,
|
|
2286
|
+
schema
|
|
2287
|
+
}));
|
|
2288
|
+
}
|
|
2289
|
+
/**
|
|
2252
2290
|
* Builds a `null` scalar node carrying the schema's documentation. Shared by the `const: null`
|
|
2253
2291
|
* and the drf-spectacular `NullEnum` (`{ enum: [null] }`) branches, which render identically.
|
|
2254
2292
|
*/
|
|
@@ -2329,7 +2367,8 @@ function convertEnum({ schema, name, nullable, type, parse }) {
|
|
|
2329
2367
|
name
|
|
2330
2368
|
});
|
|
2331
2369
|
const nullInEnum = schema.enum.includes(null);
|
|
2332
|
-
const
|
|
2370
|
+
const isMember = createEnumMemberFilter(schema);
|
|
2371
|
+
const filteredValues = schema.enum.filter(isMember);
|
|
2333
2372
|
if (nullInEnum && filteredValues.length === 0) return createNullNode(schema, name);
|
|
2334
2373
|
const enumNullable = nullable || nullInEnum || void 0;
|
|
2335
2374
|
const enumDefault = schema.default === null && enumNullable ? void 0 : schema.default;
|
|
@@ -2348,8 +2387,9 @@ function convertEnum({ schema, name, nullable, type, parse }) {
|
|
|
2348
2387
|
primitive,
|
|
2349
2388
|
enumValues: uniqueValues
|
|
2350
2389
|
});
|
|
2351
|
-
const
|
|
2352
|
-
const
|
|
2390
|
+
const memberSlots = (list) => Array.isArray(list) ? list.filter((_, index) => isMember(schema.enum[index])) : void 0;
|
|
2391
|
+
const rawEnumNames = extensionKey ? memberSlots(schema[extensionKey]) : void 0;
|
|
2392
|
+
const rawEnumDescriptions = descriptionKey ? memberSlots(schema[descriptionKey]) : void 0;
|
|
2353
2393
|
const seenNames = /* @__PURE__ */ new Set();
|
|
2354
2394
|
return createNode(ctx, {
|
|
2355
2395
|
type: "enum",
|
|
@@ -2367,6 +2407,25 @@ function convertEnum({ schema, name, nullable, type, parse }) {
|
|
|
2367
2407
|
});
|
|
2368
2408
|
}
|
|
2369
2409
|
/**
|
|
2410
|
+
* Converts an `enum` with a handled `format` into a union of its literal values. A named enum node would rename
|
|
2411
|
+
* the exported type (`Status` becomes `StatusKey`), so the union keeps the name the format type had.
|
|
2412
|
+
*/
|
|
2413
|
+
function convertFormattedEnum(context) {
|
|
2414
|
+
const { schema, nullable } = context;
|
|
2415
|
+
const values = [...new Set(schema.enum.filter(createEnumMemberFilter(schema)))];
|
|
2416
|
+
return createNode({
|
|
2417
|
+
...context,
|
|
2418
|
+
nullable: nullable || schema.enum.includes(null) || void 0
|
|
2419
|
+
}, {
|
|
2420
|
+
type: "union",
|
|
2421
|
+
members: values.map((value) => _kubb_kit.ast.factory.createSchema({
|
|
2422
|
+
type: "enum",
|
|
2423
|
+
primitive: getPrimitiveType(typeof value),
|
|
2424
|
+
enumValues: [value]
|
|
2425
|
+
}))
|
|
2426
|
+
});
|
|
2427
|
+
}
|
|
2428
|
+
/**
|
|
2370
2429
|
* Converts a `type: 'string'` schema into a `StringSchemaNode`.
|
|
2371
2430
|
*/
|
|
2372
2431
|
function convertString(context) {
|
|
@@ -2543,6 +2602,24 @@ function convertArray({ schema, name, nullable, defaultValue, options, parse })
|
|
|
2543
2602
|
}
|
|
2544
2603
|
// src/emit/parseSchema.ts
|
|
2545
2604
|
/**
|
|
2605
|
+
* Whether the `format` rule owns the schema: a handled format, and for a date format a `dateType` that is not `false`.
|
|
2606
|
+
*/
|
|
2607
|
+
function matchesFormat({ schema, options }) {
|
|
2608
|
+
if (!schema.format) return false;
|
|
2609
|
+
if (schema.format === "date-time" || schema.format === "date" || schema.format === "time") return resolveDateTypeValue(options.dateType, schema.format) !== false;
|
|
2610
|
+
return isHandledFormat(schema.format);
|
|
2611
|
+
}
|
|
2612
|
+
/**
|
|
2613
|
+
* Whether the format prints as a plain `string` or `number`, so narrowing it to literal values cannot break callers.
|
|
2614
|
+
* `Date`, `bigint` and `Blob` outputs keep the format.
|
|
2615
|
+
*/
|
|
2616
|
+
function formatPrintsPlainType({ schema, options, type }) {
|
|
2617
|
+
const format = schema.format;
|
|
2618
|
+
if (format === "date-time" || format === "date" || format === "time") return resolveDateTypeValue(options.dateType, format) !== "date";
|
|
2619
|
+
if ((format === "int64" || format === "uint64") && type !== "string") return options.integerType !== "bigint";
|
|
2620
|
+
return formatMap[format] !== "blob";
|
|
2621
|
+
}
|
|
2622
|
+
/**
|
|
2546
2623
|
* Ordered schema rule table. Order is significant: composition keywords (`not`, `$ref`, `allOf`,
|
|
2547
2624
|
* `oneOf`/`anyOf`) take precedence over `const` (except a `$ref` with a sibling `const`, where the
|
|
2548
2625
|
* `const` wins), which takes precedence over a genuine OAS 3.1 multi-type array (more than one
|
|
@@ -2580,11 +2657,11 @@ const schemaRules = [
|
|
|
2580
2657
|
convert: convertMultiType
|
|
2581
2658
|
},
|
|
2582
2659
|
{
|
|
2583
|
-
match: (
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2660
|
+
match: (ctx) => ctx.type !== "array" && !!ctx.schema.enum?.some((value) => value !== null) && matchesFormat(ctx) && formatPrintsPlainType(ctx),
|
|
2661
|
+
convert: convertFormattedEnum
|
|
2662
|
+
},
|
|
2663
|
+
{
|
|
2664
|
+
match: matchesFormat,
|
|
2588
2665
|
convert: convertFormat
|
|
2589
2666
|
},
|
|
2590
2667
|
{
|