@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.cjs +183 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +78 -55
- package/dist/index.js +183 -40
- package/dist/index.js.map +1 -1
- package/extension.yaml +690 -247
- package/package.json +5 -5
- package/src/components/Enum.tsx +3 -3
- package/src/factory.ts +6 -6
- package/src/generators/typeGenerator.tsx +13 -4
- package/src/plugin.ts +18 -9
- package/src/printers/printerTs.ts +3 -3
- package/src/resolvers/resolverTs.ts +17 -14
- package/src/types.ts +44 -37
- package/src/utils.ts +9 -9
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
|
|
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
|
|
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
|
-
*
|
|
303
|
-
*
|
|
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
|
-
*
|
|
308
|
-
*
|
|
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
|
-
*
|
|
313
|
+
* Split generated files into subfolders based on the operation's tag.
|
|
313
314
|
*/
|
|
314
315
|
group?: Group;
|
|
315
316
|
/**
|
|
316
|
-
*
|
|
317
|
+
* Skip operations matching at least one entry in the list.
|
|
317
318
|
*/
|
|
318
319
|
exclude?: Array<Exclude>;
|
|
319
320
|
/**
|
|
320
|
-
*
|
|
321
|
+
* Restrict generation to operations matching at least one entry in the list.
|
|
321
322
|
*/
|
|
322
323
|
include?: Array<Include>;
|
|
323
324
|
/**
|
|
324
|
-
*
|
|
325
|
+
* Apply a different options object to operations matching a pattern.
|
|
325
326
|
*/
|
|
326
327
|
override?: Array<Override<ResolvedOptions>>;
|
|
327
328
|
/**
|
|
328
|
-
*
|
|
329
|
-
* - 'type'
|
|
330
|
-
* - 'interface'
|
|
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
|
-
*
|
|
336
|
-
* - 'questionToken'
|
|
337
|
-
* - 'undefined'
|
|
338
|
-
* - 'questionTokenAndUndefined'
|
|
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
|
-
*
|
|
344
|
-
* - '
|
|
345
|
-
* - '
|
|
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
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
* @note
|
|
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
|
-
*
|
|
363
|
+
* Custom generators that run alongside the built-in TypeScript generators.
|
|
358
364
|
*/
|
|
359
365
|
generators?: Array<Generator<PluginTs>>;
|
|
360
366
|
/**
|
|
361
|
-
* Override
|
|
362
|
-
*
|
|
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
|
|
367
|
-
*
|
|
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
|
|
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
|
-
*
|
|
381
|
-
*
|
|
382
|
-
*
|
|
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
|
|
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(
|
|
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 |
|
|
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
|
|
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
|
-
*
|
|
496
|
-
*
|
|
497
|
-
*
|
|
498
|
-
*
|
|
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
|
|
516
|
+
* import { defineConfig } from 'kubb'
|
|
517
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
504
518
|
*
|
|
505
519
|
* export default defineConfig({
|
|
506
|
-
*
|
|
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
|
-
*
|
|
562
|
-
*
|
|
563
|
-
*
|
|
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
|
|
566
|
-
*
|
|
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 {
|
|
593
|
+
* import { resolverTs } from '@kubb/plugin-ts'
|
|
571
594
|
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
*
|
|
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 {
|
|
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:
|
|
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:
|
|
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)}` :
|
|
707
|
-
meta && "deprecated" in meta && meta.deprecated ? "@deprecated" :
|
|
708
|
-
!isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` :
|
|
709
|
-
!isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` :
|
|
710
|
-
meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` :
|
|
711
|
-
meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? stringify(meta.default) : meta.default}` :
|
|
712
|
-
meta && "example" in meta && meta.example !== void 0 ? `@example ${meta.example}` :
|
|
713
|
-
meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, "optional" in schema && schema.optional ? " | undefined" :
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
1253
|
-
*
|
|
1254
|
-
*
|
|
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
|
|
1257
|
-
*
|
|
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 {
|
|
1393
|
+
* import { resolverTs } from '@kubb/plugin-ts'
|
|
1262
1394
|
*
|
|
1263
|
-
*
|
|
1264
|
-
*
|
|
1265
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
*
|
|
1321
|
-
*
|
|
1322
|
-
*
|
|
1323
|
-
*
|
|
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
|
|
1462
|
+
* import { defineConfig } from 'kubb'
|
|
1463
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
1329
1464
|
*
|
|
1330
1465
|
* export default defineConfig({
|
|
1331
|
-
*
|
|
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
|
-
} :
|
|
1489
|
+
} : null;
|
|
1347
1490
|
return {
|
|
1348
1491
|
name: pluginTsName,
|
|
1349
1492
|
options,
|