@kubb/plugin-client 5.0.0-alpha.3 → 5.0.0-alpha.30

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 (42) hide show
  1. package/dist/clients/axios.d.ts +2 -2
  2. package/dist/index.cjs +1893 -74
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +480 -4
  5. package/dist/index.js +1885 -77
  6. package/dist/index.js.map +1 -1
  7. package/package.json +10 -25
  8. package/src/components/ClassClient.tsx +42 -138
  9. package/src/components/Client.tsx +85 -124
  10. package/src/components/ClientLegacy.tsx +501 -0
  11. package/src/components/Operations.tsx +8 -8
  12. package/src/components/StaticClassClient.tsx +41 -135
  13. package/src/components/Url.tsx +37 -46
  14. package/src/generators/classClientGenerator.tsx +129 -152
  15. package/src/generators/clientGenerator.tsx +93 -82
  16. package/src/generators/groupedClientGenerator.tsx +48 -51
  17. package/src/generators/operationsGenerator.tsx +9 -17
  18. package/src/generators/staticClassClientGenerator.tsx +163 -168
  19. package/src/index.ts +11 -1
  20. package/src/plugin.ts +115 -108
  21. package/src/presets.ts +25 -0
  22. package/src/resolvers/resolverClient.ts +26 -0
  23. package/src/resolvers/resolverClientLegacy.ts +26 -0
  24. package/src/types.ts +105 -40
  25. package/src/utils.ts +148 -0
  26. package/dist/StaticClassClient-By-aMAe4.cjs +0 -677
  27. package/dist/StaticClassClient-By-aMAe4.cjs.map +0 -1
  28. package/dist/StaticClassClient-CCn9g9eF.js +0 -636
  29. package/dist/StaticClassClient-CCn9g9eF.js.map +0 -1
  30. package/dist/components.cjs +0 -7
  31. package/dist/components.d.ts +0 -216
  32. package/dist/components.js +0 -2
  33. package/dist/generators-C2jT7XCH.js +0 -723
  34. package/dist/generators-C2jT7XCH.js.map +0 -1
  35. package/dist/generators-qkDW17Hf.cjs +0 -753
  36. package/dist/generators-qkDW17Hf.cjs.map +0 -1
  37. package/dist/generators.cjs +0 -7
  38. package/dist/generators.d.ts +0 -512
  39. package/dist/generators.js +0 -2
  40. package/dist/types-CdM4DK1M.d.ts +0 -169
  41. package/src/components/index.ts +0 -5
  42. package/src/generators/index.ts +0 -5
@@ -1,22 +1,26 @@
1
1
  import { buildJSDoc, URLPath } from '@internals/utils'
2
- import type { Operation } from '@kubb/oas'
3
- import type { OperationSchemas } from '@kubb/plugin-oas'
4
- import { getComments } from '@kubb/plugin-oas/utils'
5
- import { File, FunctionParams } from '@kubb/react-fabric'
2
+ import type { OperationNode } from '@kubb/ast/types'
3
+ import type { PluginTs } from '@kubb/plugin-ts'
4
+ import { functionPrinter } from '@kubb/plugin-ts'
5
+ import type { PluginZod } from '@kubb/plugin-zod'
6
+ import { File } from '@kubb/react-fabric'
6
7
  import type { FabricReactNode } from '@kubb/react-fabric/types'
7
8
  import type { PluginClient } from '../types.ts'
9
+ import { buildClassClientParams, buildFormDataLine, buildGenerics, buildHeaders, buildRequestDataLine, buildReturnStatement, getComments } from '../utils.ts'
8
10
  import { Client } from './Client.tsx'
9
11
 
12
+ type OperationData = {
13
+ node: OperationNode
14
+ name: string
15
+ tsResolver: PluginTs['resolver']
16
+ zodResolver?: PluginZod['resolver']
17
+ }
18
+
10
19
  type Props = {
11
20
  name: string
12
21
  isExportable?: boolean
13
22
  isIndexable?: boolean
14
- operations: Array<{
15
- operation: Operation
16
- name: string
17
- typeSchemas: OperationSchemas
18
- zodSchemas: OperationSchemas | undefined
19
- }>
23
+ operations: Array<OperationData>
20
24
  baseURL: string | undefined
21
25
  dataReturnType: PluginClient['resolvedOptions']['dataReturnType']
22
26
  paramsCasing: PluginClient['resolvedOptions']['paramsCasing']
@@ -27,10 +31,10 @@ type Props = {
27
31
  }
28
32
 
29
33
  type GenerateMethodProps = {
30
- operation: Operation
34
+ node: OperationNode
31
35
  name: string
32
- typeSchemas: OperationSchemas
33
- zodSchemas: OperationSchemas | undefined
36
+ tsResolver: PluginTs['resolver']
37
+ zodResolver?: PluginZod['resolver']
34
38
  baseURL: string | undefined
35
39
  dataReturnType: PluginClient['resolvedOptions']['dataReturnType']
36
40
  parser: PluginClient['resolvedOptions']['parser'] | undefined
@@ -39,115 +43,13 @@ type GenerateMethodProps = {
39
43
  pathParamsType: PluginClient['resolvedOptions']['pathParamsType']
40
44
  }
41
45
 
42
- function buildHeaders(contentType: string, hasHeaderParams: boolean): Array<string> {
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
- }
46
+ const declarationPrinter = functionPrinter({ mode: 'declaration' })
145
47
 
146
48
  function generateMethod({
147
- operation,
49
+ node,
148
50
  name,
149
- typeSchemas,
150
- zodSchemas,
51
+ tsResolver,
52
+ zodResolver,
151
53
  baseURL,
152
54
  dataReturnType,
153
55
  parser,
@@ -155,18 +57,23 @@ function generateMethod({
155
57
  paramsCasing,
156
58
  pathParamsType,
157
59
  }: GenerateMethodProps): string {
158
- const path = new URLPath(operation.path, { casing: paramsCasing })
159
- const contentType = operation.getContentType()
60
+ const path = new URLPath(node.path, { casing: paramsCasing })
61
+ const contentType = node.requestBody?.contentType ?? 'application/json'
160
62
  const isFormData = contentType === 'multipart/form-data'
161
- const headers = buildHeaders(contentType, !!typeSchemas.headerParams?.name)
162
- const generics = buildGenerics(typeSchemas)
163
- const params = Client.getParams({ paramsType, paramsCasing, pathParamsType, typeSchemas, isConfigurable: true })
164
- const clientParams = buildClientParams({ operation, path, baseURL, typeSchemas, isFormData, headers })
165
- const jsdoc = buildJSDoc(getComments(operation))
63
+ const headerParamsName =
64
+ node.parameters.filter((p) => p.in === 'header').length > 0
65
+ ? tsResolver.resolveHeaderParamsName(node, node.parameters.filter((p) => p.in === 'header')[0]!)
66
+ : undefined
67
+ const headers = buildHeaders(contentType, !!headerParamsName)
68
+ const generics = buildGenerics(node, tsResolver)
69
+ const paramsNode = Client.getParams({ paramsType, paramsCasing, pathParamsType, node, tsResolver, isConfigurable: true })
70
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
71
+ const clientParams = buildClassClientParams({ node, path, baseURL, tsResolver, isFormData, headers })
72
+ const jsdoc = buildJSDoc(getComments(node))
166
73
 
167
- const requestDataLine = buildRequestDataLine({ parser, zodSchemas, typeSchemas })
168
- const formDataLine = buildFormDataLine(isFormData, !!typeSchemas?.request?.name)
169
- const returnStatement = buildReturnStatement({ dataReturnType, parser, zodSchemas })
74
+ const requestDataLine = buildRequestDataLine({ parser, node, zodResolver })
75
+ const formDataLine = buildFormDataLine(isFormData, !!node.requestBody?.schema)
76
+ const returnStatement = buildReturnStatement({ dataReturnType, parser, node, zodResolver })
170
77
 
171
78
  const methodBody = [
172
79
  'const { client: request = fetch, ...requestConfig } = mergeConfig(this.#config, config)',
@@ -180,8 +87,7 @@ function generateMethod({
180
87
  .map((line) => ` ${line}`)
181
88
  .join('\n')
182
89
 
183
- // Indent static method by 2 spaces, body by 4 spaces (matching snapshot)
184
- return `${jsdoc} static async ${name}(${params.toConstructor()}) {\n${methodBody}\n }`
90
+ return `${jsdoc} static async ${name}(${paramsSignature}) {\n${methodBody}\n }`
185
91
  }
186
92
 
187
93
  export function StaticClassClient({
@@ -197,12 +103,12 @@ export function StaticClassClient({
197
103
  pathParamsType,
198
104
  children,
199
105
  }: Props): FabricReactNode {
200
- const methods = operations.map(({ operation, name: methodName, typeSchemas, zodSchemas }) =>
106
+ const methods = operations.map(({ node, name: methodName, tsResolver, zodResolver }) =>
201
107
  generateMethod({
202
- operation,
108
+ node,
203
109
  name: methodName,
204
- typeSchemas,
205
- zodSchemas,
110
+ tsResolver,
111
+ zodResolver,
206
112
  baseURL,
207
113
  dataReturnType,
208
114
  parser,
@@ -1,15 +1,14 @@
1
1
  import { isValidVarName, URLPath } from '@internals/utils'
2
- import { getDefaultValue, type Operation } from '@kubb/oas'
3
- import type { OperationSchemas } from '@kubb/plugin-oas'
4
- import { getParamsMapping, getPathParams } from '@kubb/plugin-oas/utils'
5
- import { Const, File, Function, FunctionParams } from '@kubb/react-fabric'
2
+ import { caseParams, createOperationParams } from '@kubb/ast'
3
+ import type { FunctionParametersNode, OperationNode } from '@kubb/ast/types'
4
+ import type { PluginTs } from '@kubb/plugin-ts'
5
+ import { functionPrinter } from '@kubb/plugin-ts'
6
+ import { Const, File, Function } from '@kubb/react-fabric'
6
7
  import type { FabricReactNode } from '@kubb/react-fabric/types'
7
8
  import type { PluginClient } from '../types.ts'
9
+ import { buildParamsMapping } from '../utils.ts'
8
10
 
9
11
  type Props = {
10
- /**
11
- * Name of the function
12
- */
13
12
  name: string
14
13
  isExportable?: boolean
15
14
  isIndexable?: boolean
@@ -18,45 +17,33 @@ type Props = {
18
17
  paramsCasing: PluginClient['resolvedOptions']['paramsCasing']
19
18
  paramsType: PluginClient['resolvedOptions']['pathParamsType']
20
19
  pathParamsType: PluginClient['resolvedOptions']['pathParamsType']
21
- typeSchemas: OperationSchemas
22
- operation: Operation
20
+ node: OperationNode
21
+ tsResolver: PluginTs['resolver']
23
22
  }
24
23
 
25
24
  type GetParamsProps = {
26
25
  paramsCasing: PluginClient['resolvedOptions']['paramsCasing']
27
26
  paramsType: PluginClient['resolvedOptions']['paramsType']
28
27
  pathParamsType: PluginClient['resolvedOptions']['pathParamsType']
29
- typeSchemas: OperationSchemas
28
+ node: OperationNode
29
+ tsResolver: PluginTs['resolver']
30
30
  }
31
31
 
32
- function getParams({ paramsType, paramsCasing, pathParamsType, typeSchemas }: GetParamsProps) {
33
- if (paramsType === 'object') {
34
- const pathParams = getPathParams(typeSchemas.pathParams, {
35
- typed: true,
36
- casing: paramsCasing,
37
- })
32
+ const declarationPrinter = functionPrinter({ mode: 'declaration' })
38
33
 
39
- return FunctionParams.factory({
40
- data: {
41
- mode: 'object',
42
- children: {
43
- ...pathParams,
44
- },
45
- },
46
- })
34
+ function getParams({ paramsType, paramsCasing, pathParamsType, node, tsResolver }: GetParamsProps): FunctionParametersNode {
35
+ // Build a URL-only node with only path params (no body, query, header)
36
+ const urlNode: OperationNode = {
37
+ ...node,
38
+ parameters: node.parameters.filter((p) => p.in === 'path'),
39
+ requestBody: undefined,
47
40
  }
48
41
 
49
- return FunctionParams.factory({
50
- pathParams: typeSchemas.pathParams?.name
51
- ? {
52
- mode: pathParamsType === 'object' ? 'object' : 'inlineSpread',
53
- children: getPathParams(typeSchemas.pathParams, {
54
- typed: true,
55
- casing: paramsCasing,
56
- }),
57
- default: getDefaultValue(typeSchemas.pathParams?.schema),
58
- }
59
- : undefined,
42
+ return createOperationParams(urlNode, {
43
+ paramsType: paramsType === 'object' ? 'object' : 'inline',
44
+ pathParamsType: paramsType === 'object' ? 'object' : pathParamsType === 'object' ? 'object' : 'inline',
45
+ paramsCasing,
46
+ resolver: tsResolver,
60
47
  })
61
48
  }
62
49
 
@@ -64,34 +51,38 @@ export function Url({
64
51
  name,
65
52
  isExportable = true,
66
53
  isIndexable = true,
67
- typeSchemas,
68
54
  baseURL,
69
55
  paramsType,
70
56
  paramsCasing,
71
57
  pathParamsType,
72
- operation,
58
+ node,
59
+ tsResolver,
73
60
  }: Props): FabricReactNode {
74
- const path = new URLPath(operation.path)
75
- const params = getParams({
61
+ const path = new URLPath(node.path)
62
+
63
+ const paramsNode = getParams({
76
64
  paramsType,
77
65
  paramsCasing,
78
66
  pathParamsType,
79
- typeSchemas,
67
+ node,
68
+ tsResolver,
80
69
  })
70
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
81
71
 
82
- // Generate pathParams mapping when paramsCasing is used
83
- const pathParamsMapping = paramsCasing ? getParamsMapping(typeSchemas.pathParams, { casing: paramsCasing }) : undefined
72
+ const originalPathParams = node.parameters.filter((p) => p.in === 'path')
73
+ const casedPathParams = caseParams(originalPathParams, paramsCasing)
74
+ const pathParamsMapping = paramsCasing ? buildParamsMapping(originalPathParams, casedPathParams) : undefined
84
75
 
85
76
  return (
86
77
  <File.Source name={name} isExportable={isExportable} isIndexable={isIndexable}>
87
- <Function name={name} export={isExportable} params={params.toConstructor()}>
78
+ <Function name={name} export={isExportable} params={paramsSignature}>
88
79
  {pathParamsMapping &&
89
80
  Object.entries(pathParamsMapping)
90
- .filter(([originalName, camelCaseName]) => originalName !== camelCaseName && isValidVarName(originalName))
81
+ .filter(([originalName, camelCaseName]) => isValidVarName(originalName) && originalName !== camelCaseName)
91
82
  .map(([originalName, camelCaseName]) => `const ${originalName} = ${camelCaseName}`)
92
83
  .join('\n')}
93
- {pathParamsMapping && <br />}
94
- <Const name={'res'}>{`{ method: '${operation.method.toUpperCase()}', url: ${path.toTemplateString({ prefix: baseURL })} as const }`}</Const>
84
+ {pathParamsMapping && Object.keys(pathParamsMapping).length > 0 && <br />}
85
+ <Const name={'res'}>{`{ method: '${node.method.toUpperCase()}', url: ${path.toTemplateString({ prefix: baseURL })} as const }`}</Const>
95
86
  <br />
96
87
  return res
97
88
  </Function>