@kubb/plugin-ts 5.0.0-alpha.5 → 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.
- package/dist/{components-Cwn1rflQ.js → components-CRu8IKY3.js} +4 -6
- package/dist/{components-Cwn1rflQ.js.map → components-CRu8IKY3.js.map} +1 -1
- package/dist/{components-CxTvawXI.cjs → components-DeNDKlzf.cjs} +4 -6
- package/dist/components-DeNDKlzf.cjs.map +1 -0
- package/dist/components.cjs +1 -1
- package/dist/components.d.ts +1 -3
- package/dist/components.js +1 -1
- package/dist/generators.cjs +1 -1
- package/dist/generators.d.ts +1 -1
- package/dist/generators.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{plugin-kdQ5D2cW.js → plugin-BcK4SBA0.js} +297 -215
- package/dist/plugin-BcK4SBA0.js.map +1 -0
- package/dist/{plugin-meWNDVe7.cjs → plugin-BrQcApyO.cjs} +300 -219
- package/dist/plugin-BrQcApyO.cjs.map +1 -0
- package/dist/{types-eWhVEVgF.d.ts → types-CsvB6X5Y.d.ts} +1 -14
- package/package.json +5 -5
- package/src/components/Type.tsx +0 -3
- package/src/components/v2/Enum.tsx +67 -0
- package/src/components/v2/Type.tsx +11 -119
- package/src/constants.ts +29 -0
- package/src/generators/typeGenerator.tsx +2 -4
- package/src/generators/v2/typeGenerator.tsx +22 -14
- package/src/generators/v2/utils.ts +10 -15
- package/src/parser.ts +1 -8
- package/src/plugin.ts +0 -2
- package/src/printer.ts +229 -119
- package/src/types.ts +0 -13
- package/dist/components-CxTvawXI.cjs.map +0 -1
- package/dist/plugin-kdQ5D2cW.js.map +0 -1
- package/dist/plugin-meWNDVe7.cjs.map +0 -1
package/src/printer.ts
CHANGED
|
@@ -1,32 +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: '
|
|
15
|
+
optionalType: PluginTs['resolvedOptions']['optionalType']
|
|
14
16
|
/**
|
|
15
17
|
* @default `'array'`
|
|
16
18
|
*/
|
|
17
|
-
arrayType: '
|
|
19
|
+
arrayType: PluginTs['resolvedOptions']['arrayType']
|
|
18
20
|
/**
|
|
19
21
|
* @default `'inlineLiteral'`
|
|
20
22
|
*/
|
|
21
|
-
enumType: '
|
|
23
|
+
enumType: PluginTs['resolvedOptions']['enumType']
|
|
22
24
|
/**
|
|
23
|
-
*
|
|
25
|
+
* Controls whether a `type` alias or `interface` declaration is emitted.
|
|
26
|
+
* @default `'type'`
|
|
24
27
|
*/
|
|
25
|
-
|
|
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>
|
|
26
44
|
}
|
|
27
45
|
|
|
28
|
-
|
|
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>
|
|
29
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Converts a primitive const value to a TypeScript literal type node.
|
|
53
|
+
* Handles negative numbers via a prefix unary expression.
|
|
54
|
+
*/
|
|
30
55
|
function constToTypeNode(value: string | number | boolean, format: 'string' | 'number' | 'boolean'): ts.TypeNode | undefined {
|
|
31
56
|
if (format === 'boolean') {
|
|
32
57
|
return factory.createLiteralTypeNode(value === true ? factory.createTrue() : factory.createFalse())
|
|
@@ -40,16 +65,26 @@ function constToTypeNode(value: string | number | boolean, format: 'string' | 'n
|
|
|
40
65
|
return factory.createLiteralTypeNode(factory.createStringLiteral(String(value)))
|
|
41
66
|
}
|
|
42
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Returns a `Date` reference type node when `representation` is `'date'`, otherwise falls back to `string`.
|
|
70
|
+
*/
|
|
43
71
|
function dateOrStringNode(node: { representation?: string }): ts.TypeNode {
|
|
44
72
|
return node.representation === 'date' ? factory.createTypeReferenceNode(factory.createIdentifier('Date')) : factory.keywordTypeNodes.string
|
|
45
73
|
}
|
|
46
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Maps an array of `SchemaNode`s through the printer, filtering out `null` and `undefined` results.
|
|
77
|
+
*/
|
|
47
78
|
function buildMemberNodes(members: Array<SchemaNode> | undefined, print: (node: SchemaNode) => ts.TypeNode | null | undefined): Array<ts.TypeNode> {
|
|
48
|
-
return (members ?? []).map(print).filter(Boolean)
|
|
79
|
+
return (members ?? []).map(print).filter(Boolean)
|
|
49
80
|
}
|
|
50
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
|
+
*/
|
|
51
86
|
function buildTupleNode(node: ArraySchemaNode, print: (node: SchemaNode) => ts.TypeNode | null | undefined): ts.TypeNode | undefined {
|
|
52
|
-
let items = (node.items ?? []).map(print).filter(Boolean)
|
|
87
|
+
let items = (node.items ?? []).map(print).filter(Boolean)
|
|
53
88
|
|
|
54
89
|
const restNode = node.rest ? (print(node.rest) ?? undefined) : undefined
|
|
55
90
|
const { min, max } = node
|
|
@@ -72,25 +107,31 @@ function buildTupleNode(node: ArraySchemaNode, print: (node: SchemaNode) => ts.T
|
|
|
72
107
|
return factory.createTupleTypeNode(items)
|
|
73
108
|
}
|
|
74
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Applies `nullable` and optional/nullish `| undefined` union modifiers to a property's resolved base type.
|
|
112
|
+
*/
|
|
75
113
|
function buildPropertyType(schema: SchemaNode, baseType: ts.TypeNode, optionalType: TsOptions['optionalType']): ts.TypeNode {
|
|
76
|
-
const addsUndefined =
|
|
114
|
+
const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType)
|
|
77
115
|
|
|
78
116
|
let type = baseType
|
|
79
117
|
|
|
80
118
|
if (schema.nullable) {
|
|
81
|
-
type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.null] })
|
|
119
|
+
type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.null] })
|
|
82
120
|
}
|
|
83
121
|
|
|
84
122
|
if ((schema.nullish || schema.optional) && addsUndefined) {
|
|
85
|
-
type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.undefined] })
|
|
123
|
+
type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.undefined] })
|
|
86
124
|
}
|
|
87
125
|
|
|
88
126
|
return type
|
|
89
127
|
}
|
|
90
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Collects JSDoc annotation strings (description, deprecated, min/max, pattern, default, example, type) for a schema node.
|
|
131
|
+
*/
|
|
91
132
|
function buildPropertyJSDocComments(schema: SchemaNode): Array<string | undefined> {
|
|
92
133
|
return [
|
|
93
|
-
'description' in schema && schema.description ? `@description ${jsStringEscape(schema.description
|
|
134
|
+
'description' in schema && schema.description ? `@description ${jsStringEscape(schema.description)}` : undefined,
|
|
94
135
|
'deprecated' in schema && schema.deprecated ? '@deprecated' : undefined,
|
|
95
136
|
'min' in schema && schema.min !== undefined ? `@minLength ${schema.min}` : undefined,
|
|
96
137
|
'max' in schema && schema.max !== undefined ? `@maxLength ${schema.max}` : undefined,
|
|
@@ -105,6 +146,9 @@ function buildPropertyJSDocComments(schema: SchemaNode): Array<string | undefine
|
|
|
105
146
|
]
|
|
106
147
|
}
|
|
107
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Creates TypeScript index signatures for `additionalProperties` and `patternProperties` on an object schema node.
|
|
151
|
+
*/
|
|
108
152
|
function buildIndexSignatures(
|
|
109
153
|
node: { additionalProperties?: SchemaNode | boolean; patternProperties?: Record<string, SchemaNode> },
|
|
110
154
|
propertyCount: number,
|
|
@@ -113,7 +157,8 @@ function buildIndexSignatures(
|
|
|
113
157
|
const elements: Array<ts.TypeElement> = []
|
|
114
158
|
|
|
115
159
|
if (node.additionalProperties && node.additionalProperties !== true) {
|
|
116
|
-
const additionalType =
|
|
160
|
+
const additionalType = print(node.additionalProperties) ?? factory.keywordTypeNodes.unknown
|
|
161
|
+
|
|
117
162
|
elements.push(factory.createIndexSignature(propertyCount > 0 ? factory.keywordTypeNodes.unknown : additionalType))
|
|
118
163
|
} else if (node.additionalProperties === true) {
|
|
119
164
|
elements.push(factory.createIndexSignature(factory.keywordTypeNodes.unknown))
|
|
@@ -122,9 +167,10 @@ function buildIndexSignatures(
|
|
|
122
167
|
if (node.patternProperties) {
|
|
123
168
|
const first = Object.values(node.patternProperties)[0]
|
|
124
169
|
if (first) {
|
|
125
|
-
let patternType =
|
|
170
|
+
let patternType = print(first) ?? factory.keywordTypeNodes.unknown
|
|
171
|
+
|
|
126
172
|
if (first.nullable) {
|
|
127
|
-
patternType = factory.createUnionDeclaration({ nodes: [patternType, factory.keywordTypeNodes.null] })
|
|
173
|
+
patternType = factory.createUnionDeclaration({ nodes: [patternType, factory.keywordTypeNodes.null] })
|
|
128
174
|
}
|
|
129
175
|
elements.push(factory.createIndexSignature(patternType))
|
|
130
176
|
}
|
|
@@ -134,125 +180,189 @@ function buildIndexSignatures(
|
|
|
134
180
|
}
|
|
135
181
|
|
|
136
182
|
/**
|
|
137
|
-
*
|
|
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.
|
|
138
189
|
*
|
|
139
|
-
*
|
|
140
|
-
* per printer instance
|
|
141
|
-
*
|
|
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.
|
|
192
|
+
*
|
|
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
|
+
* ```
|
|
142
204
|
*/
|
|
143
|
-
export const printerTs = definePrinter<TsPrinter>((options) =>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
+
}
|
|
177
251
|
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
.filter((v): v is string | number | boolean => v !== null)
|
|
181
|
-
.map((value) => constToTypeNode(value, typeof value === 'number' ? 'number' : typeof value === 'boolean' ? 'boolean' : 'string'))
|
|
182
|
-
.filter(Boolean) as Array<ts.TypeNode>
|
|
252
|
+
const resolvedName = pascalCase(node.name)
|
|
253
|
+
const typeName = ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enumType) ? `${resolvedName}Key` : resolvedName
|
|
183
254
|
|
|
184
|
-
return factory.
|
|
185
|
-
}
|
|
255
|
+
return factory.createTypeReferenceNode(typeName, undefined)
|
|
256
|
+
},
|
|
257
|
+
union(node) {
|
|
258
|
+
const members = node.members ?? []
|
|
186
259
|
|
|
187
|
-
|
|
260
|
+
const hasStringLiteral = members.some((m) => m.type === 'enum' && m.enumType === 'string')
|
|
261
|
+
const hasPlainString = members.some((m) => isPlainStringType(m))
|
|
188
262
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const nodes = members
|
|
199
|
-
.map((m) => {
|
|
200
|
-
if (isPlainStringType(m)) {
|
|
201
|
-
return factory.createIntersectionDeclaration({
|
|
202
|
-
nodes: [factory.keywordTypeNodes.string, factory.createTypeLiteralNode([])],
|
|
203
|
-
withParentheses: true,
|
|
204
|
-
}) as ts.TypeNode
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return this.print(m)
|
|
208
|
-
})
|
|
209
|
-
.filter(Boolean) as Array<ts.TypeNode>
|
|
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
|
+
}
|
|
210
272
|
|
|
211
|
-
|
|
212
|
-
|
|
273
|
+
return this.print(m)
|
|
274
|
+
})
|
|
275
|
+
.filter(Boolean)
|
|
213
276
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
intersection(node) {
|
|
217
|
-
return factory.createIntersectionDeclaration({ withParentheses: true, nodes: buildMemberNodes(node.members, this.print) }) ?? undefined
|
|
218
|
-
},
|
|
219
|
-
array(node) {
|
|
220
|
-
const itemNodes = (node.items ?? []).map((item) => this.print(item)).filter(Boolean) as Array<ts.TypeNode>
|
|
277
|
+
return factory.createUnionDeclaration({ withParentheses: true, nodes: memberNodes }) ?? undefined
|
|
278
|
+
}
|
|
221
279
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
+
})
|
|
307
|
+
|
|
308
|
+
return factory.appendJSDocToNode({ node: propertyNode, comments: buildPropertyJSDocComments(prop.schema) })
|
|
309
|
+
})
|
|
230
310
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
311
|
+
const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, print)]
|
|
312
|
+
|
|
313
|
+
if (!allElements.length) {
|
|
314
|
+
return factory.keywordTypeNodes.object
|
|
234
315
|
}
|
|
235
316
|
|
|
236
|
-
|
|
237
|
-
|
|
317
|
+
return factory.createTypeLiteralNode(allElements)
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
print(node) {
|
|
321
|
+
let type = this.print(node)
|
|
238
322
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
type,
|
|
243
|
-
readOnly: prop.schema.readOnly,
|
|
244
|
-
})
|
|
323
|
+
if (!type) {
|
|
324
|
+
return undefined
|
|
325
|
+
}
|
|
245
326
|
|
|
246
|
-
|
|
247
|
-
|
|
327
|
+
// Apply top-level nullable / optional union modifiers.
|
|
328
|
+
if (node.nullable) {
|
|
329
|
+
type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.null] })
|
|
330
|
+
}
|
|
248
331
|
|
|
249
|
-
|
|
332
|
+
if ((node.nullish || node.optional) && addsUndefined) {
|
|
333
|
+
type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.undefined] })
|
|
334
|
+
}
|
|
250
335
|
|
|
251
|
-
|
|
252
|
-
|
|
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
|
|
253
340
|
}
|
|
254
341
|
|
|
255
|
-
|
|
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
|
+
})
|
|
256
366
|
},
|
|
257
|
-
}
|
|
258
|
-
})
|
|
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
|
/**
|
|
@@ -127,17 +126,6 @@ export type Options = {
|
|
|
127
126
|
*/
|
|
128
127
|
name?: (name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string
|
|
129
128
|
}
|
|
130
|
-
/**
|
|
131
|
-
* @example
|
|
132
|
-
* Use https://ts-ast-viewer.com to generate factory code(see createPropertySignature)
|
|
133
|
-
* category: factory.createPropertySignature(
|
|
134
|
-
* undefined,
|
|
135
|
-
* factory.createIdentifier("category"),
|
|
136
|
-
* factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
137
|
-
* factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
|
|
138
|
-
* )
|
|
139
|
-
*/
|
|
140
|
-
mapper?: Record<string, ts.PropertySignature>
|
|
141
129
|
/**
|
|
142
130
|
* How to style your params, by default no casing is applied
|
|
143
131
|
* - 'camelcase' uses camelCase for pathParams, queryParams and headerParams property names
|
|
@@ -170,7 +158,6 @@ type ResolvedOptions = {
|
|
|
170
158
|
arrayType: NonNullable<Options['arrayType']>
|
|
171
159
|
transformers: NonNullable<Options['transformers']>
|
|
172
160
|
syntaxType: NonNullable<Options['syntaxType']>
|
|
173
|
-
mapper: Record<string, any>
|
|
174
161
|
paramsCasing: Options['paramsCasing']
|
|
175
162
|
}
|
|
176
163
|
|