@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 CHANGED
@@ -883,6 +883,22 @@ function resolveContentTypeVariants(entries, baseName) {
883
883
  }
884
884
  const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
885
885
  /**
886
+ * An OpenAPI 3.2 `querystring` parameter is the whole query string, so a form-encoded object becomes one query parameter
887
+ * per property, typed and serialized like any other.
888
+ * Another content type, such as JSON, stays one parameter named after it, and the runtime sends its value as the whole query string.
889
+ */
890
+ function spreadQuerystring(param) {
891
+ const schema = param.schema.type === "ref" ? param.schema.schema : param.schema;
892
+ const formEncoded = !param.contentType || param.contentType.split(";")[0].trim().toLowerCase() === "application/x-www-form-urlencoded";
893
+ if (schema?.type !== "object" || !formEncoded) return [param];
894
+ return schema.properties.map((property) => _kubb_kit.ast.factory.createParameter({
895
+ name: property.name,
896
+ in: "query",
897
+ schema: property.schema,
898
+ required: param.required && property.required
899
+ }));
900
+ }
901
+ /**
886
902
  * Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each
887
903
  * group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance
888
904
  * (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the
@@ -891,17 +907,18 @@ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
891
907
  function getOperationParameters(node) {
892
908
  const cached = operationParameterGroupsByNode.get(node);
893
909
  if (cached) return cached;
894
- const group = (location) => {
910
+ const dedupe = (params) => {
895
911
  const seen = /* @__PURE__ */ new Set();
896
- return node.parameters.filter((param) => {
897
- if (param.in !== location || seen.has(param.name)) return false;
912
+ return params.filter((param) => {
913
+ if (seen.has(param.name)) return false;
898
914
  seen.add(param.name);
899
915
  return true;
900
916
  });
901
917
  };
918
+ const group = (location) => dedupe(node.parameters.filter((param) => param.in === location));
902
919
  const groups = {
903
920
  path: group("path"),
904
- query: group("query"),
921
+ query: dedupe([...group("query"), ...group("querystring").flatMap(spreadQuerystring)]),
905
922
  header: group("header"),
906
923
  cookie: group("cookie")
907
924
  };
@@ -950,7 +967,7 @@ function buildOptionsSchema(node, resolver, { pairContentTypes = false } = {}) {
950
967
  properties: [
951
968
  _kubb_kit.ast.factory.createProperty({
952
969
  name: "body",
953
- required: hasBody,
970
+ required: hasBody && node.requestBody?.required === true,
954
971
  schema: body
955
972
  }),
956
973
  ...groups.map(({ name, params, resolve }) => {
@@ -1301,6 +1318,14 @@ function formatExample(value) {
1301
1318
  if (value === null || typeof value !== "object") return String(value);
1302
1319
  return (JSON.stringify(value) ?? String(value)).replaceAll("*/", "*\\/");
1303
1320
  }
1321
+ /**
1322
+ * Whether a schema is binary, or an array of binary items, so its TypeScript type is `Blob` or `Blob[]`.
1323
+ */
1324
+ function isBinarySchema(schema) {
1325
+ const meta = (0, _kubb_kit.syncSchemaRef)(schema);
1326
+ const isBlob = (node) => (0, _kubb_kit.syncSchemaRef)(node)?.type === "blob";
1327
+ return !!meta && (isBlob(meta) || meta.type === "array" && "items" in meta && (meta.items ?? []).some(isBlob));
1328
+ }
1304
1329
  function buildPropertyJSDocComments(schema, optional) {
1305
1330
  const meta = (0, _kubb_kit.syncSchemaRef)(schema);
1306
1331
  const isArray = meta?.primitive === "array";
@@ -1318,7 +1343,7 @@ function buildPropertyJSDocComments(schema, optional) {
1318
1343
  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,
1319
1344
  ...exampleValues.map((example) => `@example ${formatExample(example)}`)
1320
1345
  ].filter(Boolean);
1321
- const typeTag = comments.length && meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null;
1346
+ const typeTag = comments.length && !isBinarySchema(schema) && meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null;
1322
1347
  return [...comments, typeTag].filter(Boolean);
1323
1348
  }
1324
1349
  /**
@@ -1503,14 +1528,16 @@ const printerTs = _kubb_kit.ast.createPrinter((options) => {
1503
1528
  const optional = !property.required || !!property.schema.optional || !!property.schema.nullish;
1504
1529
  const type = buildPropertyType(property.schema, baseType, options.optionalType, optional);
1505
1530
  const propMeta = (0, _kubb_kit.syncSchemaRef)(property.schema);
1531
+ const propertyNode = createPropertySignature({
1532
+ questionToken: optional ? addsQuestionToken : false,
1533
+ name,
1534
+ type,
1535
+ readOnly: propMeta?.readOnly
1536
+ });
1537
+ const binaryRemark = isBinarySchema(property.schema) ? "@remarks Pass a `File` to send its filename. A plain `Blob` is sent with the filename `blob`." : void 0;
1506
1538
  return appendJSDocToNode({
1507
- node: createPropertySignature({
1508
- questionToken: optional ? addsQuestionToken : false,
1509
- name,
1510
- type,
1511
- readOnly: propMeta?.readOnly
1512
- }),
1513
- comments: buildPropertyJSDocComments(property.schema, optional)
1539
+ node: propertyNode,
1540
+ comments: [...buildPropertyJSDocComments(property.schema, optional), binaryRemark]
1514
1541
  });
1515
1542
  });
1516
1543
  const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, transform)];
@@ -1906,11 +1933,11 @@ const typeGenerator = (0, _kubb_kit.defineGenerator)({
1906
1933
  });
1907
1934
  // kubb-extension.json
1908
1935
  var compatibility = {
1909
- "kubb": ">=5.14.6",
1936
+ "kubb": ">=5.16.0",
1910
1937
  "node": ">=22.22"
1911
1938
  };
1912
1939
  // package.json
1913
- var version = "5.4.0";
1940
+ var version = "5.4.2";
1914
1941
  // src/resolvers/resolverTs.ts
1915
1942
  /**
1916
1943
  * Default resolver used by `@kubb/plugin-ts`. Decides the names and file paths