@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.
@@ -1,9 +1,11 @@
1
+ import { pascalCase } from '@internals/utils'
1
2
  import { applyParamsCasing } from '@kubb/ast'
2
3
  import type { SchemaNode } from '@kubb/ast/types'
3
4
  import { defineGenerator } from '@kubb/core'
4
5
  import { useKubb } from '@kubb/core/hooks'
5
6
  import { File } from '@kubb/react-fabric'
6
7
  import { Type } from '../../components/v2/Type.tsx'
8
+ import { ENUM_TYPES_WITH_KEY_SUFFIX } from '../../constants.ts'
7
9
  import type { PluginTs } from '../../types'
8
10
  import { buildDataSchemaNode, buildResponsesSchemaNode, buildResponseUnionSchemaNode } from './utils.ts'
9
11
 
@@ -11,10 +13,17 @@ export const typeGenerator = defineGenerator<PluginTs>({
11
13
  name: 'typescript',
12
14
  type: 'react',
13
15
  Operation({ node, adapter, options }) {
14
- const { enumType, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, mapper } = options
16
+ const { enumType, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group } = options
15
17
  const { mode, getFile, resolveName } = useKubb<PluginTs>()
16
18
 
17
- const file = getFile({ name: node.operationId, extname: '.ts', mode })
19
+ const file = getFile({
20
+ name: node.operationId,
21
+ extname: '.ts',
22
+ mode,
23
+ options: {
24
+ group: group ? (group.type === 'tag' ? { tag: node.tags[0] } : { path: node.path }) : undefined,
25
+ },
26
+ })
18
27
  const params = applyParamsCasing(node.parameters, paramsCasing)
19
28
 
20
29
  function renderSchemaType({
@@ -51,7 +60,6 @@ export const typeGenerator = defineGenerator<PluginTs>({
51
60
  optionalType={optionalType}
52
61
  arrayType={arrayType}
53
62
  syntaxType={syntaxType}
54
- mapper={mapper}
55
63
  />
56
64
  </>
57
65
  )
@@ -60,8 +68,8 @@ export const typeGenerator = defineGenerator<PluginTs>({
60
68
  const paramTypes = params.map((param) =>
61
69
  renderSchemaType({
62
70
  node: param.schema,
63
- name: resolveName({ name: `${node.operationId} ${param.name}`, type: 'function' }),
64
- typedName: resolveName({ name: `${node.operationId} ${param.name}`, type: 'type' }),
71
+ name: resolveName({ name: `${node.operationId} ${pascalCase(param.in)} ${param.name}`, type: 'function' }),
72
+ typedName: resolveName({ name: `${node.operationId} ${pascalCase(param.in)} ${param.name}`, type: 'type' }),
65
73
  }),
66
74
  )
67
75
 
@@ -70,8 +78,8 @@ export const typeGenerator = defineGenerator<PluginTs>({
70
78
  .map((res) =>
71
79
  renderSchemaType({
72
80
  node: res.schema!,
73
- name: resolveName({ name: `${node.operationId} ${res.statusCode}`, type: 'function' }),
74
- typedName: resolveName({ name: `${node.operationId} ${res.statusCode}`, type: 'type' }),
81
+ name: resolveName({ name: `${node.operationId} Status ${res.statusCode}`, type: 'function' }),
82
+ typedName: resolveName({ name: `${node.operationId} Status ${res.statusCode}`, type: 'type' }),
75
83
  description: res.description,
76
84
  }),
77
85
  )
@@ -79,16 +87,16 @@ export const typeGenerator = defineGenerator<PluginTs>({
79
87
  const requestType = node.requestBody
80
88
  ? renderSchemaType({
81
89
  node: node.requestBody,
82
- name: resolveName({ name: `${node.operationId} MutationRequest`, type: 'function' }),
83
- typedName: resolveName({ name: `${node.operationId} MutationRequest`, type: 'type' }),
90
+ name: resolveName({ name: `${node.operationId} Data`, type: 'function' }),
91
+ typedName: resolveName({ name: `${node.operationId} Data`, type: 'type' }),
84
92
  description: node.requestBody.description,
85
93
  })
86
94
  : null
87
95
 
88
96
  const dataType = renderSchemaType({
89
97
  node: buildDataSchemaNode({ node: { ...node, parameters: params }, resolveName }),
90
- name: resolveName({ name: `${node.operationId} Data`, type: 'function' }),
91
- typedName: resolveName({ name: `${node.operationId} Data`, type: 'type' }),
98
+ name: resolveName({ name: `${node.operationId} RequestConfig`, type: 'function' }),
99
+ typedName: resolveName({ name: `${node.operationId} RequestConfig`, type: 'type' }),
92
100
  })
93
101
 
94
102
  const responsesType = renderSchemaType({
@@ -101,6 +109,7 @@ export const typeGenerator = defineGenerator<PluginTs>({
101
109
  node: buildResponseUnionSchemaNode({ node, resolveName }),
102
110
  name: resolveName({ name: `${node.operationId} Response`, type: 'function' }),
103
111
  typedName: resolveName({ name: `${node.operationId} Response`, type: 'type' }),
112
+ description: 'Union of all possible responses',
104
113
  })
105
114
 
106
115
  return (
@@ -115,7 +124,7 @@ export const typeGenerator = defineGenerator<PluginTs>({
115
124
  )
116
125
  },
117
126
  Schema({ node, adapter, options }) {
118
- const { enumType, enumKeyCasing, syntaxType, optionalType, arrayType, mapper } = options
127
+ const { enumType, enumKeyCasing, syntaxType, optionalType, arrayType } = options
119
128
  const { mode, resolveName, getFile } = useKubb<PluginTs>()
120
129
 
121
130
  if (!node.name) {
@@ -130,7 +139,7 @@ export const typeGenerator = defineGenerator<PluginTs>({
130
139
  const isEnumSchema = node.type === 'enum'
131
140
 
132
141
  let typedName = resolveName({ name: node.name, type: 'type' })
133
- if (['asConst', 'asPascalConst'].includes(enumType) && isEnumSchema) {
142
+ if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema) {
134
143
  typedName += 'Key'
135
144
  }
136
145
 
@@ -155,7 +164,6 @@ export const typeGenerator = defineGenerator<PluginTs>({
155
164
  optionalType={optionalType}
156
165
  arrayType={arrayType}
157
166
  syntaxType={syntaxType}
158
- mapper={mapper}
159
167
  />
160
168
  </File>
161
169
  )
@@ -1,3 +1,4 @@
1
+ import { pascalCase } from '@internals/utils'
1
2
  import { createProperty, createSchema } from '@kubb/ast'
2
3
  import type { OperationNode, ParameterNode, SchemaNode } from '@kubb/ast/types'
3
4
 
@@ -12,6 +13,8 @@ type BuildParamsSchemaOptions = {
12
13
  /**
13
14
  * Builds an `ObjectSchemaNode` for a group of parameters (path/query/header).
14
15
  * Each property is a `ref` schema pointing to the individually-resolved parameter type.
16
+ * The ref name includes the parameter location so generated type names follow
17
+ * the `<OperationId><Location><ParamName>` convention.
15
18
  */
16
19
  export function buildParamsSchema({ params, operationId, resolveName }: BuildParamsSchemaOptions): SchemaNode {
17
20
  return createSchema({
@@ -21,7 +24,7 @@ export function buildParamsSchema({ params, operationId, resolveName }: BuildPar
21
24
  name: param.name,
22
25
  schema: createSchema({
23
26
  type: 'ref',
24
- name: resolveName({ name: `${operationId} ${param.name}`, type: 'function' }),
27
+ name: resolveName({ name: `${operationId} ${pascalCase(param.in)} ${param.name}`, type: 'function' }),
25
28
  optional: !param.required,
26
29
  }),
27
30
  }),
@@ -35,7 +38,7 @@ type BuildOperationSchemaOptions = {
35
38
  }
36
39
 
37
40
  /**
38
- * Builds an `ObjectSchemaNode` representing the `<OperationId>Data` type:
41
+ * Builds an `ObjectSchemaNode` representing the `<OperationId>RequestConfig` type:
39
42
  * - `data` → request body ref (optional) or `never`
40
43
  * - `pathParams` → inline object of path param refs, or `never`
41
44
  * - `queryParams` → inline object of query param refs (optional), or `never`
@@ -55,7 +58,7 @@ export function buildDataSchemaNode({ node, resolveName }: BuildOperationSchemaO
55
58
  schema: node.requestBody
56
59
  ? createSchema({
57
60
  type: 'ref',
58
- name: resolveName({ name: `${node.operationId} MutationRequest`, type: 'function' }),
61
+ name: resolveName({ name: `${node.operationId} Data`, type: 'function' }),
59
62
  optional: true,
60
63
  })
61
64
  : createSchema({ type: 'never', optional: true }),
@@ -91,11 +94,7 @@ export function buildDataSchemaNode({ node, resolveName }: BuildOperationSchemaO
91
94
 
92
95
  /**
93
96
  * Builds an `ObjectSchemaNode` representing `<OperationId>Responses` — keyed by HTTP status code.
94
- *
95
- * Example output:
96
- * ```ts
97
- * export type PlaceOrderPatchResponses = { 200: PlaceOrderPatch200; 405: PlaceOrderPatch405 }
98
- * ```
97
+ * Numeric status codes produce unquoted numeric keys (e.g. `200:`).
99
98
  */
100
99
  export function buildResponsesSchemaNode({ node, resolveName }: BuildOperationSchemaOptions): SchemaNode | null {
101
100
  const responsesWithSchema = node.responses.filter((res) => res.schema)
@@ -111,7 +110,7 @@ export function buildResponsesSchemaNode({ node, resolveName }: BuildOperationSc
111
110
  name: String(res.statusCode),
112
111
  schema: createSchema({
113
112
  type: 'ref',
114
- name: resolveName({ name: `${node.operationId} ${res.statusCode}`, type: 'function' }),
113
+ name: resolveName({ name: `${node.operationId} Status ${res.statusCode}`, type: 'function' }),
115
114
  }),
116
115
  }),
117
116
  ),
@@ -120,11 +119,7 @@ export function buildResponsesSchemaNode({ node, resolveName }: BuildOperationSc
120
119
 
121
120
  /**
122
121
  * Builds a `UnionSchemaNode` representing `<OperationId>Response` — all response types in union format.
123
- *
124
- * Example output:
125
- * ```ts
126
- * export type PlaceOrderPatchResponse = PlaceOrderPatch200 | PlaceOrderPatch405
127
- * ```
122
+ * Returns `null` when the operation has no responses with schemas.
128
123
  */
129
124
  export function buildResponseUnionSchemaNode({ node, resolveName }: BuildOperationSchemaOptions): SchemaNode | null {
130
125
  const responsesWithSchema = node.responses.filter((res) => res.schema)
@@ -138,7 +133,7 @@ export function buildResponseUnionSchemaNode({ node, resolveName }: BuildOperati
138
133
  members: responsesWithSchema.map((res) =>
139
134
  createSchema({
140
135
  type: 'ref',
141
- name: resolveName({ name: `${node.operationId} ${res.statusCode}`, type: 'function' }),
136
+ name: resolveName({ name: `${node.operationId} Status ${res.statusCode}`, type: 'function' }),
142
137
  }),
143
138
  ),
144
139
  })
package/src/parser.ts CHANGED
@@ -159,7 +159,6 @@ type ParserOptions = {
159
159
  * @note In Kubb v5, `inlineLiteral` becomes the default.
160
160
  */
161
161
  enumType: 'enum' | 'asConst' | 'asPascalConst' | 'constEnum' | 'literal' | 'inlineLiteral'
162
- mapper?: Record<string, ts.PropertySignature>
163
162
  }
164
163
 
165
164
  /**
@@ -170,7 +169,7 @@ type ParserOptions = {
170
169
  * @param current - The schema node to parse.
171
170
  * @param siblings - Sibling schema nodes, used for context in certain mappings.
172
171
  * @param name - The name of the schema or property being parsed.
173
- * @param options - Parsing options controlling output style, property handling, and custom mappers.
172
+ * @param options - Parsing options controlling output style, property handling.
174
173
  * @returns The generated TypeScript AST node, or `undefined` if the schema keyword is not mapped.
175
174
  */
176
175
  export const parse = createParser<ts.Node | null, ParserOptions>({
@@ -254,12 +253,6 @@ export const parse = createParser<ts.Node | null, ParserOptions>({
254
253
  const nameSchema = schemas.find((schema) => schema.keyword === schemaKeywords.name) as SchemaKeywordMapper['name']
255
254
  const mappedName = nameSchema?.args || name
256
255
 
257
- // custom mapper(pluginOptions)
258
- // Use Object.hasOwn to avoid matching inherited properties like 'toString', 'valueOf', etc.
259
- if (options.mapper && Object.hasOwn(options.mapper, mappedName)) {
260
- return options.mapper[mappedName]
261
- }
262
-
263
256
  const isNullish = schemas.some((schema) => schema.keyword === schemaKeywords.nullish)
264
257
  const isNullable = schemas.some((schema) => schema.keyword === schemaKeywords.nullable)
265
258
  const isOptional = schemas.some((schema) => schema.keyword === schemaKeywords.optional)
package/src/plugin.ts CHANGED
@@ -26,7 +26,6 @@ export const pluginTs = definePlugin<PluginTs>((options) => {
26
26
  emptySchemaType = unknownType,
27
27
  syntaxType = 'type',
28
28
  transformers = {},
29
- mapper = {},
30
29
  paramsCasing,
31
30
  generators = [typeGenerator, typeGeneratorV2].filter(Boolean),
32
31
  contentType,
@@ -53,7 +52,6 @@ export const pluginTs = definePlugin<PluginTs>((options) => {
53
52
  syntaxType,
54
53
  group,
55
54
  override,
56
- mapper,
57
55
  paramsCasing,
58
56
  usedEnumNames,
59
57
  },