@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.cjs CHANGED
@@ -311,47 +311,6 @@ function toFilePath(name, caseLast = camelCase) {
311
311
  return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
312
312
  }
313
313
  //#endregion
314
- //#region src/constants.ts
315
- /**
316
- * `optionalType` values that cause a property's type to include `| undefined`.
317
- */
318
- const OPTIONAL_ADDS_UNDEFINED = /* @__PURE__ */ new Set(["undefined", "questionTokenAndUndefined"]);
319
- /**
320
- * `optionalType` values that render the property key with a `?` token.
321
- */
322
- const OPTIONAL_ADDS_QUESTION_TOKEN = /* @__PURE__ */ new Set(["questionToken", "questionTokenAndUndefined"]);
323
- /**
324
- * `enum.type` values that append a `typeSuffix` to the generated enum type alias.
325
- */
326
- const ENUM_TYPES_WITH_KEY_SUFFIX = /* @__PURE__ */ new Set(["asConst"]);
327
- /**
328
- * `enum.type` values that require a runtime value declaration (object, enum, or literal).
329
- */
330
- const ENUM_TYPES_WITH_RUNTIME_VALUE = /* @__PURE__ */ new Set([
331
- "enum",
332
- "asConst",
333
- "constEnum",
334
- "literal",
335
- void 0
336
- ]);
337
- /**
338
- * `enum.type` values whose type declaration is type-only (no runtime value emitted for the type alias).
339
- */
340
- const ENUM_TYPES_WITH_TYPE_ONLY = /* @__PURE__ */ new Set([
341
- "asConst",
342
- "literal",
343
- void 0
344
- ]);
345
- /**
346
- * Ordering priority for function parameters: lower = sorted earlier.
347
- */
348
- const PARAM_RANK = {
349
- required: 0,
350
- optional: 1,
351
- withDefault: 2,
352
- rest: 3
353
- };
354
- //#endregion
355
314
  //#region src/factory.ts
356
315
  var factory_exports = /* @__PURE__ */ __exportAll({
357
316
  appendJSDocToNode: () => appendJSDocToNode,
@@ -362,14 +321,9 @@ var factory_exports = /* @__PURE__ */ __exportAll({
362
321
  constToTypeNode: () => constToTypeNode,
363
322
  createArrayDeclaration: () => createArrayDeclaration,
364
323
  createEnumDeclaration: () => createEnumDeclaration,
365
- createExportDeclaration: () => createExportDeclaration,
366
- createImportDeclaration: () => createImportDeclaration,
367
324
  createIntersectionDeclaration: () => createIntersectionDeclaration,
368
- createJSDoc: () => createJSDoc,
369
325
  createOmitDeclaration: () => createOmitDeclaration,
370
- createParameterSignature: () => createParameterSignature,
371
326
  createPropertySignature: () => createPropertySignature,
372
- createQuestionToken: () => createQuestionToken,
373
327
  createTypeDeclaration: () => createTypeDeclaration,
374
328
  createTypeLiteralNode: () => createTypeLiteralNode,
375
329
  createTypeReferenceNode: () => createTypeReferenceNode,
@@ -377,9 +331,10 @@ var factory_exports = /* @__PURE__ */ __exportAll({
377
331
  createUrlTemplateType: () => createUrlTemplateType,
378
332
  dateOrStringNode: () => dateOrStringNode,
379
333
  isNonNullable: () => isNonNullable$1,
334
+ isUnionTypeNode: () => isUnionTypeNode,
380
335
  keywordTypeNodes: () => keywordTypeNodes,
381
336
  modifiers: () => modifiers,
382
- syntaxKind: () => syntaxKind
337
+ wrapNullableOptional: () => wrapNullableOptional
383
338
  });
384
339
  /**
385
340
  * Loaded with `require`, not `import`. When ESM imports a CommonJS package, Node keeps a second
@@ -387,35 +342,14 @@ var factory_exports = /* @__PURE__ */ __exportAll({
387
342
  */
388
343
  const typescript = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href)("typescript");
389
344
  const { SyntaxKind, factory } = typescript;
390
- /**
391
- * Compares two strings by UTF-16 code unit, keeping sorted output identical across platforms
392
- * regardless of locale.
393
- */
394
- function compareStrings(a, b) {
395
- if (a < b) return -1;
396
- if (a > b) return 1;
397
- return 0;
398
- }
399
345
  function isNumber(value) {
400
346
  return typeof value === "number" && !Number.isNaN(value);
401
347
  }
402
348
  /**
403
- * TypeScript AST modifiers for common keywords (async, export, const, static).
349
+ * TypeScript AST modifiers for the `export` keyword.
404
350
  */
405
- const modifiers = {
406
- async: factory.createModifier(typescript.SyntaxKind.AsyncKeyword),
407
- export: factory.createModifier(typescript.SyntaxKind.ExportKeyword),
408
- const: factory.createModifier(typescript.SyntaxKind.ConstKeyword),
409
- static: factory.createModifier(typescript.SyntaxKind.StaticKeyword)
410
- };
411
- /**
412
- * TypeScript syntax kind constants for union, literal, and string types.
413
- */
414
- const syntaxKind = {
415
- union: SyntaxKind.UnionType,
416
- literalType: SyntaxKind.LiteralType,
417
- stringLiteral: SyntaxKind.StringLiteral
418
- };
351
+ const modifiers = { export: factory.createModifier(typescript.SyntaxKind.ExportKeyword) };
352
+ const isUnionTypeNode = typescript.isUnionTypeNode;
419
353
  function isNonNullable$1(value) {
420
354
  return value !== null && value !== void 0;
421
355
  }
@@ -469,7 +403,6 @@ function createArrayDeclaration({ nodes, arrayType = "array" }) {
469
403
  if (!nodes.length) return factory.createTupleTypeNode([]);
470
404
  if (nodes.length === 1) {
471
405
  const node = nodes[0];
472
- if (!node) return null;
473
406
  if (arrayType === "generic") return factory.createTypeReferenceNode(factory.createIdentifier("Array"), [node]);
474
407
  return factory.createArrayTypeNode(node);
475
408
  }
@@ -497,23 +430,6 @@ function createPropertySignature({ readOnly, modifiers = [], name, questionToken
497
430
  return factory.createPropertySignature([...modifiers, readOnly ? factory.createToken(typescript.SyntaxKind.ReadonlyKeyword) : void 0].filter((modifier) => modifier !== void 0), propertyName(name), createQuestionToken(questionToken), type);
498
431
  }
499
432
  /**
500
- * Creates a function parameter declaration with optional markers, rest parameters, and type annotations.
501
- */
502
- function createParameterSignature(name, { modifiers, dotDotDotToken, questionToken, type, initializer }) {
503
- return factory.createParameterDeclaration(modifiers, dotDotDotToken, name, createQuestionToken(questionToken), type, initializer);
504
- }
505
- /**
506
- * Creates a JSDoc comment node from an array of comment strings.
507
- * Returns null if no comments are provided.
508
- */
509
- function createJSDoc({ comments }) {
510
- if (!comments.length) return null;
511
- return factory.createJSDocComment(factory.createNodeArray(comments.map((comment, i) => {
512
- if (i === comments.length - 1) return factory.createJSDocText(comment);
513
- return factory.createJSDocText(`${comment}\n`);
514
- })));
515
- }
516
- /**
517
433
  * Attaches JSDoc comments to an AST node as synthetic leading comments.
518
434
  * Filters out undefined comments before attaching.
519
435
  *
@@ -532,19 +448,7 @@ function appendJSDocToNode({ node, comments }) {
532
448
  * Defines the key type (default: `string`) and value type on an object.
533
449
  */
534
450
  function createIndexSignature(type, { modifiers, indexName = "key", indexType = factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword) } = {}) {
535
- return factory.createIndexSignature(modifiers, [createParameterSignature(indexName, { type: indexType })], type);
536
- }
537
- /**
538
- * Creates a TypeScript type alias declaration with optional modifiers and type parameters.
539
- */
540
- function createTypeAliasDeclaration({ modifiers, name, typeParameters, type }) {
541
- return factory.createTypeAliasDeclaration(modifiers, name, typeParameters, type);
542
- }
543
- /**
544
- * Creates a TypeScript interface declaration with optional modifiers, type parameters, and members.
545
- */
546
- function createInterfaceDeclaration({ modifiers, name, typeParameters, members }) {
547
- return factory.createInterfaceDeclaration(modifiers, name, typeParameters, void 0, members);
451
+ return factory.createIndexSignature(modifiers, [factory.createParameterDeclaration(void 0, void 0, indexName, void 0, indexType)], type);
548
452
  }
549
453
  /**
550
454
  * Creates a TypeScript type declaration as either a type alias or interface.
@@ -552,67 +456,22 @@ function createInterfaceDeclaration({ modifiers, name, typeParameters, members }
552
456
  */
553
457
  function createTypeDeclaration({ syntax, isExportable, comments, name, type }) {
554
458
  if (syntax === "interface" && typescript.isTypeLiteralNode(type)) return appendJSDocToNode({
555
- node: createInterfaceDeclaration({
556
- members: [...type.members],
557
- modifiers: isExportable ? [modifiers.export] : [],
558
- name,
559
- typeParameters: void 0
560
- }),
459
+ node: factory.createInterfaceDeclaration(isExportable ? [modifiers.export] : [], name, void 0, void 0, [...type.members]),
561
460
  comments
562
461
  });
563
462
  return appendJSDocToNode({
564
- node: createTypeAliasDeclaration({
565
- type,
566
- modifiers: isExportable ? [modifiers.export] : [],
567
- name,
568
- typeParameters: void 0
569
- }),
463
+ node: factory.createTypeAliasDeclaration(isExportable ? [modifiers.export] : [], name, void 0, type),
570
464
  comments
571
465
  });
572
466
  }
573
467
  /**
574
- * Creates an import declaration with support for default imports, named imports, namespace imports, and type-only imports.
575
- * Optionally rename imported members with `propertyName` and `name` pairs.
576
- *
577
- * @example Default import
578
- * `import Pet from './Pet'`
579
- *
580
- * @example Named imports with rename
581
- * `import { Pet as Cat } from './Pet'`
582
- *
583
- * @example Namespace import
584
- * `import * as Pet from './Pet'`
585
- */
586
- function createImportDeclaration({ name, path, isTypeOnly = false, isNameSpace = false }) {
587
- if (!Array.isArray(name)) {
588
- const importPropertyName = isNameSpace ? void 0 : factory.createIdentifier(name);
589
- const importName = isNameSpace ? factory.createNamespaceImport(factory.createIdentifier(name)) : void 0;
590
- return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, importPropertyName, importName), factory.createStringLiteral(path), void 0);
591
- }
592
- const sortedName = name.toSorted((a, b) => compareStrings(typeof a === "object" ? a.propertyName : a, typeof b === "object" ? b.propertyName : b));
593
- return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, void 0, factory.createNamedImports(sortedName.map((item) => {
594
- if (typeof item === "object") {
595
- const obj = item;
596
- if (obj.name) return factory.createImportSpecifier(false, factory.createIdentifier(obj.propertyName), factory.createIdentifier(obj.name));
597
- return factory.createImportSpecifier(false, void 0, factory.createIdentifier(obj.propertyName));
598
- }
599
- return factory.createImportSpecifier(false, void 0, factory.createIdentifier(item));
600
- }))), factory.createStringLiteral(path), void 0);
601
- }
602
- /**
603
- * Creates an export declaration with support for named exports, namespace exports, and type-only exports.
604
- * Sorts export names alphabetically for consistent output across platforms.
468
+ * Converts an enum member value to a literal expression. Numbers become numeric literals (negatives use a prefix
469
+ * minus, as `createNumericLiteral` rejects them) unless `asNumber` is `false`, which emits the string form.
605
470
  */
606
- function createExportDeclaration({ path, asAlias, isTypeOnly = false, name }) {
607
- if (name && !Array.isArray(name) && !asAlias) console.warn(`When using name as string, asAlias should be true ${name}`);
608
- if (!Array.isArray(name)) {
609
- const parsedName = name?.match(/^\d/) ? `_${name?.slice(1)}` : name;
610
- return factory.createExportDeclaration(void 0, isTypeOnly, asAlias && parsedName ? factory.createNamespaceExport(factory.createIdentifier(parsedName)) : void 0, factory.createStringLiteral(path), void 0);
611
- }
612
- const sortedName = name.toSorted((a, b) => compareStrings(typeof a === "string" ? a : a.text, typeof b === "string" ? b : b.text));
613
- return factory.createExportDeclaration(void 0, isTypeOnly, factory.createNamedExports(sortedName.map((propertyName) => {
614
- return factory.createExportSpecifier(false, void 0, typeof propertyName === "string" ? factory.createIdentifier(propertyName) : propertyName);
615
- })), factory.createStringLiteral(path), void 0);
471
+ function valueToExpression(value, asNumber = isNumber(value)) {
472
+ if (typeof value === "boolean") return value ? factory.createTrue() : factory.createFalse();
473
+ if (asNumber && isNumber(value)) return value < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value))) : factory.createNumericLiteral(value);
474
+ return factory.createStringLiteral(value.toString());
616
475
  }
617
476
  /**
618
477
  * Apply casing transformation to enum keys
@@ -649,12 +508,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
649
508
  if (value !== null && value !== void 0) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
650
509
  }).filter((node) => node !== void 0)))];
651
510
  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]) => {
652
- let initializer = factory.createStringLiteral(value?.toString());
653
- if (Number.parseInt(value.toString(), 10) === value && isNumber(value)) {
654
- if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
655
- else initializer = factory.createNumericLiteral(value);
656
- }
657
- if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
511
+ const initializer = valueToExpression(value, Number.parseInt(value.toString(), 10) === value);
658
512
  if (isNumber(Number.parseInt(key.toString(), 10))) {
659
513
  const casingKey = applyEnumKeyCasing(`${typeName}_${key}`, enumKeyCasing);
660
514
  return appendJSDocToNode({
@@ -673,12 +527,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
673
527
  const identifierName = name;
674
528
  if (enums.length === 0) return [void 0, factory.createTypeAliasDeclaration([factory.createToken(typescript.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createKeywordTypeNode(typescript.SyntaxKind.NeverKeyword))];
675
529
  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]) => {
676
- let initializer = factory.createStringLiteral(value?.toString());
677
- if (isNumber(value)) {
678
- if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
679
- else initializer = factory.createNumericLiteral(value);
680
- }
681
- if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
530
+ const initializer = valueToExpression(value);
682
531
  if (key !== null && key !== void 0) {
683
532
  const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
684
533
  return appendJSDocToNode({
@@ -757,66 +606,19 @@ const createTypeLiteralNode = factory.createTypeLiteralNode;
757
606
  */
758
607
  const createTypeReferenceNode = factory.createTypeReferenceNode;
759
608
  /**
760
- * Creates a numeric literal type node.
761
- */
762
- const createNumericLiteral = factory.createNumericLiteral;
763
- /**
764
- * Creates a string literal type node.
765
- */
766
- const createStringLiteral = factory.createStringLiteral;
767
- /**
768
- * Creates an array type node (e.g., `T[]`).
769
- */
770
- const createArrayTypeNode = factory.createArrayTypeNode;
771
- /**
772
- * Creates a literal type node (e.g., `'hello'`, `42`, `true`).
773
- */
774
- const createLiteralTypeNode = factory.createLiteralTypeNode;
775
- /**
776
- * Creates an identifier node.
777
- */
778
- const createIdentifier = factory.createIdentifier;
779
- /**
780
- * Creates an optional type node (e.g., `T | undefined`).
781
- */
782
- const createOptionalTypeNode = factory.createOptionalTypeNode;
783
- /**
784
- * Creates a tuple type node (e.g., `[string, number]`).
785
- */
786
- const createTupleTypeNode = factory.createTupleTypeNode;
787
- /**
788
- * Creates a rest type node for variadic tuple elements (e.g., `...T[]`).
789
- */
790
- const createRestTypeNode = factory.createRestTypeNode;
791
- /**
792
- * Creates a boolean true literal type node.
793
- */
794
- const createTrue = factory.createTrue;
795
- /**
796
- * Creates a boolean false literal type node.
797
- */
798
- const createFalse = factory.createFalse;
799
- /**
800
- * Creates a prefix unary expression (e.g., negative numbers, logical not).
801
- */
802
- const createPrefixUnaryExpression = factory.createPrefixUnaryExpression;
803
- /**
804
609
  * Converts a primitive const value to a TypeScript literal type node.
805
610
  * Handles negative numbers via a prefix unary expression.
806
611
  */
807
612
  function constToTypeNode(value, format) {
808
- if (format === "boolean") return createLiteralTypeNode(value === true ? createTrue() : createFalse());
809
- if (format === "number" && typeof value === "number") {
810
- if (value < 0) return createLiteralTypeNode(createPrefixUnaryExpression(SyntaxKind.MinusToken, createNumericLiteral(Math.abs(value))));
811
- return createLiteralTypeNode(createNumericLiteral(value));
812
- }
813
- return createLiteralTypeNode(createStringLiteral(String(value)));
613
+ if (format === "boolean") return factory.createLiteralTypeNode(value === true ? factory.createTrue() : factory.createFalse());
614
+ const literal = format === "number" && typeof value === "number" ? value : String(value);
615
+ return factory.createLiteralTypeNode(valueToExpression(literal));
814
616
  }
815
617
  /**
816
618
  * Returns a `Date` reference type node when `representation` is `'date'`, otherwise falls back to `string`.
817
619
  */
818
620
  function dateOrStringNode(node) {
819
- return node.representation === "date" ? createTypeReferenceNode(createIdentifier("Date")) : keywordTypeNodes.string;
621
+ return node.representation === "date" ? createTypeReferenceNode(factory.createIdentifier("Date")) : keywordTypeNodes.string;
820
622
  }
821
623
  /**
822
624
  * Maps an array of `SchemaNode`s through the printer, filtering out `null` and `undefined` results.
@@ -836,20 +638,24 @@ function buildTupleNode(node, print) {
836
638
  items = items.slice(0, max);
837
639
  if (items.length < max && restNode) items = [...items, ...Array(max - items.length).fill(restNode)];
838
640
  }
839
- if (min !== void 0) items = items.map((item, i) => i >= min ? createOptionalTypeNode(item) : item);
840
- if (max === void 0 && restNode) items.push(createRestTypeNode(createArrayTypeNode(restNode)));
841
- return createTupleTypeNode(items);
641
+ if (min !== void 0) items = items.map((item, i) => i >= min ? factory.createOptionalTypeNode(item) : item);
642
+ if (max === void 0 && restNode) items.push(factory.createRestTypeNode(factory.createArrayTypeNode(restNode)));
643
+ return factory.createTupleTypeNode(items);
644
+ }
645
+ /**
646
+ * Appends `| null` and then `| undefined` to a type when requested.
647
+ */
648
+ function wrapNullableOptional(type, nullable, addsUndefined) {
649
+ const withNullable = nullable ? createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] }) : type;
650
+ return addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
842
651
  }
843
652
  /**
844
653
  * Applies `nullable` and optional/nullish `| undefined` union modifiers to a property's resolved base type.
845
654
  */
846
655
  function buildPropertyType(schema, baseType, optionalType, optional) {
847
- const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType);
656
+ const addsUndefined = optionalType === "undefined" || optionalType === "questionTokenAndUndefined";
848
657
  const meta = (0, kubb_kit.syncSchemaRef)(schema);
849
- let type = baseType;
850
- if (meta.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
851
- if ((optional || meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
852
- return type;
658
+ return wrapNullableOptional(baseType, !!meta.nullable, addsUndefined && !!(optional || meta.nullish || meta.optional));
853
659
  }
854
660
  const indexSignaturePrinter = typescript.createPrinter();
855
661
  const indexSignatureSource = typescript.createSourceFile("", "", typescript.ScriptTarget.Latest);
@@ -892,7 +698,7 @@ function getEnumNames({ node, enum: enumOptions, resolver }) {
892
698
  const resolved = resolver.name(node.name);
893
699
  return {
894
700
  enumName: enumOptions.constCasing === "pascalCase" ? resolved : camelCase(node.name),
895
- typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolved
701
+ typeName: enumOptions.type === "asConst" ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolved
896
702
  };
897
703
  }
898
704
  /**
@@ -933,30 +739,16 @@ function Enum({ node, enum: enumOptions, resolver }) {
933
739
  }), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
934
740
  name: typeName,
935
741
  isIndexable: !namesMerge,
936
- isExportable: !namesMerge && ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumOptions.type),
937
- isTypeOnly: ENUM_TYPES_WITH_TYPE_ONLY.has(enumOptions.type),
742
+ isExportable: !namesMerge && enumOptions.type !== "inlineLiteral",
743
+ isTypeOnly: [
744
+ "asConst",
745
+ "literal",
746
+ void 0
747
+ ].includes(enumOptions.type),
938
748
  children: (0, _kubb_parser_ts.parserTs)().print(typeNode)
939
749
  })] });
940
750
  }
941
751
  //#endregion
942
- //#region ../../internals/shared/src/params.ts
943
- /**
944
- * Drops parameters that share the same name, keeping the first.
945
- *
946
- * A malformed spec can declare the same parameter name twice within one `in` location. Both would
947
- * resolve to the same output property, so emitting both would yield an object type with a duplicate
948
- * member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
949
- * parameter names flow through unchanged, so no two distinct names ever collide here anymore.
950
- */
951
- function dedupeParams(params) {
952
- const seen = /* @__PURE__ */ new Set();
953
- return params.filter((param) => {
954
- if (seen.has(param.name)) return false;
955
- seen.add(param.name);
956
- return true;
957
- });
958
- }
959
- //#endregion
960
752
  //#region ../../internals/shared/src/operation.ts
961
753
  /**
962
754
  * Maps a content type to the PascalCase suffix used to name per-content-type variants
@@ -1016,11 +808,19 @@ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
1016
808
  function getOperationParameters(node) {
1017
809
  const cached = operationParameterGroupsByNode.get(node);
1018
810
  if (cached) return cached;
811
+ const group = (location) => {
812
+ const seen = /* @__PURE__ */ new Set();
813
+ return node.parameters.filter((param) => {
814
+ if (param.in !== location || seen.has(param.name)) return false;
815
+ seen.add(param.name);
816
+ return true;
817
+ });
818
+ };
1019
819
  const groups = {
1020
- path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
1021
- query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
1022
- header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
1023
- cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
820
+ path: group("path"),
821
+ query: group("query"),
822
+ header: group("header"),
823
+ cookie: group("cookie")
1024
824
  };
1025
825
  operationParameterGroupsByNode.set(node, groups);
1026
826
  return groups;
@@ -1222,20 +1022,6 @@ function createCasedFile(caseLast) {
1222
1022
  } };
1223
1023
  }
1224
1024
  //#endregion
1225
- //#region ../../internals/shared/src/refs.ts
1226
- /**
1227
- * Collects the resolved target name of every pointer-carrying ref in a schema tree, in
1228
- * first-occurrence order. Use this for name-only checks (e.g. redeclaration detection) where
1229
- * `resolver.imports` would resolve file paths that are then discarded.
1230
- */
1231
- function collectRefNames(schema) {
1232
- return kubb_kit.ast.collectSync(schema, { schema: (node) => {
1233
- const refNode = kubb_kit.ast.narrowSchema(node, "ref");
1234
- if (!refNode?.ref) return null;
1235
- return kubb_kit.ast.resolveRefName(refNode);
1236
- } });
1237
- }
1238
- //#endregion
1239
1025
  //#region ../../internals/shared/src/group.ts
1240
1026
  /**
1241
1027
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
@@ -1297,6 +1083,9 @@ function mapSchemaItems(node, transform) {
1297
1083
  }
1298
1084
  //#endregion
1299
1085
  //#region src/utils.ts
1086
+ function enumTypeName({ resolver, name, enumOptions, isEnum }) {
1087
+ return isEnum && enumOptions?.type === "asConst" && enumOptions.typeSuffix ? resolver.enum.keyName({ name }, enumOptions.typeSuffix) : resolver.name(name);
1088
+ }
1300
1089
  /**
1301
1090
  * Tells whether a `const` (single-value enum) should render as a bare literal type (`'active'`)
1302
1091
  * rather than a named enum reference or a runtime enum declaration.
@@ -1433,7 +1222,7 @@ const { isNonNullable } = factory_exports;
1433
1222
  * ```
1434
1223
  */
1435
1224
  const printerTs = kubb_kit.ast.createPrinter((options) => {
1436
- const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(options.optionalType);
1225
+ const addsUndefined = options.optionalType === "undefined" || options.optionalType === "questionTokenAndUndefined";
1437
1226
  return {
1438
1227
  name: "typescript",
1439
1228
  options,
@@ -1464,7 +1253,12 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1464
1253
  if (!node.name) return null;
1465
1254
  const refName = kubb_kit.ast.resolveRefName(node);
1466
1255
  if (!refName) return null;
1467
- 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;
1256
+ const name = node.ref ? enumTypeName({
1257
+ resolver: this.options.resolver,
1258
+ name: refName,
1259
+ enumOptions: this.options.enum,
1260
+ isEnum: !!this.options.enumSchemaNames?.has(refName)
1261
+ }) : refName;
1468
1262
  return createTypeReferenceNode(name, void 0);
1469
1263
  },
1470
1264
  enum(node) {
@@ -1472,8 +1266,13 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1472
1266
  if (this.options.enum.type === "inlineLiteral" || !node.name || isInlineConstEnum(node, this.options.enumSchemaNames)) return createUnionDeclaration({
1473
1267
  withParentheses: true,
1474
1268
  nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
1475
- }) ?? void 0;
1476
- 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);
1269
+ });
1270
+ const resolvedName = enumTypeName({
1271
+ resolver: this.options.resolver,
1272
+ name: node.name,
1273
+ enumOptions: this.options.enum,
1274
+ isEnum: true
1275
+ });
1477
1276
  return createTypeReferenceNode(resolvedName, void 0);
1478
1277
  },
1479
1278
  union(node) {
@@ -1491,30 +1290,30 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1491
1290
  });
1492
1291
  return this.transform(m);
1493
1292
  }).filter(isNonNullable)
1494
- }) ?? void 0;
1293
+ });
1495
1294
  return createUnionDeclaration({
1496
1295
  withParentheses: true,
1497
1296
  nodes: buildMemberNodes(members, this.transform)
1498
- }) ?? void 0;
1297
+ });
1499
1298
  },
1500
1299
  intersection(node) {
1501
1300
  return createIntersectionDeclaration({
1502
1301
  withParentheses: true,
1503
1302
  nodes: buildMemberNodes(node.members, this.transform)
1504
- }) ?? null;
1303
+ });
1505
1304
  },
1506
1305
  array(node) {
1507
1306
  return createArrayDeclaration({
1508
1307
  nodes: mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(isNonNullable),
1509
1308
  arrayType: this.options.arrayType
1510
- }) ?? null;
1309
+ });
1511
1310
  },
1512
1311
  tuple(node) {
1513
- return buildTupleNode(node, this.transform) ?? null;
1312
+ return buildTupleNode(node, this.transform);
1514
1313
  },
1515
1314
  object(node) {
1516
1315
  const { transform, options } = this;
1517
- const addsQuestionToken = OPTIONAL_ADDS_QUESTION_TOKEN.has(options.optionalType);
1316
+ const addsQuestionToken = options.optionalType === "questionToken" || options.optionalType === "questionTokenAndUndefined";
1518
1317
  const propertyNodes = mapSchemaProperties(node, (schema) => transform(schema)).map(({ name, property, output }) => {
1519
1318
  const baseType = output ?? keywordTypeNodes.unknown;
1520
1319
  const optional = !property.required || !!property.schema.optional || !!property.schema.nullish;
@@ -1542,24 +1341,21 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1542
1341
  if (!transformed) return null;
1543
1342
  const meta = (0, kubb_kit.syncSchemaRef)(node);
1544
1343
  if (!name) {
1545
- const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [transformed, keywordTypeNodes.null] }) : transformed;
1546
- const result = (meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
1344
+ const result = wrapNullableOptional(transformed, !!meta.nullable, !!(meta.nullish || meta.optional) && addsUndefined);
1547
1345
  return (0, _kubb_parser_ts.parserTs)().print(result);
1548
1346
  }
1549
1347
  const inner = (() => {
1550
- const omitted = keysToOmit?.length ? createOmitDeclaration({
1348
+ return wrapNullableOptional(keysToOmit?.length ? createOmitDeclaration({
1551
1349
  keys: keysToOmit,
1552
1350
  type: transformed,
1553
1351
  nonNullable: true
1554
- }) : transformed;
1555
- const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [omitted, keywordTypeNodes.null] }) : omitted;
1556
- return meta.nullish || meta.optional ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
1352
+ }) : transformed, !!meta.nullable, !!(meta.nullish || meta.optional));
1557
1353
  })();
1558
1354
  const typeNode = createTypeDeclaration({
1559
1355
  name,
1560
1356
  isExportable: true,
1561
1357
  type: inner,
1562
- syntax: syntaxType === "type" || inner.kind === syntaxKind.union || !!keysToOmit?.length ? "type" : "interface",
1358
+ syntax: syntaxType === "type" || isUnionTypeNode(inner) || !!keysToOmit?.length ? "type" : "interface",
1563
1359
  comments: buildPropertyJSDocComments({
1564
1360
  ...meta,
1565
1361
  description
@@ -1572,15 +1368,6 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1572
1368
  //#endregion
1573
1369
  //#region src/generators/typeGenerator.tsx
1574
1370
  /**
1575
- * Resolves the imported type name for a referenced schema. An enum schema emitted
1576
- * as a `const` object imports its suffixed key alias (e.g. `StatusKey`); every other
1577
- * schema imports its plain resolved name.
1578
- */
1579
- function resolveImportName({ schemaName, enumOptions, enumSchemaNames, resolver }) {
1580
- if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
1581
- return resolver.name(schemaName);
1582
- }
1583
- /**
1584
1371
  * Built-in generator for `@kubb/plugin-ts`. Emits one TypeScript file per
1585
1372
  * schema in the spec plus per-operation request, response, and parameter
1586
1373
  * types. Drop-replace with a custom `Generator<PluginTs>` to change how
@@ -1594,11 +1381,11 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1594
1381
  const { config, resolver, root } = ctx;
1595
1382
  if (!node.name) return;
1596
1383
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1597
- const importName = (schemaName) => resolveImportName({
1598
- schemaName,
1384
+ const importName = (schemaName) => enumTypeName({
1385
+ resolver,
1386
+ name: schemaName,
1599
1387
  enumOptions,
1600
- enumSchemaNames,
1601
- resolver
1388
+ isEnum: enumSchemaNames.has(schemaName)
1602
1389
  });
1603
1390
  const imports = resolver.imports({
1604
1391
  node,
@@ -1610,7 +1397,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1610
1397
  const enumNode = kubb_kit.ast.narrowSchema(node, kubb_kit.ast.schemaTypes.enum);
1611
1398
  const isEnumSchema = !!enumNode && !isInlineConstEnum(enumNode, enumSchemaNames);
1612
1399
  const meta = {
1613
- name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolver.name(node.name),
1400
+ name: enumOptions.type === "asConst" && isEnumSchema ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolver.name(node.name),
1614
1401
  file: resolver.file({
1615
1402
  name: node.name,
1616
1403
  extname: ".ts",
@@ -1681,11 +1468,11 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1681
1468
  group: group ?? void 0
1682
1469
  }) };
1683
1470
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1684
- const importName = (schemaName) => resolveImportName({
1685
- schemaName,
1471
+ const importName = (schemaName) => enumTypeName({
1472
+ resolver,
1473
+ name: schemaName,
1686
1474
  enumOptions,
1687
- enumSchemaNames,
1688
- resolver
1475
+ isEnum: enumSchemaNames.has(schemaName)
1689
1476
  });
1690
1477
  function renderSchemaType({ schema, name, keysToOmit }) {
1691
1478
  if (!schema) return null;
@@ -1808,7 +1595,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1808
1595
  if (!node.responses.some(hasSchema)) return null;
1809
1596
  const responseName = resolver.response.response(node);
1810
1597
  const responsesWithSchema = node.responses.filter(hasSchema);
1811
- if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? collectRefNames(entry.schema).map(importName) : []))).has(responseName)) return null;
1598
+ if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? kubb_kit.ast.collectImportedRefNames(entry.schema).map(importName) : []))).has(responseName)) return null;
1812
1599
  return renderSchemaType({
1813
1600
  schema: {
1814
1601
  ...buildResponseUnion(node, { resolver }),
@@ -1853,11 +1640,11 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1853
1640
  //#region kubb-extension.json
1854
1641
  var compatibility = {
1855
1642
  "kubb": ">=5.8.3",
1856
- "node": ">=22"
1643
+ "node": ">=22.12"
1857
1644
  };
1858
1645
  //#endregion
1859
1646
  //#region package.json
1860
- var version = "5.0.11";
1647
+ var version = "5.0.14";
1861
1648
  //#endregion
1862
1649
  //#region src/resolvers/resolverTs.ts
1863
1650
  /**
@@ -2135,6 +1922,15 @@ function createFunctionParameters(props = {}) {
2135
1922
  //#endregion
2136
1923
  //#region src/printers/functionPrinter.ts
2137
1924
  /**
1925
+ * Ordering priority for function parameters: lower = sorted earlier.
1926
+ */
1927
+ const PARAM_RANK = {
1928
+ required: 0,
1929
+ optional: 1,
1930
+ withDefault: 2,
1931
+ rest: 3
1932
+ };
1933
+ /**
2138
1934
  * Renders a {@link TypeExpression} to its TypeScript source.
2139
1935
  *
2140
1936
  * - a `string` is a type reference, returned as-is
@@ -2155,13 +1951,17 @@ function renderType(type, transformType) {
2155
1951
  function renderKey(name) {
2156
1952
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
2157
1953
  }
1954
+ function renderMembers(members) {
1955
+ return `{ ${members.map((member) => `${renderKey(member.key)}${member.optional ? "?" : ""}: ${member.type}`).join("; ")} }`;
1956
+ }
2158
1957
  function renderTypeExpression(type) {
2159
1958
  if (typeof type === "string") return type;
2160
1959
  if (isIndexedAccessType(type)) return `${type.target}['${type.key}']`;
2161
- return `{ ${type.members.map((member) => {
2162
- const value = renderTypeExpression(member.type);
2163
- return member.optional ? `${renderKey(member.name)}?: ${value}` : `${renderKey(member.name)}: ${value}`;
2164
- }).join("; ")} }`;
1960
+ return renderMembers(type.members.map((member) => ({
1961
+ key: member.name,
1962
+ type: renderTypeExpression(member.type),
1963
+ optional: member.optional
1964
+ })));
2165
1965
  }
2166
1966
  function groupMembers(param) {
2167
1967
  if (typeof param.name === "string") return null;
@@ -2174,9 +1974,6 @@ function rank(param) {
2174
1974
  if (members) return members.every((m) => m.optional) ? PARAM_RANK.optional : PARAM_RANK.required;
2175
1975
  return param.optional ? PARAM_RANK.optional : PARAM_RANK.required;
2176
1976
  }
2177
- function sortParams(params) {
2178
- return params.toSorted((a, b) => rank(a) - rank(b));
2179
- }
2180
1977
  function sortedGroupMembers(name, type) {
2181
1978
  const members = type && isTypeLiteral(type) ? type.members : [];
2182
1979
  const memberRank = (optional) => optional ? PARAM_RANK.optional : PARAM_RANK.required;
@@ -2205,11 +2002,11 @@ function renderGroupType(type, sorted, transformType) {
2205
2002
  if (!isTypeLiteral(type)) return renderType(type);
2206
2003
  const typed = sorted.filter((member) => member.type !== void 0);
2207
2004
  if (!typed.length) return void 0;
2208
- return `{ ${typed.map((member) => {
2209
- const key = renderKey(member.propertyName ?? member.name);
2210
- const value = renderType(member.type, transformType);
2211
- return member.optional ? `${key}?: ${value}` : `${key}: ${value}`;
2212
- }).join("; ")} }`;
2005
+ return renderMembers(typed.map((member) => ({
2006
+ key: member.propertyName ?? member.name,
2007
+ type: renderType(member.type, transformType),
2008
+ optional: member.optional
2009
+ })));
2213
2010
  }
2214
2011
  function printParameter(node, options) {
2215
2012
  const { mode, transformName, transformType } = options;
@@ -2262,190 +2059,11 @@ function functionPrinter(options) {
2262
2059
  name: "functionParameters",
2263
2060
  options,
2264
2061
  print(node) {
2265
- return sortParams(node.params).map((p) => printParameter(p, options)).filter(Boolean).join(", ");
2062
+ return node.params.toSorted((a, b) => rank(a) - rank(b)).map((p) => printParameter(p, options)).filter(Boolean).join(", ");
2266
2063
  }
2267
2064
  };
2268
2065
  }
2269
2066
  //#endregion
2270
- //#region src/printers/operationParams.ts
2271
- /**
2272
- * Resolves the {@link TypeExpression} for an individual parameter.
2273
- *
2274
- * Without a resolver, it falls back to the schema primitive (a plain type-name string). When the
2275
- * parameter belongs to a named group, it emits an `IndexedAccessType` like `GroupParams['petId']`,
2276
- * otherwise the resolved individual name.
2277
- */
2278
- function resolveParamType({ node, param, resolver }) {
2279
- if (!resolver) return param.schema.primitive ?? "unknown";
2280
- const individualName = resolver.param.name(node, param);
2281
- const groupLocation = param.in === "path" || param.in === "query" || param.in === "header" ? param.in : void 0;
2282
- const groupResolvers = {
2283
- path: resolver.param.path,
2284
- query: resolver.param.query,
2285
- header: resolver.param.headers
2286
- };
2287
- const groupName = groupLocation ? groupResolvers[groupLocation].call(resolver, node, param) : void 0;
2288
- if (groupName && groupName !== individualName) return createIndexedAccessType({
2289
- target: groupName,
2290
- key: param.name
2291
- });
2292
- return individualName;
2293
- }
2294
- /**
2295
- * Derives a {@link ParamGroupType} for a query or header group from the resolver.
2296
- *
2297
- * Returns `null` when there is no resolver, no params, or the group name equals the
2298
- * individual param name (so there is no real group to emit).
2299
- */
2300
- function resolveGroupType({ node, params, group, resolver }) {
2301
- if (!resolver || !params.length) return null;
2302
- const firstParam = params[0];
2303
- const groupName = (group === "query" ? resolver.param.query : resolver.param.headers).call(resolver, node, firstParam);
2304
- if (groupName === resolver.param.name(node, firstParam)) return null;
2305
- return {
2306
- type: groupName,
2307
- optional: params.every((p) => !p.required)
2308
- };
2309
- }
2310
- /**
2311
- * Converts an `OperationNode` into function parameters for code generation.
2312
- *
2313
- * Centralizes parameter grouping logic for all plugins. `paramsType` chooses between one
2314
- * destructured object parameter (`object`) and separate top-level parameters (`inline`), while
2315
- * `pathParamsType` controls how path params render in inline mode. Provide a `resolver` for type
2316
- * name resolution and `extraParams` for plugin-specific trailing parameters such as an `options` object.
2317
- */
2318
- function createOperationParams(node, options) {
2319
- const { paramsType, pathParamsType, resolver, pathParamsDefault, extraParams = [], paramNames, typeWrapper } = options;
2320
- const dataName = paramNames?.data ?? "data";
2321
- const paramsName = paramNames?.params ?? "params";
2322
- const headersName = paramNames?.headers ?? "headers";
2323
- const pathName = paramNames?.path ?? "pathParams";
2324
- const wrapType = (type) => typeWrapper ? typeWrapper(type) : type;
2325
- const wrapTypeExpression = (type) => typeof type === "string" ? wrapType(type) : type;
2326
- const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node);
2327
- const toProperty = (param) => ({
2328
- name: param.name,
2329
- type: wrapTypeExpression(resolveParamType({
2330
- node,
2331
- param,
2332
- resolver
2333
- })),
2334
- optional: !param.required
2335
- });
2336
- const emptyObjectDefault = (props) => props.every((p) => p.optional) ? "{}" : void 0;
2337
- const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.response.body(node) ?? "unknown") : void 0;
2338
- const bodyProperty = bodyType ? [{
2339
- name: dataName,
2340
- type: bodyType,
2341
- optional: !(node.requestBody?.required ?? false)
2342
- }] : [];
2343
- const trailingGroups = [{
2344
- name: paramsName,
2345
- node,
2346
- params: queryParams,
2347
- groupType: resolveGroupType({
2348
- node,
2349
- params: queryParams,
2350
- group: "query",
2351
- resolver
2352
- }),
2353
- resolver,
2354
- wrapType
2355
- }, {
2356
- name: headersName,
2357
- node,
2358
- params: headerParams,
2359
- groupType: resolveGroupType({
2360
- node,
2361
- params: headerParams,
2362
- group: "header",
2363
- resolver
2364
- }),
2365
- resolver,
2366
- wrapType
2367
- }];
2368
- const params = [];
2369
- if (paramsType === "object") {
2370
- const children = [
2371
- ...pathParams.map(toProperty),
2372
- ...bodyProperty,
2373
- ...trailingGroups.flatMap(buildGroupProperty)
2374
- ];
2375
- if (children.length) params.push(createFunctionParameter({
2376
- properties: children,
2377
- default: emptyObjectDefault(children)
2378
- }));
2379
- } else {
2380
- if (pathParamsType === "inlineSpread" && pathParams.length) {
2381
- const spreadType = resolver?.param.path(node, pathParams[0]);
2382
- params.push(createFunctionParameter({
2383
- name: pathName,
2384
- type: spreadType ? wrapType(spreadType) : void 0,
2385
- rest: true
2386
- }));
2387
- } else if (pathParamsType === "inline") params.push(...pathParams.map((p) => createFunctionParameter(toProperty(p))));
2388
- else if (pathParams.length) {
2389
- const pathChildren = pathParams.map(toProperty);
2390
- params.push(createFunctionParameter({
2391
- properties: pathChildren,
2392
- default: pathParamsDefault ?? emptyObjectDefault(pathChildren)
2393
- }));
2394
- }
2395
- params.push(...bodyProperty.map((p) => createFunctionParameter(p)));
2396
- params.push(...trailingGroups.flatMap(buildGroupParam));
2397
- }
2398
- params.push(...extraParams);
2399
- return createFunctionParameters({ params });
2400
- }
2401
- /**
2402
- * Builds the property descriptor for a query or header group.
2403
- * Returns an empty array when there are no params to emit.
2404
- *
2405
- * A pre-resolved `groupType` emits `name: GroupType`. Otherwise it builds an inline
2406
- * {@link TypeLiteralNode} from the individual params.
2407
- */
2408
- function buildGroupProperty({ name, node, params, groupType, resolver, wrapType }) {
2409
- if (groupType) return [{
2410
- name,
2411
- type: typeof groupType.type === "string" ? wrapType(groupType.type) : groupType.type,
2412
- optional: groupType.optional
2413
- }];
2414
- if (params.length) return [{
2415
- name,
2416
- type: buildTypeLiteral({
2417
- node,
2418
- params,
2419
- resolver
2420
- }),
2421
- optional: params.every((p) => !p.required)
2422
- }];
2423
- return [];
2424
- }
2425
- /**
2426
- * Builds a single {@link FunctionParameterNode} for a query or header group.
2427
- * Returns an empty array when there are no params to emit.
2428
- */
2429
- function buildGroupParam(args) {
2430
- return buildGroupProperty(args).map((p) => createFunctionParameter(p));
2431
- }
2432
- /**
2433
- * Builds a {@link TypeLiteralNode} for an inline anonymous type grouping named fields.
2434
- *
2435
- * Used when query or header parameters have no dedicated group type name.
2436
- */
2437
- function buildTypeLiteral({ node, params, resolver }) {
2438
- return createTypeLiteral({ members: params.map((p) => ({
2439
- name: p.name,
2440
- type: resolveParamType({
2441
- node,
2442
- param: p,
2443
- resolver
2444
- }),
2445
- optional: !p.required
2446
- })) });
2447
- }
2448
- //#endregion
2449
2067
  exports.Enum = Enum;
2450
2068
  exports.Type = Type;
2451
2069
  exports.buildParams = buildParams;
@@ -2453,9 +2071,9 @@ exports.createFunctionParameter = createFunctionParameter;
2453
2071
  exports.createFunctionParameters = createFunctionParameters;
2454
2072
  exports.createIndexedAccessType = createIndexedAccessType;
2455
2073
  exports.createObjectBindingPattern = createObjectBindingPattern;
2456
- exports.createOperationParams = createOperationParams;
2457
2074
  exports.createTypeLiteral = createTypeLiteral;
2458
2075
  exports.default = pluginTs;
2076
+ exports.enumTypeName = enumTypeName;
2459
2077
  exports.functionPrinter = functionPrinter;
2460
2078
  exports.pluginTs = pluginTs;
2461
2079
  exports.pluginTsName = pluginTsName;