@kubb/plugin-ts 5.0.0-beta.56 → 5.0.0-beta.64

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
@@ -31,10 +31,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  let _kubb_ast_utils = require("@kubb/ast/utils");
32
32
  let _kubb_parser_ts = require("@kubb/parser-ts");
33
33
  let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
34
- let _kubb_core = require("@kubb/core");
35
34
  let typescript = require("typescript");
36
35
  typescript = __toESM(typescript, 1);
37
36
  let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
37
+ let _kubb_core = require("@kubb/core");
38
38
  //#region ../../internals/utils/src/casing.ts
39
39
  /**
40
40
  * Shared implementation for camelCase and PascalCase conversion.
@@ -484,7 +484,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
484
484
  return factory.createLiteralTypeNode(factory.createNumericLiteral(value?.toString()));
485
485
  }
486
486
  if (typeof value === "boolean") return factory.createLiteralTypeNode(value ? factory.createTrue() : factory.createFalse());
487
- if (value) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
487
+ if (value !== null && value !== void 0) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
488
488
  }).filter((node) => node !== void 0)))];
489
489
  if (type === "enum" || type === "constEnum") return [void 0, factory.createEnumDeclaration([factory.createToken(typescript.default.SyntaxKind.ExportKeyword), type === "constEnum" ? factory.createToken(typescript.default.SyntaxKind.ConstKeyword) : void 0].filter((modifier) => modifier !== void 0), factory.createIdentifier(typeName), enums.map(([key, value]) => {
490
490
  let initializer = factory.createStringLiteral(value?.toString());
@@ -495,7 +495,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
495
495
  const casingKey = applyEnumKeyCasing(`${typeName}_${key}`, enumKeyCasing);
496
496
  return factory.createEnumMember(propertyName(casingKey), initializer);
497
497
  }
498
- if (key) {
498
+ if (key !== null && key !== void 0) {
499
499
  const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
500
500
  return factory.createEnumMember(propertyName(casingKey), initializer);
501
501
  }
@@ -507,7 +507,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
507
507
  if (isNumber(value)) if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.default.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
508
508
  else initializer = factory.createNumericLiteral(value);
509
509
  if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
510
- if (key) {
510
+ if (key !== null && key !== void 0) {
511
511
  const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
512
512
  return factory.createPropertyAssignment(propertyName(casingKey), initializer);
513
513
  }
@@ -668,12 +668,12 @@ function buildTupleNode(node, print) {
668
668
  /**
669
669
  * Applies `nullable` and optional/nullish `| undefined` union modifiers to a property's resolved base type.
670
670
  */
671
- function buildPropertyType(schema, baseType, optionalType) {
671
+ function buildPropertyType(schema, baseType, optionalType, optional) {
672
672
  const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType);
673
- const meta = _kubb_core.ast.syncSchemaRef(schema);
673
+ const meta = (0, _kubb_ast_utils.syncSchemaRef)(schema);
674
674
  let type = baseType;
675
675
  if (meta.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
676
- if ((meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
676
+ if ((optional || meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
677
677
  return type;
678
678
  }
679
679
  /**
@@ -837,7 +837,7 @@ function resolveContentTypeVariants(entries, baseName) {
837
837
  });
838
838
  }
839
839
  function getOperationParameters(node, options = {}) {
840
- const params = _kubb_core.ast.caseParams(node.parameters, options.paramsCasing);
840
+ const params = (0, _kubb_ast_utils.caseParams)(node.parameters, options.paramsCasing);
841
841
  return {
842
842
  path: params.filter((param) => param.in === "path"),
843
843
  query: params.filter((param) => param.in === "query"),
@@ -885,8 +885,11 @@ function createGroupConfig(group) {
885
885
  * Constraint metadata (min/max length, pattern, multipleOf, min/maxProperties) is emitted as plain-text lines.
886
886
 
887
887
  */
888
- function buildPropertyJSDocComments(schema) {
889
- const meta = _kubb_core.ast.syncSchemaRef(schema);
888
+ function isSchemaOptional(schema) {
889
+ return Boolean("optional" in schema && schema.optional || "nullish" in schema && schema.nullish);
890
+ }
891
+ function buildPropertyJSDocComments(schema, optional) {
892
+ const meta = (0, _kubb_ast_utils.syncSchemaRef)(schema);
890
893
  const isArray = meta?.primitive === "array";
891
894
  const hasDescription = meta && "description" in meta && meta.description;
892
895
  const formatComment = meta && "format" in meta && meta.format ? hasDescription ? [" ", `Format: \`${meta.format}\``] : ["@description", `Format: \`${meta.format}\``] : [];
@@ -899,83 +902,85 @@ function buildPropertyJSDocComments(schema) {
899
902
  meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : null,
900
903
  meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? (0, _kubb_ast_utils.stringify)(meta.default) : meta.default}` : null,
901
904
  meta && "example" in meta && meta.example !== void 0 ? `@example ${meta.example}` : null,
902
- meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, "optional" in schema && schema.optional ? " | undefined" : null].filter(Boolean).join("") : null
905
+ meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null
903
906
  ].filter(Boolean);
904
907
  }
905
908
  function buildParams(node, { params, resolver }) {
906
- return _kubb_core.ast.createSchema({
909
+ return _kubb_core.ast.factory.createSchema({
907
910
  type: "object",
908
- properties: params.map((param) => _kubb_core.ast.createProperty({
911
+ properties: params.map((param) => _kubb_core.ast.factory.createProperty({
909
912
  name: param.name,
910
913
  required: param.required,
911
- schema: _kubb_core.ast.createSchema({
914
+ schema: _kubb_core.ast.factory.createSchema({
912
915
  type: "ref",
913
- name: resolver.resolveParamName(node, param)
916
+ name: resolver.resolveParamName(node, param),
917
+ optional: !param.required
914
918
  })
915
919
  }))
916
920
  });
917
921
  }
918
922
  function buildData(node, { resolver }) {
919
923
  const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node);
920
- return _kubb_core.ast.createSchema({
924
+ return _kubb_core.ast.factory.createSchema({
921
925
  type: "object",
922
926
  deprecated: node.deprecated,
923
927
  properties: [
924
- _kubb_core.ast.createProperty({
928
+ _kubb_core.ast.factory.createProperty({
925
929
  name: "data",
926
- schema: node.requestBody?.content?.[0]?.schema ? _kubb_core.ast.createSchema({
930
+ schema: node.requestBody?.content?.[0]?.schema ? _kubb_core.ast.factory.createSchema({
927
931
  type: "ref",
928
932
  name: resolver.resolveDataName(node),
929
933
  optional: true
930
- }) : _kubb_core.ast.createSchema({
934
+ }) : _kubb_core.ast.factory.createSchema({
931
935
  type: "never",
932
936
  primitive: void 0,
933
937
  optional: true
934
938
  })
935
939
  }),
936
- _kubb_core.ast.createProperty({
940
+ _kubb_core.ast.factory.createProperty({
937
941
  name: "pathParams",
938
942
  required: pathParams.length > 0,
939
943
  schema: pathParams.length > 0 ? buildParams(node, {
940
944
  params: pathParams,
941
945
  resolver
942
- }) : _kubb_core.ast.createSchema({
946
+ }) : _kubb_core.ast.factory.createSchema({
943
947
  type: "never",
944
- primitive: void 0
948
+ primitive: void 0,
949
+ optional: true
945
950
  })
946
951
  }),
947
- _kubb_core.ast.createProperty({
952
+ _kubb_core.ast.factory.createProperty({
948
953
  name: "queryParams",
949
- schema: queryParams.length > 0 ? _kubb_core.ast.createSchema({
954
+ schema: queryParams.length > 0 ? _kubb_core.ast.factory.createSchema({
950
955
  ...buildParams(node, {
951
956
  params: queryParams,
952
957
  resolver
953
958
  }),
954
959
  optional: true
955
- }) : _kubb_core.ast.createSchema({
960
+ }) : _kubb_core.ast.factory.createSchema({
956
961
  type: "never",
957
962
  primitive: void 0,
958
963
  optional: true
959
964
  })
960
965
  }),
961
- _kubb_core.ast.createProperty({
966
+ _kubb_core.ast.factory.createProperty({
962
967
  name: "headerParams",
963
- schema: headerParams.length > 0 ? _kubb_core.ast.createSchema({
968
+ schema: headerParams.length > 0 ? _kubb_core.ast.factory.createSchema({
964
969
  ...buildParams(node, {
965
970
  params: headerParams,
966
971
  resolver
967
972
  }),
968
973
  optional: true
969
- }) : _kubb_core.ast.createSchema({
974
+ }) : _kubb_core.ast.factory.createSchema({
970
975
  type: "never",
971
976
  primitive: void 0,
972
977
  optional: true
973
978
  })
974
979
  }),
975
- _kubb_core.ast.createProperty({
980
+ _kubb_core.ast.factory.createProperty({
976
981
  name: "url",
977
982
  required: true,
978
- schema: _kubb_core.ast.createSchema({
983
+ schema: _kubb_core.ast.factory.createSchema({
979
984
  type: "url",
980
985
  path: node.path
981
986
  })
@@ -985,12 +990,12 @@ function buildData(node, { resolver }) {
985
990
  }
986
991
  function buildResponses(node, { resolver }) {
987
992
  if (node.responses.length === 0) return null;
988
- return _kubb_core.ast.createSchema({
993
+ return _kubb_core.ast.factory.createSchema({
989
994
  type: "object",
990
- properties: node.responses.map((res) => _kubb_core.ast.createProperty({
995
+ properties: node.responses.map((res) => _kubb_core.ast.factory.createProperty({
991
996
  name: String(res.statusCode),
992
997
  required: true,
993
- schema: _kubb_core.ast.createSchema({
998
+ schema: _kubb_core.ast.factory.createSchema({
994
999
  type: "ref",
995
1000
  name: resolver.resolveResponseStatusName(node, res.statusCode)
996
1001
  })
@@ -1000,9 +1005,9 @@ function buildResponses(node, { resolver }) {
1000
1005
  function buildResponseUnion(node, { resolver }) {
1001
1006
  const responsesWithSchema = node.responses.filter((res) => res.content?.some((entry) => entry.schema));
1002
1007
  if (responsesWithSchema.length === 0) return null;
1003
- return _kubb_core.ast.createSchema({
1008
+ return _kubb_core.ast.factory.createSchema({
1004
1009
  type: "union",
1005
- members: responsesWithSchema.map((res) => _kubb_core.ast.createSchema({
1010
+ members: responsesWithSchema.map((res) => _kubb_core.ast.factory.createSchema({
1006
1011
  type: "ref",
1007
1012
  name: resolver.resolveResponseStatusName(node, res.statusCode)
1008
1013
  }))
@@ -1082,11 +1087,11 @@ const printerTs = _kubb_core.ast.definePrinter((options) => {
1082
1087
  const hasStringLiteral = members.some((m) => {
1083
1088
  return _kubb_core.ast.narrowSchema(m, _kubb_core.ast.schemaTypes.enum)?.primitive === "string";
1084
1089
  });
1085
- const hasPlainString = members.some((m) => _kubb_core.ast.isStringType(m));
1090
+ const hasPlainString = members.some((m) => (0, _kubb_ast_utils.isStringType)(m));
1086
1091
  if (hasStringLiteral && hasPlainString) return createUnionDeclaration({
1087
1092
  withParentheses: true,
1088
1093
  nodes: members.map((m) => {
1089
- if (_kubb_core.ast.isStringType(m)) return createIntersectionDeclaration({
1094
+ if ((0, _kubb_ast_utils.isStringType)(m)) return createIntersectionDeclaration({
1090
1095
  nodes: [keywordTypeNodes.string, createTypeLiteralNode([])],
1091
1096
  withParentheses: true
1092
1097
  });
@@ -1106,7 +1111,7 @@ const printerTs = _kubb_core.ast.definePrinter((options) => {
1106
1111
  },
1107
1112
  array(node) {
1108
1113
  return createArrayDeclaration({
1109
- nodes: (node.items ?? []).map((item) => this.transform(item)).filter(isNonNullable),
1114
+ nodes: (0, _kubb_ast_utils.mapSchemaItems)(node, (item) => this.transform(item)).map(({ output }) => output).filter(isNonNullable),
1110
1115
  arrayType: this.options.arrayType
1111
1116
  }) ?? null;
1112
1117
  },
@@ -1116,18 +1121,19 @@ const printerTs = _kubb_core.ast.definePrinter((options) => {
1116
1121
  object(node) {
1117
1122
  const { transform, options } = this;
1118
1123
  const addsQuestionToken = OPTIONAL_ADDS_QUESTION_TOKEN.has(options.optionalType);
1119
- const propertyNodes = node.properties.map((prop) => {
1120
- const baseType = transform(prop.schema) ?? keywordTypeNodes.unknown;
1121
- const type = buildPropertyType(prop.schema, baseType, options.optionalType);
1122
- const propMeta = _kubb_core.ast.syncSchemaRef(prop.schema);
1124
+ const propertyNodes = (0, _kubb_ast_utils.mapSchemaProperties)(node, (schema) => transform(schema)).map(({ name, property, output }) => {
1125
+ const baseType = output ?? keywordTypeNodes.unknown;
1126
+ const optional = !property.required || !!property.schema.optional || !!property.schema.nullish;
1127
+ const type = buildPropertyType(property.schema, baseType, options.optionalType, optional);
1128
+ const propMeta = (0, _kubb_ast_utils.syncSchemaRef)(property.schema);
1123
1129
  return appendJSDocToNode({
1124
1130
  node: createPropertySignature({
1125
- questionToken: prop.schema.optional || prop.schema.nullish ? addsQuestionToken : false,
1126
- name: prop.name,
1131
+ questionToken: optional ? addsQuestionToken : false,
1132
+ name,
1127
1133
  type,
1128
1134
  readOnly: propMeta?.readOnly
1129
1135
  }),
1130
- comments: buildPropertyJSDocComments(prop.schema)
1136
+ comments: buildPropertyJSDocComments(property.schema, optional)
1131
1137
  });
1132
1138
  });
1133
1139
  const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, transform)];
@@ -1140,7 +1146,7 @@ const printerTs = _kubb_core.ast.definePrinter((options) => {
1140
1146
  const { name, syntaxType = "type", description, keysToOmit } = this.options;
1141
1147
  const transformed = this.transform(node);
1142
1148
  if (!transformed) return null;
1143
- const meta = _kubb_core.ast.syncSchemaRef(node);
1149
+ const meta = (0, _kubb_ast_utils.syncSchemaRef)(node);
1144
1150
  if (!name) {
1145
1151
  const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [transformed, keywordTypeNodes.null] }) : transformed;
1146
1152
  const result = (meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
@@ -1264,7 +1270,7 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
1264
1270
  operation(node, ctx) {
1265
1271
  const { enum: enumOptions, optionalType, arrayType, syntaxType, paramsCasing, group, output, printer } = ctx.options;
1266
1272
  const { adapter, config, resolver, root } = ctx;
1267
- const params = _kubb_core.ast.caseParams(node.parameters, paramsCasing);
1273
+ const params = (0, _kubb_ast_utils.caseParams)(node.parameters, paramsCasing);
1268
1274
  const meta = { file: resolver.resolveFile({
1269
1275
  name: node.operationId,
1270
1276
  extname: ".ts",
@@ -1328,9 +1334,9 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
1328
1334
  */
1329
1335
  function buildContentTypeVariants(entries, baseName, decorate) {
1330
1336
  const variants = resolveContentTypeVariants(entries, baseName);
1331
- const unionSchema = _kubb_core.ast.createSchema({
1337
+ const unionSchema = _kubb_core.ast.factory.createSchema({
1332
1338
  type: "union",
1333
- members: variants.map((variant) => _kubb_core.ast.createSchema({
1339
+ members: variants.map((variant) => _kubb_core.ast.factory.createSchema({
1334
1340
  type: "ref",
1335
1341
  name: variant.name
1336
1342
  }))
@@ -1345,7 +1351,10 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
1345
1351
  })] });
1346
1352
  }
1347
1353
  const paramTypes = params.map((param) => renderSchemaType({
1348
- schema: param.schema,
1354
+ schema: {
1355
+ ...param.schema,
1356
+ optional: !param.required
1357
+ },
1349
1358
  name: resolver.resolveParamName(node, param)
1350
1359
  }));
1351
1360
  const requestBodyContent = node.requestBody?.content ?? [];
@@ -1541,7 +1550,7 @@ const pluginTs = (0, _kubb_core.definePlugin)((options) => {
1541
1550
  const { output = {
1542
1551
  path: "types",
1543
1552
  barrel: { type: "named" }
1544
- }, group, exclude = [], include, override = [], enum: enumOptions = {}, optionalType = "questionToken", arrayType = "array", syntaxType = "type", paramsCasing, printer, resolver: userResolver, transformer: userTransformer, generators: userGenerators = [] } = options;
1553
+ }, group, exclude = [], include, override = [], enum: enumOptions = {}, optionalType = "questionToken", arrayType = "array", syntaxType = "type", paramsCasing, printer, resolver: userResolver, macros: userMacros, generators: userGenerators = [] } = options;
1545
1554
  const groupConfig = createGroupConfig(group);
1546
1555
  const resolvedEnum = {
1547
1556
  type: enumOptions.type ?? "asConst",
@@ -1570,7 +1579,7 @@ const pluginTs = (0, _kubb_core.definePlugin)((options) => {
1570
1579
  ...resolverTs,
1571
1580
  ...userResolver
1572
1581
  } : resolverTs);
1573
- if (userTransformer) ctx.setTransformer(userTransformer);
1582
+ if (userMacros?.length) ctx.setMacros(userMacros);
1574
1583
  ctx.addGenerator(typeGenerator);
1575
1584
  for (const gen of userGenerators) ctx.addGenerator(gen);
1576
1585
  } }
@@ -1578,37 +1587,75 @@ const pluginTs = (0, _kubb_core.definePlugin)((options) => {
1578
1587
  });
1579
1588
  //#endregion
1580
1589
  //#region src/printers/functionPrinter.ts
1581
- const kindToHandlerKey = {
1582
- FunctionParameter: "functionParameter",
1583
- ParameterGroup: "parameterGroup",
1584
- FunctionParameters: "functionParameters",
1585
- ParamsType: "paramsType"
1586
- };
1587
1590
  /**
1588
- * Creates a function-parameter printer factory.
1591
+ * Renders a {@link ast.TypeExpression} to its TypeScript source.
1589
1592
  *
1590
- * Uses `createPrinterFactory` and dispatches handlers by `node.kind`
1591
- * (for function nodes) rather than by `node.type` (for schema nodes).
1593
+ * - a `string` is a type reference, returned as-is
1594
+ * - an `IndexedAccessType` becomes `objectType['indexType']`
1595
+ * - a `TypeLiteral` becomes `{ key: Type; key?: Type }`
1596
+ *
1597
+ * `transformType` is applied once to the fully rendered type, matching how the
1598
+ * printer wrapped reference types before the `ts.factory` model.
1592
1599
  */
1593
- const defineFunctionPrinter = _kubb_core.ast.createPrinterFactory((node) => kindToHandlerKey[node.kind]);
1600
+ function renderType(type, transformType) {
1601
+ const rendered = renderTypeExpression(type);
1602
+ return transformType ? transformType(rendered) : rendered;
1603
+ }
1604
+ function renderTypeExpression(type) {
1605
+ if (typeof type === "string") return type;
1606
+ if (_kubb_core.ast.indexedAccessTypeDef.is(type)) return `${type.target}['${type.key}']`;
1607
+ return `{ ${type.members.map((member) => {
1608
+ const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(member.name) ? member.name : JSON.stringify(member.name);
1609
+ const value = renderTypeExpression(member.type);
1610
+ return member.optional ? `${key}?: ${value}` : `${key}: ${value}`;
1611
+ }).join("; ")} }`;
1612
+ }
1613
+ function groupMembers(param) {
1614
+ if (typeof param.name === "string") return null;
1615
+ return param.type && _kubb_core.ast.typeLiteralDef.is(param.type) ? param.type.members : [];
1616
+ }
1594
1617
  function rank(param) {
1595
- if (param.kind === "ParameterGroup") {
1596
- if (param.default) return PARAM_RANK.withDefault;
1597
- return param.optional ?? param.properties.every((p) => p.optional || p.default !== void 0) ? PARAM_RANK.optional : PARAM_RANK.required;
1598
- }
1599
1618
  if (param.rest) return PARAM_RANK.rest;
1600
1619
  if (param.default) return PARAM_RANK.withDefault;
1620
+ const members = groupMembers(param);
1621
+ if (members) return members.every((m) => m.optional) ? PARAM_RANK.optional : PARAM_RANK.required;
1601
1622
  return param.optional ? PARAM_RANK.optional : PARAM_RANK.required;
1602
1623
  }
1603
1624
  function sortParams(params) {
1604
1625
  return params.toSorted((a, b) => rank(a) - rank(b));
1605
1626
  }
1606
- function sortChildParams(params) {
1607
- return params.toSorted((a, b) => rank(a) - rank(b));
1627
+ /**
1628
+ * Orders a destructured group's binding elements and type members together,
1629
+ * required fields first, matching how grouped children were sorted before.
1630
+ */
1631
+ function sortedGroupMembers(name, type) {
1632
+ const members = type && _kubb_core.ast.typeLiteralDef.is(type) ? type.members : [];
1633
+ const memberRank = (optional) => optional ? PARAM_RANK.optional : PARAM_RANK.required;
1634
+ return name.elements.map((element, index) => ({
1635
+ name: element.name,
1636
+ type: members[index]?.type,
1637
+ optional: members[index]?.optional
1638
+ })).toSorted((a, b) => memberRank(a.optional) - memberRank(b.optional));
1639
+ }
1640
+ /**
1641
+ * Renders the type annotation of a destructured group. An inline object type is
1642
+ * rendered from the already-sorted members so its key order matches the binding;
1643
+ * a reference type is rendered as-is.
1644
+ */
1645
+ function renderGroupType(type, sorted, transformType) {
1646
+ if (!type) return void 0;
1647
+ if (!_kubb_core.ast.typeLiteralDef.is(type)) return renderType(type);
1648
+ const typed = sorted.filter((member) => member.type !== void 0);
1649
+ if (!typed.length) return void 0;
1650
+ return `{ ${typed.map((member) => {
1651
+ const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(member.name) ? member.name : JSON.stringify(member.name);
1652
+ const value = renderType(member.type, transformType);
1653
+ return member.optional ? `${key}?: ${value}` : `${key}: ${value}`;
1654
+ }).join("; ")} }`;
1608
1655
  }
1609
1656
  /**
1610
- * Default function-signature printer.
1611
- * Covers the four standard output modes used across Kubb plugins.
1657
+ * Default function-signature printer. Renders a parameter list in one of two modes:
1658
+ * `declaration` for the function signature and `call` for the call arguments.
1612
1659
  *
1613
1660
  * @example
1614
1661
  * ```ts
@@ -1624,28 +1671,31 @@ function sortChildParams(params) {
1624
1671
  * printer.print(sig) // → "petId: string, config: Config = {}"
1625
1672
  * ```
1626
1673
  */
1627
- const functionPrinter = defineFunctionPrinter((options) => ({
1674
+ const functionPrinter = _kubb_core.ast.createPrinterFactory((node) => node.kind)((options) => ({
1628
1675
  name: "functionParameters",
1629
1676
  options,
1630
1677
  nodes: {
1631
- paramsType(node) {
1632
- if (node.kind !== "ParamsType") return null;
1633
- if (node.variant === "member") return `${node.base}['${node.key}']`;
1634
- if (node.variant === "struct") return `{ ${node.properties.map((p) => {
1635
- const typeStr = this.transform(p.type);
1636
- const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(p.name) ? p.name : JSON.stringify(p.name);
1637
- return p.optional ? `${key}?: ${typeStr}` : `${key}: ${typeStr}`;
1638
- }).join("; ")} }`;
1639
- if (node.variant === "reference") return node.name;
1640
- return null;
1641
- },
1642
- functionParameter(node) {
1678
+ FunctionParameter(node) {
1643
1679
  const { mode, transformName, transformType } = this.options;
1680
+ const isGroup = typeof node.name !== "string";
1681
+ if (mode === "call") {
1682
+ if (isGroup) return `{ ${sortedGroupMembers(node.name, node.type).map((member) => member.name).join(", ")} }`;
1683
+ const name = transformName ? transformName(node.name) : node.name;
1684
+ return node.rest ? `...${name}` : name;
1685
+ }
1686
+ if (isGroup) {
1687
+ const sorted = sortedGroupMembers(node.name, node.type);
1688
+ const binding = `{ ${sorted.map((member) => transformName ? transformName(member.name) : member.name).join(", ")} }`;
1689
+ const allOptional = sorted.every((member) => member.optional);
1690
+ const type = renderGroupType(node.type, sorted, transformType);
1691
+ if (type) {
1692
+ if (allOptional) return `${binding}: ${type} = ${node.default ?? "{}"}`;
1693
+ return node.default ? `${binding}: ${type} = ${node.default}` : `${binding}: ${type}`;
1694
+ }
1695
+ return node.default ? `${binding} = ${node.default}` : binding;
1696
+ }
1644
1697
  const name = transformName ? transformName(node.name) : node.name;
1645
- const rawType = node.type ? this.transform(node.type) : void 0;
1646
- const type = rawType != null && transformType ? transformType(rawType) : rawType;
1647
- if (mode === "keys" || mode === "values") return node.rest ? `...${name}` : name;
1648
- if (mode === "call") return node.rest ? `...${name}` : name;
1698
+ const type = node.type ? renderType(node.type, transformType) : void 0;
1649
1699
  if (node.rest) return type ? `...${name}: ${type}` : `...${name}`;
1650
1700
  if (type) {
1651
1701
  if (node.optional) return `${name}?: ${type}`;
@@ -1653,34 +1703,7 @@ const functionPrinter = defineFunctionPrinter((options) => ({
1653
1703
  }
1654
1704
  return node.default ? `${name} = ${node.default}` : name;
1655
1705
  },
1656
- parameterGroup(node) {
1657
- const { mode, transformName, transformType } = this.options;
1658
- const sorted = sortChildParams(node.properties);
1659
- const isOptional = node.optional ?? sorted.every((p) => p.optional || p.default !== void 0);
1660
- if (node.inline) return sorted.map((p) => this.transform(p)).filter(Boolean).join(", ");
1661
- if (mode === "keys" || mode === "values") return `{ ${sorted.map((p) => p.name).join(", ")} }`;
1662
- if (mode === "call") return `{ ${sorted.map((p) => p.name).join(", ")} }`;
1663
- const names = sorted.map((p) => {
1664
- return transformName ? transformName(p.name) : p.name;
1665
- });
1666
- const nameStr = names.length ? `{ ${names.join(", ")} }` : void 0;
1667
- if (!nameStr) return null;
1668
- let typeAnnotation = node.type ? this.transform(node.type) ?? void 0 : void 0;
1669
- if (!typeAnnotation) {
1670
- const typeParts = sorted.filter((p) => p.type).map((p) => {
1671
- const rawT = p.type ? this.transform(p.type) : void 0;
1672
- const t = rawT != null && transformType ? transformType(rawT) : rawT;
1673
- return p.optional || p.default !== void 0 ? `${p.name}?: ${t}` : `${p.name}: ${t}`;
1674
- });
1675
- typeAnnotation = typeParts.length ? `{ ${typeParts.join("; ")} }` : void 0;
1676
- }
1677
- if (typeAnnotation) {
1678
- if (isOptional) return `${nameStr}: ${typeAnnotation} = ${node.default ?? "{}"}`;
1679
- return node.default ? `${nameStr}: ${typeAnnotation} = ${node.default}` : `${nameStr}: ${typeAnnotation}`;
1680
- }
1681
- return node.default ? `${nameStr} = ${node.default}` : nameStr;
1682
- },
1683
- functionParameters(node) {
1706
+ FunctionParameters(node) {
1684
1707
  return sortParams(node.params).map((p) => this.transform(p)).filter(Boolean).join(", ");
1685
1708
  }
1686
1709
  }
@@ -1693,6 +1716,7 @@ exports.functionPrinter = functionPrinter;
1693
1716
  exports.pluginTs = pluginTs;
1694
1717
  exports.pluginTsName = pluginTsName;
1695
1718
  exports.printerTs = printerTs;
1719
+ exports.renderType = renderType;
1696
1720
  exports.resolverTs = resolverTs;
1697
1721
  exports.typeGenerator = typeGenerator;
1698
1722