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