@kubb/plugin-ts 5.0.0-alpha.20 → 5.0.0-alpha.22

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 (71) hide show
  1. package/dist/Type-Bf8raoQX.cjs +124 -0
  2. package/dist/Type-Bf8raoQX.cjs.map +1 -0
  3. package/dist/Type-BpXxT4l_.js +113 -0
  4. package/dist/Type-BpXxT4l_.js.map +1 -0
  5. package/dist/builderTs-COUg3xtQ.cjs +135 -0
  6. package/dist/builderTs-COUg3xtQ.cjs.map +1 -0
  7. package/dist/builderTs-DPpkJKd1.js +131 -0
  8. package/dist/builderTs-DPpkJKd1.js.map +1 -0
  9. package/dist/builders.cjs +3 -0
  10. package/dist/builders.d.ts +23 -0
  11. package/dist/builders.js +2 -0
  12. package/dist/{casing-Cp-jbC_k.js → casing-BJHFg-zZ.js} +1 -1
  13. package/dist/{casing-Cp-jbC_k.js.map → casing-BJHFg-zZ.js.map} +1 -1
  14. package/dist/{casing-D2uQKLWS.cjs → casing-DHfdqpLi.cjs} +2 -39
  15. package/dist/{casing-D2uQKLWS.cjs.map → casing-DHfdqpLi.cjs.map} +1 -1
  16. package/dist/chunk-ByKO4r7w.cjs +38 -0
  17. package/dist/components.cjs +1 -1
  18. package/dist/components.d.ts +5 -2
  19. package/dist/components.js +1 -1
  20. package/dist/generators-DFDut8o-.js +555 -0
  21. package/dist/generators-DFDut8o-.js.map +1 -0
  22. package/dist/{generators-xHWQCNd9.cjs → generators-DKd7MYbx.cjs} +300 -293
  23. package/dist/generators-DKd7MYbx.cjs.map +1 -0
  24. package/dist/generators.cjs +2 -1
  25. package/dist/generators.d.ts +5 -2
  26. package/dist/generators.js +2 -2
  27. package/dist/index.cjs +75 -36
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.ts +21 -2
  30. package/dist/index.js +73 -35
  31. package/dist/index.js.map +1 -1
  32. package/dist/{Type-B70QnSzH.cjs → printerTs-BcHudagv.cjs} +41 -135
  33. package/dist/printerTs-BcHudagv.cjs.map +1 -0
  34. package/dist/{Type-CMC7L-38.js → printerTs-CMBCOuqd.js} +19 -132
  35. package/dist/printerTs-CMBCOuqd.js.map +1 -0
  36. package/dist/printers.cjs +3 -0
  37. package/dist/printers.d.ts +81 -0
  38. package/dist/printers.js +2 -0
  39. package/dist/{resolvers-DsKabI0F.js → resolverTsLegacy-CPiqqsO6.js} +10 -9
  40. package/dist/resolverTsLegacy-CPiqqsO6.js.map +1 -0
  41. package/dist/{resolvers-YIpeP5YD.cjs → resolverTsLegacy-CuR9XbKk.cjs} +11 -9
  42. package/dist/resolverTsLegacy-CuR9XbKk.cjs.map +1 -0
  43. package/dist/resolvers.cjs +3 -3
  44. package/dist/resolvers.d.ts +1 -1
  45. package/dist/resolvers.js +1 -1
  46. package/dist/{types-zqLMbIqZ.d.ts → types-CRtcZOCz.d.ts} +59 -25
  47. package/package.json +17 -5
  48. package/src/builders/builderTs.ts +107 -0
  49. package/src/builders/index.ts +1 -0
  50. package/src/components/Enum.tsx +15 -11
  51. package/src/components/Type.tsx +20 -9
  52. package/src/factory.ts +0 -32
  53. package/src/generators/index.ts +1 -0
  54. package/src/generators/typeGenerator.tsx +53 -141
  55. package/src/generators/typeGeneratorLegacy.tsx +348 -0
  56. package/src/index.ts +1 -1
  57. package/src/plugin.ts +36 -44
  58. package/src/presets.ts +27 -7
  59. package/src/printers/index.ts +1 -0
  60. package/src/{printer.ts → printers/printerTs.ts} +31 -19
  61. package/src/resolvers/resolverTs.ts +9 -6
  62. package/src/resolvers/resolverTsLegacy.ts +1 -1
  63. package/src/types.ts +72 -24
  64. package/dist/Type-B70QnSzH.cjs.map +0 -1
  65. package/dist/Type-CMC7L-38.js.map +0 -1
  66. package/dist/generators-BFkr7ecU.js +0 -556
  67. package/dist/generators-BFkr7ecU.js.map +0 -1
  68. package/dist/generators-xHWQCNd9.cjs.map +0 -1
  69. package/dist/resolvers-DsKabI0F.js.map +0 -1
  70. package/dist/resolvers-YIpeP5YD.cjs.map +0 -1
  71. package/src/generators/utils.ts +0 -308
@@ -0,0 +1,348 @@
1
+ import path from 'node:path'
2
+ import { pascalCase } from '@internals/utils'
3
+ import { caseParams, composeTransformers, createProperty, createSchema, narrowSchema, schemaTypes, transform } from '@kubb/ast'
4
+ import type { OperationNode, ParameterNode, SchemaNode } from '@kubb/ast/types'
5
+ import { defineGenerator, getMode } from '@kubb/core'
6
+ import { File } from '@kubb/react-fabric'
7
+ import { Type } from '../components/Type.tsx'
8
+ import { ENUM_TYPES_WITH_KEY_SUFFIX } from '../constants.ts'
9
+ import { resolverTsLegacy } from '../resolvers/resolverTsLegacy.ts'
10
+ import type { PluginTs, ResolverTs } from '../types'
11
+
12
+ type BuildGroupedParamsSchemaOptions = {
13
+ params: Array<ParameterNode>
14
+ parentName?: string
15
+ }
16
+
17
+ function buildGroupedParamsSchema({ params, parentName }: BuildGroupedParamsSchemaOptions): SchemaNode {
18
+ return createSchema({
19
+ type: 'object',
20
+ properties: params.map((param) => {
21
+ let schema = param.schema
22
+ if (narrowSchema(schema, 'enum') && !schema.name && parentName) {
23
+ schema = { ...schema, name: pascalCase([parentName, param.name, 'enum'].join(' ')) }
24
+ }
25
+ return createProperty({
26
+ name: param.name,
27
+ required: param.required,
28
+ schema,
29
+ })
30
+ }),
31
+ })
32
+ }
33
+
34
+ type BuildOperationSchemaOptions = {
35
+ node: OperationNode
36
+ resolver: ResolverTs
37
+ }
38
+
39
+ function buildLegacyResponsesSchemaNode({ node, resolver }: BuildOperationSchemaOptions): SchemaNode | null {
40
+ const isGet = node.method.toLowerCase() === 'get'
41
+ const successResponses = node.responses.filter((res) => {
42
+ const code = Number(res.statusCode)
43
+ return !Number.isNaN(code) && code >= 200 && code < 300
44
+ })
45
+ const errorResponses = node.responses.filter((res) => res.statusCode === 'default' || Number(res.statusCode) >= 400)
46
+
47
+ const responseSchema =
48
+ successResponses.length > 0
49
+ ? successResponses.length === 1
50
+ ? createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, successResponses[0]!.statusCode) })
51
+ : createSchema({
52
+ type: 'union',
53
+ members: successResponses.map((res) => createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, res.statusCode) })),
54
+ })
55
+ : createSchema({ type: 'any' })
56
+
57
+ const errorsSchema =
58
+ errorResponses.length > 0
59
+ ? errorResponses.length === 1
60
+ ? createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, errorResponses[0]!.statusCode) })
61
+ : createSchema({
62
+ type: 'union',
63
+ members: errorResponses.map((res) => createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, res.statusCode) })),
64
+ })
65
+ : createSchema({ type: 'any' })
66
+
67
+ const properties = [createProperty({ name: 'Response', required: true, schema: responseSchema })]
68
+
69
+ if (!isGet && node.requestBody?.schema) {
70
+ properties.push(
71
+ createProperty({
72
+ name: 'Request',
73
+ required: true,
74
+ schema: createSchema({ type: 'ref', name: resolver.resolveDataTypedName(node) }),
75
+ }),
76
+ )
77
+ }
78
+
79
+ if (node.parameters.some((p) => p.in === 'query') && resolver.resolveQueryParamsTypedName) {
80
+ properties.push(
81
+ createProperty({
82
+ name: 'QueryParams',
83
+ required: true,
84
+ schema: createSchema({ type: 'ref', name: resolver.resolveQueryParamsTypedName(node) }),
85
+ }),
86
+ )
87
+ }
88
+
89
+ if (node.parameters.some((p) => p.in === 'path') && resolver.resolvePathParamsTypedName) {
90
+ properties.push(
91
+ createProperty({
92
+ name: 'PathParams',
93
+ required: true,
94
+ schema: createSchema({ type: 'ref', name: resolver.resolvePathParamsTypedName(node) }),
95
+ }),
96
+ )
97
+ }
98
+
99
+ if (node.parameters.some((p) => p.in === 'header') && resolver.resolveHeaderParamsTypedName) {
100
+ properties.push(
101
+ createProperty({
102
+ name: 'HeaderParams',
103
+ required: true,
104
+ schema: createSchema({ type: 'ref', name: resolver.resolveHeaderParamsTypedName(node) }),
105
+ }),
106
+ )
107
+ }
108
+
109
+ properties.push(createProperty({ name: 'Errors', required: true, schema: errorsSchema }))
110
+
111
+ return createSchema({ type: 'object', properties })
112
+ }
113
+
114
+ function buildLegacyResponseUnionSchemaNode({ node, resolver }: BuildOperationSchemaOptions): SchemaNode {
115
+ const successResponses = node.responses.filter((res) => {
116
+ const code = Number(res.statusCode)
117
+ return !Number.isNaN(code) && code >= 200 && code < 300
118
+ })
119
+
120
+ if (successResponses.length === 0) {
121
+ return createSchema({ type: 'any' })
122
+ }
123
+
124
+ if (successResponses.length === 1) {
125
+ return createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, successResponses[0]!.statusCode) })
126
+ }
127
+
128
+ return createSchema({
129
+ type: 'union',
130
+ members: successResponses.map((res) => createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, res.statusCode) })),
131
+ })
132
+ }
133
+
134
+ function nameUnnamedEnums(node: SchemaNode, parentName: string): SchemaNode {
135
+ return transform(node, {
136
+ schema(n) {
137
+ const enumNode = narrowSchema(n, 'enum')
138
+ if (enumNode && !enumNode.name) {
139
+ return { ...enumNode, name: pascalCase([parentName, 'enum'].join(' ')) }
140
+ }
141
+ return undefined
142
+ },
143
+ property(p) {
144
+ const enumNode = narrowSchema(p.schema, 'enum')
145
+ if (enumNode && !enumNode.name) {
146
+ return {
147
+ ...p,
148
+ schema: { ...enumNode, name: pascalCase([parentName, p.name, 'enum'].join(' ')) },
149
+ }
150
+ }
151
+ return undefined
152
+ },
153
+ })
154
+ }
155
+
156
+ export const typeGeneratorLegacy = defineGenerator<PluginTs>({
157
+ name: 'typescript-legacy',
158
+ type: 'react',
159
+ Operation({ node, adapter, options, config }) {
160
+ const { enumType, enumTypeSuffix, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group, output, resolver, transformers = [] } = options
161
+
162
+ const root = path.resolve(config.root, config.output.path)
163
+ const mode = getMode(path.resolve(root, output.path))
164
+
165
+ const file = resolver.resolveFile({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group })
166
+ const params = caseParams(node.parameters, paramsCasing)
167
+
168
+ function renderSchemaType({
169
+ node: schemaNode,
170
+ name,
171
+ typedName,
172
+ description,
173
+ keysToOmit,
174
+ }: {
175
+ node: SchemaNode | null
176
+ name: string
177
+ typedName: string
178
+ description?: string
179
+ keysToOmit?: Array<string>
180
+ }) {
181
+ if (!schemaNode) {
182
+ return null
183
+ }
184
+
185
+ const transformedNode = transform(schemaNode, composeTransformers(...transformers))
186
+
187
+ const imports = adapter.getImports(transformedNode, (schemaName) => ({
188
+ name: resolver.default(schemaName, 'type'),
189
+ path: resolver.resolveFile({ name: schemaName, extname: '.ts' }, { root, output, group }).path,
190
+ }))
191
+
192
+ return (
193
+ <>
194
+ {mode === 'split' &&
195
+ imports.map((imp) => <File.Import key={[name, imp.path, imp.isTypeOnly].join('-')} root={file.path} path={imp.path} name={imp.name} isTypeOnly />)}
196
+ <Type
197
+ name={name}
198
+ typedName={typedName}
199
+ node={transformedNode}
200
+ description={description}
201
+ enumType={enumType}
202
+ enumTypeSuffix={enumTypeSuffix}
203
+ enumKeyCasing={enumKeyCasing}
204
+ optionalType={optionalType}
205
+ arrayType={arrayType}
206
+ syntaxType={syntaxType}
207
+ resolver={resolver}
208
+ keysToOmit={keysToOmit}
209
+ />
210
+ </>
211
+ )
212
+ }
213
+
214
+ const pathParams = params.filter((p) => p.in === 'path')
215
+ const queryParams = params.filter((p) => p.in === 'query')
216
+ const headerParams = params.filter((p) => p.in === 'header')
217
+
218
+ const responseTypes = node.responses.map((res) => {
219
+ const responseName = resolver.resolveResponseStatusName(node, res.statusCode)
220
+ const baseResponseName = resolverTsLegacy.resolveResponseStatusName(node, res.statusCode)
221
+
222
+ return renderSchemaType({
223
+ node: res.schema ? nameUnnamedEnums(res.schema, baseResponseName) : res.schema,
224
+ name: responseName,
225
+ typedName: resolver.resolveResponseStatusTypedName(node, res.statusCode),
226
+ description: res.description,
227
+ keysToOmit: res.keysToOmit,
228
+ })
229
+ })
230
+
231
+ const requestType = node.requestBody?.schema
232
+ ? renderSchemaType({
233
+ node: nameUnnamedEnums(node.requestBody.schema, resolverTsLegacy.resolveDataName(node)),
234
+ name: resolver.resolveDataName(node),
235
+ typedName: resolver.resolveDataTypedName(node),
236
+ description: node.requestBody.description ?? node.requestBody.schema.description,
237
+ keysToOmit: node.requestBody.keysToOmit,
238
+ })
239
+ : null
240
+
241
+ const legacyParamTypes = [
242
+ pathParams.length > 0
243
+ ? renderSchemaType({
244
+ node: buildGroupedParamsSchema({ params: pathParams, parentName: resolverTsLegacy.resolvePathParamsName!(node) }),
245
+ name: resolver.resolvePathParamsName!(node),
246
+ typedName: resolver.resolvePathParamsTypedName!(node),
247
+ })
248
+ : null,
249
+ queryParams.length > 0
250
+ ? renderSchemaType({
251
+ node: buildGroupedParamsSchema({ params: queryParams, parentName: resolverTsLegacy.resolveQueryParamsName!(node) }),
252
+ name: resolver.resolveQueryParamsName!(node),
253
+ typedName: resolver.resolveQueryParamsTypedName!(node),
254
+ })
255
+ : null,
256
+ headerParams.length > 0
257
+ ? renderSchemaType({
258
+ node: buildGroupedParamsSchema({ params: headerParams, parentName: resolverTsLegacy.resolveHeaderParamsName!(node) }),
259
+ name: resolver.resolveHeaderParamsName!(node),
260
+ typedName: resolver.resolveHeaderParamsTypedName!(node),
261
+ })
262
+ : null,
263
+ ]
264
+
265
+ const legacyResponsesType = renderSchemaType({
266
+ node: buildLegacyResponsesSchemaNode({ node, resolver }),
267
+ name: resolver.resolveResponsesName(node),
268
+ typedName: resolver.resolveResponsesTypedName(node),
269
+ })
270
+
271
+ const legacyResponseType = renderSchemaType({
272
+ node: buildLegacyResponseUnionSchemaNode({ node, resolver }),
273
+ name: resolver.resolveResponseName(node),
274
+ typedName: resolver.resolveResponseTypedName(node),
275
+ })
276
+
277
+ return (
278
+ <File
279
+ baseName={file.baseName}
280
+ path={file.path}
281
+ meta={file.meta}
282
+ banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
283
+ footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
284
+ >
285
+ {legacyParamTypes}
286
+ {responseTypes}
287
+ {requestType}
288
+ {legacyResponseType}
289
+ {legacyResponsesType}
290
+ </File>
291
+ )
292
+ },
293
+ Schema({ node, adapter, options, config }) {
294
+ const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, resolver, transformers = [] } = options
295
+
296
+ const root = path.resolve(config.root, config.output.path)
297
+ const mode = getMode(path.resolve(root, output.path))
298
+
299
+ if (!node.name) {
300
+ return
301
+ }
302
+
303
+ const transformedNode = transform(node, composeTransformers(...transformers))
304
+
305
+ const imports = adapter.getImports(transformedNode, (schemaName) => ({
306
+ name: resolver.default(schemaName, 'type'),
307
+ path: resolver.resolveFile({ name: schemaName, extname: '.ts' }, { root, output, group }).path,
308
+ }))
309
+
310
+ const isEnumSchema = !!narrowSchema(node, schemaTypes.enum)
311
+
312
+ const typedName =
313
+ ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyTypedName(node, enumTypeSuffix) : resolver.resolveTypedName(node.name)
314
+
315
+ const type = {
316
+ name: resolver.resolveName(node.name),
317
+ typedName,
318
+ file: resolver.resolveFile({ name: node.name, extname: '.ts' }, { root, output, group }),
319
+ } as const
320
+
321
+ return (
322
+ <File
323
+ baseName={type.file.baseName}
324
+ path={type.file.path}
325
+ meta={type.file.meta}
326
+ banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
327
+ footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
328
+ >
329
+ {mode === 'split' &&
330
+ imports.map((imp) => (
331
+ <File.Import key={[node.name, imp.path, imp.isTypeOnly].join('-')} root={type.file.path} path={imp.path} name={imp.name} isTypeOnly />
332
+ ))}
333
+ <Type
334
+ name={type.name}
335
+ typedName={type.typedName}
336
+ node={transformedNode}
337
+ enumType={enumType}
338
+ enumTypeSuffix={enumTypeSuffix}
339
+ enumKeyCasing={enumKeyCasing}
340
+ optionalType={optionalType}
341
+ arrayType={arrayType}
342
+ syntaxType={syntaxType}
343
+ resolver={resolver}
344
+ />
345
+ </File>
346
+ )
347
+ },
348
+ })
package/src/index.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { pluginTs, pluginTsName } from './plugin.ts'
2
- export type { PluginTs, ResolverTs } from './types.ts'
2
+ export type { PluginTs } from './types.ts'
package/src/plugin.ts CHANGED
@@ -1,13 +1,30 @@
1
1
  import path from 'node:path'
2
- import { camelCase } from '@internals/utils'
3
2
  import { walk } from '@kubb/ast'
4
- import { createPlugin, type Group, getBarrelFiles, getMode, renderOperation, renderSchema } from '@kubb/core'
5
- import { typeGenerator } from './generators/index.ts'
3
+ import { createPlugin, getBarrelFiles, renderOperation, renderSchema } from '@kubb/core'
6
4
  import { getPreset } from './presets.ts'
7
5
  import type { PluginTs } from './types.ts'
8
6
 
7
+ /**
8
+ * Canonical plugin name for `@kubb/plugin-ts`, used to identify the plugin in driver lookups and warnings.
9
+ */
9
10
  export const pluginTsName = 'plugin-ts' satisfies PluginTs['name']
10
11
 
12
+ /**
13
+ * The `@kubb/plugin-ts` plugin factory.
14
+ *
15
+ * Generates TypeScript type declarations from an OpenAPI/AST `RootNode`.
16
+ * Walks schemas and operations, delegates rendering to the active generators,
17
+ * and writes barrel files based on `output.barrelType`.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { pluginTs } from '@kubb/plugin-ts'
22
+ *
23
+ * export default defineConfig({
24
+ * plugins: [pluginTs({ output: { path: 'types' }, enumType: 'asConst' })],
25
+ * })
26
+ * ```
27
+ */
11
28
  export const pluginTs = createPlugin<PluginTs>((options) => {
12
29
  const {
13
30
  output = { path: 'types', barrelType: 'named' },
@@ -16,78 +33,56 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
16
33
  include,
17
34
  override = [],
18
35
  enumType = 'asConst',
36
+ enumTypeSuffix = 'Key',
19
37
  enumKeyCasing = 'none',
20
38
  optionalType = 'questionToken',
21
39
  arrayType = 'array',
22
40
  syntaxType = 'type',
23
41
  paramsCasing,
24
- generators = [typeGenerator].filter(Boolean),
25
42
  compatibilityPreset = 'default',
26
- resolvers: userResolvers,
43
+ resolvers: userResolvers = [],
27
44
  transformers: userTransformers = [],
45
+ generators: userGenerators = [],
28
46
  } = options
29
47
 
30
- const { baseResolver, resolver, transformers } = getPreset(compatibilityPreset, {
48
+ const { resolver, transformers, generators } = getPreset(compatibilityPreset, {
31
49
  resolvers: userResolvers,
32
50
  transformers: userTransformers,
51
+ generators: userGenerators,
33
52
  })
34
53
 
35
54
  let resolveNameWarning = false
55
+ let resolvePathWarning = false
36
56
 
37
57
  return {
38
58
  name: pluginTsName,
39
59
  options: {
40
60
  output,
41
61
  optionalType,
62
+ group,
42
63
  arrayType,
43
64
  enumType,
65
+ enumTypeSuffix,
44
66
  enumKeyCasing,
45
67
  syntaxType,
46
- group,
47
- override,
48
68
  paramsCasing,
49
- compatibilityPreset,
50
- baseResolver,
51
69
  resolver,
52
70
  transformers,
53
71
  },
54
72
  resolvePath(baseName, pathMode, options) {
55
- const root = path.resolve(this.config.root, this.config.output.path)
56
- const mode = pathMode ?? getMode(path.resolve(root, output.path))
57
-
58
- if (mode === 'single') {
59
- /**
60
- * when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend
61
- * Other plugins then need to call addOrAppend instead of just add from the fileManager class
62
- */
63
- return path.resolve(root, output.path)
64
- }
65
-
66
- if (group && (options?.group?.path || options?.group?.tag)) {
67
- const groupName: Group['name'] = group?.name
68
- ? group.name
69
- : (ctx) => {
70
- if (group?.type === 'path') {
71
- return `${ctx.group.split('/')[1]}`
72
- }
73
- return `${camelCase(ctx.group)}Controller`
74
- }
75
-
76
- return path.resolve(
77
- root,
78
- output.path,
79
- groupName({
80
- group: group.type === 'path' ? options.group.path! : options.group.tag!,
81
- }),
82
- baseName,
83
- )
73
+ if (!resolvePathWarning) {
74
+ this.driver.events.emit('warn', 'Do not use resolvePath for pluginTs, use resolverTs.resolvePath instead')
75
+ resolvePathWarning = true
84
76
  }
85
77
 
86
- return path.resolve(root, output.path, baseName)
78
+ return resolver.resolvePath(
79
+ { baseName, pathMode, tag: options?.group?.tag, path: options?.group?.path },
80
+ { root: path.resolve(this.config.root, this.config.output.path), output, group },
81
+ )
87
82
  },
88
83
  resolveName(name, type) {
89
84
  if (!resolveNameWarning) {
90
- this.driver.events.emit('warn', 'Do not use resolveName for pluginTs, use resolverTs instead')
85
+ this.driver.events.emit('warn', 'Do not use resolveName for pluginTs, use resolverTs.default instead')
91
86
  resolveNameWarning = true
92
87
  }
93
88
 
@@ -97,7 +92,6 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
97
92
  const { config, fabric, plugin, adapter, rootNode, driver, openInStudio } = this
98
93
 
99
94
  const root = path.resolve(config.root, config.output.path)
100
- const mode = getMode(path.resolve(root, output.path))
101
95
 
102
96
  if (!adapter) {
103
97
  throw new Error('Plugin cannot work without adapter being set')
@@ -124,7 +118,6 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
124
118
  Component: generator.Schema,
125
119
  plugin,
126
120
  driver,
127
- mode,
128
121
  })
129
122
  }
130
123
  })
@@ -148,7 +141,6 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
148
141
  Component: generator.Operation,
149
142
  plugin,
150
143
  driver,
151
- mode,
152
144
  })
153
145
  }
154
146
  })
package/src/presets.ts CHANGED
@@ -1,23 +1,43 @@
1
1
  import type { Visitor } from '@kubb/ast/types'
2
- import { type CompatibilityPreset, definePreset, definePresets, getPreset as getCorePreset } from '@kubb/core'
2
+ import { type CompatibilityPreset, definePreset, definePresets, type Generator, getPreset as getCorePreset } from '@kubb/core'
3
+ import { typeGenerator, typeGeneratorLegacy } from './generators/index.ts'
3
4
  import { resolverTs, resolverTsLegacy } from './resolvers/index.ts'
4
- import type { ResolverTs } from './types.ts'
5
+ import type { PluginTs, ResolverTs } from './types.ts'
5
6
 
7
+ /**
8
+ * Built-in preset registry for `@kubb/plugin-ts`.
9
+ *
10
+ * - `default` — uses `resolverTs` and `typeGenerator` (current naming conventions).
11
+ * - `kubbV4` — uses `resolverTsLegacy` and `typeGeneratorLegacy` (Kubb v4 naming conventions).
12
+ */
6
13
  export const presets = definePresets<ResolverTs>({
7
- default: definePreset('default', { resolvers: [resolverTs] }),
8
- kubbV4: definePreset('kubbV4', { resolvers: [resolverTsLegacy] }),
14
+ default: definePreset('default', { resolvers: [resolverTs], generators: [typeGenerator] }),
15
+ kubbV4: definePreset('kubbV4', { resolvers: [resolverTsLegacy], generators: [typeGeneratorLegacy] }),
9
16
  })
10
17
 
11
18
  type GetPresetOptions = {
12
- resolvers?: Array<ResolverTs>
13
- transformers?: Array<Visitor>
19
+ resolvers: Array<ResolverTs>
20
+ transformers: Array<Visitor>
21
+ generators: Array<Generator<PluginTs>>
14
22
  }
15
23
 
16
- export function getPreset(preset: CompatibilityPreset, { resolvers, transformers }: GetPresetOptions = {}) {
24
+ /**
25
+ * Resolves a compatibility preset for `plugin-ts`, merging user-supplied resolvers,
26
+ * transformers, and generators on top of the built-in preset defaults.
27
+ *
28
+ * `resolverTs` is always prepended to the resolver list as the baseline.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const preset = getPreset('kubbV4', { resolvers: [], transformers: [], generators: [] })
33
+ * ```
34
+ */
35
+ export function getPreset(preset: CompatibilityPreset, { resolvers, transformers, generators }: GetPresetOptions) {
17
36
  return getCorePreset({
18
37
  preset,
19
38
  presets,
20
39
  resolvers: [resolverTs, ...(resolvers ?? [])],
21
40
  transformers,
41
+ generators,
22
42
  })
23
43
  }
@@ -0,0 +1 @@
1
+ export { printerTs } from './printerTs.ts'