@kubb/plugin-ts 5.4.0 → 5.4.2
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 +42 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +42 -15
- package/dist/index.js.map +1 -1
- package/kubb-extension.json +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -879,6 +879,22 @@ function resolveContentTypeVariants(entries, baseName) {
|
|
|
879
879
|
}
|
|
880
880
|
const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
|
|
881
881
|
/**
|
|
882
|
+
* An OpenAPI 3.2 `querystring` parameter is the whole query string, so a form-encoded object becomes one query parameter
|
|
883
|
+
* per property, typed and serialized like any other.
|
|
884
|
+
* Another content type, such as JSON, stays one parameter named after it, and the runtime sends its value as the whole query string.
|
|
885
|
+
*/
|
|
886
|
+
function spreadQuerystring(param) {
|
|
887
|
+
const schema = param.schema.type === "ref" ? param.schema.schema : param.schema;
|
|
888
|
+
const formEncoded = !param.contentType || param.contentType.split(";")[0].trim().toLowerCase() === "application/x-www-form-urlencoded";
|
|
889
|
+
if (schema?.type !== "object" || !formEncoded) return [param];
|
|
890
|
+
return schema.properties.map((property) => ast.factory.createParameter({
|
|
891
|
+
name: property.name,
|
|
892
|
+
in: "query",
|
|
893
|
+
schema: property.schema,
|
|
894
|
+
required: param.required && property.required
|
|
895
|
+
}));
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
882
898
|
* Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each
|
|
883
899
|
* group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance
|
|
884
900
|
* (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the
|
|
@@ -887,17 +903,18 @@ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
|
|
|
887
903
|
function getOperationParameters(node) {
|
|
888
904
|
const cached = operationParameterGroupsByNode.get(node);
|
|
889
905
|
if (cached) return cached;
|
|
890
|
-
const
|
|
906
|
+
const dedupe = (params) => {
|
|
891
907
|
const seen = /* @__PURE__ */ new Set();
|
|
892
|
-
return
|
|
893
|
-
if (
|
|
908
|
+
return params.filter((param) => {
|
|
909
|
+
if (seen.has(param.name)) return false;
|
|
894
910
|
seen.add(param.name);
|
|
895
911
|
return true;
|
|
896
912
|
});
|
|
897
913
|
};
|
|
914
|
+
const group = (location) => dedupe(node.parameters.filter((param) => param.in === location));
|
|
898
915
|
const groups = {
|
|
899
916
|
path: group("path"),
|
|
900
|
-
query: group("query"),
|
|
917
|
+
query: dedupe([...group("query"), ...group("querystring").flatMap(spreadQuerystring)]),
|
|
901
918
|
header: group("header"),
|
|
902
919
|
cookie: group("cookie")
|
|
903
920
|
};
|
|
@@ -946,7 +963,7 @@ function buildOptionsSchema(node, resolver, { pairContentTypes = false } = {}) {
|
|
|
946
963
|
properties: [
|
|
947
964
|
ast.factory.createProperty({
|
|
948
965
|
name: "body",
|
|
949
|
-
required: hasBody,
|
|
966
|
+
required: hasBody && node.requestBody?.required === true,
|
|
950
967
|
schema: body
|
|
951
968
|
}),
|
|
952
969
|
...groups.map(({ name, params, resolve }) => {
|
|
@@ -1297,6 +1314,14 @@ function formatExample(value) {
|
|
|
1297
1314
|
if (value === null || typeof value !== "object") return String(value);
|
|
1298
1315
|
return (JSON.stringify(value) ?? String(value)).replaceAll("*/", "*\\/");
|
|
1299
1316
|
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Whether a schema is binary, or an array of binary items, so its TypeScript type is `Blob` or `Blob[]`.
|
|
1319
|
+
*/
|
|
1320
|
+
function isBinarySchema(schema) {
|
|
1321
|
+
const meta = syncSchemaRef(schema);
|
|
1322
|
+
const isBlob = (node) => syncSchemaRef(node)?.type === "blob";
|
|
1323
|
+
return !!meta && (isBlob(meta) || meta.type === "array" && "items" in meta && (meta.items ?? []).some(isBlob));
|
|
1324
|
+
}
|
|
1300
1325
|
function buildPropertyJSDocComments(schema, optional) {
|
|
1301
1326
|
const meta = syncSchemaRef(schema);
|
|
1302
1327
|
const isArray = meta?.primitive === "array";
|
|
@@ -1314,7 +1339,7 @@ function buildPropertyJSDocComments(schema, optional) {
|
|
|
1314
1339
|
meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" && typeof meta.default === "string" ? stringify(meta.default) : formatExample(meta.default)}` : null,
|
|
1315
1340
|
...exampleValues.map((example) => `@example ${formatExample(example)}`)
|
|
1316
1341
|
].filter(Boolean);
|
|
1317
|
-
const typeTag = comments.length && meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null;
|
|
1342
|
+
const typeTag = comments.length && !isBinarySchema(schema) && meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null;
|
|
1318
1343
|
return [...comments, typeTag].filter(Boolean);
|
|
1319
1344
|
}
|
|
1320
1345
|
/**
|
|
@@ -1499,14 +1524,16 @@ const printerTs = ast.createPrinter((options) => {
|
|
|
1499
1524
|
const optional = !property.required || !!property.schema.optional || !!property.schema.nullish;
|
|
1500
1525
|
const type = buildPropertyType(property.schema, baseType, options.optionalType, optional);
|
|
1501
1526
|
const propMeta = syncSchemaRef(property.schema);
|
|
1527
|
+
const propertyNode = createPropertySignature({
|
|
1528
|
+
questionToken: optional ? addsQuestionToken : false,
|
|
1529
|
+
name,
|
|
1530
|
+
type,
|
|
1531
|
+
readOnly: propMeta?.readOnly
|
|
1532
|
+
});
|
|
1533
|
+
const binaryRemark = isBinarySchema(property.schema) ? "@remarks Pass a `File` to send its filename. A plain `Blob` is sent with the filename `blob`." : void 0;
|
|
1502
1534
|
return appendJSDocToNode({
|
|
1503
|
-
node:
|
|
1504
|
-
|
|
1505
|
-
name,
|
|
1506
|
-
type,
|
|
1507
|
-
readOnly: propMeta?.readOnly
|
|
1508
|
-
}),
|
|
1509
|
-
comments: buildPropertyJSDocComments(property.schema, optional)
|
|
1535
|
+
node: propertyNode,
|
|
1536
|
+
comments: [...buildPropertyJSDocComments(property.schema, optional), binaryRemark]
|
|
1510
1537
|
});
|
|
1511
1538
|
});
|
|
1512
1539
|
const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, transform)];
|
|
@@ -1902,11 +1929,11 @@ const typeGenerator = defineGenerator({
|
|
|
1902
1929
|
});
|
|
1903
1930
|
// kubb-extension.json
|
|
1904
1931
|
var compatibility = {
|
|
1905
|
-
"kubb": ">=5.
|
|
1932
|
+
"kubb": ">=5.16.0",
|
|
1906
1933
|
"node": ">=22.22"
|
|
1907
1934
|
};
|
|
1908
1935
|
// package.json
|
|
1909
|
-
var version = "5.4.
|
|
1936
|
+
var version = "5.4.2";
|
|
1910
1937
|
// src/resolvers/resolverTs.ts
|
|
1911
1938
|
/**
|
|
1912
1939
|
* Default resolver used by `@kubb/plugin-ts`. Decides the names and file paths
|