@goast/kotlin 0.5.0 → 0.5.1-beta.1
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 +21 -21
- package/assets/client/okhttp3/ApiAbstractions.kt +30 -30
- package/assets/client/okhttp3/ApiClient.kt +253 -253
- package/assets/client/okhttp3/ApiResponse.kt +43 -43
- package/assets/client/okhttp3/Errors.kt +21 -21
- package/assets/client/okhttp3/PartConfig.kt +11 -11
- package/assets/client/okhttp3/RequestConfig.kt +18 -18
- package/assets/client/okhttp3/RequestMethod.kt +8 -8
- package/assets/client/okhttp3/ResponseExtensions.kt +24 -24
- package/assets/client/spring-reactive-web-clients/ApiRequestFile.kt +33 -33
- package/esm/src/generators/models/model-generator.d.ts.map +1 -1
- package/esm/src/generators/models/model-generator.js +10 -5
- package/package.json +2 -2
- package/script/src/generators/models/model-generator.d.ts.map +1 -1
- package/script/src/generators/models/model-generator.js +10 -5
- package/src/mod.ts +0 -8
- package/src/src/assets.ts +0 -9
- package/src/src/ast/_index.ts +0 -66
- package/src/src/ast/common.ts +0 -1
- package/src/src/ast/index.ts +0 -1
- package/src/src/ast/node.ts +0 -10
- package/src/src/ast/nodes/annotation.ts +0 -79
- package/src/src/ast/nodes/argument.ts +0 -62
- package/src/src/ast/nodes/call.ts +0 -75
- package/src/src/ast/nodes/class.ts +0 -178
- package/src/src/ast/nodes/collection-literal.ts +0 -49
- package/src/src/ast/nodes/constructor.ts +0 -126
- package/src/src/ast/nodes/doc-tag.ts +0 -138
- package/src/src/ast/nodes/doc.ts +0 -111
- package/src/src/ast/nodes/enum-value.ts +0 -100
- package/src/src/ast/nodes/enum.ts +0 -163
- package/src/src/ast/nodes/function.ts +0 -178
- package/src/src/ast/nodes/generic-parameter.ts +0 -54
- package/src/src/ast/nodes/init-block.ts +0 -38
- package/src/src/ast/nodes/interface.ts +0 -133
- package/src/src/ast/nodes/lambda-type.ts +0 -73
- package/src/src/ast/nodes/lambda.ts +0 -74
- package/src/src/ast/nodes/object.ts +0 -102
- package/src/src/ast/nodes/parameter.ts +0 -118
- package/src/src/ast/nodes/property.ts +0 -225
- package/src/src/ast/nodes/reference.ts +0 -178
- package/src/src/ast/nodes/string.ts +0 -114
- package/src/src/ast/nodes/types.ts +0 -23
- package/src/src/ast/references/index.ts +0 -10
- package/src/src/ast/references/jackson.ts +0 -44
- package/src/src/ast/references/jakarta.ts +0 -14
- package/src/src/ast/references/java.ts +0 -20
- package/src/src/ast/references/kotlin.ts +0 -41
- package/src/src/ast/references/kotlinx.ts +0 -14
- package/src/src/ast/references/okhttp3.ts +0 -5
- package/src/src/ast/references/reactor.ts +0 -5
- package/src/src/ast/references/spring-reactive.ts +0 -33
- package/src/src/ast/references/spring.ts +0 -86
- package/src/src/ast/references/swagger.ts +0 -23
- package/src/src/ast/utils/get-kotlin-builder-options.ts +0 -19
- package/src/src/ast/utils/to-kt-node.ts +0 -31
- package/src/src/ast/utils/write-kt-annotations.ts +0 -15
- package/src/src/ast/utils/write-kt-arguments.ts +0 -45
- package/src/src/ast/utils/write-kt-enum-values.ts +0 -27
- package/src/src/ast/utils/write-kt-generic-parameters.ts +0 -12
- package/src/src/ast/utils/write-kt-members.ts +0 -25
- package/src/src/ast/utils/write-kt-node.ts +0 -37
- package/src/src/ast/utils/write-kt-parameters.ts +0 -25
- package/src/src/common-results.ts +0 -4
- package/src/src/config.ts +0 -41
- package/src/src/file-builder.ts +0 -112
- package/src/src/generators/file-generator.ts +0 -29
- package/src/src/generators/index.ts +0 -5
- package/src/src/generators/models/args.ts +0 -132
- package/src/src/generators/models/index.ts +0 -4
- package/src/src/generators/models/model-generator.ts +0 -695
- package/src/src/generators/models/models-generator.ts +0 -65
- package/src/src/generators/models/models.ts +0 -95
- package/src/src/generators/services/okhttp3-clients/args.ts +0 -88
- package/src/src/generators/services/okhttp3-clients/index.ts +0 -4
- package/src/src/generators/services/okhttp3-clients/models.ts +0 -73
- package/src/src/generators/services/okhttp3-clients/okhttp3-client-generator.ts +0 -597
- package/src/src/generators/services/okhttp3-clients/okhttp3-clients-generator.ts +0 -169
- package/src/src/generators/services/okhttp3-clients/refs.ts +0 -59
- package/src/src/generators/services/spring-controllers/args.ts +0 -93
- package/src/src/generators/services/spring-controllers/index.ts +0 -4
- package/src/src/generators/services/spring-controllers/models.ts +0 -76
- package/src/src/generators/services/spring-controllers/refs.ts +0 -17
- package/src/src/generators/services/spring-controllers/spring-controller-generator.ts +0 -1084
- package/src/src/generators/services/spring-controllers/spring-controllers-generator.ts +0 -140
- package/src/src/generators/services/spring-reactive-web-clients/args.ts +0 -101
- package/src/src/generators/services/spring-reactive-web-clients/index.ts +0 -4
- package/src/src/generators/services/spring-reactive-web-clients/models.ts +0 -62
- package/src/src/generators/services/spring-reactive-web-clients/refs.ts +0 -11
- package/src/src/generators/services/spring-reactive-web-clients/spring-reactive-web-client-generator.ts +0 -571
- package/src/src/generators/services/spring-reactive-web-clients/spring-reactive-web-clients-generator.ts +0 -125
- package/src/src/import-collection.ts +0 -98
- package/src/src/types.ts +0 -3
- package/src/src/utils.ts +0 -39
|
@@ -1,571 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type ApiParameter,
|
|
3
|
-
type ApiSchema,
|
|
4
|
-
type AppendValueGroup,
|
|
5
|
-
appendValueGroup,
|
|
6
|
-
builderTemplate as s,
|
|
7
|
-
createOverwriteProxy,
|
|
8
|
-
getSourceDisplayName,
|
|
9
|
-
type MaybePromise,
|
|
10
|
-
resolveAnyOfAndAllOf,
|
|
11
|
-
SourceBuilder,
|
|
12
|
-
toCasing,
|
|
13
|
-
} from '@goast/core';
|
|
14
|
-
|
|
15
|
-
import { kt } from '../../../ast/index.js';
|
|
16
|
-
import type { KtValue } from '../../../ast/nodes/types.js';
|
|
17
|
-
import { KotlinFileBuilder } from '../../../file-builder.js';
|
|
18
|
-
import type { ApiParameterWithMultipartInfo } from '../../../types.js';
|
|
19
|
-
import { modifyString } from '../../../utils.js';
|
|
20
|
-
import { KotlinFileGenerator } from '../../file-generator.js';
|
|
21
|
-
import type { DefaultKotlinSpringReactiveWebClientGeneratorArgs as Args } from './index.js';
|
|
22
|
-
import type {
|
|
23
|
-
KotlinSpringReactiveWebClientGeneratorContext,
|
|
24
|
-
KotlinSpringReactiveWebClientGeneratorOutput,
|
|
25
|
-
} from './models.js';
|
|
26
|
-
|
|
27
|
-
type Context = KotlinSpringReactiveWebClientGeneratorContext;
|
|
28
|
-
type Output = KotlinSpringReactiveWebClientGeneratorOutput;
|
|
29
|
-
type Builder = KotlinFileBuilder;
|
|
30
|
-
|
|
31
|
-
export interface KotlinSpringReactiveWebClientGenerator<TOutput extends Output = Output> {
|
|
32
|
-
generate(ctx: Context): MaybePromise<TOutput>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export class DefaultKotlinSpringReactiveWebClientGenerator extends KotlinFileGenerator<Context, Output>
|
|
36
|
-
implements KotlinSpringReactiveWebClientGenerator {
|
|
37
|
-
public generate(ctx: Context): MaybePromise<Output> {
|
|
38
|
-
const typeName = this.getRequestsObjectName(ctx, {});
|
|
39
|
-
const packageName = this.getPackageName(ctx, {});
|
|
40
|
-
const filePath = this.getFilePath(ctx, { packageName });
|
|
41
|
-
|
|
42
|
-
console.log(`Generating client for service ${ctx.service.name} to ${filePath}...`);
|
|
43
|
-
ctx.service.endpoints.forEach((endpoint) => {
|
|
44
|
-
console.log(
|
|
45
|
-
` ${getSourceDisplayName(ctx.data, endpoint)} [${toCasing(endpoint.name, ctx.config.functionNameCasing)}]`,
|
|
46
|
-
);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const builder = new KotlinFileBuilder(packageName, ctx.config);
|
|
50
|
-
builder.append(this.getClientFileContent(ctx, {}));
|
|
51
|
-
builder.writeToFile(filePath);
|
|
52
|
-
|
|
53
|
-
return { typeName, packageName };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// deno-lint-ignore no-unused-vars
|
|
57
|
-
protected getClientFileContent(ctx: Context, args: Args.GetClientFileContent): AppendValueGroup<Builder> {
|
|
58
|
-
return appendValueGroup([this.getRequestsObject(ctx, {})], '\n\n');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// deno-lint-ignore no-unused-vars
|
|
62
|
-
protected getRequestsObject(ctx: Context, args: Args.GetRequestsObject): kt.Object<Builder> {
|
|
63
|
-
return kt.object({
|
|
64
|
-
name: this.getRequestsObjectName(ctx, {}),
|
|
65
|
-
members: ctx.service.endpoints.flatMap((endpoint) =>
|
|
66
|
-
this.getEndpointMembers(ctx, { endpoint, parameters: this.getAllParameters(ctx, { endpoint }) })
|
|
67
|
-
),
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
protected getEndpointMembers(ctx: Context, args: Args.GetEndpointMembers): kt.ObjectMember<Builder>[] {
|
|
72
|
-
const { endpoint, parameters } = args;
|
|
73
|
-
const responseSchema = this.getResponseSchema(ctx, { endpoint });
|
|
74
|
-
|
|
75
|
-
return [
|
|
76
|
-
this.getEndpointFunction(ctx, { endpoint, parameters, responseSchema }),
|
|
77
|
-
this.getEndpointFunctionWithHandler(ctx, { endpoint, parameters, responseSchema }),
|
|
78
|
-
this.getEndpointUriFunction(ctx, { endpoint, parameters }),
|
|
79
|
-
this.getEndpointRequestFunction(ctx, { endpoint, parameters, responseSchema }),
|
|
80
|
-
];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
protected getEndpointFunctionName(ctx: Context, args: Args.GetEndpointFunctionName): string {
|
|
84
|
-
const { endpoint } = args;
|
|
85
|
-
return toCasing(endpoint.name, ctx.config.functionNameCasing);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
protected getEndpointFunction(ctx: Context, args: Args.GetEndpointFunction): kt.Function<Builder> {
|
|
89
|
-
const { endpoint, parameters, responseSchema } = args;
|
|
90
|
-
const functionName = this.getEndpointFunctionName(ctx, { endpoint });
|
|
91
|
-
|
|
92
|
-
return kt.function(functionName, {
|
|
93
|
-
doc: kt.doc(endpoint.description),
|
|
94
|
-
suspend: true,
|
|
95
|
-
receiverType: kt.refs.springReactive.webClient(),
|
|
96
|
-
parameters: parameters.map((parameter) =>
|
|
97
|
-
kt.parameter(
|
|
98
|
-
toCasing(parameter.name, ctx.config.parameterNameCasing),
|
|
99
|
-
this.getParameterType(ctx, { endpoint, parameter }),
|
|
100
|
-
{ default: this.getParameterDefaultValue(ctx, { endpoint, parameter }) },
|
|
101
|
-
)
|
|
102
|
-
),
|
|
103
|
-
returnType: this.getTypeUsage(ctx, { schema: responseSchema, fallback: kt.refs.unit() }),
|
|
104
|
-
body: this.getEndpointFunctionBody(ctx, { endpoint, parameters, responseSchema }),
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
protected getEndpointFunctionBody(ctx: Context, args: Args.GetEndpointFunctionBody): AppendValueGroup<Builder> {
|
|
109
|
-
const { endpoint, parameters, responseSchema } = args;
|
|
110
|
-
const result = appendValueGroup<Builder>([], '\n');
|
|
111
|
-
|
|
112
|
-
const requestFunctionName = this.getEndpointRequestFunctionName(ctx, { endpoint });
|
|
113
|
-
const parameterNames = parameters.map((p) => toCasing(p.name, ctx.config.parameterNameCasing));
|
|
114
|
-
const call = kt.call([
|
|
115
|
-
'this',
|
|
116
|
-
kt.call(requestFunctionName, parameterNames),
|
|
117
|
-
kt.call('retrieve', []),
|
|
118
|
-
responseSchema
|
|
119
|
-
? kt.call(
|
|
120
|
-
kt.refs.springReactive.awaitBody([
|
|
121
|
-
this.getTypeUsage(ctx, { schema: responseSchema, fallback: kt.refs.unit() }),
|
|
122
|
-
]),
|
|
123
|
-
[],
|
|
124
|
-
)
|
|
125
|
-
: kt.call(kt.refs.springReactive.awaitBodilessEntity(), []),
|
|
126
|
-
]);
|
|
127
|
-
|
|
128
|
-
if (responseSchema) {
|
|
129
|
-
result.values.push(s`return ${call}`);
|
|
130
|
-
} else {
|
|
131
|
-
result.values.push(call);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return result;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
protected getEndpointFunctionWithHandler(
|
|
138
|
-
ctx: Context,
|
|
139
|
-
args: Args.GetEndpointFunctionWithHandler,
|
|
140
|
-
): kt.Function<Builder> {
|
|
141
|
-
const { endpoint, parameters, responseSchema } = args;
|
|
142
|
-
const functionName = this.getEndpointFunctionName(ctx, { endpoint });
|
|
143
|
-
|
|
144
|
-
return kt.function(functionName, {
|
|
145
|
-
doc: kt.doc(endpoint.description),
|
|
146
|
-
suspend: true,
|
|
147
|
-
generics: [kt.genericParameter('T')],
|
|
148
|
-
receiverType: kt.refs.springReactive.webClient(),
|
|
149
|
-
parameters: [
|
|
150
|
-
...parameters.map((parameter) =>
|
|
151
|
-
kt.parameter(
|
|
152
|
-
toCasing(parameter.name, ctx.config.parameterNameCasing),
|
|
153
|
-
this.getParameterType(ctx, { endpoint, parameter }),
|
|
154
|
-
{ default: this.getParameterDefaultValue(ctx, { endpoint, parameter }) },
|
|
155
|
-
)
|
|
156
|
-
),
|
|
157
|
-
kt.parameter(
|
|
158
|
-
'responseHandler',
|
|
159
|
-
kt.lambdaType([kt.refs.springReactive.clientResponse()], 'T', { suspend: true }),
|
|
160
|
-
),
|
|
161
|
-
],
|
|
162
|
-
returnType: 'T',
|
|
163
|
-
body: this.getEndpointFunctionWithHandlerBody(ctx, { endpoint, parameters, responseSchema }),
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
protected getEndpointFunctionWithHandlerBody(
|
|
168
|
-
ctx: Context,
|
|
169
|
-
args: Args.GetEndpointFunctionWithHandlerBody,
|
|
170
|
-
): AppendValueGroup<Builder> {
|
|
171
|
-
const { endpoint, parameters } = args;
|
|
172
|
-
const result = appendValueGroup<Builder>([], '\n');
|
|
173
|
-
|
|
174
|
-
const requestFunctionName = this.getEndpointRequestFunctionName(ctx, { endpoint });
|
|
175
|
-
const parameterNames = parameters.map((p) => toCasing(p.name, ctx.config.parameterNameCasing));
|
|
176
|
-
|
|
177
|
-
result.values.push(s`return ${
|
|
178
|
-
kt.call([
|
|
179
|
-
kt.call(['this', requestFunctionName], parameterNames),
|
|
180
|
-
kt.call(['exchangeToMono'], [
|
|
181
|
-
kt.lambda(
|
|
182
|
-
[],
|
|
183
|
-
kt.call(kt.refs.kotlinx.mono.infer(), [kt.lambda([], 'responseHandler(it)', { singleline: true })]),
|
|
184
|
-
{ singleline: true },
|
|
185
|
-
),
|
|
186
|
-
]),
|
|
187
|
-
kt.call([kt.refs.kotlinx.awaitFirstOrNull.infer()], []),
|
|
188
|
-
])
|
|
189
|
-
} as T`);
|
|
190
|
-
|
|
191
|
-
return result;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
protected getEndpointRequestFunctionName(ctx: Context, args: Args.GetEndpointRequestFunctionName): string {
|
|
195
|
-
const { endpoint } = args;
|
|
196
|
-
return toCasing(`${this.getEndpointFunctionName(ctx, { endpoint })}_request`, ctx.config.functionNameCasing);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
protected getEndpointRequestFunction(ctx: Context, args: Args.GetEndpointRequestFunction): kt.Function<Builder> {
|
|
200
|
-
const { endpoint, parameters, responseSchema } = args;
|
|
201
|
-
const functionName = this.getEndpointRequestFunctionName(ctx, { endpoint });
|
|
202
|
-
|
|
203
|
-
return kt.function(functionName, {
|
|
204
|
-
doc: kt.doc(endpoint.description),
|
|
205
|
-
receiverType: kt.refs.springReactive.webClient(),
|
|
206
|
-
parameters: parameters.map((parameter) =>
|
|
207
|
-
kt.parameter(
|
|
208
|
-
toCasing(parameter.name, ctx.config.parameterNameCasing),
|
|
209
|
-
this.getParameterType(ctx, { endpoint, parameter }),
|
|
210
|
-
{ default: this.getParameterDefaultValue(ctx, { endpoint, parameter }) },
|
|
211
|
-
)
|
|
212
|
-
),
|
|
213
|
-
returnType: kt.refs.springReactive.requestHeadersSpec(['*']),
|
|
214
|
-
body: this.getEndpointRequestFunctionBody(ctx, { endpoint, parameters, responseSchema }),
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
protected getEndpointRequestFunctionBody(
|
|
219
|
-
ctx: Context,
|
|
220
|
-
args: Args.GetEndpointRequestFunctionBody,
|
|
221
|
-
): AppendValueGroup<Builder> {
|
|
222
|
-
const { endpoint, parameters, responseSchema } = args;
|
|
223
|
-
const result = appendValueGroup<Builder>([], '\n');
|
|
224
|
-
|
|
225
|
-
const callChain: KtValue<Builder>[] = [];
|
|
226
|
-
callChain.push(
|
|
227
|
-
s`return this.method(${kt.refs.spring.httpMethod()}.${endpoint.method.toUpperCase()})`,
|
|
228
|
-
kt.call('uri', [kt.call(
|
|
229
|
-
[this.getEndpointUriFunctionName(ctx, { endpoint })],
|
|
230
|
-
parameters.filter((p) => p.target === 'path' || p.target === 'query').map((p) =>
|
|
231
|
-
toCasing(p.name, ctx.config.parameterNameCasing)
|
|
232
|
-
),
|
|
233
|
-
)]),
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
if (responseSchema) {
|
|
237
|
-
callChain.push(s`accept(${kt.refs.spring.mediaType()}.APPLICATION_JSON)`);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (endpoint.requestBody?.content[0] !== undefined) {
|
|
241
|
-
callChain.push(
|
|
242
|
-
s`contentType(${kt.refs.spring.mediaType()}.parseMediaType(${
|
|
243
|
-
kt.string(endpoint.requestBody.content[0].type)
|
|
244
|
-
}))`,
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (endpoint.requestBody?.content[0]) {
|
|
249
|
-
if (endpoint.requestBody.content[0].type === 'multipart/form-data') {
|
|
250
|
-
callChain.push(
|
|
251
|
-
kt.call('body', [
|
|
252
|
-
kt.call([kt.refs.springReactive.bodyInserters(), 'fromMultipartData'], [
|
|
253
|
-
kt.call([
|
|
254
|
-
kt.call(kt.refs.spring.multipartBodyBuilder(), []),
|
|
255
|
-
kt.call('apply', [
|
|
256
|
-
kt.lambda(
|
|
257
|
-
[],
|
|
258
|
-
appendValueGroup(
|
|
259
|
-
parameters.filter((x) => x.multipart).map((p) => {
|
|
260
|
-
const parameterName = toCasing(p.name, ctx.config.parameterNameCasing);
|
|
261
|
-
if (p.multipart?.isFile) {
|
|
262
|
-
return kt.call([
|
|
263
|
-
p.required && !p.schema?.nullable ? parameterName : `${parameterName}?`,
|
|
264
|
-
'addToBuilder',
|
|
265
|
-
], ['this']);
|
|
266
|
-
} else {
|
|
267
|
-
const call = kt.call([
|
|
268
|
-
kt.call('part', [kt.string(p.multipart!.name), parameterName]),
|
|
269
|
-
kt.call('contentType', [
|
|
270
|
-
kt.call([
|
|
271
|
-
kt.refs.spring.mediaType(),
|
|
272
|
-
'APPLICATION_JSON',
|
|
273
|
-
]),
|
|
274
|
-
]),
|
|
275
|
-
]);
|
|
276
|
-
return p.required && !p.schema?.nullable ? call : kt.call([`${parameterName}?`, 'also'], [
|
|
277
|
-
kt.lambda([parameterName], call, { singleline: true }),
|
|
278
|
-
]);
|
|
279
|
-
}
|
|
280
|
-
}),
|
|
281
|
-
'\n',
|
|
282
|
-
),
|
|
283
|
-
),
|
|
284
|
-
]),
|
|
285
|
-
'build',
|
|
286
|
-
], []),
|
|
287
|
-
]),
|
|
288
|
-
]),
|
|
289
|
-
);
|
|
290
|
-
} else {
|
|
291
|
-
const bodySchema = endpoint.requestBody.content[0].schema;
|
|
292
|
-
const parameterName = this.getRequestBodyParamName(ctx, { endpoint });
|
|
293
|
-
const call = kt.call('bodyValue', [
|
|
294
|
-
toCasing(parameterName, ctx.config.parameterNameCasing),
|
|
295
|
-
]);
|
|
296
|
-
callChain.push(
|
|
297
|
-
endpoint.requestBody.required && !bodySchema?.nullable ? call : kt.call('apply', [
|
|
298
|
-
kt.lambda(
|
|
299
|
-
[],
|
|
300
|
-
kt.call([`${parameterName}?`, 'also'], [kt.lambda([parameterName], call, { singleline: true })]),
|
|
301
|
-
{ singleline: true },
|
|
302
|
-
),
|
|
303
|
-
]),
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (parameters.some((x) => x.target === 'header')) {
|
|
309
|
-
callChain.push(
|
|
310
|
-
kt.call('headers', [
|
|
311
|
-
kt.lambda(
|
|
312
|
-
['headers'],
|
|
313
|
-
appendValueGroup(
|
|
314
|
-
parameters.filter((x) => x.target === 'header').map((p) => {
|
|
315
|
-
const parameterName = toCasing(p.name, ctx.config.parameterNameCasing);
|
|
316
|
-
const toString = this.getParameterToString(ctx, { endpoint, parameter: p });
|
|
317
|
-
return p.required && !p.schema?.nullable
|
|
318
|
-
? kt.call(['headers', 'add'], [kt.string(p.name), parameterName + toString])
|
|
319
|
-
: kt.call([`${parameterName}?`, 'also'], [
|
|
320
|
-
kt.lambda([], kt.call(['headers', 'add'], [kt.string(p.name), 'it' + toString]), {
|
|
321
|
-
singleline: true,
|
|
322
|
-
}),
|
|
323
|
-
]);
|
|
324
|
-
}),
|
|
325
|
-
'\n',
|
|
326
|
-
),
|
|
327
|
-
),
|
|
328
|
-
]),
|
|
329
|
-
);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
result.values.push(kt.call(callChain));
|
|
333
|
-
return result;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
protected getEndpointUriFunctionName(ctx: Context, args: Args.GetEndpointUriFunctionName): string {
|
|
337
|
-
const { endpoint } = args;
|
|
338
|
-
return toCasing(`${this.getEndpointFunctionName(ctx, { endpoint })}_uri`, ctx.config.functionNameCasing);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
protected getEndpointUriFunction(ctx: Context, args: Args.GetEndpointUriFunction): kt.Function<Builder> {
|
|
342
|
-
const { endpoint, parameters } = args;
|
|
343
|
-
const functionName = this.getEndpointUriFunctionName(ctx, { endpoint });
|
|
344
|
-
|
|
345
|
-
return kt.function(functionName, {
|
|
346
|
-
parameters: parameters.filter((p) => p.target === 'path' || p.target === 'query').map((parameter) =>
|
|
347
|
-
kt.parameter(
|
|
348
|
-
toCasing(parameter.name, ctx.config.parameterNameCasing),
|
|
349
|
-
this.getParameterType(ctx, { endpoint, parameter }),
|
|
350
|
-
{ default: this.getParameterDefaultValue(ctx, { endpoint, parameter }) },
|
|
351
|
-
)
|
|
352
|
-
),
|
|
353
|
-
returnType: kt.refs.string(),
|
|
354
|
-
body: this.getEndpointUriFunctionBody(ctx, { endpoint, parameters }),
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
protected getEndpointUriFunctionBody(ctx: Context, args: Args.GetEndpointUriFunctionBody): AppendValueGroup<Builder> {
|
|
359
|
-
const { endpoint } = args;
|
|
360
|
-
const result = appendValueGroup<Builder>([], '\n');
|
|
361
|
-
|
|
362
|
-
const callChain: KtValue<Builder>[] = [];
|
|
363
|
-
callChain.push(
|
|
364
|
-
s`${kt.refs.spring.uriComponentsBuilder()}.fromPath(${kt.string(this.getEndpointPath(ctx, { endpoint }))})`,
|
|
365
|
-
);
|
|
366
|
-
|
|
367
|
-
if (endpoint.parameters.some((x) => x.target === 'query')) {
|
|
368
|
-
callChain.push(
|
|
369
|
-
kt.call('apply', [kt.lambda(
|
|
370
|
-
[],
|
|
371
|
-
appendValueGroup(
|
|
372
|
-
endpoint.parameters.filter((x) => x.target === 'query').map((p) => {
|
|
373
|
-
const parameterName = toCasing(p.name, ctx.config.parameterNameCasing);
|
|
374
|
-
const toString = this.getParameterToString(ctx, { endpoint, parameter: p });
|
|
375
|
-
return p.required && !p.schema?.nullable
|
|
376
|
-
? kt.call('queryParam', [kt.string(p.name), parameterName + toString])
|
|
377
|
-
: kt.call([`${parameterName}?`, 'also'], [
|
|
378
|
-
kt.lambda([], kt.call('queryParam', [kt.string(p.name), 'it' + toString]), { singleline: true }),
|
|
379
|
-
]);
|
|
380
|
-
}),
|
|
381
|
-
'\n',
|
|
382
|
-
),
|
|
383
|
-
)]),
|
|
384
|
-
);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
if (endpoint.parameters.some((x) => x.target === 'path')) {
|
|
388
|
-
callChain.push(kt.call('buildAndExpand', [
|
|
389
|
-
kt.call(
|
|
390
|
-
[kt.refs.mapOf.infer()],
|
|
391
|
-
endpoint.parameters.filter((p) => p.target === 'path').map((p) =>
|
|
392
|
-
s`${kt.string(p.name)} to ${toCasing(p.name, ctx.config.parameterNameCasing)}${
|
|
393
|
-
this.getParameterToString(ctx, { endpoint, parameter: p })
|
|
394
|
-
}`
|
|
395
|
-
),
|
|
396
|
-
),
|
|
397
|
-
]));
|
|
398
|
-
} else {
|
|
399
|
-
callChain.push(kt.call('build', []));
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
callChain.push('toUriString');
|
|
403
|
-
result.values.push(s`return ${kt.call(callChain, [])}`);
|
|
404
|
-
return result;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
protected getParameterToString(ctx: Context, args: Args.GetParameterToString): kt.Value<Builder> {
|
|
408
|
-
const { parameter } = args;
|
|
409
|
-
if (parameter.schema?.kind === 'array') {
|
|
410
|
-
return '.joinToString()';
|
|
411
|
-
} else if (
|
|
412
|
-
parameter.schema?.kind === 'string' && parameter.schema.enum?.length &&
|
|
413
|
-
this.getSchemaType(ctx, { schema: parameter.schema })
|
|
414
|
-
) {
|
|
415
|
-
return '.value';
|
|
416
|
-
} else {
|
|
417
|
-
return '.toString()';
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
protected getParameterType(ctx: Context, args: Args.GetParameterType): kt.Type<Builder> {
|
|
422
|
-
const { parameter } = args;
|
|
423
|
-
if (parameter.multipart?.isFile) {
|
|
424
|
-
return ctx.refs.apiRequestFile();
|
|
425
|
-
}
|
|
426
|
-
return this.getTypeUsage(ctx, {
|
|
427
|
-
schema: parameter.schema,
|
|
428
|
-
nullable: !parameter.required,
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
protected getParameterDefaultValue(ctx: Context, args: Args.GetParameterDefaultValue): kt.Value<Builder> | null {
|
|
433
|
-
const { parameter } = args;
|
|
434
|
-
|
|
435
|
-
return !parameter.required
|
|
436
|
-
? parameter.schema?.kind === 'string' && parameter.schema.enum && parameter.schema.default
|
|
437
|
-
? s`${this.getTypeUsage(ctx, { schema: parameter.schema, nullable: false })}.${
|
|
438
|
-
toCasing(String(parameter.schema.default), ctx.config.enumValueNameCasing)
|
|
439
|
-
}`
|
|
440
|
-
: kt.toNode(parameter.schema?.default)
|
|
441
|
-
: null;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
protected getTypeUsage(ctx: Context, args: Args.GetTypeUsage<Builder>): kt.Type<Builder> {
|
|
445
|
-
const { schema, nullable, fallback } = args;
|
|
446
|
-
const type = this.getSchemaType(ctx, { schema });
|
|
447
|
-
return type
|
|
448
|
-
? createOverwriteProxy(type, { nullable: nullable ?? type.nullable })
|
|
449
|
-
: (fallback ?? kt.refs.any({ nullable }));
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// deno-lint-ignore no-unused-vars
|
|
453
|
-
protected getPackageName(ctx: Context, args: Args.GetPackageName): string {
|
|
454
|
-
const packageSuffix = typeof ctx.config.packageSuffix === 'string'
|
|
455
|
-
? ctx.config.packageSuffix
|
|
456
|
-
: ctx.config.packageSuffix(ctx.service);
|
|
457
|
-
return ctx.config.packageName + packageSuffix;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
protected getResponseSchema(_ctx: Context, args: Args.GetResponseSchema): ApiSchema | undefined {
|
|
461
|
-
const { endpoint } = args;
|
|
462
|
-
return endpoint.responses.find((x) => !x.statusCode || (x.statusCode >= 200 && x.statusCode < 300))
|
|
463
|
-
?.contentOptions[0]?.schema;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
protected getSchemaType(ctx: Context, args: Args.GetSchemaType): kt.Reference<SourceBuilder> | undefined {
|
|
467
|
-
const { schema } = args;
|
|
468
|
-
return schema && ctx.input.kotlin.models[schema.id].type;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
protected getAllParameters(ctx: Context, args: Args.GetAllParameters): ApiParameterWithMultipartInfo[] {
|
|
472
|
-
const { endpoint } = args;
|
|
473
|
-
const parameters = endpoint.parameters.filter(
|
|
474
|
-
(parameter) => parameter.target === 'query' || parameter.target === 'path' || parameter.target === 'header',
|
|
475
|
-
);
|
|
476
|
-
if (endpoint.requestBody) {
|
|
477
|
-
const content = endpoint.requestBody.content[0];
|
|
478
|
-
let schema = content.schema;
|
|
479
|
-
|
|
480
|
-
if (content.type === 'multipart/form-data') {
|
|
481
|
-
if (schema && schema.kind === 'object') {
|
|
482
|
-
schema = resolveAnyOfAndAllOf(schema, true) ?? schema;
|
|
483
|
-
const properties = schema.properties ?? {};
|
|
484
|
-
for (const [name, property] of properties.entries()) {
|
|
485
|
-
parameters.push(
|
|
486
|
-
Object.assign(
|
|
487
|
-
this.createApiParameter({
|
|
488
|
-
id: `multipart-${name}`,
|
|
489
|
-
name,
|
|
490
|
-
target: 'body',
|
|
491
|
-
schema: property.schema,
|
|
492
|
-
required: schema.required.has(name),
|
|
493
|
-
description: property.schema.description,
|
|
494
|
-
}),
|
|
495
|
-
{
|
|
496
|
-
multipart: {
|
|
497
|
-
name,
|
|
498
|
-
isFile: property.schema.kind === 'string' && property.schema.format === 'binary',
|
|
499
|
-
},
|
|
500
|
-
},
|
|
501
|
-
),
|
|
502
|
-
);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
} else {
|
|
506
|
-
parameters.push(
|
|
507
|
-
this.createApiParameter({
|
|
508
|
-
id: 'body',
|
|
509
|
-
name: this.getRequestBodyParamName(ctx, { endpoint }),
|
|
510
|
-
target: 'body',
|
|
511
|
-
schema,
|
|
512
|
-
required: endpoint.requestBody.required,
|
|
513
|
-
description: endpoint.requestBody.description,
|
|
514
|
-
}),
|
|
515
|
-
);
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
return parameters.sort((a, b) => (a.required === b.required ? 0 : a.required ? -1 : 1));
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
protected getRequestBodyParamName(ctx: Context, args: Args.GetRequestBodyParamName): string {
|
|
523
|
-
const { endpoint } = args;
|
|
524
|
-
const schema = endpoint.requestBody?.content[0].schema;
|
|
525
|
-
const schemaInfo = this.getSchemaType(ctx, { schema });
|
|
526
|
-
return toCasing(
|
|
527
|
-
schemaInfo && schemaInfo.name !== 'Any' ? SourceBuilder.build((b) => kt.reference.write(b, schemaInfo)) : 'body',
|
|
528
|
-
ctx.config.parameterNameCasing,
|
|
529
|
-
);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
protected getBasePath(ctx: Context, _args: Args.GetBasePath): string {
|
|
533
|
-
return modifyString(
|
|
534
|
-
(ctx.service.$src ?? ctx.service.endpoints[0]?.$src)?.document.servers?.[0]?.url ?? '/',
|
|
535
|
-
ctx.config.basePath,
|
|
536
|
-
ctx.service,
|
|
537
|
-
);
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
protected getEndpointPath(ctx: Context, args: Args.GetEndpointPath): string {
|
|
541
|
-
const { endpoint } = args;
|
|
542
|
-
return modifyString(endpoint.path.replace(/^\/*/, ''), ctx.config.pathModifier, endpoint);
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
protected getFilePath(ctx: Context, args: Args.GetFilePath): string {
|
|
546
|
-
const { packageName } = args;
|
|
547
|
-
return `${ctx.config.outputDir}/${packageName.replace(/\./g, '/')}/${this.getRequestsObjectName(ctx, {})}.kt`;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
// deno-lint-ignore no-unused-vars
|
|
551
|
-
protected getRequestsObjectName(ctx: Context, args: Args.GetRequestsObjectName): string {
|
|
552
|
-
return toCasing(`${ctx.service.name}_Requests`, ctx.config.typeNameCasing);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
private createApiParameter(data: Partial<ApiParameter> & Pick<ApiParameter, 'id' | 'name' | 'target'>): ApiParameter {
|
|
556
|
-
return {
|
|
557
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
558
|
-
$src: undefined!,
|
|
559
|
-
$ref: undefined,
|
|
560
|
-
schema: undefined,
|
|
561
|
-
required: false,
|
|
562
|
-
description: undefined,
|
|
563
|
-
allowEmptyValue: undefined,
|
|
564
|
-
allowReserved: undefined,
|
|
565
|
-
deprecated: false,
|
|
566
|
-
explode: undefined,
|
|
567
|
-
style: undefined,
|
|
568
|
-
...data,
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
type ApiService,
|
|
5
|
-
Factory,
|
|
6
|
-
type MaybePromise,
|
|
7
|
-
type OpenApiGeneratorContext,
|
|
8
|
-
OpenApiServicesGenerationProviderBase,
|
|
9
|
-
writeGeneratedFile,
|
|
10
|
-
} from '@goast/core';
|
|
11
|
-
|
|
12
|
-
import { getAssetFileContent } from '../../../assets.js';
|
|
13
|
-
import type { KotlinServicesGeneratorInput } from '../spring-controllers/index.js';
|
|
14
|
-
import {
|
|
15
|
-
defaultKotlinSpringReactiveWebClientsGeneratorConfig,
|
|
16
|
-
type KotlinSpringReactiveWebClientGeneratorOutput,
|
|
17
|
-
type KotlinSpringReactiveWebClientsGeneratorConfig,
|
|
18
|
-
type KotlinSpringReactiveWebClientsGeneratorContext,
|
|
19
|
-
type KotlinSpringReactiveWebClientsGeneratorInput,
|
|
20
|
-
type KotlinSpringReactiveWebClientsGeneratorOutput,
|
|
21
|
-
} from './models.js';
|
|
22
|
-
import { getReferenceFactories } from './refs.js';
|
|
23
|
-
import {
|
|
24
|
-
DefaultKotlinSpringReactiveWebClientGenerator,
|
|
25
|
-
type KotlinSpringReactiveWebClientGenerator,
|
|
26
|
-
} from './spring-reactive-web-client-generator.js';
|
|
27
|
-
|
|
28
|
-
type Input = KotlinSpringReactiveWebClientsGeneratorInput;
|
|
29
|
-
type Output = KotlinSpringReactiveWebClientsGeneratorOutput;
|
|
30
|
-
type Config = KotlinSpringReactiveWebClientsGeneratorConfig;
|
|
31
|
-
type ServiceOutput = KotlinSpringReactiveWebClientGeneratorOutput;
|
|
32
|
-
type Context = KotlinSpringReactiveWebClientsGeneratorContext;
|
|
33
|
-
|
|
34
|
-
export class KotlinSpringReactiveWebClientsGenerator extends OpenApiServicesGenerationProviderBase<
|
|
35
|
-
Input,
|
|
36
|
-
Output,
|
|
37
|
-
Config,
|
|
38
|
-
ServiceOutput,
|
|
39
|
-
Context
|
|
40
|
-
> {
|
|
41
|
-
private readonly _serviceGeneratorFactory: Factory<KotlinSpringReactiveWebClientGenerator, []>;
|
|
42
|
-
|
|
43
|
-
constructor(serviceGeneratorFactory?: Factory<KotlinSpringReactiveWebClientGenerator, []>) {
|
|
44
|
-
super();
|
|
45
|
-
this._serviceGeneratorFactory = serviceGeneratorFactory ??
|
|
46
|
-
Factory.fromValue(new DefaultKotlinSpringReactiveWebClientGenerator());
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
protected override async generateAdditionalFiles(ctx: Context): Promise<void> {
|
|
50
|
-
await this.copyInfrastructureFiles(ctx);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
protected initResult(): Output {
|
|
54
|
-
return {
|
|
55
|
-
kotlin: {
|
|
56
|
-
clients: {},
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
protected generateService(ctx: Context, service: ApiService): MaybePromise<ServiceOutput> {
|
|
62
|
-
const serviceGenerator = this._serviceGeneratorFactory.create();
|
|
63
|
-
return serviceGenerator.generate({
|
|
64
|
-
...ctx,
|
|
65
|
-
service,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
protected addServiceResult(ctx: Context, service: ApiService, result: ServiceOutput): void {
|
|
70
|
-
ctx.output.kotlin.clients[service.id] = result;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
protected buildContext(
|
|
74
|
-
context: OpenApiGeneratorContext<KotlinServicesGeneratorInput>,
|
|
75
|
-
config?: Partial<Config> | undefined,
|
|
76
|
-
): Context {
|
|
77
|
-
context.data.services = context.data.services.filter((x) => x.name !== 'exclude-from-generation');
|
|
78
|
-
const providerContext = this.getProviderContext(
|
|
79
|
-
context,
|
|
80
|
-
config,
|
|
81
|
-
defaultKotlinSpringReactiveWebClientsGeneratorConfig,
|
|
82
|
-
);
|
|
83
|
-
const infrastructurePackageName = this.getInfrastructurePackageName(providerContext.config);
|
|
84
|
-
return Object.assign(providerContext, {
|
|
85
|
-
infrastructurePackageName,
|
|
86
|
-
refs: getReferenceFactories(infrastructurePackageName),
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
protected getInfrastructurePackageName(config: Config): string {
|
|
91
|
-
if (typeof config.infrastructurePackageName === 'string') {
|
|
92
|
-
return config.infrastructurePackageName;
|
|
93
|
-
}
|
|
94
|
-
if (config.infrastructurePackageName.mode === 'append-package-name') {
|
|
95
|
-
return config.packageName + config.infrastructurePackageName.value;
|
|
96
|
-
}
|
|
97
|
-
if (config.infrastructurePackageName.mode === 'append-full-package-name') {
|
|
98
|
-
return this.getPackageName(config) + config.infrastructurePackageName.value;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return config.infrastructurePackageName.value;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
protected getPackageName(config: Config): string {
|
|
105
|
-
const packageSuffix = typeof config.packageSuffix === 'string' ? config.packageSuffix : config.packageSuffix();
|
|
106
|
-
return config.packageName + packageSuffix;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
private async copyInfrastructureFiles(ctx: Context): Promise<void> {
|
|
110
|
-
const targetDir = resolve(ctx.config.outputDir, ctx.infrastructurePackageName.replace(/\./g, '/'));
|
|
111
|
-
|
|
112
|
-
const files = [
|
|
113
|
-
'ApiRequestFile.kt',
|
|
114
|
-
];
|
|
115
|
-
|
|
116
|
-
for (const file of files) {
|
|
117
|
-
const sourcePath = `client/spring-reactive-web-clients/${file}`;
|
|
118
|
-
const targetPath = resolve(targetDir, file);
|
|
119
|
-
console.log(`Copying asset file "${sourcePath}" to "${targetPath}"`);
|
|
120
|
-
const fileContent = (await getAssetFileContent(sourcePath))
|
|
121
|
-
.replace(/@PACKAGE_NAME@/g, ctx.infrastructurePackageName);
|
|
122
|
-
writeGeneratedFile(ctx.config, targetPath, fileContent);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|