@kubb/plugin-ts 5.0.11 → 5.0.14

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.js CHANGED
@@ -1,9 +1,24 @@
1
- import { n as __name, t as __exportAll } from "./rolldown-runtime-CthDji9g.js";
2
1
  import { createRequire } from "node:module";
3
2
  import { parserTs } from "@kubb/parser-ts";
4
3
  import { File, jsxRenderer } from "kubb/jsx";
5
4
  import { Resolver, addGenerator, assertPluginOption, ast, createResolver, defineExtension, defineGenerator, isStringType, setMacros, setResolver, syncSchemaRef } from "kubb/kit";
6
5
  import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
6
+ //#region \0rolldown/runtime.js
7
+ var __defProp = Object.defineProperty;
8
+ var __name = (target, value) => __defProp(target, "name", {
9
+ value,
10
+ configurable: true
11
+ });
12
+ var __exportAll = (all, no_symbols) => {
13
+ let target = {};
14
+ for (var name in all) __defProp(target, name, {
15
+ get: all[name],
16
+ enumerable: true
17
+ });
18
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
19
+ return target;
20
+ };
21
+ //#endregion
7
22
  //#region ../../internals/utils/src/casing.ts
8
23
  /**
9
24
  * Shared implementation for camelCase and PascalCase conversion.
@@ -292,47 +307,6 @@ function toFilePath(name, caseLast = camelCase) {
292
307
  return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
293
308
  }
294
309
  //#endregion
295
- //#region src/constants.ts
296
- /**
297
- * `optionalType` values that cause a property's type to include `| undefined`.
298
- */
299
- const OPTIONAL_ADDS_UNDEFINED = /* @__PURE__ */ new Set(["undefined", "questionTokenAndUndefined"]);
300
- /**
301
- * `optionalType` values that render the property key with a `?` token.
302
- */
303
- const OPTIONAL_ADDS_QUESTION_TOKEN = /* @__PURE__ */ new Set(["questionToken", "questionTokenAndUndefined"]);
304
- /**
305
- * `enum.type` values that append a `typeSuffix` to the generated enum type alias.
306
- */
307
- const ENUM_TYPES_WITH_KEY_SUFFIX = /* @__PURE__ */ new Set(["asConst"]);
308
- /**
309
- * `enum.type` values that require a runtime value declaration (object, enum, or literal).
310
- */
311
- const ENUM_TYPES_WITH_RUNTIME_VALUE = /* @__PURE__ */ new Set([
312
- "enum",
313
- "asConst",
314
- "constEnum",
315
- "literal",
316
- void 0
317
- ]);
318
- /**
319
- * `enum.type` values whose type declaration is type-only (no runtime value emitted for the type alias).
320
- */
321
- const ENUM_TYPES_WITH_TYPE_ONLY = /* @__PURE__ */ new Set([
322
- "asConst",
323
- "literal",
324
- void 0
325
- ]);
326
- /**
327
- * Ordering priority for function parameters: lower = sorted earlier.
328
- */
329
- const PARAM_RANK = {
330
- required: 0,
331
- optional: 1,
332
- withDefault: 2,
333
- rest: 3
334
- };
335
- //#endregion
336
310
  //#region src/factory.ts
337
311
  var factory_exports = /* @__PURE__ */ __exportAll({
338
312
  appendJSDocToNode: () => appendJSDocToNode,
@@ -343,14 +317,9 @@ var factory_exports = /* @__PURE__ */ __exportAll({
343
317
  constToTypeNode: () => constToTypeNode,
344
318
  createArrayDeclaration: () => createArrayDeclaration,
345
319
  createEnumDeclaration: () => createEnumDeclaration,
346
- createExportDeclaration: () => createExportDeclaration,
347
- createImportDeclaration: () => createImportDeclaration,
348
320
  createIntersectionDeclaration: () => createIntersectionDeclaration,
349
- createJSDoc: () => createJSDoc,
350
321
  createOmitDeclaration: () => createOmitDeclaration,
351
- createParameterSignature: () => createParameterSignature,
352
322
  createPropertySignature: () => createPropertySignature,
353
- createQuestionToken: () => createQuestionToken,
354
323
  createTypeDeclaration: () => createTypeDeclaration,
355
324
  createTypeLiteralNode: () => createTypeLiteralNode,
356
325
  createTypeReferenceNode: () => createTypeReferenceNode,
@@ -358,9 +327,10 @@ var factory_exports = /* @__PURE__ */ __exportAll({
358
327
  createUrlTemplateType: () => createUrlTemplateType,
359
328
  dateOrStringNode: () => dateOrStringNode,
360
329
  isNonNullable: () => isNonNullable$1,
330
+ isUnionTypeNode: () => isUnionTypeNode,
361
331
  keywordTypeNodes: () => keywordTypeNodes,
362
332
  modifiers: () => modifiers,
363
- syntaxKind: () => syntaxKind
333
+ wrapNullableOptional: () => wrapNullableOptional
364
334
  });
365
335
  /**
366
336
  * Loaded with `require`, not `import`. When ESM imports a CommonJS package, Node keeps a second
@@ -368,35 +338,14 @@ var factory_exports = /* @__PURE__ */ __exportAll({
368
338
  */
369
339
  const typescript = createRequire(import.meta.url)("typescript");
370
340
  const { SyntaxKind, factory } = typescript;
371
- /**
372
- * Compares two strings by UTF-16 code unit, keeping sorted output identical across platforms
373
- * regardless of locale.
374
- */
375
- function compareStrings(a, b) {
376
- if (a < b) return -1;
377
- if (a > b) return 1;
378
- return 0;
379
- }
380
341
  function isNumber(value) {
381
342
  return typeof value === "number" && !Number.isNaN(value);
382
343
  }
383
344
  /**
384
- * TypeScript AST modifiers for common keywords (async, export, const, static).
385
- */
386
- const modifiers = {
387
- async: factory.createModifier(typescript.SyntaxKind.AsyncKeyword),
388
- export: factory.createModifier(typescript.SyntaxKind.ExportKeyword),
389
- const: factory.createModifier(typescript.SyntaxKind.ConstKeyword),
390
- static: factory.createModifier(typescript.SyntaxKind.StaticKeyword)
391
- };
392
- /**
393
- * TypeScript syntax kind constants for union, literal, and string types.
345
+ * TypeScript AST modifiers for the `export` keyword.
394
346
  */
395
- const syntaxKind = {
396
- union: SyntaxKind.UnionType,
397
- literalType: SyntaxKind.LiteralType,
398
- stringLiteral: SyntaxKind.StringLiteral
399
- };
347
+ const modifiers = { export: factory.createModifier(typescript.SyntaxKind.ExportKeyword) };
348
+ const isUnionTypeNode = typescript.isUnionTypeNode;
400
349
  function isNonNullable$1(value) {
401
350
  return value !== null && value !== void 0;
402
351
  }
@@ -450,7 +399,6 @@ function createArrayDeclaration({ nodes, arrayType = "array" }) {
450
399
  if (!nodes.length) return factory.createTupleTypeNode([]);
451
400
  if (nodes.length === 1) {
452
401
  const node = nodes[0];
453
- if (!node) return null;
454
402
  if (arrayType === "generic") return factory.createTypeReferenceNode(factory.createIdentifier("Array"), [node]);
455
403
  return factory.createArrayTypeNode(node);
456
404
  }
@@ -478,23 +426,6 @@ function createPropertySignature({ readOnly, modifiers = [], name, questionToken
478
426
  return factory.createPropertySignature([...modifiers, readOnly ? factory.createToken(typescript.SyntaxKind.ReadonlyKeyword) : void 0].filter((modifier) => modifier !== void 0), propertyName(name), createQuestionToken(questionToken), type);
479
427
  }
480
428
  /**
481
- * Creates a function parameter declaration with optional markers, rest parameters, and type annotations.
482
- */
483
- function createParameterSignature(name, { modifiers, dotDotDotToken, questionToken, type, initializer }) {
484
- return factory.createParameterDeclaration(modifiers, dotDotDotToken, name, createQuestionToken(questionToken), type, initializer);
485
- }
486
- /**
487
- * Creates a JSDoc comment node from an array of comment strings.
488
- * Returns null if no comments are provided.
489
- */
490
- function createJSDoc({ comments }) {
491
- if (!comments.length) return null;
492
- return factory.createJSDocComment(factory.createNodeArray(comments.map((comment, i) => {
493
- if (i === comments.length - 1) return factory.createJSDocText(comment);
494
- return factory.createJSDocText(`${comment}\n`);
495
- })));
496
- }
497
- /**
498
429
  * Attaches JSDoc comments to an AST node as synthetic leading comments.
499
430
  * Filters out undefined comments before attaching.
500
431
  *
@@ -513,19 +444,7 @@ function appendJSDocToNode({ node, comments }) {
513
444
  * Defines the key type (default: `string`) and value type on an object.
514
445
  */
515
446
  function createIndexSignature(type, { modifiers, indexName = "key", indexType = factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword) } = {}) {
516
- return factory.createIndexSignature(modifiers, [createParameterSignature(indexName, { type: indexType })], type);
517
- }
518
- /**
519
- * Creates a TypeScript type alias declaration with optional modifiers and type parameters.
520
- */
521
- function createTypeAliasDeclaration({ modifiers, name, typeParameters, type }) {
522
- return factory.createTypeAliasDeclaration(modifiers, name, typeParameters, type);
523
- }
524
- /**
525
- * Creates a TypeScript interface declaration with optional modifiers, type parameters, and members.
526
- */
527
- function createInterfaceDeclaration({ modifiers, name, typeParameters, members }) {
528
- return factory.createInterfaceDeclaration(modifiers, name, typeParameters, void 0, members);
447
+ return factory.createIndexSignature(modifiers, [factory.createParameterDeclaration(void 0, void 0, indexName, void 0, indexType)], type);
529
448
  }
530
449
  /**
531
450
  * Creates a TypeScript type declaration as either a type alias or interface.
@@ -533,67 +452,22 @@ function createInterfaceDeclaration({ modifiers, name, typeParameters, members }
533
452
  */
534
453
  function createTypeDeclaration({ syntax, isExportable, comments, name, type }) {
535
454
  if (syntax === "interface" && typescript.isTypeLiteralNode(type)) return appendJSDocToNode({
536
- node: createInterfaceDeclaration({
537
- members: [...type.members],
538
- modifiers: isExportable ? [modifiers.export] : [],
539
- name,
540
- typeParameters: void 0
541
- }),
455
+ node: factory.createInterfaceDeclaration(isExportable ? [modifiers.export] : [], name, void 0, void 0, [...type.members]),
542
456
  comments
543
457
  });
544
458
  return appendJSDocToNode({
545
- node: createTypeAliasDeclaration({
546
- type,
547
- modifiers: isExportable ? [modifiers.export] : [],
548
- name,
549
- typeParameters: void 0
550
- }),
459
+ node: factory.createTypeAliasDeclaration(isExportable ? [modifiers.export] : [], name, void 0, type),
551
460
  comments
552
461
  });
553
462
  }
554
463
  /**
555
- * Creates an import declaration with support for default imports, named imports, namespace imports, and type-only imports.
556
- * Optionally rename imported members with `propertyName` and `name` pairs.
557
- *
558
- * @example Default import
559
- * `import Pet from './Pet'`
560
- *
561
- * @example Named imports with rename
562
- * `import { Pet as Cat } from './Pet'`
563
- *
564
- * @example Namespace import
565
- * `import * as Pet from './Pet'`
566
- */
567
- function createImportDeclaration({ name, path, isTypeOnly = false, isNameSpace = false }) {
568
- if (!Array.isArray(name)) {
569
- const importPropertyName = isNameSpace ? void 0 : factory.createIdentifier(name);
570
- const importName = isNameSpace ? factory.createNamespaceImport(factory.createIdentifier(name)) : void 0;
571
- return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, importPropertyName, importName), factory.createStringLiteral(path), void 0);
572
- }
573
- const sortedName = name.toSorted((a, b) => compareStrings(typeof a === "object" ? a.propertyName : a, typeof b === "object" ? b.propertyName : b));
574
- return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, void 0, factory.createNamedImports(sortedName.map((item) => {
575
- if (typeof item === "object") {
576
- const obj = item;
577
- if (obj.name) return factory.createImportSpecifier(false, factory.createIdentifier(obj.propertyName), factory.createIdentifier(obj.name));
578
- return factory.createImportSpecifier(false, void 0, factory.createIdentifier(obj.propertyName));
579
- }
580
- return factory.createImportSpecifier(false, void 0, factory.createIdentifier(item));
581
- }))), factory.createStringLiteral(path), void 0);
582
- }
583
- /**
584
- * Creates an export declaration with support for named exports, namespace exports, and type-only exports.
585
- * Sorts export names alphabetically for consistent output across platforms.
464
+ * Converts an enum member value to a literal expression. Numbers become numeric literals (negatives use a prefix
465
+ * minus, as `createNumericLiteral` rejects them) unless `asNumber` is `false`, which emits the string form.
586
466
  */
587
- function createExportDeclaration({ path, asAlias, isTypeOnly = false, name }) {
588
- if (name && !Array.isArray(name) && !asAlias) console.warn(`When using name as string, asAlias should be true ${name}`);
589
- if (!Array.isArray(name)) {
590
- const parsedName = name?.match(/^\d/) ? `_${name?.slice(1)}` : name;
591
- return factory.createExportDeclaration(void 0, isTypeOnly, asAlias && parsedName ? factory.createNamespaceExport(factory.createIdentifier(parsedName)) : void 0, factory.createStringLiteral(path), void 0);
592
- }
593
- const sortedName = name.toSorted((a, b) => compareStrings(typeof a === "string" ? a : a.text, typeof b === "string" ? b : b.text));
594
- return factory.createExportDeclaration(void 0, isTypeOnly, factory.createNamedExports(sortedName.map((propertyName) => {
595
- return factory.createExportSpecifier(false, void 0, typeof propertyName === "string" ? factory.createIdentifier(propertyName) : propertyName);
596
- })), factory.createStringLiteral(path), void 0);
467
+ function valueToExpression(value, asNumber = isNumber(value)) {
468
+ if (typeof value === "boolean") return value ? factory.createTrue() : factory.createFalse();
469
+ if (asNumber && isNumber(value)) return value < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value))) : factory.createNumericLiteral(value);
470
+ return factory.createStringLiteral(value.toString());
597
471
  }
598
472
  /**
599
473
  * Apply casing transformation to enum keys
@@ -630,12 +504,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
630
504
  if (value !== null && value !== void 0) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
631
505
  }).filter((node) => node !== void 0)))];
632
506
  if (type === "enum" || type === "constEnum") return [void 0, factory.createEnumDeclaration([factory.createToken(typescript.SyntaxKind.ExportKeyword), type === "constEnum" ? factory.createToken(typescript.SyntaxKind.ConstKeyword) : void 0].filter((modifier) => modifier !== void 0), factory.createIdentifier(typeName), enums.map(([key, value, description]) => {
633
- let initializer = factory.createStringLiteral(value?.toString());
634
- if (Number.parseInt(value.toString(), 10) === value && isNumber(value)) {
635
- if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
636
- else initializer = factory.createNumericLiteral(value);
637
- }
638
- if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
507
+ const initializer = valueToExpression(value, Number.parseInt(value.toString(), 10) === value);
639
508
  if (isNumber(Number.parseInt(key.toString(), 10))) {
640
509
  const casingKey = applyEnumKeyCasing(`${typeName}_${key}`, enumKeyCasing);
641
510
  return appendJSDocToNode({
@@ -654,12 +523,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
654
523
  const identifierName = name;
655
524
  if (enums.length === 0) return [void 0, factory.createTypeAliasDeclaration([factory.createToken(typescript.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createKeywordTypeNode(typescript.SyntaxKind.NeverKeyword))];
656
525
  return [factory.createVariableStatement([factory.createToken(typescript.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier(identifierName), void 0, void 0, factory.createAsExpression(factory.createObjectLiteralExpression(enums.map(([key, value, description]) => {
657
- let initializer = factory.createStringLiteral(value?.toString());
658
- if (isNumber(value)) {
659
- if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
660
- else initializer = factory.createNumericLiteral(value);
661
- }
662
- if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
526
+ const initializer = valueToExpression(value);
663
527
  if (key !== null && key !== void 0) {
664
528
  const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
665
529
  return appendJSDocToNode({
@@ -738,66 +602,19 @@ const createTypeLiteralNode = factory.createTypeLiteralNode;
738
602
  */
739
603
  const createTypeReferenceNode = factory.createTypeReferenceNode;
740
604
  /**
741
- * Creates a numeric literal type node.
742
- */
743
- const createNumericLiteral = factory.createNumericLiteral;
744
- /**
745
- * Creates a string literal type node.
746
- */
747
- const createStringLiteral = factory.createStringLiteral;
748
- /**
749
- * Creates an array type node (e.g., `T[]`).
750
- */
751
- const createArrayTypeNode = factory.createArrayTypeNode;
752
- /**
753
- * Creates a literal type node (e.g., `'hello'`, `42`, `true`).
754
- */
755
- const createLiteralTypeNode = factory.createLiteralTypeNode;
756
- /**
757
- * Creates an identifier node.
758
- */
759
- const createIdentifier = factory.createIdentifier;
760
- /**
761
- * Creates an optional type node (e.g., `T | undefined`).
762
- */
763
- const createOptionalTypeNode = factory.createOptionalTypeNode;
764
- /**
765
- * Creates a tuple type node (e.g., `[string, number]`).
766
- */
767
- const createTupleTypeNode = factory.createTupleTypeNode;
768
- /**
769
- * Creates a rest type node for variadic tuple elements (e.g., `...T[]`).
770
- */
771
- const createRestTypeNode = factory.createRestTypeNode;
772
- /**
773
- * Creates a boolean true literal type node.
774
- */
775
- const createTrue = factory.createTrue;
776
- /**
777
- * Creates a boolean false literal type node.
778
- */
779
- const createFalse = factory.createFalse;
780
- /**
781
- * Creates a prefix unary expression (e.g., negative numbers, logical not).
782
- */
783
- const createPrefixUnaryExpression = factory.createPrefixUnaryExpression;
784
- /**
785
605
  * Converts a primitive const value to a TypeScript literal type node.
786
606
  * Handles negative numbers via a prefix unary expression.
787
607
  */
788
608
  function constToTypeNode(value, format) {
789
- if (format === "boolean") return createLiteralTypeNode(value === true ? createTrue() : createFalse());
790
- if (format === "number" && typeof value === "number") {
791
- if (value < 0) return createLiteralTypeNode(createPrefixUnaryExpression(SyntaxKind.MinusToken, createNumericLiteral(Math.abs(value))));
792
- return createLiteralTypeNode(createNumericLiteral(value));
793
- }
794
- return createLiteralTypeNode(createStringLiteral(String(value)));
609
+ if (format === "boolean") return factory.createLiteralTypeNode(value === true ? factory.createTrue() : factory.createFalse());
610
+ const literal = format === "number" && typeof value === "number" ? value : String(value);
611
+ return factory.createLiteralTypeNode(valueToExpression(literal));
795
612
  }
796
613
  /**
797
614
  * Returns a `Date` reference type node when `representation` is `'date'`, otherwise falls back to `string`.
798
615
  */
799
616
  function dateOrStringNode(node) {
800
- return node.representation === "date" ? createTypeReferenceNode(createIdentifier("Date")) : keywordTypeNodes.string;
617
+ return node.representation === "date" ? createTypeReferenceNode(factory.createIdentifier("Date")) : keywordTypeNodes.string;
801
618
  }
802
619
  /**
803
620
  * Maps an array of `SchemaNode`s through the printer, filtering out `null` and `undefined` results.
@@ -817,20 +634,24 @@ function buildTupleNode(node, print) {
817
634
  items = items.slice(0, max);
818
635
  if (items.length < max && restNode) items = [...items, ...Array(max - items.length).fill(restNode)];
819
636
  }
820
- if (min !== void 0) items = items.map((item, i) => i >= min ? createOptionalTypeNode(item) : item);
821
- if (max === void 0 && restNode) items.push(createRestTypeNode(createArrayTypeNode(restNode)));
822
- return createTupleTypeNode(items);
637
+ if (min !== void 0) items = items.map((item, i) => i >= min ? factory.createOptionalTypeNode(item) : item);
638
+ if (max === void 0 && restNode) items.push(factory.createRestTypeNode(factory.createArrayTypeNode(restNode)));
639
+ return factory.createTupleTypeNode(items);
640
+ }
641
+ /**
642
+ * Appends `| null` and then `| undefined` to a type when requested.
643
+ */
644
+ function wrapNullableOptional(type, nullable, addsUndefined) {
645
+ const withNullable = nullable ? createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] }) : type;
646
+ return addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
823
647
  }
824
648
  /**
825
649
  * Applies `nullable` and optional/nullish `| undefined` union modifiers to a property's resolved base type.
826
650
  */
827
651
  function buildPropertyType(schema, baseType, optionalType, optional) {
828
- const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType);
652
+ const addsUndefined = optionalType === "undefined" || optionalType === "questionTokenAndUndefined";
829
653
  const meta = syncSchemaRef(schema);
830
- let type = baseType;
831
- if (meta.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
832
- if ((optional || meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
833
- return type;
654
+ return wrapNullableOptional(baseType, !!meta.nullable, addsUndefined && !!(optional || meta.nullish || meta.optional));
834
655
  }
835
656
  const indexSignaturePrinter = typescript.createPrinter();
836
657
  const indexSignatureSource = typescript.createSourceFile("", "", typescript.ScriptTarget.Latest);
@@ -873,7 +694,7 @@ function getEnumNames({ node, enum: enumOptions, resolver }) {
873
694
  const resolved = resolver.name(node.name);
874
695
  return {
875
696
  enumName: enumOptions.constCasing === "pascalCase" ? resolved : camelCase(node.name),
876
- typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolved
697
+ typeName: enumOptions.type === "asConst" ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolved
877
698
  };
878
699
  }
879
700
  /**
@@ -914,30 +735,16 @@ function Enum({ node, enum: enumOptions, resolver }) {
914
735
  }), /* @__PURE__ */ jsx(File.Source, {
915
736
  name: typeName,
916
737
  isIndexable: !namesMerge,
917
- isExportable: !namesMerge && ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumOptions.type),
918
- isTypeOnly: ENUM_TYPES_WITH_TYPE_ONLY.has(enumOptions.type),
738
+ isExportable: !namesMerge && enumOptions.type !== "inlineLiteral",
739
+ isTypeOnly: [
740
+ "asConst",
741
+ "literal",
742
+ void 0
743
+ ].includes(enumOptions.type),
919
744
  children: parserTs().print(typeNode)
920
745
  })] });
921
746
  }
922
747
  //#endregion
923
- //#region ../../internals/shared/src/params.ts
924
- /**
925
- * Drops parameters that share the same name, keeping the first.
926
- *
927
- * A malformed spec can declare the same parameter name twice within one `in` location. Both would
928
- * resolve to the same output property, so emitting both would yield an object type with a duplicate
929
- * member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
930
- * parameter names flow through unchanged, so no two distinct names ever collide here anymore.
931
- */
932
- function dedupeParams(params) {
933
- const seen = /* @__PURE__ */ new Set();
934
- return params.filter((param) => {
935
- if (seen.has(param.name)) return false;
936
- seen.add(param.name);
937
- return true;
938
- });
939
- }
940
- //#endregion
941
748
  //#region ../../internals/shared/src/operation.ts
942
749
  /**
943
750
  * Maps a content type to the PascalCase suffix used to name per-content-type variants
@@ -997,11 +804,19 @@ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
997
804
  function getOperationParameters(node) {
998
805
  const cached = operationParameterGroupsByNode.get(node);
999
806
  if (cached) return cached;
807
+ const group = (location) => {
808
+ const seen = /* @__PURE__ */ new Set();
809
+ return node.parameters.filter((param) => {
810
+ if (param.in !== location || seen.has(param.name)) return false;
811
+ seen.add(param.name);
812
+ return true;
813
+ });
814
+ };
1000
815
  const groups = {
1001
- path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
1002
- query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
1003
- header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
1004
- cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
816
+ path: group("path"),
817
+ query: group("query"),
818
+ header: group("header"),
819
+ cookie: group("cookie")
1005
820
  };
1006
821
  operationParameterGroupsByNode.set(node, groups);
1007
822
  return groups;
@@ -1203,20 +1018,6 @@ function createCasedFile(caseLast) {
1203
1018
  } };
1204
1019
  }
1205
1020
  //#endregion
1206
- //#region ../../internals/shared/src/refs.ts
1207
- /**
1208
- * Collects the resolved target name of every pointer-carrying ref in a schema tree, in
1209
- * first-occurrence order. Use this for name-only checks (e.g. redeclaration detection) where
1210
- * `resolver.imports` would resolve file paths that are then discarded.
1211
- */
1212
- function collectRefNames(schema) {
1213
- return ast.collectSync(schema, { schema: (node) => {
1214
- const refNode = ast.narrowSchema(node, "ref");
1215
- if (!refNode?.ref) return null;
1216
- return ast.resolveRefName(refNode);
1217
- } });
1218
- }
1219
- //#endregion
1220
1021
  //#region ../../internals/shared/src/group.ts
1221
1022
  /**
1222
1023
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
@@ -1278,6 +1079,9 @@ function mapSchemaItems(node, transform) {
1278
1079
  }
1279
1080
  //#endregion
1280
1081
  //#region src/utils.ts
1082
+ function enumTypeName({ resolver, name, enumOptions, isEnum }) {
1083
+ return isEnum && enumOptions?.type === "asConst" && enumOptions.typeSuffix ? resolver.enum.keyName({ name }, enumOptions.typeSuffix) : resolver.name(name);
1084
+ }
1281
1085
  /**
1282
1086
  * Tells whether a `const` (single-value enum) should render as a bare literal type (`'active'`)
1283
1087
  * rather than a named enum reference or a runtime enum declaration.
@@ -1414,7 +1218,7 @@ const { isNonNullable } = factory_exports;
1414
1218
  * ```
1415
1219
  */
1416
1220
  const printerTs = ast.createPrinter((options) => {
1417
- const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(options.optionalType);
1221
+ const addsUndefined = options.optionalType === "undefined" || options.optionalType === "questionTokenAndUndefined";
1418
1222
  return {
1419
1223
  name: "typescript",
1420
1224
  options,
@@ -1445,7 +1249,12 @@ const printerTs = ast.createPrinter((options) => {
1445
1249
  if (!node.name) return null;
1446
1250
  const refName = ast.resolveRefName(node);
1447
1251
  if (!refName) return null;
1448
- const name = node.ref && ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enum.type) && this.options.enum.typeSuffix && this.options.enumSchemaNames?.has(refName) ? this.options.resolver.enum.keyName({ name: refName }, this.options.enum.typeSuffix) : node.ref ? this.options.resolver.name(refName) : refName;
1252
+ const name = node.ref ? enumTypeName({
1253
+ resolver: this.options.resolver,
1254
+ name: refName,
1255
+ enumOptions: this.options.enum,
1256
+ isEnum: !!this.options.enumSchemaNames?.has(refName)
1257
+ }) : refName;
1449
1258
  return createTypeReferenceNode(name, void 0);
1450
1259
  },
1451
1260
  enum(node) {
@@ -1453,8 +1262,13 @@ const printerTs = ast.createPrinter((options) => {
1453
1262
  if (this.options.enum.type === "inlineLiteral" || !node.name || isInlineConstEnum(node, this.options.enumSchemaNames)) return createUnionDeclaration({
1454
1263
  withParentheses: true,
1455
1264
  nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
1456
- }) ?? void 0;
1457
- const resolvedName = ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enum.type) && this.options.enum.typeSuffix ? this.options.resolver.enum.keyName(node, this.options.enum.typeSuffix) : this.options.resolver.name(node.name);
1265
+ });
1266
+ const resolvedName = enumTypeName({
1267
+ resolver: this.options.resolver,
1268
+ name: node.name,
1269
+ enumOptions: this.options.enum,
1270
+ isEnum: true
1271
+ });
1458
1272
  return createTypeReferenceNode(resolvedName, void 0);
1459
1273
  },
1460
1274
  union(node) {
@@ -1472,30 +1286,30 @@ const printerTs = ast.createPrinter((options) => {
1472
1286
  });
1473
1287
  return this.transform(m);
1474
1288
  }).filter(isNonNullable)
1475
- }) ?? void 0;
1289
+ });
1476
1290
  return createUnionDeclaration({
1477
1291
  withParentheses: true,
1478
1292
  nodes: buildMemberNodes(members, this.transform)
1479
- }) ?? void 0;
1293
+ });
1480
1294
  },
1481
1295
  intersection(node) {
1482
1296
  return createIntersectionDeclaration({
1483
1297
  withParentheses: true,
1484
1298
  nodes: buildMemberNodes(node.members, this.transform)
1485
- }) ?? null;
1299
+ });
1486
1300
  },
1487
1301
  array(node) {
1488
1302
  return createArrayDeclaration({
1489
1303
  nodes: mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(isNonNullable),
1490
1304
  arrayType: this.options.arrayType
1491
- }) ?? null;
1305
+ });
1492
1306
  },
1493
1307
  tuple(node) {
1494
- return buildTupleNode(node, this.transform) ?? null;
1308
+ return buildTupleNode(node, this.transform);
1495
1309
  },
1496
1310
  object(node) {
1497
1311
  const { transform, options } = this;
1498
- const addsQuestionToken = OPTIONAL_ADDS_QUESTION_TOKEN.has(options.optionalType);
1312
+ const addsQuestionToken = options.optionalType === "questionToken" || options.optionalType === "questionTokenAndUndefined";
1499
1313
  const propertyNodes = mapSchemaProperties(node, (schema) => transform(schema)).map(({ name, property, output }) => {
1500
1314
  const baseType = output ?? keywordTypeNodes.unknown;
1501
1315
  const optional = !property.required || !!property.schema.optional || !!property.schema.nullish;
@@ -1523,24 +1337,21 @@ const printerTs = ast.createPrinter((options) => {
1523
1337
  if (!transformed) return null;
1524
1338
  const meta = syncSchemaRef(node);
1525
1339
  if (!name) {
1526
- const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [transformed, keywordTypeNodes.null] }) : transformed;
1527
- const result = (meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
1340
+ const result = wrapNullableOptional(transformed, !!meta.nullable, !!(meta.nullish || meta.optional) && addsUndefined);
1528
1341
  return parserTs().print(result);
1529
1342
  }
1530
1343
  const inner = (() => {
1531
- const omitted = keysToOmit?.length ? createOmitDeclaration({
1344
+ return wrapNullableOptional(keysToOmit?.length ? createOmitDeclaration({
1532
1345
  keys: keysToOmit,
1533
1346
  type: transformed,
1534
1347
  nonNullable: true
1535
- }) : transformed;
1536
- const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [omitted, keywordTypeNodes.null] }) : omitted;
1537
- return meta.nullish || meta.optional ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
1348
+ }) : transformed, !!meta.nullable, !!(meta.nullish || meta.optional));
1538
1349
  })();
1539
1350
  const typeNode = createTypeDeclaration({
1540
1351
  name,
1541
1352
  isExportable: true,
1542
1353
  type: inner,
1543
- syntax: syntaxType === "type" || inner.kind === syntaxKind.union || !!keysToOmit?.length ? "type" : "interface",
1354
+ syntax: syntaxType === "type" || isUnionTypeNode(inner) || !!keysToOmit?.length ? "type" : "interface",
1544
1355
  comments: buildPropertyJSDocComments({
1545
1356
  ...meta,
1546
1357
  description
@@ -1553,15 +1364,6 @@ const printerTs = ast.createPrinter((options) => {
1553
1364
  //#endregion
1554
1365
  //#region src/generators/typeGenerator.tsx
1555
1366
  /**
1556
- * Resolves the imported type name for a referenced schema. An enum schema emitted
1557
- * as a `const` object imports its suffixed key alias (e.g. `StatusKey`); every other
1558
- * schema imports its plain resolved name.
1559
- */
1560
- function resolveImportName({ schemaName, enumOptions, enumSchemaNames, resolver }) {
1561
- if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
1562
- return resolver.name(schemaName);
1563
- }
1564
- /**
1565
1367
  * Built-in generator for `@kubb/plugin-ts`. Emits one TypeScript file per
1566
1368
  * schema in the spec plus per-operation request, response, and parameter
1567
1369
  * types. Drop-replace with a custom `Generator<PluginTs>` to change how
@@ -1575,11 +1377,11 @@ const typeGenerator = defineGenerator({
1575
1377
  const { config, resolver, root } = ctx;
1576
1378
  if (!node.name) return;
1577
1379
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1578
- const importName = (schemaName) => resolveImportName({
1579
- schemaName,
1380
+ const importName = (schemaName) => enumTypeName({
1381
+ resolver,
1382
+ name: schemaName,
1580
1383
  enumOptions,
1581
- enumSchemaNames,
1582
- resolver
1384
+ isEnum: enumSchemaNames.has(schemaName)
1583
1385
  });
1584
1386
  const imports = resolver.imports({
1585
1387
  node,
@@ -1591,7 +1393,7 @@ const typeGenerator = defineGenerator({
1591
1393
  const enumNode = ast.narrowSchema(node, ast.schemaTypes.enum);
1592
1394
  const isEnumSchema = !!enumNode && !isInlineConstEnum(enumNode, enumSchemaNames);
1593
1395
  const meta = {
1594
- name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolver.name(node.name),
1396
+ name: enumOptions.type === "asConst" && isEnumSchema ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolver.name(node.name),
1595
1397
  file: resolver.file({
1596
1398
  name: node.name,
1597
1399
  extname: ".ts",
@@ -1662,11 +1464,11 @@ const typeGenerator = defineGenerator({
1662
1464
  group: group ?? void 0
1663
1465
  }) };
1664
1466
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1665
- const importName = (schemaName) => resolveImportName({
1666
- schemaName,
1467
+ const importName = (schemaName) => enumTypeName({
1468
+ resolver,
1469
+ name: schemaName,
1667
1470
  enumOptions,
1668
- enumSchemaNames,
1669
- resolver
1471
+ isEnum: enumSchemaNames.has(schemaName)
1670
1472
  });
1671
1473
  function renderSchemaType({ schema, name, keysToOmit }) {
1672
1474
  if (!schema) return null;
@@ -1789,7 +1591,7 @@ const typeGenerator = defineGenerator({
1789
1591
  if (!node.responses.some(hasSchema)) return null;
1790
1592
  const responseName = resolver.response.response(node);
1791
1593
  const responsesWithSchema = node.responses.filter(hasSchema);
1792
- if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? collectRefNames(entry.schema).map(importName) : []))).has(responseName)) return null;
1594
+ if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? ast.collectImportedRefNames(entry.schema).map(importName) : []))).has(responseName)) return null;
1793
1595
  return renderSchemaType({
1794
1596
  schema: {
1795
1597
  ...buildResponseUnion(node, { resolver }),
@@ -1834,11 +1636,11 @@ const typeGenerator = defineGenerator({
1834
1636
  //#region kubb-extension.json
1835
1637
  var compatibility = {
1836
1638
  "kubb": ">=5.8.3",
1837
- "node": ">=22"
1639
+ "node": ">=22.12"
1838
1640
  };
1839
1641
  //#endregion
1840
1642
  //#region package.json
1841
- var version = "5.0.11";
1643
+ var version = "5.0.14";
1842
1644
  //#endregion
1843
1645
  //#region src/resolvers/resolverTs.ts
1844
1646
  /**
@@ -2116,6 +1918,15 @@ function createFunctionParameters(props = {}) {
2116
1918
  //#endregion
2117
1919
  //#region src/printers/functionPrinter.ts
2118
1920
  /**
1921
+ * Ordering priority for function parameters: lower = sorted earlier.
1922
+ */
1923
+ const PARAM_RANK = {
1924
+ required: 0,
1925
+ optional: 1,
1926
+ withDefault: 2,
1927
+ rest: 3
1928
+ };
1929
+ /**
2119
1930
  * Renders a {@link TypeExpression} to its TypeScript source.
2120
1931
  *
2121
1932
  * - a `string` is a type reference, returned as-is
@@ -2136,13 +1947,17 @@ function renderType(type, transformType) {
2136
1947
  function renderKey(name) {
2137
1948
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
2138
1949
  }
1950
+ function renderMembers(members) {
1951
+ return `{ ${members.map((member) => `${renderKey(member.key)}${member.optional ? "?" : ""}: ${member.type}`).join("; ")} }`;
1952
+ }
2139
1953
  function renderTypeExpression(type) {
2140
1954
  if (typeof type === "string") return type;
2141
1955
  if (isIndexedAccessType(type)) return `${type.target}['${type.key}']`;
2142
- return `{ ${type.members.map((member) => {
2143
- const value = renderTypeExpression(member.type);
2144
- return member.optional ? `${renderKey(member.name)}?: ${value}` : `${renderKey(member.name)}: ${value}`;
2145
- }).join("; ")} }`;
1956
+ return renderMembers(type.members.map((member) => ({
1957
+ key: member.name,
1958
+ type: renderTypeExpression(member.type),
1959
+ optional: member.optional
1960
+ })));
2146
1961
  }
2147
1962
  function groupMembers(param) {
2148
1963
  if (typeof param.name === "string") return null;
@@ -2155,9 +1970,6 @@ function rank(param) {
2155
1970
  if (members) return members.every((m) => m.optional) ? PARAM_RANK.optional : PARAM_RANK.required;
2156
1971
  return param.optional ? PARAM_RANK.optional : PARAM_RANK.required;
2157
1972
  }
2158
- function sortParams(params) {
2159
- return params.toSorted((a, b) => rank(a) - rank(b));
2160
- }
2161
1973
  function sortedGroupMembers(name, type) {
2162
1974
  const members = type && isTypeLiteral(type) ? type.members : [];
2163
1975
  const memberRank = (optional) => optional ? PARAM_RANK.optional : PARAM_RANK.required;
@@ -2186,11 +1998,11 @@ function renderGroupType(type, sorted, transformType) {
2186
1998
  if (!isTypeLiteral(type)) return renderType(type);
2187
1999
  const typed = sorted.filter((member) => member.type !== void 0);
2188
2000
  if (!typed.length) return void 0;
2189
- return `{ ${typed.map((member) => {
2190
- const key = renderKey(member.propertyName ?? member.name);
2191
- const value = renderType(member.type, transformType);
2192
- return member.optional ? `${key}?: ${value}` : `${key}: ${value}`;
2193
- }).join("; ")} }`;
2001
+ return renderMembers(typed.map((member) => ({
2002
+ key: member.propertyName ?? member.name,
2003
+ type: renderType(member.type, transformType),
2004
+ optional: member.optional
2005
+ })));
2194
2006
  }
2195
2007
  function printParameter(node, options) {
2196
2008
  const { mode, transformName, transformType } = options;
@@ -2243,190 +2055,11 @@ function functionPrinter(options) {
2243
2055
  name: "functionParameters",
2244
2056
  options,
2245
2057
  print(node) {
2246
- return sortParams(node.params).map((p) => printParameter(p, options)).filter(Boolean).join(", ");
2058
+ return node.params.toSorted((a, b) => rank(a) - rank(b)).map((p) => printParameter(p, options)).filter(Boolean).join(", ");
2247
2059
  }
2248
2060
  };
2249
2061
  }
2250
2062
  //#endregion
2251
- //#region src/printers/operationParams.ts
2252
- /**
2253
- * Resolves the {@link TypeExpression} for an individual parameter.
2254
- *
2255
- * Without a resolver, it falls back to the schema primitive (a plain type-name string). When the
2256
- * parameter belongs to a named group, it emits an `IndexedAccessType` like `GroupParams['petId']`,
2257
- * otherwise the resolved individual name.
2258
- */
2259
- function resolveParamType({ node, param, resolver }) {
2260
- if (!resolver) return param.schema.primitive ?? "unknown";
2261
- const individualName = resolver.param.name(node, param);
2262
- const groupLocation = param.in === "path" || param.in === "query" || param.in === "header" ? param.in : void 0;
2263
- const groupResolvers = {
2264
- path: resolver.param.path,
2265
- query: resolver.param.query,
2266
- header: resolver.param.headers
2267
- };
2268
- const groupName = groupLocation ? groupResolvers[groupLocation].call(resolver, node, param) : void 0;
2269
- if (groupName && groupName !== individualName) return createIndexedAccessType({
2270
- target: groupName,
2271
- key: param.name
2272
- });
2273
- return individualName;
2274
- }
2275
- /**
2276
- * Derives a {@link ParamGroupType} for a query or header group from the resolver.
2277
- *
2278
- * Returns `null` when there is no resolver, no params, or the group name equals the
2279
- * individual param name (so there is no real group to emit).
2280
- */
2281
- function resolveGroupType({ node, params, group, resolver }) {
2282
- if (!resolver || !params.length) return null;
2283
- const firstParam = params[0];
2284
- const groupName = (group === "query" ? resolver.param.query : resolver.param.headers).call(resolver, node, firstParam);
2285
- if (groupName === resolver.param.name(node, firstParam)) return null;
2286
- return {
2287
- type: groupName,
2288
- optional: params.every((p) => !p.required)
2289
- };
2290
- }
2291
- /**
2292
- * Converts an `OperationNode` into function parameters for code generation.
2293
- *
2294
- * Centralizes parameter grouping logic for all plugins. `paramsType` chooses between one
2295
- * destructured object parameter (`object`) and separate top-level parameters (`inline`), while
2296
- * `pathParamsType` controls how path params render in inline mode. Provide a `resolver` for type
2297
- * name resolution and `extraParams` for plugin-specific trailing parameters such as an `options` object.
2298
- */
2299
- function createOperationParams(node, options) {
2300
- const { paramsType, pathParamsType, resolver, pathParamsDefault, extraParams = [], paramNames, typeWrapper } = options;
2301
- const dataName = paramNames?.data ?? "data";
2302
- const paramsName = paramNames?.params ?? "params";
2303
- const headersName = paramNames?.headers ?? "headers";
2304
- const pathName = paramNames?.path ?? "pathParams";
2305
- const wrapType = (type) => typeWrapper ? typeWrapper(type) : type;
2306
- const wrapTypeExpression = (type) => typeof type === "string" ? wrapType(type) : type;
2307
- const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node);
2308
- const toProperty = (param) => ({
2309
- name: param.name,
2310
- type: wrapTypeExpression(resolveParamType({
2311
- node,
2312
- param,
2313
- resolver
2314
- })),
2315
- optional: !param.required
2316
- });
2317
- const emptyObjectDefault = (props) => props.every((p) => p.optional) ? "{}" : void 0;
2318
- const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.response.body(node) ?? "unknown") : void 0;
2319
- const bodyProperty = bodyType ? [{
2320
- name: dataName,
2321
- type: bodyType,
2322
- optional: !(node.requestBody?.required ?? false)
2323
- }] : [];
2324
- const trailingGroups = [{
2325
- name: paramsName,
2326
- node,
2327
- params: queryParams,
2328
- groupType: resolveGroupType({
2329
- node,
2330
- params: queryParams,
2331
- group: "query",
2332
- resolver
2333
- }),
2334
- resolver,
2335
- wrapType
2336
- }, {
2337
- name: headersName,
2338
- node,
2339
- params: headerParams,
2340
- groupType: resolveGroupType({
2341
- node,
2342
- params: headerParams,
2343
- group: "header",
2344
- resolver
2345
- }),
2346
- resolver,
2347
- wrapType
2348
- }];
2349
- const params = [];
2350
- if (paramsType === "object") {
2351
- const children = [
2352
- ...pathParams.map(toProperty),
2353
- ...bodyProperty,
2354
- ...trailingGroups.flatMap(buildGroupProperty)
2355
- ];
2356
- if (children.length) params.push(createFunctionParameter({
2357
- properties: children,
2358
- default: emptyObjectDefault(children)
2359
- }));
2360
- } else {
2361
- if (pathParamsType === "inlineSpread" && pathParams.length) {
2362
- const spreadType = resolver?.param.path(node, pathParams[0]);
2363
- params.push(createFunctionParameter({
2364
- name: pathName,
2365
- type: spreadType ? wrapType(spreadType) : void 0,
2366
- rest: true
2367
- }));
2368
- } else if (pathParamsType === "inline") params.push(...pathParams.map((p) => createFunctionParameter(toProperty(p))));
2369
- else if (pathParams.length) {
2370
- const pathChildren = pathParams.map(toProperty);
2371
- params.push(createFunctionParameter({
2372
- properties: pathChildren,
2373
- default: pathParamsDefault ?? emptyObjectDefault(pathChildren)
2374
- }));
2375
- }
2376
- params.push(...bodyProperty.map((p) => createFunctionParameter(p)));
2377
- params.push(...trailingGroups.flatMap(buildGroupParam));
2378
- }
2379
- params.push(...extraParams);
2380
- return createFunctionParameters({ params });
2381
- }
2382
- /**
2383
- * Builds the property descriptor for a query or header group.
2384
- * Returns an empty array when there are no params to emit.
2385
- *
2386
- * A pre-resolved `groupType` emits `name: GroupType`. Otherwise it builds an inline
2387
- * {@link TypeLiteralNode} from the individual params.
2388
- */
2389
- function buildGroupProperty({ name, node, params, groupType, resolver, wrapType }) {
2390
- if (groupType) return [{
2391
- name,
2392
- type: typeof groupType.type === "string" ? wrapType(groupType.type) : groupType.type,
2393
- optional: groupType.optional
2394
- }];
2395
- if (params.length) return [{
2396
- name,
2397
- type: buildTypeLiteral({
2398
- node,
2399
- params,
2400
- resolver
2401
- }),
2402
- optional: params.every((p) => !p.required)
2403
- }];
2404
- return [];
2405
- }
2406
- /**
2407
- * Builds a single {@link FunctionParameterNode} for a query or header group.
2408
- * Returns an empty array when there are no params to emit.
2409
- */
2410
- function buildGroupParam(args) {
2411
- return buildGroupProperty(args).map((p) => createFunctionParameter(p));
2412
- }
2413
- /**
2414
- * Builds a {@link TypeLiteralNode} for an inline anonymous type grouping named fields.
2415
- *
2416
- * Used when query or header parameters have no dedicated group type name.
2417
- */
2418
- function buildTypeLiteral({ node, params, resolver }) {
2419
- return createTypeLiteral({ members: params.map((p) => ({
2420
- name: p.name,
2421
- type: resolveParamType({
2422
- node,
2423
- param: p,
2424
- resolver
2425
- }),
2426
- optional: !p.required
2427
- })) });
2428
- }
2429
- //#endregion
2430
- export { Enum, Type, buildParams, createFunctionParameter, createFunctionParameters, createIndexedAccessType, createObjectBindingPattern, createOperationParams, createTypeLiteral, pluginTs as default, pluginTs, functionPrinter, pluginTsName, printerTs, renderType, resolverTs, typeGenerator };
2063
+ export { Enum, Type, buildParams, createFunctionParameter, createFunctionParameters, createIndexedAccessType, createObjectBindingPattern, createTypeLiteral, pluginTs as default, pluginTs, enumTypeName, functionPrinter, pluginTsName, printerTs, renderType, resolverTs, typeGenerator };
2431
2064
 
2432
2065
  //# sourceMappingURL=index.js.map