@kubb/plugin-client 5.0.0-alpha.9 → 5.0.0-beta.3
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 +4 -4
- package/dist/clients/axios.cjs +2 -2
- package/dist/clients/axios.cjs.map +1 -1
- package/dist/clients/axios.d.ts +4 -4
- package/dist/clients/axios.js +1 -1
- package/dist/clients/axios.js.map +1 -1
- package/dist/clients/fetch.cjs +1 -1
- package/dist/clients/fetch.cjs.map +1 -1
- package/dist/clients/fetch.d.ts +2 -2
- package/dist/clients/fetch.js +1 -1
- package/dist/clients/fetch.js.map +1 -1
- package/dist/index.cjs +1739 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +324 -4
- package/dist/index.js +1725 -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/package.json +67 -84
- package/src/clients/axios.ts +5 -1
- package/src/clients/fetch.ts +5 -1
- package/src/components/ClassClient.tsx +45 -142
- package/src/components/Client.tsx +90 -129
- package/src/components/Operations.tsx +10 -10
- package/src/components/StaticClassClient.tsx +44 -138
- package/src/components/Url.tsx +38 -48
- package/src/components/WrapperClient.tsx +3 -3
- package/src/functionParams.ts +118 -0
- package/src/generators/classClientGenerator.tsx +148 -171
- package/src/generators/clientGenerator.tsx +95 -82
- package/src/generators/groupedClientGenerator.tsx +50 -52
- package/src/generators/operationsGenerator.tsx +11 -18
- package/src/generators/staticClassClientGenerator.tsx +178 -183
- package/src/index.ts +9 -2
- package/src/plugin.ts +115 -145
- package/src/resolvers/resolverClient.ts +22 -0
- package/src/types.ts +104 -44
- package/src/utils.ts +180 -0
- package/templates/clients/axios.ts +5 -2
- package/templates/clients/fetch.ts +5 -2
- 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 -517
- 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
|
@@ -1,36 +1,40 @@
|
|
|
1
1
|
import { buildJSDoc, URLPath } from '@internals/utils'
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
2
|
+
import type { ast } from '@kubb/core'
|
|
3
|
+
import type { ResolverTs } from '@kubb/plugin-ts'
|
|
4
|
+
import { functionPrinter } from '@kubb/plugin-ts'
|
|
5
|
+
import type { ResolverZod } from '@kubb/plugin-zod'
|
|
6
|
+
import { File } from '@kubb/renderer-jsx'
|
|
7
|
+
import type { KubbReactNode } from '@kubb/renderer-jsx/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: ast.OperationNode
|
|
14
|
+
name: string
|
|
15
|
+
tsResolver: ResolverTs
|
|
16
|
+
zodResolver?: ResolverZod
|
|
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']
|
|
23
27
|
paramsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
24
28
|
pathParamsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
25
29
|
parser: PluginClient['resolvedOptions']['parser'] | undefined
|
|
26
|
-
children?:
|
|
30
|
+
children?: KubbReactNode
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
type GenerateMethodProps = {
|
|
30
|
-
|
|
34
|
+
node: ast.OperationNode
|
|
31
35
|
name: string
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
tsResolver: ResolverTs
|
|
37
|
+
zodResolver?: ResolverZod
|
|
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
|
-
|
|
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
|
-
|
|
49
|
+
node,
|
|
148
50
|
name,
|
|
149
|
-
|
|
150
|
-
|
|
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(
|
|
159
|
-
const contentType =
|
|
60
|
+
const path = new URLPath(node.path, { casing: paramsCasing })
|
|
61
|
+
const contentType = node.requestBody?.content?.[0]?.contentType ?? 'application/json'
|
|
160
62
|
const isFormData = contentType === 'multipart/form-data'
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const
|
|
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,
|
|
168
|
-
const formDataLine = buildFormDataLine(isFormData, !!
|
|
169
|
-
const returnStatement = buildReturnStatement({ dataReturnType, parser,
|
|
74
|
+
const requestDataLine = buildRequestDataLine({ parser, node, zodResolver })
|
|
75
|
+
const formDataLine = buildFormDataLine(isFormData, !!node.requestBody?.content?.[0]?.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
|
-
|
|
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({
|
|
@@ -196,13 +102,13 @@ export function StaticClassClient({
|
|
|
196
102
|
paramsCasing,
|
|
197
103
|
pathParamsType,
|
|
198
104
|
children,
|
|
199
|
-
}: Props):
|
|
200
|
-
const methods = operations.map(({
|
|
105
|
+
}: Props): KubbReactNode {
|
|
106
|
+
const methods = operations.map(({ node, name: methodName, tsResolver, zodResolver }) =>
|
|
201
107
|
generateMethod({
|
|
202
|
-
|
|
108
|
+
node,
|
|
203
109
|
name: methodName,
|
|
204
|
-
|
|
205
|
-
|
|
110
|
+
tsResolver,
|
|
111
|
+
zodResolver,
|
|
206
112
|
baseURL,
|
|
207
113
|
dataReturnType,
|
|
208
114
|
parser,
|
package/src/components/Url.tsx
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { isValidVarName, URLPath } from '@internals/utils'
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import { Const, File, Function
|
|
6
|
-
import type {
|
|
2
|
+
import { ast } from '@kubb/core'
|
|
3
|
+
import type { ResolverTs } from '@kubb/plugin-ts'
|
|
4
|
+
import { functionPrinter } from '@kubb/plugin-ts'
|
|
5
|
+
import { Const, File, Function } from '@kubb/renderer-jsx'
|
|
6
|
+
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
7
7
|
import type { PluginClient } from '../types.ts'
|
|
8
|
+
import { buildParamsMapping } from '../utils.ts'
|
|
8
9
|
|
|
9
10
|
type Props = {
|
|
10
|
-
/**
|
|
11
|
-
* Name of the function
|
|
12
|
-
*/
|
|
13
11
|
name: string
|
|
14
12
|
isExportable?: boolean
|
|
15
13
|
isIndexable?: boolean
|
|
@@ -18,45 +16,33 @@ type Props = {
|
|
|
18
16
|
paramsCasing: PluginClient['resolvedOptions']['paramsCasing']
|
|
19
17
|
paramsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
20
18
|
pathParamsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
node: ast.OperationNode
|
|
20
|
+
tsResolver: ResolverTs
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
type GetParamsProps = {
|
|
26
24
|
paramsCasing: PluginClient['resolvedOptions']['paramsCasing']
|
|
27
25
|
paramsType: PluginClient['resolvedOptions']['paramsType']
|
|
28
26
|
pathParamsType: PluginClient['resolvedOptions']['pathParamsType']
|
|
29
|
-
|
|
27
|
+
node: ast.OperationNode
|
|
28
|
+
tsResolver: ResolverTs
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
if (paramsType === 'object') {
|
|
34
|
-
const pathParams = getPathParams(typeSchemas.pathParams, {
|
|
35
|
-
typed: true,
|
|
36
|
-
casing: paramsCasing,
|
|
37
|
-
})
|
|
31
|
+
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
},
|
|
46
|
-
})
|
|
33
|
+
function getParams({ paramsType, paramsCasing, pathParamsType, node, tsResolver }: GetParamsProps): ast.FunctionParametersNode {
|
|
34
|
+
// Build a URL-only node with only path params (no body, query, header)
|
|
35
|
+
const urlNode: ast.OperationNode = {
|
|
36
|
+
...node,
|
|
37
|
+
parameters: node.parameters.filter((p) => p.in === 'path'),
|
|
38
|
+
requestBody: undefined,
|
|
47
39
|
}
|
|
48
40
|
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
typed: true,
|
|
55
|
-
casing: paramsCasing,
|
|
56
|
-
}),
|
|
57
|
-
default: getDefaultValue(typeSchemas.pathParams?.schema),
|
|
58
|
-
}
|
|
59
|
-
: undefined,
|
|
41
|
+
return ast.createOperationParams(urlNode, {
|
|
42
|
+
paramsType: paramsType === 'object' ? 'object' : 'inline',
|
|
43
|
+
pathParamsType: paramsType === 'object' ? 'object' : pathParamsType === 'object' ? 'object' : 'inline',
|
|
44
|
+
paramsCasing,
|
|
45
|
+
resolver: tsResolver,
|
|
60
46
|
})
|
|
61
47
|
}
|
|
62
48
|
|
|
@@ -64,34 +50,38 @@ export function Url({
|
|
|
64
50
|
name,
|
|
65
51
|
isExportable = true,
|
|
66
52
|
isIndexable = true,
|
|
67
|
-
typeSchemas,
|
|
68
53
|
baseURL,
|
|
69
54
|
paramsType,
|
|
70
55
|
paramsCasing,
|
|
71
56
|
pathParamsType,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
57
|
+
node,
|
|
58
|
+
tsResolver,
|
|
59
|
+
}: Props): KubbReactNode {
|
|
60
|
+
const path = new URLPath(node.path)
|
|
61
|
+
|
|
62
|
+
const paramsNode = getParams({
|
|
76
63
|
paramsType,
|
|
77
64
|
paramsCasing,
|
|
78
65
|
pathParamsType,
|
|
79
|
-
|
|
66
|
+
node,
|
|
67
|
+
tsResolver,
|
|
80
68
|
})
|
|
69
|
+
const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
|
|
81
70
|
|
|
82
|
-
|
|
83
|
-
const
|
|
71
|
+
const originalPathParams = node.parameters.filter((p) => p.in === 'path')
|
|
72
|
+
const casedPathParams = ast.caseParams(originalPathParams, paramsCasing)
|
|
73
|
+
const pathParamsMapping = paramsCasing ? buildParamsMapping(originalPathParams, casedPathParams) : undefined
|
|
84
74
|
|
|
85
75
|
return (
|
|
86
76
|
<File.Source name={name} isExportable={isExportable} isIndexable={isIndexable}>
|
|
87
|
-
<Function name={name} export={isExportable} params={
|
|
77
|
+
<Function name={name} export={isExportable} params={paramsSignature}>
|
|
88
78
|
{pathParamsMapping &&
|
|
89
79
|
Object.entries(pathParamsMapping)
|
|
90
|
-
.filter(([originalName, camelCaseName]) => originalName !== camelCaseName
|
|
80
|
+
.filter(([originalName, camelCaseName]) => isValidVarName(originalName) && originalName !== camelCaseName)
|
|
91
81
|
.map(([originalName, camelCaseName]) => `const ${originalName} = ${camelCaseName}`)
|
|
92
82
|
.join('\n')}
|
|
93
|
-
{pathParamsMapping && <br />}
|
|
94
|
-
<Const name={'res'}>{`{ method: '${
|
|
83
|
+
{pathParamsMapping && Object.keys(pathParamsMapping).length > 0 && <br />}
|
|
84
|
+
<Const name={'res'}>{`{ method: '${node.method.toUpperCase()}', url: ${path.toTemplateString({ prefix: baseURL })} as const }`}</Const>
|
|
95
85
|
<br />
|
|
96
86
|
return res
|
|
97
87
|
</Function>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { camelCase } from '@internals/utils'
|
|
2
|
-
import { File } from '@kubb/
|
|
3
|
-
import type {
|
|
2
|
+
import { File } from '@kubb/renderer-jsx'
|
|
3
|
+
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
4
4
|
|
|
5
5
|
type Props = {
|
|
6
6
|
name: string
|
|
@@ -9,7 +9,7 @@ type Props = {
|
|
|
9
9
|
isIndexable?: boolean
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export function WrapperClient({ name, classNames, isExportable = true, isIndexable = true }: Props):
|
|
12
|
+
export function WrapperClient({ name, classNames, isExportable = true, isIndexable = true }: Props): KubbReactNode {
|
|
13
13
|
const properties = classNames.map((className) => ` readonly ${camelCase(className)}: ${className}`).join('\n')
|
|
14
14
|
const assignments = classNames.map((className) => ` this.${camelCase(className)} = new ${className}(config)`).join('\n')
|
|
15
15
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { ast } from '@kubb/core'
|
|
2
|
+
import { functionPrinter } from '@kubb/plugin-ts'
|
|
3
|
+
|
|
4
|
+
type ParamLeaf = {
|
|
5
|
+
type?: string
|
|
6
|
+
optional?: boolean
|
|
7
|
+
default?: string
|
|
8
|
+
value?: string
|
|
9
|
+
mode?: 'inlineSpread'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type ParamGroup = {
|
|
13
|
+
mode: 'object' | 'inlineSpread'
|
|
14
|
+
children: Record<string, ParamLeaf | undefined>
|
|
15
|
+
default?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type ParamSpec = ParamLeaf | ParamGroup
|
|
19
|
+
|
|
20
|
+
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
21
|
+
const callPrinter = functionPrinter({ mode: 'call' })
|
|
22
|
+
|
|
23
|
+
function isGroup(spec: ParamSpec): spec is ParamGroup {
|
|
24
|
+
return 'children' in spec
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function createType(type?: string) {
|
|
28
|
+
return type ? ast.createParamsType({ variant: 'reference', name: type }) : undefined
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function createDeclarationLeaf(name: string, spec: ParamLeaf): ast.FunctionParameterNode {
|
|
32
|
+
if (spec.default !== undefined) {
|
|
33
|
+
return ast.createFunctionParameter({
|
|
34
|
+
name,
|
|
35
|
+
type: createType(spec.type),
|
|
36
|
+
default: spec.default,
|
|
37
|
+
rest: spec.mode === 'inlineSpread',
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return ast.createFunctionParameter({
|
|
42
|
+
name,
|
|
43
|
+
type: createType(spec.type),
|
|
44
|
+
optional: !!spec.optional,
|
|
45
|
+
rest: spec.mode === 'inlineSpread',
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function createDeclarationParam(name: string, spec: ParamSpec): ast.FunctionParameterNode | ast.ParameterGroupNode {
|
|
50
|
+
if (isGroup(spec)) {
|
|
51
|
+
return ast.createParameterGroup({
|
|
52
|
+
inline: spec.mode === 'inlineSpread',
|
|
53
|
+
default: spec.default,
|
|
54
|
+
properties: Object.entries(spec.children)
|
|
55
|
+
.filter(([, child]) => child !== undefined)
|
|
56
|
+
.map(([childName, child]) => createDeclarationLeaf(childName, child!)),
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return createDeclarationLeaf(name, spec)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function createCallParam(name: string, spec: ParamSpec): ast.FunctionParameterNode | ast.ParameterGroupNode {
|
|
64
|
+
if (isGroup(spec)) {
|
|
65
|
+
return ast.createParameterGroup({
|
|
66
|
+
inline: spec.mode === 'inlineSpread',
|
|
67
|
+
properties: Object.entries(spec.children)
|
|
68
|
+
.filter(([, child]) => child !== undefined)
|
|
69
|
+
.map(([childName, child]) =>
|
|
70
|
+
ast.createFunctionParameter({
|
|
71
|
+
name:
|
|
72
|
+
child?.mode === 'inlineSpread'
|
|
73
|
+
? spec.mode === 'inlineSpread'
|
|
74
|
+
? (child.value ?? childName)
|
|
75
|
+
: `...${child.value ?? childName}`
|
|
76
|
+
: child?.value
|
|
77
|
+
? `${childName}: ${child.value}`
|
|
78
|
+
: childName,
|
|
79
|
+
rest: spec.mode === 'inlineSpread' && child?.mode === 'inlineSpread',
|
|
80
|
+
}),
|
|
81
|
+
),
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return ast.createFunctionParameter({
|
|
86
|
+
name: spec.value ?? name,
|
|
87
|
+
rest: spec.mode === 'inlineSpread',
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Creates function parameter builders for generating function signatures and calls.
|
|
93
|
+
* Returns utilities to output constructor signatures (`toConstructor()`) or call expressions (`toCall()`).
|
|
94
|
+
*/
|
|
95
|
+
export function createFunctionParams(params: Record<string, ParamSpec | undefined>) {
|
|
96
|
+
const entries = Object.entries(params).filter(([, spec]) => spec !== undefined) as Array<[string, ParamSpec]>
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
toConstructor() {
|
|
100
|
+
return (
|
|
101
|
+
declarationPrinter.print(
|
|
102
|
+
ast.createFunctionParameters({
|
|
103
|
+
params: entries.map(([name, spec]) => createDeclarationParam(name, spec)),
|
|
104
|
+
}),
|
|
105
|
+
) ?? ''
|
|
106
|
+
)
|
|
107
|
+
},
|
|
108
|
+
toCall() {
|
|
109
|
+
return (
|
|
110
|
+
callPrinter.print(
|
|
111
|
+
ast.createFunctionParameters({
|
|
112
|
+
params: entries.map(([name, spec]) => createCallParam(name, spec)),
|
|
113
|
+
}),
|
|
114
|
+
) ?? ''
|
|
115
|
+
)
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
}
|