@kubb/adapter-oas 5.17.0 → 5.17.1
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 +74 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +74 -39
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var compatibility = {
|
|
|
19
19
|
"node": ">=22.22"
|
|
20
20
|
};
|
|
21
21
|
// package.json
|
|
22
|
-
var version = "5.17.
|
|
22
|
+
var version = "5.17.1";
|
|
23
23
|
// src/constants.ts
|
|
24
24
|
/**
|
|
25
25
|
* Default parser options applied when no explicit options are provided.
|
|
@@ -429,17 +429,32 @@ function isBinary(schema) {
|
|
|
429
429
|
return schema.contentMediaType === "application/octet-stream" && schema.contentEncoding === void 0 && (schema.type === void 0 || schema.type === "string");
|
|
430
430
|
}
|
|
431
431
|
/**
|
|
432
|
+
* Keywords that only annotate a schema. A schema with nothing else does not constrain the value.
|
|
433
|
+
*/
|
|
434
|
+
const annotationKeywords = /* @__PURE__ */ new Set([
|
|
435
|
+
"title",
|
|
436
|
+
"description",
|
|
437
|
+
"default",
|
|
438
|
+
"example",
|
|
439
|
+
"examples",
|
|
440
|
+
"deprecated",
|
|
441
|
+
"readOnly",
|
|
442
|
+
"writeOnly",
|
|
443
|
+
"externalDocs"
|
|
444
|
+
]);
|
|
445
|
+
/**
|
|
432
446
|
* Returns the binary schema for a non-JSON entry the OAS 3.1 upgrade emptied out, or `undefined`
|
|
433
447
|
* when the entry carries a schema of its own. The upgrade rewrites `format: 'binary'` into
|
|
434
448
|
* `contentMediaType` and drops it whenever it only repeats the media type key, for any binary
|
|
435
449
|
* media type (`application/octet-stream`, `application/pdf`, `image/png`, ...), not just
|
|
436
450
|
* `application/octet-stream`. Without the fallback such a body resolves to the empty schema type
|
|
437
|
-
* instead of a blob.
|
|
451
|
+
* instead of a blob. Annotations such as `description` survive the upgrade and are kept.
|
|
438
452
|
*/
|
|
439
453
|
function getBinaryFallbackSchema(mediaType, schema) {
|
|
440
454
|
if (!mediaType || isJsonMimeType(mediaType)) return void 0;
|
|
441
|
-
if (schema && Object.keys(schema).
|
|
455
|
+
if (schema && Object.keys(schema).some((key) => !annotationKeywords.has(key) && !key.startsWith("x-"))) return void 0;
|
|
442
456
|
return {
|
|
457
|
+
...schema,
|
|
443
458
|
type: "string",
|
|
444
459
|
contentMediaType: "application/octet-stream"
|
|
445
460
|
};
|
|
@@ -1409,6 +1424,39 @@ function flattenSchema(schema) {
|
|
|
1409
1424
|
function scanSchema(node, pointer = node.pointer) {
|
|
1410
1425
|
if (pointer) visit(node, pointer);
|
|
1411
1426
|
}
|
|
1427
|
+
let formatTally;
|
|
1428
|
+
/**
|
|
1429
|
+
* Runs `fn` and reports `KUBB_UNSUPPORTED_FORMAT` once per format with the number of schemas that use it,
|
|
1430
|
+
* instead of once per schema. `format` is an open value in OpenAPI, so a large spec would otherwise print
|
|
1431
|
+
* thousands of warnings that say the same thing. `fn` must be synchronous.
|
|
1432
|
+
*/
|
|
1433
|
+
function groupUnsupportedFormats(fn) {
|
|
1434
|
+
formatTally = /* @__PURE__ */ new Map();
|
|
1435
|
+
try {
|
|
1436
|
+
return fn();
|
|
1437
|
+
} finally {
|
|
1438
|
+
const tally = formatTally;
|
|
1439
|
+
formatTally = void 0;
|
|
1440
|
+
for (const [format, pointers] of tally) reportUnsupportedFormat(format, [...pointers]);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
function tallyFormat(format, pointer) {
|
|
1444
|
+
if (!formatTally) return reportUnsupportedFormat(format, [pointer]);
|
|
1445
|
+
formatTally.set(format, (formatTally.get(format) ?? /* @__PURE__ */ new Set()).add(pointer));
|
|
1446
|
+
}
|
|
1447
|
+
function reportUnsupportedFormat(format, pointers) {
|
|
1448
|
+
const count = pointers.length;
|
|
1449
|
+
Diagnostics.report({
|
|
1450
|
+
code: Diagnostics.code.unsupportedFormat,
|
|
1451
|
+
severity: "warning",
|
|
1452
|
+
message: count === 1 ? `Kubb does not map the format "${format}" to a specific type, so it falls back to the base type.` : `Kubb does not map the format "${format}" to a specific type, so ${count} schemas fall back to the base type.`,
|
|
1453
|
+
help: `Use a format Kubb supports, or handle "${format}" with a custom parser or plugin.`,
|
|
1454
|
+
location: {
|
|
1455
|
+
kind: "schema",
|
|
1456
|
+
pointer: pointers[0]
|
|
1457
|
+
}
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1412
1460
|
function visit(node, pointer) {
|
|
1413
1461
|
node.pointer ??= pointer;
|
|
1414
1462
|
if (node.deprecated) Diagnostics.report({
|
|
@@ -1420,16 +1468,7 @@ function visit(node, pointer) {
|
|
|
1420
1468
|
pointer
|
|
1421
1469
|
}
|
|
1422
1470
|
});
|
|
1423
|
-
if (typeof node.format === "string" && !isHandledFormat(node.format))
|
|
1424
|
-
code: Diagnostics.code.unsupportedFormat,
|
|
1425
|
-
severity: "warning",
|
|
1426
|
-
message: `Kubb does not map the format "${node.format}" to a specific type, so it falls back to the base type.`,
|
|
1427
|
-
help: `Use a format Kubb supports, or handle "${node.format}" with a custom parser or plugin.`,
|
|
1428
|
-
location: {
|
|
1429
|
-
kind: "schema",
|
|
1430
|
-
pointer
|
|
1431
|
-
}
|
|
1432
|
-
});
|
|
1471
|
+
if (typeof node.format === "string" && !isHandledFormat(node.format)) tallyFormat(node.format, pointer);
|
|
1433
1472
|
if (node.type === "object") {
|
|
1434
1473
|
for (const property of node.properties) visit(property.schema, `${pointer}/properties/${escapePointerToken(property.name)}`);
|
|
1435
1474
|
if (node.additionalProperties && typeof node.additionalProperties === "object") visit(node.additionalProperties, `${pointer}/additionalProperties`);
|
|
@@ -1538,18 +1577,6 @@ function getResponseByStatusCode({ operation, refs, statusCode }) {
|
|
|
1538
1577
|
function getRequestBody({ operation, refs }) {
|
|
1539
1578
|
return refs.deref(operation.schema.requestBody);
|
|
1540
1579
|
}
|
|
1541
|
-
/**
|
|
1542
|
-
* Returns the primary request content type. Prefers a JSON-like media type (the last one wins
|
|
1543
|
-
* when several are declared), then the first declared one, defaulting to `'application/json'`.
|
|
1544
|
-
*/
|
|
1545
|
-
function getRequestContentType({ operation, refs }) {
|
|
1546
|
-
const content = getRequestBody({
|
|
1547
|
-
operation,
|
|
1548
|
-
refs
|
|
1549
|
-
})?.content;
|
|
1550
|
-
const mediaTypes = content ? Object.keys(content) : [];
|
|
1551
|
-
return mediaTypes.findLast(isJsonMimeType) ?? mediaTypes[0] ?? "application/json";
|
|
1552
|
-
}
|
|
1553
1580
|
/** Merges path-level and operation-level parameters; operation-level wins per `in:name`. */
|
|
1554
1581
|
function getParameters({ operation, refs }) {
|
|
1555
1582
|
const resolveParams = (params, pointer) => params.flatMap((entry, index) => {
|
|
@@ -1812,15 +1839,13 @@ function parseOperation({ operation, ...ctx }) {
|
|
|
1812
1839
|
}) : {}
|
|
1813
1840
|
};
|
|
1814
1841
|
};
|
|
1815
|
-
const
|
|
1842
|
+
const declaredContentTypes = Object.keys(response?.content ?? {});
|
|
1843
|
+
const responseContent = (contentType && declaredContentTypes.length ? [contentType] : declaredContentTypes).map((ct) => ast.factory.createContent({
|
|
1816
1844
|
contentType: ct,
|
|
1817
1845
|
...parseEntrySchema(ct)
|
|
1818
1846
|
}));
|
|
1819
1847
|
if (responseContent.length === 0) responseContent.push(ast.factory.createContent({
|
|
1820
|
-
contentType:
|
|
1821
|
-
operation,
|
|
1822
|
-
refs
|
|
1823
|
-
}),
|
|
1848
|
+
contentType: "",
|
|
1824
1849
|
...parseEntrySchema(contentType)
|
|
1825
1850
|
}));
|
|
1826
1851
|
return ast.factory.createResponse({
|
|
@@ -2000,6 +2025,15 @@ function removeInheritedDiscriminator({ members, refs }) {
|
|
|
2000
2025
|
});
|
|
2001
2026
|
}
|
|
2002
2027
|
/**
|
|
2028
|
+
* Whether a member can carry the discriminator property. A discriminator is only a hint, so an array
|
|
2029
|
+
* or primitive member keeps its own type instead of an intersection no value can satisfy.
|
|
2030
|
+
*/
|
|
2031
|
+
function isObjectLike(member, refs) {
|
|
2032
|
+
const type = (isReference(member) ? refs.resolve(member.$ref, { report: false }) : member)?.type;
|
|
2033
|
+
if (type === void 0) return true;
|
|
2034
|
+
return Array.isArray(type) ? type.includes("object") : type === "object";
|
|
2035
|
+
}
|
|
2036
|
+
/**
|
|
2003
2037
|
* Narrows each `oneOf`/`anyOf` member with its discriminant value, intersecting the member's own
|
|
2004
2038
|
* node with either the shared-properties slice carrying that value, or a synthetic discriminant
|
|
2005
2039
|
* literal. The referenced child schema's own definition is left untouched — narrowing happens only
|
|
@@ -2062,7 +2096,7 @@ function narrowUnionMembers({ unionMembers, discriminator, sharedPropertiesNode,
|
|
|
2062
2096
|
schema: s,
|
|
2063
2097
|
name
|
|
2064
2098
|
});
|
|
2065
|
-
if (!discriminatorValues.length || !discriminator) return memberNode;
|
|
2099
|
+
if (!discriminatorValues.length || !discriminator || !isObjectLike(s, refs)) return memberNode;
|
|
2066
2100
|
const narrowedDiscriminatorNode = sharedPropertiesNode ? pickDiscriminatorPropertyNode(ast.applyMacros(sharedPropertiesNode, [macroDiscriminatorEnum({
|
|
2067
2101
|
propertyName: discriminator.propertyName,
|
|
2068
2102
|
values: discriminatorValues
|
|
@@ -3463,18 +3497,19 @@ const adapterOas = defineExtension({
|
|
|
3463
3497
|
parsedDocument = document;
|
|
3464
3498
|
const refs = createRefs(document);
|
|
3465
3499
|
const { schemas, renames, pointers } = getSchemas(document, { contentType }, refs);
|
|
3466
|
-
|
|
3500
|
+
const parseSchema = createSchemaParser({
|
|
3501
|
+
document,
|
|
3502
|
+
refs,
|
|
3503
|
+
renames,
|
|
3504
|
+
options: parserOptions
|
|
3505
|
+
});
|
|
3506
|
+
return groupUnsupportedFormats(() => parseInput({
|
|
3467
3507
|
document,
|
|
3468
3508
|
refs,
|
|
3469
3509
|
schemas,
|
|
3470
3510
|
pointers,
|
|
3471
|
-
parseSchema
|
|
3472
|
-
|
|
3473
|
-
refs,
|
|
3474
|
-
renames,
|
|
3475
|
-
options: parserOptions
|
|
3476
|
-
})
|
|
3477
|
-
});
|
|
3511
|
+
parseSchema
|
|
3512
|
+
}));
|
|
3478
3513
|
})();
|
|
3479
3514
|
inputCache.set(source, {
|
|
3480
3515
|
promise,
|