@kubb/plugin-ts 5.0.0-alpha.4 → 5.0.0-alpha.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.
Files changed (35) hide show
  1. package/dist/{components-CRjwjdyE.js → components-CRu8IKY3.js} +12 -8
  2. package/dist/components-CRu8IKY3.js.map +1 -0
  3. package/dist/{components-DI0aTIBg.cjs → components-DeNDKlzf.cjs} +12 -8
  4. package/dist/components-DeNDKlzf.cjs.map +1 -0
  5. package/dist/components.cjs +1 -1
  6. package/dist/components.d.ts +1 -3
  7. package/dist/components.js +1 -1
  8. package/dist/generators.cjs +1 -1
  9. package/dist/generators.d.ts +2 -3
  10. package/dist/generators.js +1 -1
  11. package/dist/index.cjs +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.js +1 -1
  14. package/dist/{plugin-Bgm8TNUt.js → plugin-BcK4SBA0.js} +510 -243
  15. package/dist/plugin-BcK4SBA0.js.map +1 -0
  16. package/dist/{plugin-DvK-Uhvv.cjs → plugin-BrQcApyO.cjs} +510 -244
  17. package/dist/plugin-BrQcApyO.cjs.map +1 -0
  18. package/dist/{types-aotMcdUB.d.ts → types-CsvB6X5Y.d.ts} +11 -14
  19. package/package.json +8 -8
  20. package/src/components/Type.tsx +0 -3
  21. package/src/components/v2/Enum.tsx +67 -0
  22. package/src/components/v2/Type.tsx +22 -117
  23. package/src/constants.ts +29 -0
  24. package/src/factory.ts +12 -16
  25. package/src/generators/typeGenerator.tsx +2 -4
  26. package/src/generators/v2/typeGenerator.tsx +78 -103
  27. package/src/generators/v2/utils.ts +140 -0
  28. package/src/parser.ts +1 -8
  29. package/src/plugin.ts +11 -2
  30. package/src/printer.ts +235 -111
  31. package/src/types.ts +10 -13
  32. package/dist/components-CRjwjdyE.js.map +0 -1
  33. package/dist/components-DI0aTIBg.cjs.map +0 -1
  34. package/dist/plugin-Bgm8TNUt.js.map +0 -1
  35. package/dist/plugin-DvK-Uhvv.cjs.map +0 -1
package/src/printer.ts CHANGED
@@ -1,28 +1,57 @@
1
- import { jsStringEscape, stringify } from '@internals/utils'
1
+ import { jsStringEscape, pascalCase, stringify } from '@internals/utils'
2
2
  import { isPlainStringType } from '@kubb/ast'
3
3
  import type { ArraySchemaNode, SchemaNode } from '@kubb/ast/types'
4
4
  import type { PrinterFactoryOptions } from '@kubb/core'
5
5
  import { definePrinter } from '@kubb/core'
6
6
  import type ts from 'typescript'
7
+ import { ENUM_TYPES_WITH_KEY_SUFFIX, OPTIONAL_ADDS_QUESTION_TOKEN, OPTIONAL_ADDS_UNDEFINED } from './constants.ts'
7
8
  import * as factory from './factory.ts'
9
+ import type { PluginTs } from './types.ts'
8
10
 
9
11
  type TsOptions = {
10
12
  /**
11
13
  * @default `'questionToken'`
12
14
  */
13
- optionalType: 'questionToken' | 'undefined' | 'questionTokenAndUndefined'
15
+ optionalType: PluginTs['resolvedOptions']['optionalType']
14
16
  /**
15
17
  * @default `'array'`
16
18
  */
17
- arrayType: 'array' | 'generic'
19
+ arrayType: PluginTs['resolvedOptions']['arrayType']
18
20
  /**
19
21
  * @default `'inlineLiteral'`
20
22
  */
21
- enumType: 'enum' | 'asConst' | 'asPascalConst' | 'constEnum' | 'literal' | 'inlineLiteral'
23
+ enumType: PluginTs['resolvedOptions']['enumType']
24
+ /**
25
+ * Controls whether a `type` alias or `interface` declaration is emitted.
26
+ * @default `'type'`
27
+ */
28
+ syntaxType?: PluginTs['resolvedOptions']['syntaxType']
29
+ /**
30
+ * When set, `printer.print(node)` produces a full `type Name = …` declaration.
31
+ * When omitted, `printer.print(node)` returns the raw type node.
32
+ */
33
+ typeName?: string
34
+
35
+ /**
36
+ * JSDoc `@description` comment added to the generated type or interface declaration.
37
+ */
38
+ description?: string
39
+ /**
40
+ * Property keys to exclude from the generated type via `Omit<Type, Keys>`.
41
+ * Forces type-alias syntax even when `syntaxType` is `'interface'`.
42
+ */
43
+ keysToOmit?: Array<string>
22
44
  }
23
45
 
24
- type TsPrinter = PrinterFactoryOptions<'typescript', TsOptions, ts.TypeNode>
46
+ /**
47
+ * TypeScript printer factory options: maps `SchemaNode` → `ts.TypeNode` (raw) or `ts.Node` (full declaration).
48
+ */
49
+ type TsPrinter = PrinterFactoryOptions<'typescript', TsOptions, ts.TypeNode, ts.Node>
25
50
 
51
+ /**
52
+ * Converts a primitive const value to a TypeScript literal type node.
53
+ * Handles negative numbers via a prefix unary expression.
54
+ */
26
55
  function constToTypeNode(value: string | number | boolean, format: 'string' | 'number' | 'boolean'): ts.TypeNode | undefined {
27
56
  if (format === 'boolean') {
28
57
  return factory.createLiteralTypeNode(value === true ? factory.createTrue() : factory.createFalse())
@@ -36,16 +65,26 @@ function constToTypeNode(value: string | number | boolean, format: 'string' | 'n
36
65
  return factory.createLiteralTypeNode(factory.createStringLiteral(String(value)))
37
66
  }
38
67
 
68
+ /**
69
+ * Returns a `Date` reference type node when `representation` is `'date'`, otherwise falls back to `string`.
70
+ */
39
71
  function dateOrStringNode(node: { representation?: string }): ts.TypeNode {
40
72
  return node.representation === 'date' ? factory.createTypeReferenceNode(factory.createIdentifier('Date')) : factory.keywordTypeNodes.string
41
73
  }
42
74
 
75
+ /**
76
+ * Maps an array of `SchemaNode`s through the printer, filtering out `null` and `undefined` results.
77
+ */
43
78
  function buildMemberNodes(members: Array<SchemaNode> | undefined, print: (node: SchemaNode) => ts.TypeNode | null | undefined): Array<ts.TypeNode> {
44
- return (members ?? []).map(print).filter(Boolean) as Array<ts.TypeNode>
79
+ return (members ?? []).map(print).filter(Boolean)
45
80
  }
46
81
 
82
+ /**
83
+ * Builds a TypeScript tuple type node from an array schema's `items`,
84
+ * applying min/max slice and optional/rest element rules.
85
+ */
47
86
  function buildTupleNode(node: ArraySchemaNode, print: (node: SchemaNode) => ts.TypeNode | null | undefined): ts.TypeNode | undefined {
48
- let items = (node.items ?? []).map(print).filter(Boolean) as Array<ts.TypeNode>
87
+ let items = (node.items ?? []).map(print).filter(Boolean)
49
88
 
50
89
  const restNode = node.rest ? (print(node.rest) ?? undefined) : undefined
51
90
  const { min, max } = node
@@ -68,25 +107,31 @@ function buildTupleNode(node: ArraySchemaNode, print: (node: SchemaNode) => ts.T
68
107
  return factory.createTupleTypeNode(items)
69
108
  }
70
109
 
110
+ /**
111
+ * Applies `nullable` and optional/nullish `| undefined` union modifiers to a property's resolved base type.
112
+ */
71
113
  function buildPropertyType(schema: SchemaNode, baseType: ts.TypeNode, optionalType: TsOptions['optionalType']): ts.TypeNode {
72
- const addsUndefined = ['undefined', 'questionTokenAndUndefined'].includes(optionalType)
114
+ const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType)
73
115
 
74
116
  let type = baseType
75
117
 
76
118
  if (schema.nullable) {
77
- type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.null] }) as ts.TypeNode
119
+ type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.null] })
78
120
  }
79
121
 
80
122
  if ((schema.nullish || schema.optional) && addsUndefined) {
81
- type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.undefined] }) as ts.TypeNode
123
+ type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.undefined] })
82
124
  }
83
125
 
84
126
  return type
85
127
  }
86
128
 
129
+ /**
130
+ * Collects JSDoc annotation strings (description, deprecated, min/max, pattern, default, example, type) for a schema node.
131
+ */
87
132
  function buildPropertyJSDocComments(schema: SchemaNode): Array<string | undefined> {
88
133
  return [
89
- 'description' in schema && schema.description ? `@description ${jsStringEscape(schema.description as string)}` : undefined,
134
+ 'description' in schema && schema.description ? `@description ${jsStringEscape(schema.description)}` : undefined,
90
135
  'deprecated' in schema && schema.deprecated ? '@deprecated' : undefined,
91
136
  'min' in schema && schema.min !== undefined ? `@minLength ${schema.min}` : undefined,
92
137
  'max' in schema && schema.max !== undefined ? `@maxLength ${schema.max}` : undefined,
@@ -101,6 +146,9 @@ function buildPropertyJSDocComments(schema: SchemaNode): Array<string | undefine
101
146
  ]
102
147
  }
103
148
 
149
+ /**
150
+ * Creates TypeScript index signatures for `additionalProperties` and `patternProperties` on an object schema node.
151
+ */
104
152
  function buildIndexSignatures(
105
153
  node: { additionalProperties?: SchemaNode | boolean; patternProperties?: Record<string, SchemaNode> },
106
154
  propertyCount: number,
@@ -109,7 +157,8 @@ function buildIndexSignatures(
109
157
  const elements: Array<ts.TypeElement> = []
110
158
 
111
159
  if (node.additionalProperties && node.additionalProperties !== true) {
112
- const additionalType = (print(node.additionalProperties as SchemaNode) ?? factory.keywordTypeNodes.unknown) as ts.TypeNode
160
+ const additionalType = print(node.additionalProperties) ?? factory.keywordTypeNodes.unknown
161
+
113
162
  elements.push(factory.createIndexSignature(propertyCount > 0 ? factory.keywordTypeNodes.unknown : additionalType))
114
163
  } else if (node.additionalProperties === true) {
115
164
  elements.push(factory.createIndexSignature(factory.keywordTypeNodes.unknown))
@@ -118,9 +167,10 @@ function buildIndexSignatures(
118
167
  if (node.patternProperties) {
119
168
  const first = Object.values(node.patternProperties)[0]
120
169
  if (first) {
121
- let patternType = (print(first) ?? factory.keywordTypeNodes.unknown) as ts.TypeNode
170
+ let patternType = print(first) ?? factory.keywordTypeNodes.unknown
171
+
122
172
  if (first.nullable) {
123
- patternType = factory.createUnionDeclaration({ nodes: [patternType, factory.keywordTypeNodes.null] }) as ts.TypeNode
173
+ patternType = factory.createUnionDeclaration({ nodes: [patternType, factory.keywordTypeNodes.null] })
124
174
  }
125
175
  elements.push(factory.createIndexSignature(patternType))
126
176
  }
@@ -130,115 +180,189 @@ function buildIndexSignatures(
130
180
  }
131
181
 
132
182
  /**
133
- * Converts a `SchemaNode` AST node into a TypeScript `ts.TypeNode`.
183
+ * TypeScript type printer built with `definePrinter`.
184
+ *
185
+ * Converts a `SchemaNode` AST node into a TypeScript AST node:
186
+ * - **`printer.print(node)`** — when `options.typeName` is set, returns a full
187
+ * `type Name = …` or `interface Name { … }` declaration (`ts.Node`).
188
+ * Without `typeName`, returns the raw `ts.TypeNode` for the schema.
189
+ *
190
+ * Dispatches on `node.type` to the appropriate handler in `nodes`. Options are closed
191
+ * over per printer instance, so each call to `printerTs(options)` produces an independent printer.
134
192
  *
135
- * Built on `definePrinter` dispatches on `node.type`, with options closed over
136
- * per printer instance. Produces the same `ts.TypeNode` output as the keyword-based
137
- * `parse` in `parser.ts`.
193
+ * @example Raw type node (no `typeName`)
194
+ * ```ts
195
+ * const printer = printerTs({ optionalType: 'questionToken', arrayType: 'array', enumType: 'inlineLiteral' })
196
+ * const typeNode = printer.print(schemaNode) // ts.TypeNode
197
+ * ```
198
+ *
199
+ * @example Full declaration (with `typeName`)
200
+ * ```ts
201
+ * const printer = printerTs({ optionalType: 'questionToken', arrayType: 'array', enumType: 'inlineLiteral', typeName: 'MyType' })
202
+ * const declaration = printer.print(schemaNode) // ts.TypeAliasDeclaration | ts.InterfaceDeclaration
203
+ * ```
138
204
  */
139
- export const printerTs = definePrinter<TsPrinter>((options) => ({
140
- name: 'typescript',
141
- options,
142
- nodes: {
143
- any: () => factory.keywordTypeNodes.any,
144
- unknown: () => factory.keywordTypeNodes.unknown,
145
- void: () => factory.keywordTypeNodes.void,
146
- boolean: () => factory.keywordTypeNodes.boolean,
147
- null: () => factory.keywordTypeNodes.null,
148
- blob: () => factory.createTypeReferenceNode('Blob', []),
149
- string: () => factory.keywordTypeNodes.string,
150
- uuid: () => factory.keywordTypeNodes.string,
151
- email: () => factory.keywordTypeNodes.string,
152
- url: () => factory.keywordTypeNodes.string,
153
- datetime: () => factory.keywordTypeNodes.string,
154
- number: () => factory.keywordTypeNodes.number,
155
- integer: () => factory.keywordTypeNodes.number,
156
- bigint: () => factory.keywordTypeNodes.bigint,
157
- date: (node) => dateOrStringNode(node),
158
- time: (node) => dateOrStringNode(node),
159
- ref(node) {
160
- if (!node.name) {
161
- return undefined
162
- }
163
- return factory.createTypeReferenceNode(node.name, undefined)
164
- },
165
- enum(node) {
166
- const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? []
205
+ export const printerTs = definePrinter<TsPrinter>((options) => {
206
+ const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(options.optionalType)
207
+
208
+ return {
209
+ name: 'typescript',
210
+ options,
211
+ nodes: {
212
+ any: () => factory.keywordTypeNodes.any,
213
+ unknown: () => factory.keywordTypeNodes.unknown,
214
+ void: () => factory.keywordTypeNodes.void,
215
+ never: () => factory.keywordTypeNodes.never,
216
+ boolean: () => factory.keywordTypeNodes.boolean,
217
+ null: () => factory.keywordTypeNodes.null,
218
+ blob: () => factory.createTypeReferenceNode('Blob', []),
219
+ string: () => factory.keywordTypeNodes.string,
220
+ uuid: () => factory.keywordTypeNodes.string,
221
+ email: () => factory.keywordTypeNodes.string,
222
+ url: (node) => {
223
+ if (node.path) {
224
+ return factory.createUrlTemplateType(node.path)
225
+ }
226
+ return factory.keywordTypeNodes.string
227
+ },
228
+ datetime: () => factory.keywordTypeNodes.string,
229
+ number: () => factory.keywordTypeNodes.number,
230
+ integer: () => factory.keywordTypeNodes.number,
231
+ bigint: () => factory.keywordTypeNodes.bigint,
232
+ date: dateOrStringNode,
233
+ time: dateOrStringNode,
234
+ ref(node) {
235
+ if (!node.name) {
236
+ return undefined
237
+ }
238
+ return factory.createTypeReferenceNode(node.name, undefined)
239
+ },
240
+ enum(node) {
241
+ const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? []
242
+
243
+ if (this.options.enumType === 'inlineLiteral' || !node.name) {
244
+ const literalNodes = values
245
+ .filter((v): v is string | number | boolean => v !== null)
246
+ .map((value) => constToTypeNode(value, typeof value as 'string' | 'number' | 'boolean'))
247
+ .filter(Boolean)
248
+
249
+ return factory.createUnionDeclaration({ withParentheses: true, nodes: literalNodes }) ?? undefined
250
+ }
251
+
252
+ const resolvedName = pascalCase(node.name)
253
+ const typeName = ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enumType) ? `${resolvedName}Key` : resolvedName
254
+
255
+ return factory.createTypeReferenceNode(typeName, undefined)
256
+ },
257
+ union(node) {
258
+ const members = node.members ?? []
259
+
260
+ const hasStringLiteral = members.some((m) => m.type === 'enum' && m.enumType === 'string')
261
+ const hasPlainString = members.some((m) => isPlainStringType(m))
262
+
263
+ if (hasStringLiteral && hasPlainString) {
264
+ const memberNodes = members
265
+ .map((m) => {
266
+ if (isPlainStringType(m)) {
267
+ return factory.createIntersectionDeclaration({
268
+ nodes: [factory.keywordTypeNodes.string, factory.createTypeLiteralNode([])],
269
+ withParentheses: true,
270
+ })
271
+ }
272
+
273
+ return this.print(m)
274
+ })
275
+ .filter(Boolean)
276
+
277
+ return factory.createUnionDeclaration({ withParentheses: true, nodes: memberNodes }) ?? undefined
278
+ }
279
+
280
+ return factory.createUnionDeclaration({ withParentheses: true, nodes: buildMemberNodes(members, this.print) }) ?? undefined
281
+ },
282
+ intersection(node) {
283
+ return factory.createIntersectionDeclaration({ withParentheses: true, nodes: buildMemberNodes(node.members, this.print) }) ?? undefined
284
+ },
285
+ array(node) {
286
+ const itemNodes = (node.items ?? []).map((item) => this.print(item)).filter(Boolean)
287
+
288
+ return factory.createArrayDeclaration({ nodes: itemNodes, arrayType: this.options.arrayType }) ?? undefined
289
+ },
290
+ tuple(node) {
291
+ return buildTupleNode(node, this.print)
292
+ },
293
+ object(node) {
294
+ const { print, options } = this
295
+ const addsQuestionToken = OPTIONAL_ADDS_QUESTION_TOKEN.has(options.optionalType)
296
+
297
+ const propertyNodes: Array<ts.TypeElement> = node.properties.map((prop) => {
298
+ const baseType = print(prop.schema) ?? factory.keywordTypeNodes.unknown
299
+ const type = buildPropertyType(prop.schema, baseType, options.optionalType)
300
+
301
+ const propertyNode = factory.createPropertySignature({
302
+ questionToken: prop.schema.optional || prop.schema.nullish ? addsQuestionToken : false,
303
+ name: prop.name,
304
+ type,
305
+ readOnly: prop.schema.readOnly,
306
+ })
167
307
 
168
- if (this.options.enumType === 'inlineLiteral' || !node.name) {
169
- const literalNodes = values
170
- .filter((v): v is string | number | boolean => v !== null)
171
- .map((value) => constToTypeNode(value, typeof value === 'number' ? 'number' : typeof value === 'boolean' ? 'boolean' : 'string'))
172
- .filter(Boolean) as Array<ts.TypeNode>
308
+ return factory.appendJSDocToNode({ node: propertyNode, comments: buildPropertyJSDocComments(prop.schema) })
309
+ })
173
310
 
174
- return factory.createUnionDeclaration({ withParentheses: true, nodes: literalNodes }) ?? undefined
175
- }
311
+ const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, print)]
176
312
 
177
- const typeName = ['asConst', 'asPascalConst'].includes(this.options.enumType) ? `${node.name}Key` : node.name
313
+ if (!allElements.length) {
314
+ return factory.keywordTypeNodes.object
315
+ }
178
316
 
179
- return factory.createTypeReferenceNode(typeName, undefined)
317
+ return factory.createTypeLiteralNode(allElements)
318
+ },
180
319
  },
181
- union(node) {
182
- const members = node.members ?? []
183
-
184
- const hasStringLiteral = members.some((m) => m.type === 'enum' && m.enumType === 'string')
185
- const hasPlainString = members.some((m) => isPlainStringType(m))
186
-
187
- if (hasStringLiteral && hasPlainString) {
188
- const nodes = members
189
- .map((m) => {
190
- if (isPlainStringType(m)) {
191
- return factory.createIntersectionDeclaration({
192
- nodes: [factory.keywordTypeNodes.string, factory.createTypeLiteralNode([])],
193
- withParentheses: true,
194
- }) as ts.TypeNode
195
- }
196
-
197
- return this.print(m)
198
- })
199
- .filter(Boolean) as Array<ts.TypeNode>
320
+ print(node) {
321
+ let type = this.print(node)
200
322
 
201
- return factory.createUnionDeclaration({ withParentheses: true, nodes }) ?? undefined
323
+ if (!type) {
324
+ return undefined
202
325
  }
203
326
 
204
- return factory.createUnionDeclaration({ withParentheses: true, nodes: buildMemberNodes(members, this.print) }) ?? undefined
205
- },
206
- intersection(node) {
207
- return factory.createIntersectionDeclaration({ withParentheses: true, nodes: buildMemberNodes(node.members, this.print) }) ?? undefined
208
- },
209
- array(node) {
210
- const itemNodes = (node.items ?? []).map((item) => this.print(item)).filter(Boolean) as Array<ts.TypeNode>
211
-
212
- return factory.createArrayDeclaration({ nodes: itemNodes, arrayType: this.options.arrayType }) ?? undefined
213
- },
214
- tuple(node) {
215
- return buildTupleNode(node, this.print)
216
- },
217
- object(node) {
218
- const addsQuestionToken = ['questionToken', 'questionTokenAndUndefined'].includes(this.options.optionalType)
219
- const { print } = this
220
-
221
- const propertyNodes: Array<ts.TypeElement> = node.properties.map((prop) => {
222
- const baseType = (print(prop.schema) ?? factory.keywordTypeNodes.unknown) as ts.TypeNode
223
- const type = buildPropertyType(prop.schema, baseType, this.options.optionalType)
224
-
225
- const propertyNode = factory.createPropertySignature({
226
- questionToken: prop.schema.optional || prop.schema.nullish ? addsQuestionToken : false,
227
- name: prop.name,
228
- type,
229
- readOnly: prop.schema.readOnly,
230
- })
231
-
232
- return factory.appendJSDocToNode({ node: propertyNode, comments: buildPropertyJSDocComments(prop.schema) })
233
- })
327
+ // Apply top-level nullable / optional union modifiers.
328
+ if (node.nullable) {
329
+ type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.null] })
330
+ }
234
331
 
235
- const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, print)]
332
+ if ((node.nullish || node.optional) && addsUndefined) {
333
+ type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.undefined] })
334
+ }
236
335
 
237
- if (!allElements.length) {
238
- return factory.keywordTypeNodes.object
336
+ // Without typeName, return the type node as-is (no declaration wrapping).
337
+ const { typeName, syntaxType = 'type', description, keysToOmit } = this.options
338
+ if (!typeName) {
339
+ return type
239
340
  }
240
341
 
241
- return factory.createTypeLiteralNode(allElements)
342
+ const useTypeGeneration = syntaxType === 'type' || type.kind === factory.syntaxKind.union || !!keysToOmit?.length
343
+
344
+ return factory.createTypeDeclaration({
345
+ name: typeName,
346
+ isExportable: true,
347
+ type: keysToOmit?.length
348
+ ? factory.createOmitDeclaration({
349
+ keys: keysToOmit,
350
+ type,
351
+ nonNullable: true,
352
+ })
353
+ : type,
354
+ syntax: useTypeGeneration ? 'type' : 'interface',
355
+ comments: [
356
+ node?.title ? jsStringEscape(node.title) : undefined,
357
+ description ? `@description ${jsStringEscape(description)}` : undefined,
358
+ node?.deprecated ? '@deprecated' : undefined,
359
+ node && 'min' in node && node.min !== undefined ? `@minLength ${node.min}` : undefined,
360
+ node && 'max' in node && node.max !== undefined ? `@maxLength ${node.max}` : undefined,
361
+ node && 'pattern' in node && node.pattern ? `@pattern ${node.pattern}` : undefined,
362
+ node?.default ? `@default ${node.default}` : undefined,
363
+ node?.example ? `@example ${node.example}` : undefined,
364
+ ],
365
+ })
242
366
  },
243
- },
244
- }))
367
+ }
368
+ })
package/src/types.ts CHANGED
@@ -2,7 +2,6 @@ import type { Group, Output, PluginFactoryOptions, ResolveNameParams } from '@ku
2
2
  import type { contentType, Oas } from '@kubb/oas'
3
3
  import type { Exclude, Include, Override, ResolvePathOptions } from '@kubb/plugin-oas'
4
4
  import type { Generator } from '@kubb/plugin-oas/generators'
5
- import type ts from 'typescript'
6
5
 
7
6
  export type Options = {
8
7
  /**
@@ -63,6 +62,8 @@ export type Options = {
63
62
  /**
64
63
  * Set a suffix for the generated enums.
65
64
  * @default 'enum'
65
+ * @deprecated Set `enumSuffix` on the adapter (`adapterOas({ enumSuffix })`) instead.
66
+ * In v5, the adapter owns this decision at parse time; the plugin option is ignored.
66
67
  */
67
68
  enumSuffix?: string
68
69
  /**
@@ -70,6 +71,8 @@ export type Options = {
70
71
  * - 'string' represents dates as string values.
71
72
  * - 'date' represents dates as JavaScript Date objects.
72
73
  * @default 'string'
74
+ * @deprecated Set `dateType` on the adapter (`adapterOas({ dateType })`) instead.
75
+ * In v5, the adapter owns this decision at parse time; the plugin option is ignored.
73
76
  */
74
77
  dateType?: 'string' | 'date'
75
78
  /**
@@ -78,6 +81,8 @@ export type Options = {
78
81
  * - 'bigint' uses the TypeScript `bigint` type (accurate for values exceeding Number.MAX_SAFE_INTEGER).
79
82
  * @note in v5 of Kubb 'bigint' will become the default to better align with OpenAPI's int64 specification.
80
83
  * @default 'number'
84
+ * @deprecated Set `integerType` on the adapter (`adapterOas({ integerType })`) instead.
85
+ * In v5, the adapter owns this decision at parse time; the plugin option is ignored.
81
86
  */
82
87
  integerType?: 'number' | 'bigint'
83
88
  /**
@@ -86,6 +91,8 @@ export type Options = {
86
91
  * - 'unknown' requires type narrowing before use.
87
92
  * - 'void' represents no value.
88
93
  * @default 'any'
94
+ * @deprecated Set `unknownType` on the adapter (`adapterOas({ unknownType })`) instead.
95
+ * In v5, the adapter owns this decision at parse time; the plugin option is ignored.
89
96
  */
90
97
  unknownType?: 'any' | 'unknown' | 'void'
91
98
  /**
@@ -94,6 +101,8 @@ export type Options = {
94
101
  * - 'unknown' requires type narrowing before use.
95
102
  * - 'void' represents no value.
96
103
  * @default `unknownType`
104
+ * @deprecated Set `emptySchemaType` on the adapter (`adapterOas({ emptySchemaType })`) instead.
105
+ * In v5, the adapter owns this decision at parse time; the plugin option is ignored.
97
106
  */
98
107
  emptySchemaType?: 'any' | 'unknown' | 'void'
99
108
  /**
@@ -117,17 +126,6 @@ export type Options = {
117
126
  */
118
127
  name?: (name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string
119
128
  }
120
- /**
121
- * @example
122
- * Use https://ts-ast-viewer.com to generate factory code(see createPropertySignature)
123
- * category: factory.createPropertySignature(
124
- * undefined,
125
- * factory.createIdentifier("category"),
126
- * factory.createToken(ts.SyntaxKind.QuestionToken),
127
- * factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
128
- * )
129
- */
130
- mapper?: Record<string, ts.PropertySignature>
131
129
  /**
132
130
  * How to style your params, by default no casing is applied
133
131
  * - 'camelcase' uses camelCase for pathParams, queryParams and headerParams property names
@@ -160,7 +158,6 @@ type ResolvedOptions = {
160
158
  arrayType: NonNullable<Options['arrayType']>
161
159
  transformers: NonNullable<Options['transformers']>
162
160
  syntaxType: NonNullable<Options['syntaxType']>
163
- mapper: Record<string, any>
164
161
  paramsCasing: Options['paramsCasing']
165
162
  }
166
163