@kubb/plugin-client 5.0.0-alpha.8 → 5.0.0-beta.10
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/LICENSE +17 -10
- package/README.md +27 -7
- package/dist/clients/axios.cjs +10 -3
- package/dist/clients/axios.cjs.map +1 -1
- package/dist/clients/axios.d.ts +5 -4
- package/dist/clients/axios.js +9 -2
- package/dist/clients/axios.js.map +1 -1
- package/dist/clients/fetch.cjs +5 -2
- package/dist/clients/fetch.cjs.map +1 -1
- package/dist/clients/fetch.d.ts +3 -2
- package/dist/clients/fetch.js +5 -2
- package/dist/clients/fetch.js.map +1 -1
- package/dist/index.cjs +1818 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +330 -4
- package/dist/index.js +1804 -95
- package/dist/index.js.map +1 -1
- package/dist/templates/clients/axios.source.cjs +1 -1
- package/dist/templates/clients/axios.source.js +1 -1
- package/dist/templates/clients/fetch.source.cjs +1 -1
- package/dist/templates/clients/fetch.source.js +1 -1
- package/extension.yaml +776 -0
- package/package.json +62 -85
- package/src/clients/axios.ts +19 -4
- package/src/clients/fetch.ts +10 -2
- package/src/components/ClassClient.tsx +46 -145
- package/src/components/Client.tsx +109 -139
- package/src/components/Operations.tsx +10 -10
- package/src/components/StaticClassClient.tsx +46 -142
- package/src/components/Url.tsx +38 -50
- package/src/components/WrapperClient.tsx +11 -7
- package/src/functionParams.ts +118 -0
- package/src/generators/classClientGenerator.tsx +143 -172
- package/src/generators/clientGenerator.tsx +83 -81
- package/src/generators/groupedClientGenerator.tsx +50 -52
- package/src/generators/operationsGenerator.tsx +11 -18
- package/src/generators/staticClassClientGenerator.tsx +172 -184
- package/src/index.ts +9 -2
- package/src/plugin.ts +115 -145
- package/src/resolvers/resolverClient.ts +38 -0
- package/src/types.ts +128 -44
- package/src/utils.ts +156 -0
- package/dist/StaticClassClient-By-aMAe4.cjs +0 -677
- package/dist/StaticClassClient-By-aMAe4.cjs.map +0 -1
- package/dist/StaticClassClient-CCn9g9eF.js +0 -636
- package/dist/StaticClassClient-CCn9g9eF.js.map +0 -1
- package/dist/components.cjs +0 -7
- package/dist/components.d.ts +0 -216
- package/dist/components.js +0 -2
- package/dist/generators-BYUJaeZP.js +0 -723
- package/dist/generators-BYUJaeZP.js.map +0 -1
- package/dist/generators-DTxD9FDY.cjs +0 -753
- package/dist/generators-DTxD9FDY.cjs.map +0 -1
- package/dist/generators.cjs +0 -7
- package/dist/generators.d.ts +0 -488
- package/dist/generators.js +0 -2
- package/dist/types-DBQdg-BV.d.ts +0 -169
- package/src/components/index.ts +0 -5
- package/src/generators/index.ts +0 -5
- package/templates/clients/axios.ts +0 -70
- package/templates/clients/fetch.ts +0 -93
- package/templates/config.ts +0 -43
|
@@ -1,16 +1,16 @@
|
|
|
1
|
+
import { buildOperationComments, buildParamsMapping, buildRequestConfigType, getContentTypeInfo, getOperationParameters } from '@internals/shared'
|
|
1
2
|
import { isValidVarName, URLPath } from '@internals/utils'
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
3
|
+
import { ast } from '@kubb/core'
|
|
4
|
+
import type { ResolverTs } from '@kubb/plugin-ts'
|
|
5
|
+
import { functionPrinter } from '@kubb/plugin-ts'
|
|
6
|
+
import type { ResolverZod } from '@kubb/plugin-zod'
|
|
7
|
+
import { File, Function } from '@kubb/renderer-jsx'
|
|
8
|
+
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
9
|
+
import { createFunctionParams } from '../functionParams.ts'
|
|
7
10
|
import type { PluginClient } from '../types.ts'
|
|
8
|
-
import {
|
|
11
|
+
import { buildUrlParamsNode } from './Url.tsx'
|
|
9
12
|
|
|
10
13
|
type Props = {
|
|
11
|
-
/**
|
|
12
|
-
* Name of the function
|
|
13
|
-
*/
|
|
14
14
|
name: string
|
|
15
15
|
urlName?: string
|
|
16
16
|
isExportable?: boolean
|
|
@@ -24,106 +24,50 @@ type Props = {
|
|
|
24
24
|
paramsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
25
25
|
pathParamsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
26
26
|
parser: PluginClient['resolvedOptions']['parser'] | undefined
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
children?:
|
|
27
|
+
node: ast.OperationNode
|
|
28
|
+
tsResolver: ResolverTs
|
|
29
|
+
zodResolver?: ResolverZod
|
|
30
|
+
children?: KubbReactNode
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
type GetParamsProps = {
|
|
34
34
|
paramsCasing: PluginClient['resolvedOptions']['paramsCasing']
|
|
35
35
|
paramsType: PluginClient['resolvedOptions']['paramsType']
|
|
36
36
|
pathParamsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
37
|
-
|
|
37
|
+
node: ast.OperationNode
|
|
38
|
+
tsResolver: ResolverTs
|
|
38
39
|
isConfigurable: boolean
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
if (paramsType === 'object') {
|
|
43
|
-
const pathParams = getPathParams(typeSchemas.pathParams, {
|
|
44
|
-
typed: true,
|
|
45
|
-
casing: paramsCasing,
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
const children = {
|
|
49
|
-
...pathParams,
|
|
50
|
-
data: typeSchemas.request?.name
|
|
51
|
-
? {
|
|
52
|
-
type: typeSchemas.request?.name,
|
|
53
|
-
optional: isOptional(typeSchemas.request?.schema),
|
|
54
|
-
}
|
|
55
|
-
: undefined,
|
|
56
|
-
params: typeSchemas.queryParams?.name
|
|
57
|
-
? {
|
|
58
|
-
type: typeSchemas.queryParams?.name,
|
|
59
|
-
optional: isOptional(typeSchemas.queryParams?.schema),
|
|
60
|
-
}
|
|
61
|
-
: undefined,
|
|
62
|
-
headers: typeSchemas.headerParams?.name
|
|
63
|
-
? {
|
|
64
|
-
type: typeSchemas.headerParams?.name,
|
|
65
|
-
optional: isOptional(typeSchemas.headerParams?.schema),
|
|
66
|
-
}
|
|
67
|
-
: undefined,
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Check if all children are optional or undefined
|
|
71
|
-
const allChildrenAreOptional = Object.values(children).every((child) => !child || child.optional)
|
|
72
|
-
|
|
73
|
-
return FunctionParams.factory({
|
|
74
|
-
data: {
|
|
75
|
-
mode: 'object',
|
|
76
|
-
children,
|
|
77
|
-
default: allChildrenAreOptional ? '{}' : undefined,
|
|
78
|
-
},
|
|
79
|
-
config: isConfigurable
|
|
80
|
-
? {
|
|
81
|
-
type: typeSchemas.request?.name
|
|
82
|
-
? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }`
|
|
83
|
-
: 'Partial<RequestConfig> & { client?: Client }',
|
|
84
|
-
default: '{}',
|
|
85
|
-
}
|
|
86
|
-
: undefined,
|
|
87
|
-
})
|
|
88
|
-
}
|
|
42
|
+
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
89
43
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
: undefined,
|
|
119
|
-
config: isConfigurable
|
|
120
|
-
? {
|
|
121
|
-
type: typeSchemas.request?.name
|
|
122
|
-
? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }`
|
|
123
|
-
: 'Partial<RequestConfig> & { client?: Client }',
|
|
124
|
-
default: '{}',
|
|
125
|
-
}
|
|
126
|
-
: undefined,
|
|
44
|
+
export function buildClientParamsNode({
|
|
45
|
+
paramsType,
|
|
46
|
+
paramsCasing,
|
|
47
|
+
pathParamsType,
|
|
48
|
+
node,
|
|
49
|
+
tsResolver,
|
|
50
|
+
isConfigurable,
|
|
51
|
+
}: GetParamsProps): ast.FunctionParametersNode {
|
|
52
|
+
return ast.createOperationParams(node, {
|
|
53
|
+
paramsType,
|
|
54
|
+
pathParamsType: paramsType === 'object' ? 'object' : pathParamsType === 'object' ? 'object' : 'inline',
|
|
55
|
+
paramsCasing,
|
|
56
|
+
resolver: tsResolver,
|
|
57
|
+
extraParams: [
|
|
58
|
+
...(isConfigurable
|
|
59
|
+
? [
|
|
60
|
+
ast.createFunctionParameter({
|
|
61
|
+
name: 'config',
|
|
62
|
+
type: ast.createParamsType({
|
|
63
|
+
variant: 'reference',
|
|
64
|
+
name: buildRequestConfigType(node, tsResolver),
|
|
65
|
+
}),
|
|
66
|
+
default: '{}',
|
|
67
|
+
}),
|
|
68
|
+
]
|
|
69
|
+
: []),
|
|
70
|
+
],
|
|
127
71
|
})
|
|
128
72
|
}
|
|
129
73
|
|
|
@@ -132,60 +76,82 @@ export function Client({
|
|
|
132
76
|
isExportable = true,
|
|
133
77
|
isIndexable = true,
|
|
134
78
|
returnType,
|
|
135
|
-
typeSchemas,
|
|
136
79
|
baseURL,
|
|
137
80
|
dataReturnType,
|
|
138
81
|
parser,
|
|
139
|
-
zodSchemas,
|
|
140
82
|
paramsType,
|
|
141
83
|
paramsCasing,
|
|
142
84
|
pathParamsType,
|
|
143
|
-
|
|
85
|
+
node,
|
|
86
|
+
tsResolver,
|
|
87
|
+
zodResolver,
|
|
144
88
|
urlName,
|
|
145
89
|
children,
|
|
146
90
|
isConfigurable = true,
|
|
147
|
-
}: Props):
|
|
148
|
-
const path = new URLPath(
|
|
149
|
-
const contentType =
|
|
150
|
-
const isFormData = contentType === 'multipart/form-data'
|
|
91
|
+
}: Props): KubbReactNode {
|
|
92
|
+
const path = new URLPath(node.path)
|
|
93
|
+
const { defaultContentType: contentType, isMultipleContentTypes, hasFormData } = getContentTypeInfo(node)
|
|
94
|
+
const isFormData = !isMultipleContentTypes && contentType === 'multipart/form-data'
|
|
95
|
+
|
|
96
|
+
const { path: originalPathParams, query: originalQueryParams, header: originalHeaderParams } = getOperationParameters(node)
|
|
97
|
+
const { path: casedPathParams, query: casedQueryParams, header: casedHeaderParams } = getOperationParameters(node, { paramsCasing })
|
|
98
|
+
|
|
99
|
+
const pathParamsMapping = paramsCasing && !urlName ? buildParamsMapping(originalPathParams, casedPathParams) : undefined
|
|
100
|
+
const queryParamsMapping = paramsCasing ? buildParamsMapping(originalQueryParams, casedQueryParams) : undefined
|
|
101
|
+
const headerParamsMapping = paramsCasing ? buildParamsMapping(originalHeaderParams, casedHeaderParams) : undefined
|
|
151
102
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const
|
|
155
|
-
const
|
|
156
|
-
|
|
103
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : undefined
|
|
104
|
+
const responseName = tsResolver.resolveResponseName(node)
|
|
105
|
+
const queryParamsName = originalQueryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, originalQueryParams[0]!) : undefined
|
|
106
|
+
const headerParamsName = originalHeaderParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, originalHeaderParams[0]!) : undefined
|
|
107
|
+
|
|
108
|
+
const zodResponseName = zodResolver && parser === 'zod' ? zodResolver.resolveResponseName?.(node) : undefined
|
|
109
|
+
const zodRequestName = zodResolver && parser === 'zod' && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : undefined
|
|
110
|
+
|
|
111
|
+
const errorNames = node.responses
|
|
112
|
+
.filter((r) => {
|
|
113
|
+
const code = Number.parseInt(r.statusCode, 10)
|
|
114
|
+
return code >= 400
|
|
115
|
+
})
|
|
116
|
+
.map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode))
|
|
157
117
|
|
|
158
118
|
const headers = [
|
|
159
|
-
contentType !== 'application/json' && contentType !== 'multipart/form-data' ? `'Content-Type': '${contentType}'` : undefined,
|
|
160
|
-
|
|
119
|
+
!isMultipleContentTypes && contentType !== 'application/json' && contentType !== 'multipart/form-data' ? `'Content-Type': '${contentType}'` : undefined,
|
|
120
|
+
headerParamsName ? (headerParamsMapping ? '...mappedHeaders' : '...headers') : undefined,
|
|
161
121
|
].filter(Boolean)
|
|
162
122
|
|
|
163
|
-
const TError = `ResponseErrorConfig<${
|
|
123
|
+
const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
|
|
164
124
|
|
|
165
|
-
const generics = [
|
|
166
|
-
const
|
|
125
|
+
const generics = [responseName, TError, requestName || 'unknown'].filter(Boolean)
|
|
126
|
+
const paramsNode = buildClientParamsNode({
|
|
167
127
|
paramsType,
|
|
168
128
|
paramsCasing,
|
|
169
129
|
pathParamsType,
|
|
170
|
-
|
|
130
|
+
node,
|
|
131
|
+
tsResolver,
|
|
171
132
|
isConfigurable,
|
|
172
133
|
})
|
|
173
|
-
const
|
|
134
|
+
const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
|
|
135
|
+
|
|
136
|
+
const urlParamsNode = buildUrlParamsNode({
|
|
174
137
|
paramsType,
|
|
175
138
|
paramsCasing,
|
|
176
139
|
pathParamsType,
|
|
177
|
-
|
|
140
|
+
node,
|
|
141
|
+
tsResolver,
|
|
178
142
|
})
|
|
143
|
+
const callPrinter = functionPrinter({ mode: 'call' })
|
|
144
|
+
const urlParamsCall = callPrinter.print(urlParamsNode) ?? ''
|
|
179
145
|
|
|
180
|
-
const clientParams =
|
|
146
|
+
const clientParams = createFunctionParams({
|
|
181
147
|
config: {
|
|
182
148
|
mode: 'object',
|
|
183
149
|
children: {
|
|
184
150
|
method: {
|
|
185
|
-
value: JSON.stringify(
|
|
151
|
+
value: JSON.stringify(node.method.toUpperCase()),
|
|
186
152
|
},
|
|
187
153
|
url: {
|
|
188
|
-
value: urlName ? `${urlName}(${
|
|
154
|
+
value: urlName ? `${urlName}(${urlParamsCall}).url.toString()` : path.template,
|
|
189
155
|
},
|
|
190
156
|
baseURL:
|
|
191
157
|
baseURL && !urlName
|
|
@@ -193,12 +159,18 @@ export function Client({
|
|
|
193
159
|
value: `\`${baseURL}\``,
|
|
194
160
|
}
|
|
195
161
|
: undefined,
|
|
196
|
-
params:
|
|
197
|
-
data:
|
|
162
|
+
params: queryParamsName ? (queryParamsMapping ? { value: 'mappedParams' } : {}) : undefined,
|
|
163
|
+
data: requestName
|
|
198
164
|
? {
|
|
199
|
-
value:
|
|
165
|
+
value:
|
|
166
|
+
isMultipleContentTypes && hasFormData
|
|
167
|
+
? "contentType === 'multipart/form-data' ? formData as FormData : requestData"
|
|
168
|
+
: isFormData
|
|
169
|
+
? 'formData as FormData'
|
|
170
|
+
: 'requestData',
|
|
200
171
|
}
|
|
201
172
|
: undefined,
|
|
173
|
+
contentType: isConfigurable && isMultipleContentTypes ? {} : undefined,
|
|
202
174
|
requestConfig: isConfigurable
|
|
203
175
|
? {
|
|
204
176
|
mode: 'inlineSpread',
|
|
@@ -217,8 +189,8 @@ export function Client({
|
|
|
217
189
|
children
|
|
218
190
|
) : (
|
|
219
191
|
<>
|
|
220
|
-
{dataReturnType === 'full' && parser === 'zod' &&
|
|
221
|
-
{dataReturnType === 'data' && parser === 'zod' &&
|
|
192
|
+
{dataReturnType === 'full' && parser === 'zod' && zodResponseName && `return {...res, data: ${zodResponseName}.parse(res.data)}`}
|
|
193
|
+
{dataReturnType === 'data' && parser === 'zod' && zodResponseName && `return ${zodResponseName}.parse(res.data)`}
|
|
222
194
|
{dataReturnType === 'full' && parser === 'client' && 'return res'}
|
|
223
195
|
{dataReturnType === 'data' && parser === 'client' && 'return res.data'}
|
|
224
196
|
</>
|
|
@@ -233,18 +205,20 @@ export function Client({
|
|
|
233
205
|
name={name}
|
|
234
206
|
async
|
|
235
207
|
export={isExportable}
|
|
236
|
-
params={
|
|
208
|
+
params={paramsSignature}
|
|
237
209
|
JSDoc={{
|
|
238
|
-
comments:
|
|
210
|
+
comments: buildOperationComments(node, { link: 'urlPath', linkPosition: 'beforeDeprecated', splitLines: true }),
|
|
239
211
|
}}
|
|
240
212
|
returnType={returnType}
|
|
241
213
|
>
|
|
242
|
-
{isConfigurable
|
|
214
|
+
{isConfigurable
|
|
215
|
+
? `const { client: request = fetch, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ''}...requestConfig } = config`
|
|
216
|
+
: ''}
|
|
243
217
|
<br />
|
|
244
218
|
<br />
|
|
245
219
|
{pathParamsMapping &&
|
|
246
220
|
Object.entries(pathParamsMapping)
|
|
247
|
-
.filter(([originalName, camelCaseName]) => originalName !== camelCaseName
|
|
221
|
+
.filter(([originalName, camelCaseName]) => isValidVarName(originalName) && originalName !== camelCaseName)
|
|
248
222
|
.map(([originalName, camelCaseName]) => `const ${originalName} = ${camelCaseName}`)
|
|
249
223
|
.join('\n')}
|
|
250
224
|
{pathParamsMapping && (
|
|
@@ -253,7 +227,7 @@ export function Client({
|
|
|
253
227
|
<br />
|
|
254
228
|
</>
|
|
255
229
|
)}
|
|
256
|
-
{queryParamsMapping &&
|
|
230
|
+
{queryParamsMapping && queryParamsName && (
|
|
257
231
|
<>
|
|
258
232
|
{`const mappedParams = params ? { ${Object.entries(queryParamsMapping)
|
|
259
233
|
.map(([originalName, camelCaseName]) => `"${originalName}": params.${camelCaseName}`)
|
|
@@ -262,7 +236,7 @@ export function Client({
|
|
|
262
236
|
<br />
|
|
263
237
|
</>
|
|
264
238
|
)}
|
|
265
|
-
{headerParamsMapping &&
|
|
239
|
+
{headerParamsMapping && headerParamsName && (
|
|
266
240
|
<>
|
|
267
241
|
{`const mappedHeaders = headers ? { ${Object.entries(headerParamsMapping)
|
|
268
242
|
.map(([originalName, camelCaseName]) => `"${originalName}": headers.${camelCaseName}`)
|
|
@@ -271,11 +245,9 @@ export function Client({
|
|
|
271
245
|
<br />
|
|
272
246
|
</>
|
|
273
247
|
)}
|
|
274
|
-
{parser === 'zod' &&
|
|
275
|
-
? `const requestData = ${zodSchemas.request.name}.parse(data)`
|
|
276
|
-
: typeSchemas?.request?.name && 'const requestData = data'}
|
|
248
|
+
{parser === 'zod' && zodRequestName ? `const requestData = ${zodRequestName}.parse(data)` : requestName && 'const requestData = data'}
|
|
277
249
|
<br />
|
|
278
|
-
{isFormData &&
|
|
250
|
+
{(isFormData || (isMultipleContentTypes && hasFormData)) && requestName && 'const formData = buildFormData(requestData)'}
|
|
279
251
|
<br />
|
|
280
252
|
{isConfigurable
|
|
281
253
|
? `const res = await request<${generics.join(', ')}>(${clientParams.toCall()})`
|
|
@@ -287,5 +259,3 @@ export function Client({
|
|
|
287
259
|
</>
|
|
288
260
|
)
|
|
289
261
|
}
|
|
290
|
-
|
|
291
|
-
Client.getParams = getParams
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { URLPath } from '@internals/utils'
|
|
2
|
-
import type {
|
|
3
|
-
import { Const, File } from '@kubb/
|
|
4
|
-
import type {
|
|
2
|
+
import type { ast } from '@kubb/core'
|
|
3
|
+
import { Const, File } from '@kubb/renderer-jsx'
|
|
4
|
+
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
5
5
|
|
|
6
6
|
type OperationsProps = {
|
|
7
7
|
name: string
|
|
8
|
-
|
|
8
|
+
nodes: Array<ast.OperationNode>
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export function Operations({ name,
|
|
12
|
-
const operationsObject: Record<string, { path: string; method:
|
|
11
|
+
export function Operations({ name, nodes }: OperationsProps): KubbReactNode {
|
|
12
|
+
const operationsObject: Record<string, { path: string; method: string }> = {}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
operationsObject[
|
|
16
|
-
path: new URLPath(
|
|
17
|
-
method:
|
|
14
|
+
nodes.forEach((node) => {
|
|
15
|
+
operationsObject[node.operationId] = {
|
|
16
|
+
path: new URLPath(node.path).URL,
|
|
17
|
+
method: node.method.toLowerCase(),
|
|
18
18
|
}
|
|
19
19
|
})
|
|
20
20
|
|
|
@@ -1,36 +1,41 @@
|
|
|
1
|
+
import { buildOperationComments, getContentTypeInfo, getOperationParameters } from '@internals/shared'
|
|
1
2
|
import { buildJSDoc, URLPath } from '@internals/utils'
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
3
|
+
import type { ast } from '@kubb/core'
|
|
4
|
+
import type { ResolverTs } from '@kubb/plugin-ts'
|
|
5
|
+
import { functionPrinter } from '@kubb/plugin-ts'
|
|
6
|
+
import type { ResolverZod } from '@kubb/plugin-zod'
|
|
7
|
+
import { File } from '@kubb/renderer-jsx'
|
|
8
|
+
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
7
9
|
import type { PluginClient } from '../types.ts'
|
|
8
|
-
import {
|
|
10
|
+
import { buildClassClientParams, buildFormDataLine, buildGenerics, buildHeaders, buildRequestDataLine, buildReturnStatement } from '../utils.ts'
|
|
11
|
+
import { buildClientParamsNode } from './Client.tsx'
|
|
12
|
+
|
|
13
|
+
type OperationData = {
|
|
14
|
+
node: ast.OperationNode
|
|
15
|
+
name: string
|
|
16
|
+
tsResolver: ResolverTs
|
|
17
|
+
zodResolver?: ResolverZod
|
|
18
|
+
}
|
|
9
19
|
|
|
10
20
|
type Props = {
|
|
11
21
|
name: string
|
|
12
22
|
isExportable?: boolean
|
|
13
23
|
isIndexable?: boolean
|
|
14
|
-
operations: Array<
|
|
15
|
-
operation: Operation
|
|
16
|
-
name: string
|
|
17
|
-
typeSchemas: OperationSchemas
|
|
18
|
-
zodSchemas: OperationSchemas | undefined
|
|
19
|
-
}>
|
|
24
|
+
operations: Array<OperationData>
|
|
20
25
|
baseURL: string | undefined
|
|
21
26
|
dataReturnType: PluginClient['resolvedOptions']['dataReturnType']
|
|
22
27
|
paramsCasing: PluginClient['resolvedOptions']['paramsCasing']
|
|
23
28
|
paramsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
24
29
|
pathParamsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
25
30
|
parser: PluginClient['resolvedOptions']['parser'] | undefined
|
|
26
|
-
children?:
|
|
31
|
+
children?: KubbReactNode
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
type GenerateMethodProps = {
|
|
30
|
-
|
|
35
|
+
node: ast.OperationNode
|
|
31
36
|
name: string
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
tsResolver: ResolverTs
|
|
38
|
+
zodResolver?: ResolverZod
|
|
34
39
|
baseURL: string | undefined
|
|
35
40
|
dataReturnType: PluginClient['resolvedOptions']['dataReturnType']
|
|
36
41
|
parser: PluginClient['resolvedOptions']['parser'] | undefined
|
|
@@ -39,115 +44,13 @@ type GenerateMethodProps = {
|
|
|
39
44
|
pathParamsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
40
45
|
}
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
return [
|
|
44
|
-
contentType !== 'application/json' && contentType !== 'multipart/form-data' ? `'Content-Type': '${contentType}'` : undefined,
|
|
45
|
-
hasHeaderParams ? '...headers' : undefined,
|
|
46
|
-
].filter(Boolean) as Array<string>
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function buildGenerics(typeSchemas: OperationSchemas): Array<string> {
|
|
50
|
-
const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error'}>`
|
|
51
|
-
return [typeSchemas.response.name, TError, typeSchemas.request?.name || 'unknown'].filter(Boolean)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function buildClientParams({
|
|
55
|
-
operation,
|
|
56
|
-
path,
|
|
57
|
-
baseURL,
|
|
58
|
-
typeSchemas,
|
|
59
|
-
isFormData,
|
|
60
|
-
headers,
|
|
61
|
-
}: {
|
|
62
|
-
operation: Operation
|
|
63
|
-
path: URLPath
|
|
64
|
-
baseURL: string | undefined
|
|
65
|
-
typeSchemas: OperationSchemas
|
|
66
|
-
isFormData: boolean
|
|
67
|
-
headers: Array<string>
|
|
68
|
-
}) {
|
|
69
|
-
return FunctionParams.factory({
|
|
70
|
-
config: {
|
|
71
|
-
mode: 'object',
|
|
72
|
-
children: {
|
|
73
|
-
requestConfig: {
|
|
74
|
-
mode: 'inlineSpread',
|
|
75
|
-
},
|
|
76
|
-
method: {
|
|
77
|
-
value: JSON.stringify(operation.method.toUpperCase()),
|
|
78
|
-
},
|
|
79
|
-
url: {
|
|
80
|
-
value: path.template,
|
|
81
|
-
},
|
|
82
|
-
baseURL: baseURL
|
|
83
|
-
? {
|
|
84
|
-
value: JSON.stringify(baseURL),
|
|
85
|
-
}
|
|
86
|
-
: undefined,
|
|
87
|
-
params: typeSchemas.queryParams?.name ? {} : undefined,
|
|
88
|
-
data: typeSchemas.request?.name
|
|
89
|
-
? {
|
|
90
|
-
value: isFormData ? 'formData as FormData' : 'requestData',
|
|
91
|
-
}
|
|
92
|
-
: undefined,
|
|
93
|
-
headers: headers.length
|
|
94
|
-
? {
|
|
95
|
-
value: `{ ${headers.join(', ')}, ...requestConfig.headers }`,
|
|
96
|
-
}
|
|
97
|
-
: undefined,
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function buildRequestDataLine({
|
|
104
|
-
parser,
|
|
105
|
-
zodSchemas,
|
|
106
|
-
typeSchemas,
|
|
107
|
-
}: {
|
|
108
|
-
parser: PluginClient['resolvedOptions']['parser'] | undefined
|
|
109
|
-
zodSchemas: OperationSchemas | undefined
|
|
110
|
-
typeSchemas: OperationSchemas
|
|
111
|
-
}): string {
|
|
112
|
-
if (parser === 'zod' && zodSchemas?.request?.name) {
|
|
113
|
-
return `const requestData = ${zodSchemas.request.name}.parse(data)`
|
|
114
|
-
}
|
|
115
|
-
if (typeSchemas?.request?.name) {
|
|
116
|
-
return 'const requestData = data'
|
|
117
|
-
}
|
|
118
|
-
return ''
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function buildFormDataLine(isFormData: boolean, hasRequest: boolean): string {
|
|
122
|
-
return isFormData && hasRequest ? 'const formData = buildFormData(requestData)' : ''
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function buildReturnStatement({
|
|
126
|
-
dataReturnType,
|
|
127
|
-
parser,
|
|
128
|
-
zodSchemas,
|
|
129
|
-
}: {
|
|
130
|
-
dataReturnType: PluginClient['resolvedOptions']['dataReturnType']
|
|
131
|
-
parser: PluginClient['resolvedOptions']['parser'] | undefined
|
|
132
|
-
zodSchemas: OperationSchemas | undefined
|
|
133
|
-
}): string {
|
|
134
|
-
if (dataReturnType === 'full' && parser === 'zod' && zodSchemas) {
|
|
135
|
-
return `return {...res, data: ${zodSchemas.response.name}.parse(res.data)}`
|
|
136
|
-
}
|
|
137
|
-
if (dataReturnType === 'data' && parser === 'zod' && zodSchemas) {
|
|
138
|
-
return `return ${zodSchemas.response.name}.parse(res.data)`
|
|
139
|
-
}
|
|
140
|
-
if (dataReturnType === 'full' && parser === 'client') {
|
|
141
|
-
return 'return res'
|
|
142
|
-
}
|
|
143
|
-
return 'return res.data'
|
|
144
|
-
}
|
|
47
|
+
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
145
48
|
|
|
146
49
|
function generateMethod({
|
|
147
|
-
|
|
50
|
+
node,
|
|
148
51
|
name,
|
|
149
|
-
|
|
150
|
-
|
|
52
|
+
tsResolver,
|
|
53
|
+
zodResolver,
|
|
151
54
|
baseURL,
|
|
152
55
|
dataReturnType,
|
|
153
56
|
parser,
|
|
@@ -155,21 +58,24 @@ function generateMethod({
|
|
|
155
58
|
paramsCasing,
|
|
156
59
|
pathParamsType,
|
|
157
60
|
}: GenerateMethodProps): string {
|
|
158
|
-
const path = new URLPath(
|
|
159
|
-
const contentType =
|
|
160
|
-
const isFormData = contentType === 'multipart/form-data'
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
const
|
|
164
|
-
const
|
|
165
|
-
const
|
|
61
|
+
const path = new URLPath(node.path, { casing: paramsCasing })
|
|
62
|
+
const { defaultContentType: contentType, isMultipleContentTypes, hasFormData } = getContentTypeInfo(node)
|
|
63
|
+
const isFormData = !isMultipleContentTypes && contentType === 'multipart/form-data'
|
|
64
|
+
const { header: headerParams } = getOperationParameters(node)
|
|
65
|
+
const headerParamsName = headerParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, headerParams[0]!) : undefined
|
|
66
|
+
const headers = isMultipleContentTypes ? (headerParamsName ? ['...headers'] : []) : buildHeaders(contentType, !!headerParamsName)
|
|
67
|
+
const generics = buildGenerics(node, tsResolver)
|
|
68
|
+
const paramsNode = buildClientParamsNode({ paramsType, paramsCasing, pathParamsType, node, tsResolver, isConfigurable: true })
|
|
69
|
+
const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
|
|
70
|
+
const clientParams = buildClassClientParams({ node, path, baseURL, tsResolver, isFormData, isMultipleContentTypes, hasFormData, headers })
|
|
71
|
+
const jsdoc = buildJSDoc(buildOperationComments(node, { link: 'urlPath', linkPosition: 'beforeDeprecated', splitLines: true }))
|
|
166
72
|
|
|
167
|
-
const requestDataLine = buildRequestDataLine({ parser,
|
|
168
|
-
const formDataLine = buildFormDataLine(isFormData, !!
|
|
169
|
-
const returnStatement = buildReturnStatement({ dataReturnType, parser,
|
|
73
|
+
const requestDataLine = buildRequestDataLine({ parser, node, zodResolver })
|
|
74
|
+
const formDataLine = buildFormDataLine(isFormData || (isMultipleContentTypes && hasFormData), !!node.requestBody?.content?.[0]?.schema)
|
|
75
|
+
const returnStatement = buildReturnStatement({ dataReturnType, parser, node, zodResolver })
|
|
170
76
|
|
|
171
77
|
const methodBody = [
|
|
172
|
-
|
|
78
|
+
`const { client: request = fetch, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ''}...requestConfig } = mergeConfig(this.#config, config)`,
|
|
173
79
|
'',
|
|
174
80
|
requestDataLine,
|
|
175
81
|
formDataLine,
|
|
@@ -180,8 +86,7 @@ function generateMethod({
|
|
|
180
86
|
.map((line) => ` ${line}`)
|
|
181
87
|
.join('\n')
|
|
182
88
|
|
|
183
|
-
|
|
184
|
-
return `${jsdoc} static async ${name}(${params.toConstructor()}) {\n${methodBody}\n }`
|
|
89
|
+
return `${jsdoc} static async ${name}(${paramsSignature}) {\n${methodBody}\n }`
|
|
185
90
|
}
|
|
186
91
|
|
|
187
92
|
export function StaticClassClient({
|
|
@@ -196,13 +101,13 @@ export function StaticClassClient({
|
|
|
196
101
|
paramsCasing,
|
|
197
102
|
pathParamsType,
|
|
198
103
|
children,
|
|
199
|
-
}: Props):
|
|
200
|
-
const methods = operations.map(({
|
|
104
|
+
}: Props): KubbReactNode {
|
|
105
|
+
const methods = operations.map(({ node, name: methodName, tsResolver, zodResolver }) =>
|
|
201
106
|
generateMethod({
|
|
202
|
-
|
|
107
|
+
node,
|
|
203
108
|
name: methodName,
|
|
204
|
-
|
|
205
|
-
|
|
109
|
+
tsResolver,
|
|
110
|
+
zodResolver,
|
|
206
111
|
baseURL,
|
|
207
112
|
dataReturnType,
|
|
208
113
|
parser,
|
|
@@ -221,4 +126,3 @@ export function StaticClassClient({
|
|
|
221
126
|
</File.Source>
|
|
222
127
|
)
|
|
223
128
|
}
|
|
224
|
-
StaticClassClient.getParams = Client.getParams
|