@kubb/plugin-ts 5.0.0-beta.76 → 5.0.0-beta.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -550,7 +550,7 @@ function applyEnumKeyCasing(key, casing = "none") {
550
550
  * type: 'enum',
551
551
  * name: 'petType',
552
552
  * typeName: 'PetType',
553
- * enums: [['cat', 'cat'], ['dog', 'dog']],
553
+ * enums: [['cat', 'cat', 'A cat'], ['dog', 'dog']],
554
554
  * })
555
555
  * ```
556
556
  */
@@ -563,30 +563,39 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
563
563
  if (typeof value === "boolean") return factory.createLiteralTypeNode(value ? factory.createTrue() : factory.createFalse());
564
564
  if (value !== null && value !== void 0) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
565
565
  }).filter((node) => node !== void 0)))];
566
- 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]) => {
566
+ 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]) => {
567
567
  let initializer = factory.createStringLiteral(value?.toString());
568
568
  if (Number.parseInt(value.toString(), 10) === value && isNumber(Number.parseInt(value.toString(), 10))) if (value < 0) initializer = factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
569
569
  else initializer = factory.createNumericLiteral(value);
570
570
  if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
571
571
  if (isNumber(Number.parseInt(key.toString(), 10))) {
572
572
  const casingKey = applyEnumKeyCasing(`${typeName}_${key}`, enumKeyCasing);
573
- return factory.createEnumMember(propertyName(casingKey), initializer);
573
+ return appendJSDocToNode({
574
+ node: factory.createEnumMember(propertyName(casingKey), initializer),
575
+ comments: [description]
576
+ });
574
577
  }
575
578
  if (key !== null && key !== void 0) {
576
579
  const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
577
- return factory.createEnumMember(propertyName(casingKey), initializer);
580
+ return appendJSDocToNode({
581
+ node: factory.createEnumMember(propertyName(casingKey), initializer),
582
+ comments: [description]
583
+ });
578
584
  }
579
585
  }).filter((member) => member !== void 0))];
580
586
  const identifierName = name;
581
587
  if (enums.length === 0) return [void 0, factory.createTypeAliasDeclaration([factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword))];
582
- 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]) => {
588
+ 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]) => {
583
589
  let initializer = factory.createStringLiteral(value?.toString());
584
590
  if (isNumber(value)) if (value < 0) initializer = factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
585
591
  else initializer = factory.createNumericLiteral(value);
586
592
  if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
587
593
  if (key !== null && key !== void 0) {
588
594
  const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
589
- return factory.createPropertyAssignment(propertyName(casingKey), initializer);
595
+ return appendJSDocToNode({
596
+ node: factory.createPropertyAssignment(propertyName(casingKey), initializer),
597
+ comments: [description]
598
+ });
590
599
  }
591
600
  }).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))))];
592
601
  }
@@ -817,7 +826,11 @@ function Enum({ node, enum: enumOptions, resolver }) {
817
826
  const [nameNode, typeNode] = createEnumDeclaration({
818
827
  name: enumName,
819
828
  typeName,
820
- enums: node.namedEnumValues?.map((v) => [trimQuotes(v.name.toString()), v.value]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [trimQuotes(v.toString()), v]) ?? [],
829
+ enums: node.namedEnumValues?.map((v) => [
830
+ trimQuotes(v.name.toString()),
831
+ v.value,
832
+ v.description
833
+ ]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [trimQuotes(v.toString()), v]) ?? [],
821
834
  type: enumOptions.type,
822
835
  enumKeyCasing: enumOptions.keyCasing
823
836
  });
@@ -837,39 +850,6 @@ function Enum({ node, enum: enumOptions, resolver }) {
837
850
  })] });
838
851
  }
839
852
  //#endregion
840
- //#region src/components/Type.tsx
841
- function Type({ name, node, printer, enum: enumOptions, resolver }) {
842
- const enumSchemaNodes = ast.collect(node, { schema(n) {
843
- const enumNode = ast.narrowSchema(n, ast.schemaTypes.enum);
844
- if (enumNode?.name) return enumNode;
845
- } });
846
- const output = printer.print(node);
847
- if (!output) return;
848
- const enums = [...new Map(enumSchemaNodes.map((n) => [n.name, n])).values()].map((node) => {
849
- return {
850
- node,
851
- ...getEnumNames({
852
- node,
853
- enum: enumOptions,
854
- resolver
855
- })
856
- };
857
- });
858
- const shouldExportEnums = enumOptions.type !== "inlineLiteral";
859
- const shouldExportType = enumOptions.type === "inlineLiteral" || enums.every((item) => item.typeName !== name);
860
- return /* @__PURE__ */ jsxs(Fragment, { children: [shouldExportEnums && enums.map(({ node }) => /* @__PURE__ */ jsx(Enum, {
861
- node,
862
- enum: enumOptions,
863
- resolver
864
- }, node.name)), shouldExportType && /* @__PURE__ */ jsx(File.Source, {
865
- name,
866
- isTypeOnly: true,
867
- isExportable: true,
868
- isIndexable: true,
869
- children: output
870
- })] });
871
- }
872
- //#endregion
873
853
  //#region ../../internals/shared/src/params.ts
874
854
  const caseParamsCache = /* @__PURE__ */ new WeakMap();
875
855
  /**
@@ -983,6 +963,18 @@ function createGroupConfig(group) {
983
963
  //#endregion
984
964
  //#region src/utils.ts
985
965
  /**
966
+ * Tells whether a `const` (single-value enum) should render as a bare literal type (`'active'`)
967
+ * rather than a named enum reference or a runtime enum declaration.
968
+ *
969
+ * The parser folds `const` into a single-value enum node. The adapter decides which schemas are
970
+ * named enums and lists them in `enumSchemaNames`, and references to those names get suffixed (for
971
+ * example `StatusKey`). A const renders as a literal only when the adapter has not registered it as
972
+ * a named enum, which keeps the declaration and its references in sync across adapter versions.
973
+ */
974
+ function isInlineConstEnum(node, enumSchemaNames) {
975
+ return (node.namedEnumValues ?? node.enumValues ?? []).length === 1 && !(node.name && enumSchemaNames?.has(node.name));
976
+ }
977
+ /**
986
978
  * Collects JSDoc annotation strings for a schema node.
987
979
  *
988
980
  * Only uses official JSDoc tags from https://jsdoc.app/: `@description`, `@deprecated`, `@default`, `@example`, `@type`.
@@ -1120,6 +1112,39 @@ function buildResponseUnion(node, { resolver }) {
1120
1112
  });
1121
1113
  }
1122
1114
  //#endregion
1115
+ //#region src/components/Type.tsx
1116
+ function Type({ name, node, printer, enum: enumOptions, resolver }) {
1117
+ const enumSchemaNodes = ast.collect(node, { schema(n) {
1118
+ const enumNode = ast.narrowSchema(n, ast.schemaTypes.enum);
1119
+ if (enumNode?.name && !isInlineConstEnum(enumNode, printer.options.enumSchemaNames)) return enumNode;
1120
+ } });
1121
+ const output = printer.print(node);
1122
+ if (!output) return;
1123
+ const enums = [...new Map(enumSchemaNodes.map((n) => [n.name, n])).values()].map((node) => {
1124
+ return {
1125
+ node,
1126
+ ...getEnumNames({
1127
+ node,
1128
+ enum: enumOptions,
1129
+ resolver
1130
+ })
1131
+ };
1132
+ });
1133
+ const shouldExportEnums = enumOptions.type !== "inlineLiteral";
1134
+ const shouldExportType = enumOptions.type === "inlineLiteral" || enums.every((item) => item.typeName !== name);
1135
+ return /* @__PURE__ */ jsxs(Fragment, { children: [shouldExportEnums && enums.map(({ node }) => /* @__PURE__ */ jsx(Enum, {
1136
+ node,
1137
+ enum: enumOptions,
1138
+ resolver
1139
+ }, node.name)), shouldExportType && /* @__PURE__ */ jsx(File.Source, {
1140
+ name,
1141
+ isTypeOnly: true,
1142
+ isExportable: true,
1143
+ isIndexable: true,
1144
+ children: output
1145
+ })] });
1146
+ }
1147
+ //#endregion
1123
1148
  //#region src/printers/printerTs.ts
1124
1149
  const { isNonNullable } = factory_exports;
1125
1150
  /**
@@ -1180,7 +1205,7 @@ const printerTs = ast.createPrinter((options) => {
1180
1205
  },
1181
1206
  enum(node) {
1182
1207
  const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
1183
- if (this.options.enum.type === "inlineLiteral" || !node.name) return createUnionDeclaration({
1208
+ if (this.options.enum.type === "inlineLiteral" || !node.name || isInlineConstEnum(node, this.options.enumSchemaNames)) return createUnionDeclaration({
1184
1209
  withParentheses: true,
1185
1210
  nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
1186
1211
  }) ?? void 0;
@@ -1310,7 +1335,8 @@ const typeGenerator = defineGenerator({
1310
1335
  group: group ?? void 0
1311
1336
  }).path
1312
1337
  }));
1313
- const isEnumSchema = !!ast.narrowSchema(node, ast.schemaTypes.enum);
1338
+ const enumNode = ast.narrowSchema(node, ast.schemaTypes.enum);
1339
+ const isEnumSchema = !!enumNode && !isInlineConstEnum(enumNode, enumSchemaNames);
1314
1340
  const meta = {
1315
1341
  name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.resolveEnumKeyName(node, enumOptions.typeSuffix) : resolver.resolveTypeName(node.name),
1316
1342
  file: resolver.resolveFile({