@kubb/plugin-ts 5.1.0-canary.20261023T200213 → 5.1.0

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
@@ -18,11 +18,11 @@ var __exportAll = (all, no_symbols) => {
18
18
  return target;
19
19
  };
20
20
  //#endregion
21
- let _kubb_parser_ts = require("@kubb/parser-ts");
22
21
  let kubb_jsx = require("kubb/jsx");
23
- let node_module = require("node:module");
24
22
  let kubb_kit = require("kubb/kit");
23
+ let yuku_codegen = require("yuku-codegen");
25
24
  let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
25
+ let _kubb_parser_ts = require("@kubb/parser-ts");
26
26
  //#region ../../internals/utils/src/casing.ts
27
27
  /**
28
28
  * Shared implementation for camelCase and PascalCase conversion.
@@ -322,6 +322,7 @@ var factory_exports = /* @__PURE__ */ __exportAll({
322
322
  createIntersectionDeclaration: () => createIntersectionDeclaration,
323
323
  createOmitDeclaration: () => createOmitDeclaration,
324
324
  createPropertySignature: () => createPropertySignature,
325
+ createRaw: () => createRaw,
325
326
  createTypeDeclaration: () => createTypeDeclaration,
326
327
  createTypeLiteralNode: () => createTypeLiteralNode,
327
328
  createTypeReferenceNode: () => createTypeReferenceNode,
@@ -329,84 +330,113 @@ var factory_exports = /* @__PURE__ */ __exportAll({
329
330
  createUrlTemplateType: () => createUrlTemplateType,
330
331
  dateOrStringNode: () => dateOrStringNode,
331
332
  isNonNullable: () => isNonNullable$1,
332
- isUnionTypeNode: () => isUnionTypeNode,
333
333
  keywordTypeNodes: () => keywordTypeNodes,
334
- modifiers: () => modifiers,
334
+ print: () => print,
335
335
  wrapNullableOptional: () => wrapNullableOptional
336
336
  });
337
- /**
338
- * Loaded with `require`, not `import`. When ESM imports a CommonJS package, Node keeps a second
339
- * copy of its source to detect named exports, and for TypeScript that copy is about 9 MB.
340
- */
341
- const typescript = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href)("@typescript/typescript6");
342
- const { SyntaxKind, factory } = typescript;
343
337
  function isNumber(value) {
344
338
  return typeof value === "number" && !Number.isNaN(value);
345
339
  }
346
- /**
347
- * TypeScript AST modifiers for the `export` keyword.
348
- */
349
- const modifiers = { export: factory.createModifier(typescript.SyntaxKind.ExportKeyword) };
350
- const isUnionTypeNode = typescript.isUnionTypeNode;
351
340
  function isNonNullable$1(value) {
352
341
  return value !== null && value !== void 0;
353
342
  }
354
343
  __name(isNonNullable$1, "isNonNullable");
355
- function isValidIdentifier(str) {
356
- if (!str.length || str.trim() !== str) return false;
357
- let ch = str.codePointAt(0);
358
- if (!typescript.isIdentifierStart(ch, typescript.ScriptTarget.Latest)) return false;
359
- for (let i = ch > 65535 ? 2 : 1; i < str.length; i += ch > 65535 ? 2 : 1) {
360
- ch = str.codePointAt(i);
361
- if (!typescript.isIdentifierPart(ch, typescript.ScriptTarget.Latest)) return false;
362
- }
363
- return true;
344
+ /**
345
+ * Prints `node` as TypeScript source with single quotes and two-space indentation.
346
+ */
347
+ function print(node) {
348
+ return (0, yuku_codegen.generate)(node, { quotes: "single" }).code;
349
+ }
350
+ /**
351
+ * Wraps already printed TypeScript, such as a user override result, so it can sit inside a node tree.
352
+ * Parentheses keep a union or function type intact when it lands inside an array or intersection.
353
+ */
354
+ function createRaw(text) {
355
+ const name = {
356
+ type: "TSTypeReference",
357
+ typeName: identifier(text),
358
+ typeArguments: null
359
+ };
360
+ return /[|&?]|=>/.test(text) ? {
361
+ type: "TSParenthesizedType",
362
+ typeAnnotation: name
363
+ } : name;
364
+ }
365
+ function identifier(name) {
366
+ return {
367
+ type: "Identifier",
368
+ name
369
+ };
370
+ }
371
+ function literal(value) {
372
+ return {
373
+ type: "Literal",
374
+ value
375
+ };
376
+ }
377
+ function createLiteralType(value) {
378
+ return {
379
+ type: "TSLiteralType",
380
+ literal: literal(value)
381
+ };
382
+ }
383
+ /**
384
+ * Whether `name` can be written as a bare property name instead of a quoted string.
385
+ */
386
+ function isValidIdentifier(name) {
387
+ return /^[\p{ID_Start}$_][\p{ID_Continue}$‌‍]*$/u.test(name);
364
388
  }
389
+ /**
390
+ * A property or enum member name, quoted when it is not a valid identifier.
391
+ */
365
392
  function propertyName(name) {
366
- if (typeof name === "string") return isValidIdentifier(name) ? factory.createIdentifier(name) : factory.createStringLiteral(name);
367
- return name;
393
+ return isValidIdentifier(name) ? identifier(name) : literal(name);
368
394
  }
369
- const questionToken = factory.createToken(typescript.SyntaxKind.QuestionToken);
370
395
  /**
371
- * Creates a question token for optional type annotations.
372
- * Pass `true` to use the cached token, or provide a pre-created token.
396
+ * Indents every non-empty line of `text` by two spaces.
373
397
  */
374
- function createQuestionToken(token) {
375
- if (!token) return;
376
- if (token === true) return questionToken;
377
- return token;
398
+ function indent(text) {
399
+ return text.split("\n").map((line) => line ? ` ${line}` : line).join("\n");
378
400
  }
379
401
  /**
380
- * Creates a TypeScript intersection type node from multiple type nodes.
381
- * Returns the single node if only one is provided, or wraps in parentheses if requested.
402
+ * Creates a TypeScript intersection type.
403
+ * Returns the single type if only one is provided. `yuku-codegen` adds the parentheses a union member needs.
382
404
  */
383
405
  function createIntersectionDeclaration({ nodes, withParentheses }) {
384
406
  if (!nodes.length) return null;
385
407
  if (nodes.length === 1) return nodes[0] || null;
386
- const node = factory.createIntersectionTypeNode(nodes);
387
- if (withParentheses) return factory.createParenthesizedType(node);
388
- return node;
408
+ const node = {
409
+ type: "TSIntersectionType",
410
+ types: nodes
411
+ };
412
+ return withParentheses ? {
413
+ type: "TSParenthesizedType",
414
+ typeAnnotation: node
415
+ } : node;
389
416
  }
390
417
  /**
391
- * Creates a TypeScript array type node.
418
+ * Creates a TypeScript array type.
392
419
  * Use `arrayType: 'array'` for bracket syntax (`T[]`), or `'generic'` for `Array<T>`.
393
420
  *
394
421
  * @example Array bracket syntax
395
- * `createArrayDeclaration({ nodes: [stringType], arrayType: 'array' }) // → string[]`
422
+ * `createArrayDeclaration({ nodes: [string], arrayType: 'array' }) // → string[]`
396
423
  *
397
424
  * @example Generic Array syntax
398
- * `createArrayDeclaration({ nodes: [stringType], arrayType: 'generic' }) // → Array<string>`
425
+ * `createArrayDeclaration({ nodes: [string], arrayType: 'generic' }) // → Array<string>`
399
426
  */
400
427
  function createArrayDeclaration({ nodes, arrayType = "array" }) {
401
- if (!nodes.length) return factory.createTupleTypeNode([]);
402
- if (nodes.length === 1) {
403
- const node = nodes[0];
404
- if (arrayType === "generic") return factory.createTypeReferenceNode(factory.createIdentifier("Array"), [node]);
405
- return factory.createArrayTypeNode(node);
406
- }
407
- const unionType = factory.createUnionTypeNode(nodes);
408
- if (arrayType === "generic") return factory.createTypeReferenceNode(factory.createIdentifier("Array"), [unionType]);
409
- return factory.createArrayTypeNode(factory.createParenthesizedType(unionType));
428
+ if (!nodes.length) return {
429
+ type: "TSTupleType",
430
+ elementTypes: []
431
+ };
432
+ const node = nodes.length === 1 ? nodes[0] : {
433
+ type: "TSUnionType",
434
+ types: nodes
435
+ };
436
+ return arrayType === "generic" ? createTypeReferenceNode("Array", [node]) : {
437
+ type: "TSArrayType",
438
+ elementType: node
439
+ };
410
440
  }
411
441
  /**
412
442
  * Minimum nodes length of 2
@@ -416,60 +446,115 @@ function createArrayDeclaration({ nodes, arrayType = "array" }) {
416
446
  function createUnionDeclaration({ nodes, withParentheses }) {
417
447
  if (!nodes.length) return keywordTypeNodes.any;
418
448
  if (nodes.length === 1) return nodes[0];
419
- const node = factory.createUnionTypeNode(nodes);
420
- if (withParentheses) return factory.createParenthesizedType(node);
421
- return node;
449
+ const node = {
450
+ type: "TSUnionType",
451
+ types: nodes
452
+ };
453
+ return withParentheses ? {
454
+ type: "TSParenthesizedType",
455
+ typeAnnotation: node
456
+ } : node;
422
457
  }
423
458
  /**
424
459
  * Creates a TypeScript property signature for object/interface members.
425
460
  * Supports optional markers, readonly modifiers, and type annotations.
426
461
  */
427
- function createPropertySignature({ readOnly, modifiers = [], name, questionToken, type }) {
428
- return factory.createPropertySignature([...modifiers, readOnly ? factory.createToken(typescript.SyntaxKind.ReadonlyKeyword) : void 0].filter((modifier) => modifier !== void 0), propertyName(name), createQuestionToken(questionToken), type);
462
+ function createPropertySignature({ readOnly, name, questionToken, type }) {
463
+ return {
464
+ type: "TSPropertySignature",
465
+ key: propertyName(name),
466
+ computed: false,
467
+ optional: !!questionToken,
468
+ readonly: !!readOnly,
469
+ static: false,
470
+ typeAnnotation: type ? {
471
+ type: "TSTypeAnnotation",
472
+ typeAnnotation: type
473
+ } : null
474
+ };
429
475
  }
430
476
  /**
431
- * Attaches JSDoc comments to an AST node as synthetic leading comments.
432
- * Filters out undefined comments before attaching.
433
- *
434
- * @see https://github.com/microsoft/TypeScript/issues/44151
477
+ * Attaches a JSDoc block built from `comments` to `node`, dropping empty comments.
435
478
  */
436
479
  function appendJSDocToNode({ node, comments }) {
437
- const filteredComments = comments.filter(Boolean);
438
- if (!filteredComments.length) return node;
439
- const text = filteredComments.flatMap((comment = "") => comment.split(/\r?\n/)).reduce((acc = "", comment = "") => {
440
- return `${acc}\n * ${comment.replaceAll("*/", "*\\/")}`;
441
- }, "*");
442
- return typescript.addSyntheticLeadingComment(node, typescript.SyntaxKind.MultiLineCommentTrivia, `${text || "*"}\n`, true);
480
+ const lines = comments.filter(Boolean).flatMap((comment = "") => comment.split(/\r?\n/));
481
+ if (!lines.length) return node;
482
+ const value = `*\n${lines.map((line) => ` * ${line.replaceAll("*/", "*\\/")}`.trimEnd()).join("\n")}\n `;
483
+ return {
484
+ ...node,
485
+ comments: [{
486
+ type: "Block",
487
+ value,
488
+ position: "before",
489
+ sameLine: false
490
+ }]
491
+ };
443
492
  }
444
493
  /**
445
- * Creates a TypeScript index signature for dynamic property access.
446
- * Defines the key type (default: `string`) and value type on an object.
494
+ * Creates a TypeScript type literal (anonymous object type) with one member per line.
447
495
  */
448
- function createIndexSignature(type, { modifiers, indexName = "key", indexType = factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword) } = {}) {
449
- return factory.createIndexSignature(modifiers, [factory.createParameterDeclaration(void 0, void 0, indexName, void 0, indexType)], type);
496
+ function createTypeLiteralNode(members) {
497
+ return {
498
+ type: "TSTypeLiteral",
499
+ members
500
+ };
501
+ }
502
+ /**
503
+ * Creates a TypeScript type reference (e.g., `Array<string>`, `Record<K, V>`).
504
+ */
505
+ function createTypeReferenceNode(name, typeArguments) {
506
+ return {
507
+ type: "TSTypeReference",
508
+ typeName: identifier(name),
509
+ typeArguments: typeArguments?.length ? {
510
+ type: "TSTypeParameterInstantiation",
511
+ params: typeArguments
512
+ } : null
513
+ };
514
+ }
515
+ function exportNamed(declaration, exportKind) {
516
+ return {
517
+ type: "ExportNamedDeclaration",
518
+ declaration,
519
+ specifiers: [],
520
+ source: null,
521
+ attributes: [],
522
+ exportKind
523
+ };
450
524
  }
451
525
  /**
452
- * Creates a TypeScript type declaration as either a type alias or interface.
453
- * Intelligently selects the syntax based on the type structure and attaches JSDoc comments.
526
+ * Prints a TypeScript type declaration as either a type alias or interface.
527
+ * Uses interface syntax only when requested and the type is an object literal, and attaches JSDoc comments.
454
528
  */
455
529
  function createTypeDeclaration({ syntax, isExportable, comments, name, type }) {
456
- if (syntax === "interface" && typescript.isTypeLiteralNode(type)) return appendJSDocToNode({
457
- node: factory.createInterfaceDeclaration(isExportable ? [modifiers.export] : [], name, void 0, void 0, [...type.members]),
458
- comments
459
- });
460
- return appendJSDocToNode({
461
- node: factory.createTypeAliasDeclaration(isExportable ? [modifiers.export] : [], name, void 0, type),
530
+ const declaration = syntax === "interface" && type.type === "TSTypeLiteral" ? {
531
+ type: "TSInterfaceDeclaration",
532
+ declare: false,
533
+ id: identifier(name),
534
+ typeParameters: null,
535
+ extends: [],
536
+ body: {
537
+ type: "TSInterfaceBody",
538
+ body: type.members
539
+ }
540
+ } : {
541
+ type: "TSTypeAliasDeclaration",
542
+ declare: false,
543
+ id: identifier(name),
544
+ typeParameters: null,
545
+ typeAnnotation: type
546
+ };
547
+ return print(appendJSDocToNode({
548
+ node: isExportable ? exportNamed(declaration, "type") : declaration,
462
549
  comments
463
- });
550
+ }));
464
551
  }
465
552
  /**
466
- * Converts an enum member value to a literal expression. Numbers become numeric literals (negatives use a prefix
467
- * minus, as `createNumericLiteral` rejects them) unless `asNumber` is `false`, which emits the string form.
553
+ * Converts an enum member value to a literal. Numbers become numeric literals unless `asNumber` is `false`,
554
+ * which emits the string form.
468
555
  */
469
556
  function valueToExpression(value, asNumber = isNumber(value)) {
470
- if (typeof value === "boolean") return value ? factory.createTrue() : factory.createFalse();
471
- if (asNumber && isNumber(value)) return value < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value))) : factory.createNumericLiteral(value);
472
- return factory.createStringLiteral(value.toString());
557
+ return literal(typeof value === "boolean" || asNumber && isNumber(value) ? value : value.toString());
473
558
  }
474
559
  /**
475
560
  * Apply casing transformation to enum keys
@@ -484,7 +569,7 @@ function applyEnumKeyCasing(key, casing = "none") {
484
569
  }
485
570
  /**
486
571
  * Creates a TypeScript enum declaration or equivalent construct in various formats.
487
- * Returns a tuple of [name node, type node] - name node may be undefined for certain types.
572
+ * Returns a tuple of [name declaration, type declaration] - the name declaration may be undefined for certain types.
488
573
  *
489
574
  * @example
490
575
  * ```ts
@@ -497,126 +582,135 @@ function applyEnumKeyCasing(key, casing = "none") {
497
582
  * ```
498
583
  */
499
584
  function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCasing = "none" }) {
500
- if (type === "literal" || type === "inlineLiteral") return [void 0, factory.createTypeAliasDeclaration([factory.createToken(typescript.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createUnionTypeNode(enums.map(([_key, value]) => {
501
- if (isNumber(value)) {
502
- if (value < 0) return factory.createLiteralTypeNode(factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value))));
503
- return factory.createLiteralTypeNode(factory.createNumericLiteral(value?.toString()));
504
- }
505
- if (typeof value === "boolean") return factory.createLiteralTypeNode(value ? factory.createTrue() : factory.createFalse());
506
- if (value !== null && value !== void 0) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
507
- }).filter((node) => node !== void 0)))];
508
- 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]) => {
509
- const initializer = valueToExpression(value, Number.parseInt(value.toString(), 10) === value);
510
- if (isNumber(Number.parseInt(key.toString(), 10))) {
511
- const casingKey = applyEnumKeyCasing(`${typeName}_${key}`, enumKeyCasing);
512
- return appendJSDocToNode({
513
- node: factory.createEnumMember(propertyName(casingKey), initializer),
514
- comments: [description]
515
- });
516
- }
517
- if (key !== null && key !== void 0) {
518
- const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
585
+ const typeAlias = (annotation) => createTypeDeclaration({
586
+ syntax: "type",
587
+ isExportable: true,
588
+ name: typeName,
589
+ comments: [],
590
+ type: annotation
591
+ });
592
+ if (type === "literal" || type === "inlineLiteral") {
593
+ const members = enums.map(([_key, value]) => isNonNullable$1(value) ? {
594
+ type: "TSLiteralType",
595
+ literal: valueToExpression(value)
596
+ } : void 0).filter(isNonNullable$1);
597
+ return [void 0, typeAlias(members.length ? createUnionDeclaration({ nodes: members }) : keywordTypeNodes.never)];
598
+ }
599
+ if (type === "enum" || type === "constEnum") {
600
+ const members = enums.map(([key, value, description]) => {
601
+ const initializer = valueToExpression(value, Number.parseInt(value.toString(), 10) === value);
602
+ const memberName = isNumber(Number.parseInt(key.toString(), 10)) ? `${typeName}_${key}` : key?.toString();
603
+ if (memberName === void 0) return void 0;
519
604
  return appendJSDocToNode({
520
- node: factory.createEnumMember(propertyName(casingKey), initializer),
605
+ node: {
606
+ type: "TSEnumMember",
607
+ id: propertyName(applyEnumKeyCasing(memberName, enumKeyCasing)),
608
+ initializer
609
+ },
521
610
  comments: [description]
522
611
  });
523
- }
524
- }).filter((member) => member !== void 0))];
612
+ }).filter(isNonNullable$1);
613
+ return [void 0, print(exportNamed({
614
+ type: "TSEnumDeclaration",
615
+ declare: false,
616
+ const: type === "constEnum",
617
+ id: identifier(typeName),
618
+ body: {
619
+ type: "TSEnumBody",
620
+ members
621
+ }
622
+ }, "value"))];
623
+ }
525
624
  const identifierName = name;
526
- if (enums.length === 0) return [void 0, factory.createTypeAliasDeclaration([factory.createToken(typescript.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createKeywordTypeNode(typescript.SyntaxKind.NeverKeyword))];
527
- 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]) => {
528
- const initializer = valueToExpression(value);
529
- if (key !== null && key !== void 0) {
530
- const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
531
- return appendJSDocToNode({
532
- node: factory.createPropertyAssignment(propertyName(casingKey), initializer),
533
- comments: [description]
534
- });
625
+ if (enums.length === 0) return [void 0, typeAlias(keywordTypeNodes.never)];
626
+ const properties = enums.map(([key, value, description]) => {
627
+ if (key === null || key === void 0) return void 0;
628
+ return print(appendJSDocToNode({
629
+ node: {
630
+ type: "Property",
631
+ kind: "init",
632
+ key: propertyName(applyEnumKeyCasing(key.toString(), enumKeyCasing)),
633
+ value: valueToExpression(value),
634
+ computed: false,
635
+ method: false,
636
+ shorthand: false
637
+ },
638
+ comments: [description]
639
+ }));
640
+ }).filter(isNonNullable$1);
641
+ const query = {
642
+ type: "TSTypeQuery",
643
+ exprName: identifier(identifierName),
644
+ typeArguments: null
645
+ };
646
+ return [`export const ${identifierName} = {\n${properties.map(indent).join(",\n")},\n} as const;`, typeAlias({
647
+ type: "TSIndexedAccessType",
648
+ objectType: {
649
+ type: "TSParenthesizedType",
650
+ typeAnnotation: query
651
+ },
652
+ indexType: {
653
+ type: "TSTypeOperator",
654
+ operator: "keyof",
655
+ typeAnnotation: query
535
656
  }
536
- }).filter((property) => property !== void 0), true), factory.createTypeReferenceNode(factory.createIdentifier("const"), void 0)))], typescript.NodeFlags.Const)), factory.createTypeAliasDeclaration([factory.createToken(typescript.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createIndexedAccessTypeNode(factory.createParenthesizedType(factory.createTypeQueryNode(factory.createIdentifier(identifierName), void 0)), factory.createTypeOperatorNode(typescript.SyntaxKind.KeyOfKeyword, factory.createTypeQueryNode(factory.createIdentifier(identifierName), void 0))))];
657
+ })];
537
658
  }
538
659
  /**
539
- * Creates a TypeScript `Omit<T, Keys>` type reference node.
660
+ * Creates a TypeScript `Omit<T, Keys>` type reference.
540
661
  * Optionally wraps the type in `NonNullable<T>` if `nonNullable` is true.
541
662
  */
542
663
  function createOmitDeclaration({ keys, type, nonNullable }) {
543
- const node = nonNullable ? factory.createTypeReferenceNode(factory.createIdentifier("NonNullable"), [type]) : type;
544
- if (Array.isArray(keys)) return factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [node, factory.createUnionTypeNode(keys.map((key) => {
545
- return factory.createLiteralTypeNode(factory.createStringLiteral(key));
546
- }))]);
547
- return factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [node, factory.createLiteralTypeNode(factory.createStringLiteral(keys))]);
664
+ return createTypeReferenceNode("Omit", [nonNullable ? createTypeReferenceNode("NonNullable", [type]) : type, createUnionDeclaration({ nodes: [keys].flat().map(createLiteralType) })]);
548
665
  }
549
666
  /**
550
- * Pre-built TypeScript keyword type nodes for common primitive types.
551
- * Use these to avoid repeatedly creating the same type nodes.
667
+ * TypeScript keyword types for common primitive types.
552
668
  */
553
669
  const keywordTypeNodes = {
554
- any: factory.createKeywordTypeNode(typescript.SyntaxKind.AnyKeyword),
555
- unknown: factory.createKeywordTypeNode(typescript.SyntaxKind.UnknownKeyword),
556
- void: factory.createKeywordTypeNode(typescript.SyntaxKind.VoidKeyword),
557
- number: factory.createKeywordTypeNode(typescript.SyntaxKind.NumberKeyword),
558
- integer: factory.createKeywordTypeNode(typescript.SyntaxKind.NumberKeyword),
559
- bigint: factory.createKeywordTypeNode(typescript.SyntaxKind.BigIntKeyword),
560
- object: factory.createKeywordTypeNode(typescript.SyntaxKind.ObjectKeyword),
561
- string: factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword),
562
- boolean: factory.createKeywordTypeNode(typescript.SyntaxKind.BooleanKeyword),
563
- undefined: factory.createKeywordTypeNode(typescript.SyntaxKind.UndefinedKeyword),
564
- null: factory.createLiteralTypeNode(factory.createToken(typescript.SyntaxKind.NullKeyword)),
565
- never: factory.createKeywordTypeNode(typescript.SyntaxKind.NeverKeyword)
670
+ any: { type: "TSAnyKeyword" },
671
+ unknown: { type: "TSUnknownKeyword" },
672
+ void: { type: "TSVoidKeyword" },
673
+ number: { type: "TSNumberKeyword" },
674
+ integer: { type: "TSNumberKeyword" },
675
+ bigint: { type: "TSBigIntKeyword" },
676
+ object: { type: "TSObjectKeyword" },
677
+ string: { type: "TSStringKeyword" },
678
+ boolean: { type: "TSBooleanKeyword" },
679
+ undefined: { type: "TSUndefinedKeyword" },
680
+ null: { type: "TSNullKeyword" },
681
+ never: { type: "TSNeverKeyword" }
566
682
  };
567
683
  /**
568
- * Converts a path like '/pet/{petId}/uploadImage' to a template literal type
569
- * like `/pet/${string}/uploadImage`
570
- */
571
- /**
572
684
  * Converts an OAS-style path (e.g. `/pets/{petId}`) or an Express-style path
573
685
  * (e.g. `/pets/:petId`) to a TypeScript template literal type
574
686
  * like `` `/pets/${string}` ``.
575
687
  */
576
688
  function createUrlTemplateType(path) {
577
689
  const normalized = path.replace(/:([^/]+)/g, "{$1}");
578
- if (!normalized.includes("{")) return factory.createLiteralTypeNode(factory.createStringLiteral(normalized));
579
- const segments = normalized.split(/(\{[^}]+\})/);
580
- const parts = [];
581
- const parameterIndices = [];
582
- segments.forEach((segment) => {
583
- if (segment.startsWith("{") && segment.endsWith("}")) {
584
- parameterIndices.push(parts.length);
585
- parts.push(segment);
586
- } else if (segment) parts.push(segment);
587
- });
588
- const head = typescript.factory.createTemplateHead(parts[0] || "");
589
- const templateSpans = [];
590
- parameterIndices.forEach((paramIndex, i) => {
591
- const isLast = i === parameterIndices.length - 1;
592
- const nextPart = parts[paramIndex + 1] || "";
593
- const literal = isLast ? typescript.factory.createTemplateTail(nextPart) : typescript.factory.createTemplateMiddle(nextPart);
594
- templateSpans.push(typescript.factory.createTemplateLiteralTypeSpan(keywordTypeNodes.string, literal));
595
- });
596
- return typescript.factory.createTemplateLiteralType(head, templateSpans);
690
+ if (!normalized.includes("{")) return createLiteralType(normalized);
691
+ const segments = normalized.split(/\{[^}]+\}/);
692
+ return {
693
+ type: "TSTemplateLiteralType",
694
+ quasis: segments.map((cooked, i) => ({
695
+ type: "TemplateElement",
696
+ value: { cooked },
697
+ tail: i === segments.length - 1
698
+ })),
699
+ types: segments.slice(1).map(() => keywordTypeNodes.string)
700
+ };
597
701
  }
598
702
  /**
599
- * Creates a TypeScript type literal node (anonymous object type).
600
- */
601
- const createTypeLiteralNode = factory.createTypeLiteralNode;
602
- /**
603
- * Creates a TypeScript type reference node (e.g., `Array<string>`, `Record<K, V>`).
604
- */
605
- const createTypeReferenceNode = factory.createTypeReferenceNode;
606
- /**
607
- * Converts a primitive const value to a TypeScript literal type node.
608
- * Handles negative numbers via a prefix unary expression.
703
+ * Converts a primitive const value to a TypeScript literal type.
609
704
  */
610
705
  function constToTypeNode(value, format) {
611
- if (format === "boolean") return factory.createLiteralTypeNode(value === true ? factory.createTrue() : factory.createFalse());
612
- const literal = format === "number" && typeof value === "number" ? value : String(value);
613
- return factory.createLiteralTypeNode(valueToExpression(literal));
706
+ if (format === "boolean") return createLiteralType(value === true);
707
+ return createLiteralType(format === "number" && typeof value === "number" ? value : String(value));
614
708
  }
615
709
  /**
616
- * Returns a `Date` reference type node when `representation` is `'date'`, otherwise falls back to `string`.
710
+ * Returns a `Date` reference type when `representation` is `'date'`, otherwise falls back to `string`.
617
711
  */
618
712
  function dateOrStringNode(node) {
619
- return node.representation === "date" ? createTypeReferenceNode(factory.createIdentifier("Date")) : keywordTypeNodes.string;
713
+ return node.representation === "date" ? createTypeReferenceNode("Date") : keywordTypeNodes.string;
620
714
  }
621
715
  /**
622
716
  * Maps an array of `SchemaNode`s through the printer, filtering out `null` and `undefined` results.
@@ -625,7 +719,7 @@ function buildMemberNodes(members, print) {
625
719
  return (members ?? []).map(print).filter(isNonNullable$1);
626
720
  }
627
721
  /**
628
- * Builds a TypeScript tuple type node from an array schema's `items`,
722
+ * Builds a TypeScript tuple type from an array schema's `items`,
629
723
  * applying min/max slice and optional/rest element rules.
630
724
  */
631
725
  function buildTupleNode(node, print) {
@@ -636,9 +730,21 @@ function buildTupleNode(node, print) {
636
730
  items = items.slice(0, max);
637
731
  if (items.length < max && restNode) items = [...items, ...Array(max - items.length).fill(restNode)];
638
732
  }
639
- if (min !== void 0) items = items.map((item, i) => i >= min ? factory.createOptionalTypeNode(item) : item);
640
- if (max === void 0 && restNode) items.push(factory.createRestTypeNode(factory.createArrayTypeNode(restNode)));
641
- return factory.createTupleTypeNode(items);
733
+ if (min !== void 0) items = items.map((item, i) => i >= min ? {
734
+ type: "TSOptionalType",
735
+ typeAnnotation: item
736
+ } : item);
737
+ if (max === void 0 && restNode) items.push({
738
+ type: "TSRestType",
739
+ typeAnnotation: {
740
+ type: "TSArrayType",
741
+ elementType: restNode
742
+ }
743
+ });
744
+ return {
745
+ type: "TSTupleType",
746
+ elementTypes: items
747
+ };
642
748
  }
643
749
  /**
644
750
  * Appends `| null` and then `| undefined` to a type when requested.
@@ -655,8 +761,6 @@ function buildPropertyType(schema, baseType, optionalType, optional) {
655
761
  const meta = (0, kubb_kit.syncSchemaRef)(schema);
656
762
  return wrapNullableOptional(baseType, !!meta.nullable, addsUndefined && !!(optional || meta.nullish || meta.optional));
657
763
  }
658
- const indexSignaturePrinter = typescript.createPrinter();
659
- const indexSignatureSource = typescript.createSourceFile("", "", typescript.ScriptTarget.Latest);
660
764
  /**
661
765
  * Creates a TypeScript index signature for `additionalProperties` and `patternProperties` on an
662
766
  * object schema node. TypeScript allows only one string index signature and its value must be
@@ -664,21 +768,35 @@ const indexSignatureSource = typescript.createSourceFile("", "", typescript.Scri
664
768
  * union of all value types (deduplicated), or `unknown` when the object also has fixed properties.
665
769
  * The key regex of `patternProperties` cannot be expressed by an index signature and is dropped.
666
770
  */
667
- function buildIndexSignatures(node, propertyCount, print) {
771
+ function buildIndexSignatures(node, propertyCount, printNode) {
668
772
  const valueTypes = [];
669
- if (node.additionalProperties && node.additionalProperties !== true) valueTypes.push(print(node.additionalProperties) ?? keywordTypeNodes.unknown);
773
+ if (node.additionalProperties && node.additionalProperties !== true) valueTypes.push(printNode(node.additionalProperties) ?? keywordTypeNodes.unknown);
670
774
  else if (node.additionalProperties === true) valueTypes.push(keywordTypeNodes.unknown);
671
775
  for (const schema of Object.values(node.patternProperties ?? {})) {
672
- const patternType = print(schema) ?? keywordTypeNodes.unknown;
776
+ const patternType = printNode(schema) ?? keywordTypeNodes.unknown;
673
777
  valueTypes.push(schema.nullable ? createUnionDeclaration({ nodes: [patternType, keywordTypeNodes.null] }) : patternType);
674
778
  }
675
779
  if (valueTypes.length === 0) return [];
676
- const seen = /* @__PURE__ */ new Set();
677
- const distinct = valueTypes.filter((type) => {
678
- const key = indexSignaturePrinter.printNode(typescript.EmitHint.Unspecified, type, indexSignatureSource);
679
- return seen.has(key) ? false : (seen.add(key), true);
680
- });
681
- return [createIndexSignature(propertyCount > 0 ? keywordTypeNodes.unknown : createUnionDeclaration({ nodes: distinct }))];
780
+ const distinct = [...new Map(valueTypes.map((type) => [print(type), type])).values()];
781
+ const valueType = propertyCount > 0 ? keywordTypeNodes.unknown : createUnionDeclaration({ nodes: distinct });
782
+ return [{
783
+ type: "TSIndexSignature",
784
+ parameters: [{
785
+ type: "Identifier",
786
+ name: "key",
787
+ typeAnnotation: {
788
+ type: "TSTypeAnnotation",
789
+ typeAnnotation: keywordTypeNodes.string
790
+ }
791
+ }],
792
+ typeAnnotation: {
793
+ type: "TSTypeAnnotation",
794
+ typeAnnotation: valueType
795
+ },
796
+ readonly: false,
797
+ static: false,
798
+ accessibility: null
799
+ }];
682
800
  }
683
801
  //#endregion
684
802
  //#region src/components/Enum.tsx
@@ -730,12 +848,14 @@ function Enum({ node, enum: enumOptions, resolver }) {
730
848
  const namesMerge = !!nameNode && enumName === typeName;
731
849
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [nameNode && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
732
850
  name: enumName,
851
+ pointer: node.pointer,
733
852
  isExportable: true,
734
853
  isIndexable: true,
735
854
  isTypeOnly: false,
736
- children: (0, _kubb_parser_ts.parserTs)().print(nameNode)
855
+ children: nameNode
737
856
  }), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
738
857
  name: typeName,
858
+ pointer: node.pointer,
739
859
  isIndexable: !namesMerge,
740
860
  isExportable: !namesMerge && enumOptions.type !== "inlineLiteral",
741
861
  isTypeOnly: [
@@ -743,7 +863,7 @@ function Enum({ node, enum: enumOptions, resolver }) {
743
863
  "literal",
744
864
  void 0
745
865
  ].includes(enumOptions.type),
746
- children: (0, _kubb_parser_ts.parserTs)().print(typeNode)
866
+ children: typeNode
747
867
  })] });
748
868
  }
749
869
  //#endregion
@@ -1137,6 +1257,7 @@ function buildPropertyJSDocComments(schema, optional) {
1137
1257
  function buildParams({ params }) {
1138
1258
  return kubb_kit.ast.factory.createSchema({
1139
1259
  type: "object",
1260
+ pointer: params[0]?.pointer?.replace(/\/\d+$/, ""),
1140
1261
  properties: params.map((param) => kubb_kit.ast.factory.createProperty({
1141
1262
  name: param.name,
1142
1263
  required: param.required,
@@ -1187,6 +1308,7 @@ function Type({ name, node, printer, enum: enumOptions, resolver }) {
1187
1308
  resolver
1188
1309
  }, node.name)), shouldExportType && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1189
1310
  name,
1311
+ pointer: node.pointer,
1190
1312
  isTypeOnly: true,
1191
1313
  isExportable: true,
1192
1314
  isIndexable: true,
@@ -1197,12 +1319,30 @@ function Type({ name, node, printer, enum: enumOptions, resolver }) {
1197
1319
  //#region src/printers/printerTs.ts
1198
1320
  const { isNonNullable } = factory_exports;
1199
1321
  /**
1322
+ * Adapts user overrides, which work in strings, to the node-based printer: `this.transform` hands them printed
1323
+ * strings and their result is wrapped back into a node. A deprecated compiler node prints through `@kubb/parser-ts`.
1324
+ */
1325
+ function toNodeHandlers(nodes) {
1326
+ return Object.fromEntries(Object.entries(nodes ?? {}).map(([type, handler]) => [type, function(node) {
1327
+ const transform = (child) => {
1328
+ const output = this.transform(child);
1329
+ return output ? print(output) : null;
1330
+ };
1331
+ const result = handler.call({
1332
+ ...this,
1333
+ transform
1334
+ }, node);
1335
+ if (result === null || result === void 0) return result;
1336
+ return createRaw(typeof result === "string" ? result : (0, _kubb_parser_ts.parserTs)().print(result).trimEnd());
1337
+ }]));
1338
+ }
1339
+ /**
1200
1340
  * TypeScript type printer built with `definePrinter`.
1201
1341
  *
1202
- * Converts a `SchemaNode` AST node into a TypeScript AST node:
1203
- * - **`printer.print(node)`** — when `options.typeName` is set, returns a full
1204
- * `type Name = …` or `interface Name { … }` declaration (`ts.Node`).
1205
- * Without `typeName`, returns the raw `ts.TypeNode` for the schema.
1342
+ * Converts a `SchemaNode` AST node into TypeScript source:
1343
+ * - **`printer.print(node)`** — when `options.name` is set, returns a full
1344
+ * `type Name = …` or `interface Name { … }` declaration.
1345
+ * Without `name`, returns the type for the schema, such as `string | null`.
1206
1346
  *
1207
1347
  * Dispatches on `node.type` to the appropriate handler in `nodes`. Options are closed
1208
1348
  * over per printer instance, so each call to `printerTs(options)` produces an independent printer.
@@ -1210,13 +1350,13 @@ const { isNonNullable } = factory_exports;
1210
1350
  * @example Raw type node (no `typeName`)
1211
1351
  * ```ts
1212
1352
  * const printer = printerTs({ optionalType: 'questionToken', arrayType: 'array', enum: { type: 'inlineLiteral' } })
1213
- * const typeNode = printer.print(schemaNode) // ts.TypeNode
1353
+ * const type = printer.print(schemaNode) // 'string | null'
1214
1354
  * ```
1215
1355
  *
1216
1356
  * @example Full declaration (with `typeName`)
1217
1357
  * ```ts
1218
1358
  * const printer = printerTs({ optionalType: 'questionToken', arrayType: 'array', enum: { type: 'inlineLiteral' }, typeName: 'MyType' })
1219
- * const declaration = printer.print(schemaNode) // ts.TypeAliasDeclaration | ts.InterfaceDeclaration
1359
+ * const declaration = printer.print(schemaNode) // 'export type MyType = …'
1220
1360
  * ```
1221
1361
  */
1222
1362
  const printerTs = kubb_kit.ast.createPrinter((options) => {
@@ -1231,7 +1371,7 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1231
1371
  never: () => keywordTypeNodes.never,
1232
1372
  boolean: () => keywordTypeNodes.boolean,
1233
1373
  null: () => keywordTypeNodes.null,
1234
- blob: () => createTypeReferenceNode("Blob", []),
1374
+ blob: () => createTypeReferenceNode("Blob"),
1235
1375
  string: () => keywordTypeNodes.string,
1236
1376
  uuid: () => keywordTypeNodes.string,
1237
1377
  email: () => keywordTypeNodes.string,
@@ -1251,27 +1391,22 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1251
1391
  if (!node.name) return null;
1252
1392
  const refName = kubb_kit.ast.resolveRefName(node);
1253
1393
  if (!refName) return null;
1254
- const name = node.ref ? enumTypeName({
1394
+ return createTypeReferenceNode(node.ref ? enumTypeName({
1255
1395
  resolver: this.options.resolver,
1256
1396
  name: refName,
1257
1397
  enumOptions: this.options.enum,
1258
1398
  isEnum: !!this.options.enumSchemaNames?.has(refName)
1259
- }) : refName;
1260
- return createTypeReferenceNode(name, void 0);
1399
+ }) : refName);
1261
1400
  },
1262
1401
  enum(node) {
1263
1402
  const values = kubb_kit.ast.getSchemaLiteralValues(node);
1264
- if (this.options.enum.type === "inlineLiteral" || !node.name || isInlineConstEnum(node, this.options.enumSchemaNames)) return createUnionDeclaration({
1265
- withParentheses: true,
1266
- nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
1267
- });
1268
- const resolvedName = enumTypeName({
1403
+ if (this.options.enum.type === "inlineLiteral" || !node.name || isInlineConstEnum(node, this.options.enumSchemaNames)) return createUnionDeclaration({ nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable) });
1404
+ return createTypeReferenceNode(enumTypeName({
1269
1405
  resolver: this.options.resolver,
1270
1406
  name: node.name,
1271
1407
  enumOptions: this.options.enum,
1272
1408
  isEnum: true
1273
- });
1274
- return createTypeReferenceNode(resolvedName, void 0);
1409
+ }));
1275
1410
  },
1276
1411
  union(node) {
1277
1412
  const members = node.members ?? [];
@@ -1279,26 +1414,14 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1279
1414
  return kubb_kit.ast.narrowSchema(m, kubb_kit.ast.schemaTypes.enum)?.primitive === "string";
1280
1415
  });
1281
1416
  const hasPlainString = members.some((m) => (0, kubb_kit.isStringType)(m));
1282
- if (hasStringLiteral && hasPlainString) return createUnionDeclaration({
1283
- withParentheses: true,
1284
- nodes: members.map((m) => {
1285
- if ((0, kubb_kit.isStringType)(m)) return createIntersectionDeclaration({
1286
- nodes: [keywordTypeNodes.string, createTypeLiteralNode([])],
1287
- withParentheses: true
1288
- });
1289
- return this.transform(m);
1290
- }).filter(isNonNullable)
1291
- });
1292
- return createUnionDeclaration({
1293
- withParentheses: true,
1294
- nodes: buildMemberNodes(members, this.transform)
1295
- });
1417
+ if (hasStringLiteral && hasPlainString) return createUnionDeclaration({ nodes: members.map((m) => {
1418
+ if ((0, kubb_kit.isStringType)(m)) return createIntersectionDeclaration({ nodes: [keywordTypeNodes.string, createTypeLiteralNode([])] });
1419
+ return this.transform(m);
1420
+ }).filter(isNonNullable) });
1421
+ return createUnionDeclaration({ nodes: buildMemberNodes(members, this.transform) });
1296
1422
  },
1297
1423
  intersection(node) {
1298
- return createIntersectionDeclaration({
1299
- withParentheses: true,
1300
- nodes: buildMemberNodes(node.members, this.transform)
1301
- });
1424
+ return createIntersectionDeclaration({ nodes: buildMemberNodes(node.members, this.transform) });
1302
1425
  },
1303
1426
  array(node) {
1304
1427
  return createArrayDeclaration({
@@ -1331,35 +1454,30 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1331
1454
  if (!allElements.length) return keywordTypeNodes.object;
1332
1455
  return createTypeLiteralNode(allElements);
1333
1456
  },
1334
- ...options.nodes
1457
+ ...toNodeHandlers(options.nodes)
1335
1458
  },
1336
1459
  print(node) {
1337
1460
  const { name, syntaxType = "type", description, keysToOmit } = this.options;
1338
1461
  const transformed = this.transform(node);
1339
1462
  if (!transformed) return null;
1340
1463
  const meta = (0, kubb_kit.syncSchemaRef)(node);
1341
- if (!name) {
1342
- const result = wrapNullableOptional(transformed, !!meta.nullable, !!(meta.nullish || meta.optional) && addsUndefined);
1343
- return (0, _kubb_parser_ts.parserTs)().print(result);
1344
- }
1345
- const inner = (() => {
1346
- return wrapNullableOptional(keysToOmit?.length ? createOmitDeclaration({
1347
- keys: keysToOmit,
1348
- type: transformed,
1349
- nonNullable: true
1350
- }) : transformed, !!meta.nullable, !!(meta.nullish || meta.optional));
1351
- })();
1352
- const typeNode = createTypeDeclaration({
1464
+ if (!name) return print(wrapNullableOptional(transformed, !!meta.nullable, !!(meta.nullish || meta.optional) && addsUndefined));
1465
+ return createTypeDeclaration({
1353
1466
  name,
1354
1467
  isExportable: true,
1355
- type: inner,
1356
- syntax: syntaxType === "type" || isUnionTypeNode(inner) || !!keysToOmit?.length ? "type" : "interface",
1468
+ type: (() => {
1469
+ return wrapNullableOptional(keysToOmit?.length ? createOmitDeclaration({
1470
+ keys: keysToOmit,
1471
+ type: transformed,
1472
+ nonNullable: true
1473
+ }) : transformed, !!meta.nullable, !!(meta.nullish || meta.optional));
1474
+ })(),
1475
+ syntax: syntaxType === "type" || !!keysToOmit?.length ? "type" : "interface",
1357
1476
  comments: buildPropertyJSDocComments({
1358
1477
  ...meta,
1359
1478
  description
1360
1479
  })
1361
1480
  });
1362
- return (0, _kubb_parser_ts.parserTs)().print(typeNode);
1363
1481
  }
1364
1482
  };
1365
1483
  });
@@ -1516,10 +1634,11 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1516
1634
  * variants by content type in {@link buildResponses}; the standalone alias stays a plain union so
1517
1635
  * query hooks and `result.data` keep the bare body.
1518
1636
  */
1519
- function buildContentTypeVariants(entries, baseName, decorate) {
1637
+ function buildContentTypeVariants(entries, baseName, pointer, decorate) {
1520
1638
  const variants = resolveContentTypeVariants(entries, baseName);
1521
1639
  const unionSchema = kubb_kit.ast.factory.createSchema({
1522
1640
  type: "union",
1641
+ pointer,
1523
1642
  members: variants.map((variant) => kubb_kit.ast.factory.createSchema({
1524
1643
  type: "ref",
1525
1644
  name: variant.name
@@ -1558,13 +1677,14 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1558
1677
  return renderSchemaType({
1559
1678
  schema: {
1560
1679
  ...entry.schema,
1680
+ pointer: node.requestBody.pointer ?? entry.schema.pointer,
1561
1681
  description: node.requestBody.description ?? entry.schema.description
1562
1682
  },
1563
1683
  name: resolver.response.body(node),
1564
1684
  keysToOmit: entry.keysToOmit
1565
1685
  });
1566
1686
  }
1567
- return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
1687
+ return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), node.requestBody.pointer, (schema) => ({
1568
1688
  ...schema,
1569
1689
  description: node.requestBody.description ?? schema.description
1570
1690
  }));
@@ -1572,10 +1692,13 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1572
1692
  const requestType = buildRequestType();
1573
1693
  const responseTypes = node.responses.map((res) => {
1574
1694
  const variants = (res.content ?? []).filter((entry) => entry.schema);
1575
- if (variants.length > 1) return buildContentTypeVariants(variants, resolver.response.status(node, res.statusCode));
1695
+ if (variants.length > 1) return buildContentTypeVariants(variants, resolver.response.status(node, res.statusCode), res.pointer);
1576
1696
  const primary = variants[0] ?? res.content?.[0];
1577
1697
  return renderSchemaType({
1578
- schema: primary?.schema ?? null,
1698
+ schema: primary?.schema ? {
1699
+ ...primary.schema,
1700
+ pointer: res.pointer ?? primary.schema.pointer
1701
+ } : null,
1579
1702
  name: resolver.response.status(node, res.statusCode),
1580
1703
  keysToOmit: primary?.keysToOmit
1581
1704
  });
@@ -1638,11 +1761,11 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1638
1761
  //#region kubb-extension.json
1639
1762
  var compatibility = {
1640
1763
  "kubb": ">=5.8.3",
1641
- "node": ">=22.12"
1764
+ "node": ">=22.22"
1642
1765
  };
1643
1766
  //#endregion
1644
1767
  //#region package.json
1645
- var version = "5.1.0-canary.20261023T200213";
1768
+ var version = "5.1.0";
1646
1769
  //#endregion
1647
1770
  //#region src/resolvers/resolverTs.ts
1648
1771
  /**