@kubb/plugin-ts 5.0.0-beta.22 → 5.0.0-beta.27

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
@@ -238,7 +238,7 @@ type EnumTypeOptions = {
238
238
  /**
239
239
  * Suffix appended to the generated type alias name.
240
240
  *
241
- * Only affects the type alias the const object name is unchanged.
241
+ * Only affects the type alias; the const object name is unchanged.
242
242
  *
243
243
  * @default 'Key'
244
244
  * @example enumTypeSuffix: 'Value' → `export type PetStatusValue = …`
@@ -293,80 +293,88 @@ type EnumTypeOptions = {
293
293
  enumTypeSuffix?: never;
294
294
  /**
295
295
  * `enumKeyCasing` has no effect for this `enumType`.
296
- * Literal and inlineLiteral modes emit only values keys are discarded entirely.
296
+ * Literal and inlineLiteral modes emit only values; keys are discarded entirely.
297
297
  */
298
298
  enumKeyCasing?: never;
299
299
  };
300
300
  type Options = {
301
301
  /**
302
- * Specify the export location for the files and define the behavior of the output
303
- * @default { path: 'types', barrelType: 'named' }
302
+ * Where the generated `.ts` files are written and how they are exported.
303
+ *
304
+ * @default { path: 'types', barrel: { type: 'named' } }
304
305
  */
305
306
  output?: Output;
306
307
  /**
307
- * Define which contentType should be used.
308
- * By default, uses the first valid JSON media type.
308
+ * Media type read from the OpenAPI spec when an operation defines several.
309
+ * Defaults to the first JSON-compatible media type Kubb finds.
309
310
  */
310
311
  contentType?: 'application/json' | (string & {});
311
312
  /**
312
- * Group the clients based on the provided name.
313
+ * Split generated files into subfolders based on the operation's tag.
313
314
  */
314
315
  group?: Group;
315
316
  /**
316
- * Array containing exclude parameters to exclude/skip tags/operations/methods/paths.
317
+ * Skip operations matching at least one entry in the list.
317
318
  */
318
319
  exclude?: Array<Exclude>;
319
320
  /**
320
- * Array containing include parameters to include tags/operations/methods/paths.
321
+ * Restrict generation to operations matching at least one entry in the list.
321
322
  */
322
323
  include?: Array<Include>;
323
324
  /**
324
- * Array containing override parameters to override `options` based on tags/operations/methods/paths.
325
+ * Apply a different options object to operations matching a pattern.
325
326
  */
326
327
  override?: Array<Override<ResolvedOptions>>;
327
328
  /**
328
- * Switch between type or interface for creating TypeScript types.
329
- * - 'type' generates type alias declarations.
330
- * - 'interface' generates interface declarations.
329
+ * Whether object schemas are emitted as `type` aliases or `interface` declarations.
330
+ * - `'type'` emits closed type aliases. Safer default for generated code.
331
+ * - `'interface'` emits interfaces. Useful when consumers rely on declaration merging.
332
+ *
331
333
  * @default 'type'
334
+ * @see https://www.totaltypescript.com/type-vs-interface-which-should-you-use
332
335
  */
333
336
  syntaxType?: 'type' | 'interface';
334
337
  /**
335
- * Choose what to use as mode for an optional value.
336
- * - 'questionToken' marks the property as optional with ? (e.g., type?: string).
337
- * - 'undefined' adds undefined to the type union (e.g., type: string | undefined).
338
- * - 'questionTokenAndUndefined' combines both approaches (e.g., type?: string | undefined).
338
+ * How optional properties are written in generated types.
339
+ * - `'questionToken'` `type?: string`. The property may be missing.
340
+ * - `'undefined'` `type: string | undefined`. Required to exist, may be `undefined`.
341
+ * - `'questionTokenAndUndefined'` `type?: string | undefined`. Strictest.
342
+ *
339
343
  * @default 'questionToken'
344
+ * @note Pick `'questionTokenAndUndefined'` when `exactOptionalPropertyTypes` is on in `tsconfig.json`.
340
345
  */
341
346
  optionalType?: 'questionToken' | 'undefined' | 'questionTokenAndUndefined';
342
347
  /**
343
- * Choose between Array<string> or string[] for array types.
344
- * - 'generic' generates Array<Type> syntax.
345
- * - 'array' generates Type[] syntax.
348
+ * Syntax used for array types.
349
+ * - `'array'` `Type[]`. Shorter.
350
+ * - `'generic'` `Array<Type>`. More readable for complex element types.
351
+ *
346
352
  * @default 'array'
347
353
  */
348
354
  arrayType?: 'generic' | 'array';
349
355
  /**
350
- * How to style your params, by default no casing is applied
351
- * - 'camelcase' uses camelCase for pathParams, queryParams and headerParams property names
352
- * @default undefined
353
- * @note response types (data/body) are NOT affected by this option
356
+ * Rename properties inside `PathParams`, `QueryParams`, and `HeaderParams` types.
357
+ * Response and request body types are not affected.
358
+ *
359
+ * @note Every plugin that touches operation parameters must use the same value.
354
360
  */
355
361
  paramsCasing?: 'camelcase';
356
362
  /**
357
- * Define some generators next to the ts generators
363
+ * Custom generators that run alongside the built-in TypeScript generators.
358
364
  */
359
365
  generators?: Array<Generator<PluginTs>>;
360
366
  /**
361
- * Override naming conventions. When a method returns `null` or `undefined`, the preset
362
- * resolver (`resolverTs`) is used as fallback.
367
+ * Override how names and file paths are built for generated symbols.
368
+ * Methods you omit fall back to the default `resolverTs`. `this` is bound to the
369
+ * full resolver, so `this.default(name, 'function')` delegates to the built-in
370
+ * implementation.
363
371
  */
364
372
  resolver?: Partial<ResolverTs> & ThisType<ResolverTs>;
365
373
  /**
366
- * AST visitor applied to each schema/operation node before printing.
367
- * Returning `null` or `undefined` from a visitor method falls back to the preset transformer.
374
+ * AST visitor applied to each schema or operation node before printing.
375
+ * Methods you omit fall back to the preset transformer.
368
376
  *
369
- * @example Remove writeOnly properties from response types
377
+ * @example Drop writeOnly properties from response types
370
378
  * ```ts
371
379
  * transformer: {
372
380
  * property(node) {
@@ -377,18 +385,17 @@ type Options = {
377
385
  */
378
386
  transformer?: ast.Visitor;
379
387
  /**
380
- * Override individual printer node handlers to customize rendering of specific schema types.
381
- *
382
- * Each key is a `SchemaType` (e.g. `'date'`, `'string'`). The function replaces the
383
- * built-in handler for that type. Use `this.transform` to recurse into nested schema nodes.
388
+ * Replace the TypeScript handler for a specific schema type (`'integer'`, `'date'`, ...).
389
+ * Each handler returns a TypeScript AST node for that schema type. Use `this.transform`
390
+ * to recurse into nested schema nodes.
384
391
  *
385
- * @example Override the `date` node to use the `Date` object type
392
+ * @example Use the JavaScript `Date` object for date schemas
386
393
  * ```ts
387
394
  * import ts from 'typescript'
388
395
  * pluginTs({
389
396
  * printer: {
390
397
  * nodes: {
391
- * date(node) {
398
+ * date() {
392
399
  * return ts.factory.createTypeReferenceNode('Date', [])
393
400
  * },
394
401
  * },
@@ -405,7 +412,7 @@ type ResolvedOptions = {
405
412
  exclude: Array<Exclude>;
406
413
  include: Array<Include> | undefined;
407
414
  override: Array<Override<ResolvedOptions>>;
408
- group: Group | undefined;
415
+ group: Group | null;
409
416
  enumType: NonNullable<Options['enumType']>;
410
417
  enumTypeSuffix: NonNullable<Options['enumTypeSuffix']>;
411
418
  enumKeyCasing: EnumKeyCasing;
@@ -484,26 +491,41 @@ declare function Type({
484
491
  }: Props): KubbReactNode;
485
492
  //#endregion
486
493
  //#region src/generators/typeGenerator.d.ts
494
+ /**
495
+ * Built-in generator for `@kubb/plugin-ts`. Emits one TypeScript file per
496
+ * schema in the spec plus per-operation request, response, and parameter
497
+ * types. Drop-replace with a custom `Generator<PluginTs>` to change how
498
+ * TypeScript output is produced.
499
+ */
487
500
  declare const typeGenerator: _$_kubb_core0.Generator<PluginTs, unknown>;
488
501
  //#endregion
489
502
  //#region src/plugin.d.ts
490
503
  /**
491
- * Canonical plugin name for `@kubb/plugin-ts`, used to identify the plugin in driver lookups and warnings.
504
+ * Canonical plugin name for `@kubb/plugin-ts`. Used for driver lookups and
505
+ * cross-plugin dependency references.
492
506
  */
493
507
  declare const pluginTsName = "plugin-ts";
494
508
  /**
495
- * The `@kubb/plugin-ts` plugin factory.
496
- *
497
- * Generates TypeScript type declarations from an OpenAPI/AST `RootNode`.
498
- * Walks schemas and operations, delegates rendering to the active generators,
499
- * and writes barrel files based on `output.barrelType`.
509
+ * Generates TypeScript `type` aliases and `interface` declarations from an
510
+ * OpenAPI spec. The foundation that every other Kubb plugin builds on:
511
+ * clients, query hooks, mocks, and validators all reference the names this
512
+ * plugin produces.
500
513
  *
501
514
  * @example
502
515
  * ```ts
503
- * import pluginTs from '@kubb/plugin-ts'
516
+ * import { defineConfig } from 'kubb'
517
+ * import { pluginTs } from '@kubb/plugin-ts'
504
518
  *
505
519
  * export default defineConfig({
506
- * plugins: [pluginTs({ output: { path: 'types' }, enumType: 'asConst' })],
520
+ * input: { path: './petStore.yaml' },
521
+ * output: { path: './src/gen' },
522
+ * plugins: [
523
+ * pluginTs({
524
+ * output: { path: './types' },
525
+ * enumType: 'asConst',
526
+ * optionalType: 'questionTokenAndUndefined',
527
+ * }),
528
+ * ],
507
529
  * })
508
530
  * ```
509
531
  */
@@ -558,20 +580,21 @@ declare const functionPrinter: (options?: FunctionPrinterOptions | undefined) =>
558
580
  //#endregion
559
581
  //#region src/resolvers/resolverTs.d.ts
560
582
  /**
561
- * Resolver for `@kubb/plugin-ts` that provides the default naming and path-resolution
562
- * helpers used by the plugin. Import this in other plugins to resolve the exact names and
563
- * paths that `plugin-ts` generates without hardcoding the conventions.
583
+ * Default resolver used by `@kubb/plugin-ts`. Decides the names and file paths
584
+ * for every generated TypeScript type. Import this in other plugins that need
585
+ * to reference the exact names `plugin-ts` produces without duplicating the
586
+ * casing/file-layout rules.
564
587
  *
565
- * The `default` method is automatically injected by `defineResolver` it uses `camelCase`
566
- * for identifiers/files and `pascalCase` for type names.
588
+ * The `default` method is supplied by `defineResolver`. It uses PascalCase for
589
+ * type names and PascalCase-with-isFile for files.
567
590
  *
568
- * @example
591
+ * @example Resolve a type and file name
569
592
  * ```ts
570
- * import { resolver } from '@kubb/plugin-ts'
593
+ * import { resolverTs } from '@kubb/plugin-ts'
571
594
  *
572
- * resolver.default('list pets', 'type') // 'ListPets'
573
- * resolver.resolveName('list pets status 200') // 'ListPetsStatus200'
574
- * resolver.resolvePathName('list pets', 'file') // 'listPets'
595
+ * resolverTs.default('list pets', 'type') // 'ListPets'
596
+ * resolverTs.resolvePathName('list pets', 'file') // 'ListPets'
597
+ * resolverTs.resolveResponseStatusName(node, 200) // 'ListPetsStatus200'
575
598
  * ```
576
599
  */
577
600
  declare const resolverTs: ResolverTs;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __name } from "./chunk--u3MIqq1.js";
2
- import { safePrint } from "@kubb/parser-ts";
2
+ import { parserTs } from "@kubb/parser-ts";
3
3
  import { File, jsxRendererSync } from "@kubb/renderer-jsx";
4
4
  import { ast, defineGenerator, definePlugin, defineResolver } from "@kubb/core";
5
5
  import { isNumber } from "remeda";
@@ -141,6 +141,129 @@ function stringify(value) {
141
141
  return JSON.stringify(trimQuotes(value.toString()));
142
142
  }
143
143
  //#endregion
144
+ //#region ../../internals/utils/src/reserved.ts
145
+ /**
146
+ * JavaScript and Java reserved words.
147
+ * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
148
+ */
149
+ const reservedWords = new Set([
150
+ "abstract",
151
+ "arguments",
152
+ "boolean",
153
+ "break",
154
+ "byte",
155
+ "case",
156
+ "catch",
157
+ "char",
158
+ "class",
159
+ "const",
160
+ "continue",
161
+ "debugger",
162
+ "default",
163
+ "delete",
164
+ "do",
165
+ "double",
166
+ "else",
167
+ "enum",
168
+ "eval",
169
+ "export",
170
+ "extends",
171
+ "false",
172
+ "final",
173
+ "finally",
174
+ "float",
175
+ "for",
176
+ "function",
177
+ "goto",
178
+ "if",
179
+ "implements",
180
+ "import",
181
+ "in",
182
+ "instanceof",
183
+ "int",
184
+ "interface",
185
+ "let",
186
+ "long",
187
+ "native",
188
+ "new",
189
+ "null",
190
+ "package",
191
+ "private",
192
+ "protected",
193
+ "public",
194
+ "return",
195
+ "short",
196
+ "static",
197
+ "super",
198
+ "switch",
199
+ "synchronized",
200
+ "this",
201
+ "throw",
202
+ "throws",
203
+ "transient",
204
+ "true",
205
+ "try",
206
+ "typeof",
207
+ "var",
208
+ "void",
209
+ "volatile",
210
+ "while",
211
+ "with",
212
+ "yield",
213
+ "Array",
214
+ "Date",
215
+ "hasOwnProperty",
216
+ "Infinity",
217
+ "isFinite",
218
+ "isNaN",
219
+ "isPrototypeOf",
220
+ "length",
221
+ "Math",
222
+ "name",
223
+ "NaN",
224
+ "Number",
225
+ "Object",
226
+ "prototype",
227
+ "String",
228
+ "toString",
229
+ "undefined",
230
+ "valueOf"
231
+ ]);
232
+ /**
233
+ * Returns `true` when `name` is a syntactically valid JavaScript variable name.
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * isValidVarName('status') // true
238
+ * isValidVarName('class') // false (reserved word)
239
+ * isValidVarName('42foo') // false (starts with digit)
240
+ * ```
241
+ */
242
+ function isValidVarName(name) {
243
+ if (!name || reservedWords.has(name)) return false;
244
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
245
+ }
246
+ /**
247
+ * Returns `name` when it's a syntactically valid JavaScript variable name,
248
+ * otherwise prefixes it with `_` so the result is a valid identifier.
249
+ *
250
+ * Useful for sanitizing OpenAPI schema names or operation IDs that start with
251
+ * a digit (e.g. `409`, `504AccountCancel`) before using them as exported
252
+ * variable, type, or function names.
253
+ *
254
+ * @example
255
+ * ```ts
256
+ * ensureValidVarName('409') // '_409'
257
+ * ensureValidVarName('504AccountCancel') // '_504AccountCancel'
258
+ * ensureValidVarName('Pet') // 'Pet'
259
+ * ensureValidVarName('class') // '_class'
260
+ * ```
261
+ */
262
+ function ensureValidVarName(name) {
263
+ if (!name || isValidVarName(name)) return name;
264
+ return `_${name}`;
265
+ }
266
+ //#endregion
144
267
  //#region src/constants.ts
145
268
  /**
146
269
  * `optionalType` values that cause a property's type to include `| undefined`.
@@ -634,13 +757,13 @@ function Enum({ node, enumType, enumTypeSuffix, enumKeyCasing, resolver }) {
634
757
  isExportable: true,
635
758
  isIndexable: true,
636
759
  isTypeOnly: false,
637
- children: safePrint(nameNode)
760
+ children: parserTs.print(nameNode)
638
761
  }), /* @__PURE__ */ jsx(File.Source, {
639
762
  name: typeName,
640
763
  isIndexable: true,
641
764
  isExportable: ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumType),
642
765
  isTypeOnly: ENUM_TYPES_WITH_TYPE_ONLY.has(enumType),
643
- children: safePrint(typeNode)
766
+ children: parserTs.print(typeNode)
644
767
  })] });
645
768
  }
646
769
  //#endregion
@@ -703,14 +826,14 @@ function buildPropertyJSDocComments(schema) {
703
826
  const meta = ast.syncSchemaRef(schema);
704
827
  const isArray = meta?.primitive === "array";
705
828
  return [
706
- meta && "description" in meta && meta.description ? `@description ${jsStringEscape(meta.description)}` : void 0,
707
- meta && "deprecated" in meta && meta.deprecated ? "@deprecated" : void 0,
708
- !isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` : void 0,
709
- !isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` : void 0,
710
- meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : void 0,
711
- meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? stringify(meta.default) : meta.default}` : void 0,
712
- meta && "example" in meta && meta.example !== void 0 ? `@example ${meta.example}` : void 0,
713
- meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, "optional" in schema && schema.optional ? " | undefined" : void 0].filter(Boolean).join("") : void 0
829
+ meta && "description" in meta && meta.description ? `@description ${jsStringEscape(meta.description)}` : null,
830
+ meta && "deprecated" in meta && meta.deprecated ? "@deprecated" : null,
831
+ !isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` : null,
832
+ !isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` : null,
833
+ meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : null,
834
+ meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? stringify(meta.default) : meta.default}` : null,
835
+ meta && "example" in meta && meta.example !== void 0 ? `@example ${meta.example}` : null,
836
+ meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, "optional" in schema && schema.optional ? " | undefined" : null].filter(Boolean).join("") : null
714
837
  ].filter(Boolean);
715
838
  }
716
839
  function buildParams(node, { params, resolver }) {
@@ -954,7 +1077,8 @@ const printerTs = ast.definePrinter((options) => {
954
1077
  const meta = ast.syncSchemaRef(node);
955
1078
  if (!name) {
956
1079
  const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [transformed, keywordTypeNodes.null] }) : transformed;
957
- return safePrint((meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable);
1080
+ const result = (meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
1081
+ return parserTs.print(result);
958
1082
  }
959
1083
  const inner = (() => {
960
1084
  const omitted = keysToOmit?.length ? createOmitDeclaration({
@@ -965,7 +1089,7 @@ const printerTs = ast.definePrinter((options) => {
965
1089
  const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [omitted, keywordTypeNodes.null] }) : omitted;
966
1090
  return meta.nullish || meta.optional ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
967
1091
  })();
968
- return safePrint(createTypeDeclaration({
1092
+ const typeNode = createTypeDeclaration({
969
1093
  name,
970
1094
  isExportable: true,
971
1095
  type: inner,
@@ -974,7 +1098,8 @@ const printerTs = ast.definePrinter((options) => {
974
1098
  ...meta,
975
1099
  description
976
1100
  })
977
- }));
1101
+ });
1102
+ return parserTs.print(typeNode);
978
1103
  }
979
1104
  };
980
1105
  });
@@ -993,6 +1118,12 @@ function getPerContentTypeName(dataName, suffix) {
993
1118
  if (dataName.endsWith("Data")) return suffix.endsWith("Data") ? dataName.slice(0, -4) + suffix : `${dataName.slice(0, -4)}${suffix}Data`;
994
1119
  return dataName + suffix;
995
1120
  }
1121
+ /**
1122
+ * Built-in generator for `@kubb/plugin-ts`. Emits one TypeScript file per
1123
+ * schema in the spec plus per-operation request, response, and parameter
1124
+ * types. Drop-replace with a custom `Generator<PluginTs>` to change how
1125
+ * TypeScript output is produced.
1126
+ */
996
1127
  const typeGenerator = defineGenerator({
997
1128
  name: "typescript",
998
1129
  renderer: jsxRendererSync,
@@ -1014,7 +1145,7 @@ const typeGenerator = defineGenerator({
1014
1145
  }, {
1015
1146
  root,
1016
1147
  output,
1017
- group
1148
+ group: group ?? void 0
1018
1149
  }).path
1019
1150
  }));
1020
1151
  const isEnumSchema = !!ast.narrowSchema(node, ast.schemaTypes.enum);
@@ -1026,7 +1157,7 @@ const typeGenerator = defineGenerator({
1026
1157
  }, {
1027
1158
  root,
1028
1159
  output,
1029
- group
1160
+ group: group ?? void 0
1030
1161
  })
1031
1162
  };
1032
1163
  const schemaPrinter = printerTs({
@@ -1086,7 +1217,7 @@ const typeGenerator = defineGenerator({
1086
1217
  }, {
1087
1218
  root,
1088
1219
  output,
1089
- group
1220
+ group: group ?? void 0
1090
1221
  }) };
1091
1222
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1092
1223
  function resolveImportName(schemaName) {
@@ -1103,7 +1234,7 @@ const typeGenerator = defineGenerator({
1103
1234
  }, {
1104
1235
  root,
1105
1236
  output,
1106
- group
1237
+ group: group ?? void 0
1107
1238
  }).path
1108
1239
  }));
1109
1240
  const schemaPrinter = printerTs({
@@ -1249,20 +1380,21 @@ const typeGenerator = defineGenerator({
1249
1380
  //#endregion
1250
1381
  //#region src/resolvers/resolverTs.ts
1251
1382
  /**
1252
- * Resolver for `@kubb/plugin-ts` that provides the default naming and path-resolution
1253
- * helpers used by the plugin. Import this in other plugins to resolve the exact names and
1254
- * paths that `plugin-ts` generates without hardcoding the conventions.
1383
+ * Default resolver used by `@kubb/plugin-ts`. Decides the names and file paths
1384
+ * for every generated TypeScript type. Import this in other plugins that need
1385
+ * to reference the exact names `plugin-ts` produces without duplicating the
1386
+ * casing/file-layout rules.
1255
1387
  *
1256
- * The `default` method is automatically injected by `defineResolver` it uses `camelCase`
1257
- * for identifiers/files and `pascalCase` for type names.
1388
+ * The `default` method is supplied by `defineResolver`. It uses PascalCase for
1389
+ * type names and PascalCase-with-isFile for files.
1258
1390
  *
1259
- * @example
1391
+ * @example Resolve a type and file name
1260
1392
  * ```ts
1261
- * import { resolver } from '@kubb/plugin-ts'
1393
+ * import { resolverTs } from '@kubb/plugin-ts'
1262
1394
  *
1263
- * resolver.default('list pets', 'type') // 'ListPets'
1264
- * resolver.resolveName('list pets status 200') // 'ListPetsStatus200'
1265
- * resolver.resolvePathName('list pets', 'file') // 'listPets'
1395
+ * resolverTs.default('list pets', 'type') // 'ListPets'
1396
+ * resolverTs.resolvePathName('list pets', 'file') // 'ListPets'
1397
+ * resolverTs.resolveResponseStatusName(node, 200) // 'ListPetsStatus200'
1266
1398
  * ```
1267
1399
  */
1268
1400
  const resolverTs = defineResolver(() => {
@@ -1270,13 +1402,15 @@ const resolverTs = defineResolver(() => {
1270
1402
  name: "default",
1271
1403
  pluginName: "plugin-ts",
1272
1404
  default(name, type) {
1273
- return pascalCase(name, { isFile: type === "file" });
1405
+ const resolved = pascalCase(name, { isFile: type === "file" });
1406
+ return type === "file" ? resolved : ensureValidVarName(resolved);
1274
1407
  },
1275
1408
  resolveTypeName(name) {
1276
- return pascalCase(name);
1409
+ return ensureValidVarName(pascalCase(name));
1277
1410
  },
1278
1411
  resolvePathName(name, type) {
1279
- return pascalCase(name, { isFile: type === "file" });
1412
+ const resolved = pascalCase(name, { isFile: type === "file" });
1413
+ return type === "file" ? resolved : ensureValidVarName(resolved);
1280
1414
  },
1281
1415
  resolveParamName(node, param) {
1282
1416
  return this.resolveTypeName(`${node.operationId} ${param.in} ${param.name}`);
@@ -1313,22 +1447,31 @@ const resolverTs = defineResolver(() => {
1313
1447
  //#endregion
1314
1448
  //#region src/plugin.ts
1315
1449
  /**
1316
- * Canonical plugin name for `@kubb/plugin-ts`, used to identify the plugin in driver lookups and warnings.
1450
+ * Canonical plugin name for `@kubb/plugin-ts`. Used for driver lookups and
1451
+ * cross-plugin dependency references.
1317
1452
  */
1318
1453
  const pluginTsName = "plugin-ts";
1319
1454
  /**
1320
- * The `@kubb/plugin-ts` plugin factory.
1321
- *
1322
- * Generates TypeScript type declarations from an OpenAPI/AST `RootNode`.
1323
- * Walks schemas and operations, delegates rendering to the active generators,
1324
- * and writes barrel files based on `output.barrelType`.
1455
+ * Generates TypeScript `type` aliases and `interface` declarations from an
1456
+ * OpenAPI spec. The foundation that every other Kubb plugin builds on:
1457
+ * clients, query hooks, mocks, and validators all reference the names this
1458
+ * plugin produces.
1325
1459
  *
1326
1460
  * @example
1327
1461
  * ```ts
1328
- * import pluginTs from '@kubb/plugin-ts'
1462
+ * import { defineConfig } from 'kubb'
1463
+ * import { pluginTs } from '@kubb/plugin-ts'
1329
1464
  *
1330
1465
  * export default defineConfig({
1331
- * plugins: [pluginTs({ output: { path: 'types' }, enumType: 'asConst' })],
1466
+ * input: { path: './petStore.yaml' },
1467
+ * output: { path: './src/gen' },
1468
+ * plugins: [
1469
+ * pluginTs({
1470
+ * output: { path: './types' },
1471
+ * enumType: 'asConst',
1472
+ * optionalType: 'questionTokenAndUndefined',
1473
+ * }),
1474
+ * ],
1332
1475
  * })
1333
1476
  * ```
1334
1477
  */
@@ -1343,7 +1486,7 @@ const pluginTs = definePlugin((options) => {
1343
1486
  if (group.type === "path") return `${ctx.group.split("/")[1]}`;
1344
1487
  return `${camelCase(ctx.group)}Controller`;
1345
1488
  }
1346
- } : void 0;
1489
+ } : null;
1347
1490
  return {
1348
1491
  name: pluginTsName,
1349
1492
  options,