@kubb/plugin-ts 5.0.4 → 5.0.6

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.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as __name } from "./rolldown-runtime-CNktS9qV.js";
1
+ import { n as __name } from "./rolldown-runtime-CthDji9g.js";
2
2
  import { KubbReactNode } from "kubb/jsx";
3
3
  import { Exclude, Group, Include, Output, OutputOptions, Override, PluginFactoryOptions, Resolver, ResolverPatch, ast } from "kubb/kit";
4
4
  import ts from "typescript";
@@ -298,7 +298,6 @@ type EnumOptions$1 = {
298
298
  * site (`'inlineLiteral'`).
299
299
  *
300
300
  * @default 'asConst'
301
- * @note In Kubb v5, 'inlineLiteral' becomes the default.
302
301
  */
303
302
  type?: 'literal' | 'inlineLiteral';
304
303
  /**
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { n as __name, t as __exportAll } from "./rolldown-runtime-CNktS9qV.js";
1
+ import { n as __name, t as __exportAll } from "./rolldown-runtime-CthDji9g.js";
2
+ import { createRequire } from "node:module";
2
3
  import { parserTs } from "@kubb/parser-ts";
3
4
  import { File, jsxRenderer } from "kubb/jsx";
4
- import { Resolver, ast, createResolver, defineGenerator, definePlugin, isStringType, syncSchemaRef } from "kubb/kit";
5
- import ts from "typescript";
5
+ import { Resolver, assertPluginOption, ast, createResolver, defineGenerator, definePlugin, isStringType, syncSchemaRef } from "kubb/kit";
6
6
  import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
7
7
  //#region ../../internals/utils/src/casing.ts
8
8
  /**
@@ -362,7 +362,12 @@ var factory_exports = /* @__PURE__ */ __exportAll({
362
362
  modifiers: () => modifiers,
363
363
  syntaxKind: () => syntaxKind
364
364
  });
365
- const { SyntaxKind, factory } = ts;
365
+ /**
366
+ * Loaded with `require`, not `import`. When ESM imports a CommonJS package, Node keeps a second
367
+ * copy of its source to detect named exports, and for TypeScript that copy is about 9 MB.
368
+ */
369
+ const typescript = createRequire(import.meta.url)("typescript");
370
+ const { SyntaxKind, factory } = typescript;
366
371
  /**
367
372
  * Compares two strings by UTF-16 code unit, keeping sorted output identical across platforms
368
373
  * regardless of locale.
@@ -379,10 +384,10 @@ function isNumber(value) {
379
384
  * TypeScript AST modifiers for common keywords (async, export, const, static).
380
385
  */
381
386
  const modifiers = {
382
- async: factory.createModifier(ts.SyntaxKind.AsyncKeyword),
383
- export: factory.createModifier(ts.SyntaxKind.ExportKeyword),
384
- const: factory.createModifier(ts.SyntaxKind.ConstKeyword),
385
- static: factory.createModifier(ts.SyntaxKind.StaticKeyword)
387
+ async: factory.createModifier(typescript.SyntaxKind.AsyncKeyword),
388
+ export: factory.createModifier(typescript.SyntaxKind.ExportKeyword),
389
+ const: factory.createModifier(typescript.SyntaxKind.ConstKeyword),
390
+ static: factory.createModifier(typescript.SyntaxKind.StaticKeyword)
386
391
  };
387
392
  /**
388
393
  * TypeScript syntax kind constants for union, literal, and string types.
@@ -399,10 +404,10 @@ __name(isNonNullable$1, "isNonNullable");
399
404
  function isValidIdentifier(str) {
400
405
  if (!str.length || str.trim() !== str) return false;
401
406
  let ch = str.codePointAt(0);
402
- if (!ts.isIdentifierStart(ch, ts.ScriptTarget.Latest)) return false;
407
+ if (!typescript.isIdentifierStart(ch, typescript.ScriptTarget.Latest)) return false;
403
408
  for (let i = ch > 65535 ? 2 : 1; i < str.length; i += ch > 65535 ? 2 : 1) {
404
409
  ch = str.codePointAt(i);
405
- if (!ts.isIdentifierPart(ch, ts.ScriptTarget.Latest)) return false;
410
+ if (!typescript.isIdentifierPart(ch, typescript.ScriptTarget.Latest)) return false;
406
411
  }
407
412
  return true;
408
413
  }
@@ -410,7 +415,7 @@ function propertyName(name) {
410
415
  if (typeof name === "string") return isValidIdentifier(name) ? factory.createIdentifier(name) : factory.createStringLiteral(name);
411
416
  return name;
412
417
  }
413
- const questionToken = factory.createToken(ts.SyntaxKind.QuestionToken);
418
+ const questionToken = factory.createToken(typescript.SyntaxKind.QuestionToken);
414
419
  /**
415
420
  * Creates a question token for optional type annotations.
416
421
  * Pass `true` to use the cached token, or provide a pre-created token.
@@ -470,7 +475,7 @@ function createUnionDeclaration({ nodes, withParentheses }) {
470
475
  * Supports optional markers, readonly modifiers, and type annotations.
471
476
  */
472
477
  function createPropertySignature({ readOnly, modifiers = [], name, questionToken, type }) {
473
- return factory.createPropertySignature([...modifiers, readOnly ? factory.createToken(ts.SyntaxKind.ReadonlyKeyword) : void 0].filter((modifier) => modifier !== void 0), propertyName(name), createQuestionToken(questionToken), type);
478
+ return factory.createPropertySignature([...modifiers, readOnly ? factory.createToken(typescript.SyntaxKind.ReadonlyKeyword) : void 0].filter((modifier) => modifier !== void 0), propertyName(name), createQuestionToken(questionToken), type);
474
479
  }
475
480
  /**
476
481
  * Creates a function parameter declaration with optional markers, rest parameters, and type annotations.
@@ -501,13 +506,13 @@ function appendJSDocToNode({ node, comments }) {
501
506
  const text = filteredComments.reduce((acc = "", comment = "") => {
502
507
  return `${acc}\n * ${comment.replaceAll("*/", "*\\/")}`;
503
508
  }, "*");
504
- return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, `${text || "*"}\n`, true);
509
+ return typescript.addSyntheticLeadingComment(node, typescript.SyntaxKind.MultiLineCommentTrivia, `${text || "*"}\n`, true);
505
510
  }
506
511
  /**
507
512
  * Creates a TypeScript index signature for dynamic property access.
508
513
  * Defines the key type (default: `string`) and value type on an object.
509
514
  */
510
- function createIndexSignature(type, { modifiers, indexName = "key", indexType = factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword) } = {}) {
515
+ function createIndexSignature(type, { modifiers, indexName = "key", indexType = factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword) } = {}) {
511
516
  return factory.createIndexSignature(modifiers, [createParameterSignature(indexName, { type: indexType })], type);
512
517
  }
513
518
  /**
@@ -527,7 +532,7 @@ function createInterfaceDeclaration({ modifiers, name, typeParameters, members }
527
532
  * Intelligently selects the syntax based on the type structure and attaches JSDoc comments.
528
533
  */
529
534
  function createTypeDeclaration({ syntax, isExportable, comments, name, type }) {
530
- if (syntax === "interface" && ts.isTypeLiteralNode(type)) return appendJSDocToNode({
535
+ if (syntax === "interface" && typescript.isTypeLiteralNode(type)) return appendJSDocToNode({
531
536
  node: createInterfaceDeclaration({
532
537
  members: [...type.members],
533
538
  modifiers: isExportable ? [modifiers.export] : [],
@@ -616,18 +621,18 @@ function applyEnumKeyCasing(key, casing = "none") {
616
621
  * ```
617
622
  */
618
623
  function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCasing = "none" }) {
619
- if (type === "literal" || type === "inlineLiteral") return [void 0, factory.createTypeAliasDeclaration([factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createUnionTypeNode(enums.map(([_key, value]) => {
624
+ 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]) => {
620
625
  if (isNumber(value)) {
621
- if (value < 0) return factory.createLiteralTypeNode(factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value))));
626
+ if (value < 0) return factory.createLiteralTypeNode(factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value))));
622
627
  return factory.createLiteralTypeNode(factory.createNumericLiteral(value?.toString()));
623
628
  }
624
629
  if (typeof value === "boolean") return factory.createLiteralTypeNode(value ? factory.createTrue() : factory.createFalse());
625
630
  if (value !== null && value !== void 0) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
626
631
  }).filter((node) => node !== void 0)))];
627
- if (type === "enum" || type === "constEnum") return [void 0, factory.createEnumDeclaration([factory.createToken(ts.SyntaxKind.ExportKeyword), type === "constEnum" ? factory.createToken(ts.SyntaxKind.ConstKeyword) : void 0].filter((modifier) => modifier !== void 0), factory.createIdentifier(typeName), enums.map(([key, value, description]) => {
632
+ 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]) => {
628
633
  let initializer = factory.createStringLiteral(value?.toString());
629
634
  if (Number.parseInt(value.toString(), 10) === value && isNumber(value)) {
630
- if (value < 0) initializer = factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
635
+ if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
631
636
  else initializer = factory.createNumericLiteral(value);
632
637
  }
633
638
  if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
@@ -647,11 +652,11 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
647
652
  }
648
653
  }).filter((member) => member !== void 0))];
649
654
  const identifierName = name;
650
- if (enums.length === 0) return [void 0, factory.createTypeAliasDeclaration([factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword))];
651
- return [factory.createVariableStatement([factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier(identifierName), void 0, void 0, factory.createAsExpression(factory.createObjectLiteralExpression(enums.map(([key, value, description]) => {
655
+ if (enums.length === 0) return [void 0, factory.createTypeAliasDeclaration([factory.createToken(typescript.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createKeywordTypeNode(typescript.SyntaxKind.NeverKeyword))];
656
+ 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]) => {
652
657
  let initializer = factory.createStringLiteral(value?.toString());
653
658
  if (isNumber(value)) {
654
- if (value < 0) initializer = factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
659
+ if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
655
660
  else initializer = factory.createNumericLiteral(value);
656
661
  }
657
662
  if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
@@ -662,7 +667,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
662
667
  comments: [description]
663
668
  });
664
669
  }
665
- }).filter((property) => property !== void 0), true), factory.createTypeReferenceNode(factory.createIdentifier("const"), void 0)))], ts.NodeFlags.Const)), factory.createTypeAliasDeclaration([factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createIndexedAccessTypeNode(factory.createParenthesizedType(factory.createTypeQueryNode(factory.createIdentifier(identifierName), void 0)), factory.createTypeOperatorNode(ts.SyntaxKind.KeyOfKeyword, factory.createTypeQueryNode(factory.createIdentifier(identifierName), void 0))))];
670
+ }).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))))];
666
671
  }
667
672
  /**
668
673
  * Creates a TypeScript `Omit<T, Keys>` type reference node.
@@ -680,18 +685,18 @@ function createOmitDeclaration({ keys, type, nonNullable }) {
680
685
  * Use these to avoid repeatedly creating the same type nodes.
681
686
  */
682
687
  const keywordTypeNodes = {
683
- any: factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),
684
- unknown: factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword),
685
- void: factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword),
686
- number: factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
687
- integer: factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
688
- bigint: factory.createKeywordTypeNode(ts.SyntaxKind.BigIntKeyword),
689
- object: factory.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword),
690
- string: factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
691
- boolean: factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword),
692
- undefined: factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),
693
- null: factory.createLiteralTypeNode(factory.createToken(ts.SyntaxKind.NullKeyword)),
694
- never: factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword)
688
+ any: factory.createKeywordTypeNode(typescript.SyntaxKind.AnyKeyword),
689
+ unknown: factory.createKeywordTypeNode(typescript.SyntaxKind.UnknownKeyword),
690
+ void: factory.createKeywordTypeNode(typescript.SyntaxKind.VoidKeyword),
691
+ number: factory.createKeywordTypeNode(typescript.SyntaxKind.NumberKeyword),
692
+ integer: factory.createKeywordTypeNode(typescript.SyntaxKind.NumberKeyword),
693
+ bigint: factory.createKeywordTypeNode(typescript.SyntaxKind.BigIntKeyword),
694
+ object: factory.createKeywordTypeNode(typescript.SyntaxKind.ObjectKeyword),
695
+ string: factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword),
696
+ boolean: factory.createKeywordTypeNode(typescript.SyntaxKind.BooleanKeyword),
697
+ undefined: factory.createKeywordTypeNode(typescript.SyntaxKind.UndefinedKeyword),
698
+ null: factory.createLiteralTypeNode(factory.createToken(typescript.SyntaxKind.NullKeyword)),
699
+ never: factory.createKeywordTypeNode(typescript.SyntaxKind.NeverKeyword)
695
700
  };
696
701
  /**
697
702
  * Converts a path like '/pet/{petId}/uploadImage' to a template literal type
@@ -714,15 +719,15 @@ function createUrlTemplateType(path) {
714
719
  parts.push(segment);
715
720
  } else if (segment) parts.push(segment);
716
721
  });
717
- const head = ts.factory.createTemplateHead(parts[0] || "");
722
+ const head = typescript.factory.createTemplateHead(parts[0] || "");
718
723
  const templateSpans = [];
719
724
  parameterIndices.forEach((paramIndex, i) => {
720
725
  const isLast = i === parameterIndices.length - 1;
721
726
  const nextPart = parts[paramIndex + 1] || "";
722
- const literal = isLast ? ts.factory.createTemplateTail(nextPart) : ts.factory.createTemplateMiddle(nextPart);
723
- templateSpans.push(ts.factory.createTemplateLiteralTypeSpan(keywordTypeNodes.string, literal));
727
+ const literal = isLast ? typescript.factory.createTemplateTail(nextPart) : typescript.factory.createTemplateMiddle(nextPart);
728
+ templateSpans.push(typescript.factory.createTemplateLiteralTypeSpan(keywordTypeNodes.string, literal));
724
729
  });
725
- return ts.factory.createTemplateLiteralType(head, templateSpans);
730
+ return typescript.factory.createTemplateLiteralType(head, templateSpans);
726
731
  }
727
732
  /**
728
733
  * Creates a TypeScript type literal node (anonymous object type).
@@ -827,8 +832,8 @@ function buildPropertyType(schema, baseType, optionalType, optional) {
827
832
  if ((optional || meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
828
833
  return type;
829
834
  }
830
- const indexSignaturePrinter = ts.createPrinter();
831
- const indexSignatureSource = ts.createSourceFile("", "", ts.ScriptTarget.Latest);
835
+ const indexSignaturePrinter = typescript.createPrinter();
836
+ const indexSignatureSource = typescript.createSourceFile("", "", typescript.ScriptTarget.Latest);
832
837
  /**
833
838
  * Creates a TypeScript index signature for `additionalProperties` and `patternProperties` on an
834
839
  * object schema node. TypeScript allows only one string index signature and its value must be
@@ -847,7 +852,7 @@ function buildIndexSignatures(node, propertyCount, print) {
847
852
  if (valueTypes.length === 0) return [];
848
853
  const seen = /* @__PURE__ */ new Set();
849
854
  const distinct = valueTypes.filter((type) => {
850
- const key = indexSignaturePrinter.printNode(ts.EmitHint.Unspecified, type, indexSignatureSource);
855
+ const key = indexSignaturePrinter.printNode(typescript.EmitHint.Unspecified, type, indexSignatureSource);
851
856
  return seen.has(key) ? false : (seen.add(key), true);
852
857
  });
853
858
  return [createIndexSignature(propertyCount > 0 ? keywordTypeNodes.unknown : createUnionDeclaration({ nodes: distinct }))];
@@ -1312,7 +1317,7 @@ function buildPropertyJSDocComments(schema, optional) {
1312
1317
  !isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` : null,
1313
1318
  !isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` : null,
1314
1319
  meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : null,
1315
- meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" && typeof meta.default === "string" ? stringify(meta.default) : meta.default}` : null,
1320
+ meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" && typeof meta.default === "string" ? stringify(meta.default) : formatExample(meta.default)}` : null,
1316
1321
  ...exampleValues.map((example) => `@example ${formatExample(example)}`)
1317
1322
  ].filter(Boolean);
1318
1323
  const typeTag = comments.length && meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null;
@@ -1870,6 +1875,53 @@ const resolverTs = createResolver({
1870
1875
  * cross-plugin dependency references.
1871
1876
  */
1872
1877
  const pluginTsName = "plugin-ts";
1878
+ const allowedEnumTypes = [
1879
+ "asConst",
1880
+ "enum",
1881
+ "constEnum",
1882
+ "literal",
1883
+ "inlineLiteral"
1884
+ ];
1885
+ const allowedSyntaxTypes = ["type", "interface"];
1886
+ const allowedArrayTypes = ["array", "generic"];
1887
+ const allowedOptionalTypes = [
1888
+ "questionToken",
1889
+ "undefined",
1890
+ "questionTokenAndUndefined"
1891
+ ];
1892
+ /**
1893
+ * Throws when an enum-like option holds a value outside its allowed set. Options left out are skipped.
1894
+ */
1895
+ function assertEnumLikeOptions({ prefix, options }) {
1896
+ const checks = [
1897
+ {
1898
+ option: "enum.type",
1899
+ value: options.enum?.type,
1900
+ allowed: allowedEnumTypes
1901
+ },
1902
+ {
1903
+ option: "syntaxType",
1904
+ value: options.syntaxType,
1905
+ allowed: allowedSyntaxTypes
1906
+ },
1907
+ {
1908
+ option: "arrayType",
1909
+ value: options.arrayType,
1910
+ allowed: allowedArrayTypes
1911
+ },
1912
+ {
1913
+ option: "optionalType",
1914
+ value: options.optionalType,
1915
+ allowed: allowedOptionalTypes
1916
+ }
1917
+ ];
1918
+ for (const { option, value, allowed } of checks) if (value !== void 0) assertPluginOption({
1919
+ plugin: pluginTsName,
1920
+ option: `${prefix}${option}`,
1921
+ value,
1922
+ allowed
1923
+ });
1924
+ }
1873
1925
  /**
1874
1926
  * Generates TypeScript `type` aliases and `interface` declarations from an
1875
1927
  * OpenAPI spec. The foundation that every other Kubb plugin builds on:
@@ -1910,6 +1962,19 @@ const pluginTs = definePlugin((options) => {
1910
1962
  name: pluginTsName,
1911
1963
  options,
1912
1964
  hooks: { "kubb:plugin:setup"(ctx) {
1965
+ assertEnumLikeOptions({
1966
+ prefix: "",
1967
+ options: {
1968
+ enum: resolvedEnum,
1969
+ syntaxType,
1970
+ arrayType,
1971
+ optionalType
1972
+ }
1973
+ });
1974
+ for (const [index, entry] of override.entries()) assertEnumLikeOptions({
1975
+ prefix: `override[${index}].options.`,
1976
+ options: entry.options
1977
+ });
1913
1978
  ctx.setOptions({
1914
1979
  output,
1915
1980
  exclude,