@goast/kotlin 0.5.10 → 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 (106) hide show
  1. package/LICENSE +21 -21
  2. package/assets/client/okhttp3/ApiAbstractions.kt +30 -30
  3. package/assets/client/okhttp3/ApiClient.kt +252 -252
  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/spring-reactive.d.ts +1 -0
  12. package/esm/src/ast/references/spring-reactive.d.ts.map +1 -1
  13. package/esm/src/ast/references/spring-reactive.js +1 -0
  14. package/esm/src/generators/services/okhttp3-clients/okhttp3-client-generator.js +28 -28
  15. package/esm/src/generators/services/okhttp3-clients/okhttp3-clients-generator.js +9 -9
  16. package/esm/src/generators/services/spring-controllers/spring-controller-generator.js +9 -9
  17. package/esm/src/generators/services/spring-reactive-web-clients/spring-reactive-web-client-generator.d.ts.map +1 -1
  18. package/esm/src/generators/services/spring-reactive-web-clients/spring-reactive-web-client-generator.js +3 -6
  19. package/package.json +1 -1
  20. package/script/src/ast/references/spring-reactive.d.ts +1 -0
  21. package/script/src/ast/references/spring-reactive.d.ts.map +1 -1
  22. package/script/src/ast/references/spring-reactive.js +2 -1
  23. package/script/src/generators/services/okhttp3-clients/okhttp3-client-generator.js +28 -28
  24. package/script/src/generators/services/okhttp3-clients/okhttp3-clients-generator.js +9 -9
  25. package/script/src/generators/services/spring-controllers/spring-controller-generator.js +9 -9
  26. package/script/src/generators/services/spring-reactive-web-clients/spring-reactive-web-client-generator.d.ts.map +1 -1
  27. package/script/src/generators/services/spring-reactive-web-clients/spring-reactive-web-client-generator.js +3 -6
  28. package/src/mod.ts +0 -8
  29. package/src/src/assets.ts +0 -9
  30. package/src/src/ast/_index.ts +0 -66
  31. package/src/src/ast/common.ts +0 -1
  32. package/src/src/ast/index.ts +0 -1
  33. package/src/src/ast/node.ts +0 -10
  34. package/src/src/ast/nodes/annotation.ts +0 -79
  35. package/src/src/ast/nodes/argument.ts +0 -62
  36. package/src/src/ast/nodes/call.ts +0 -75
  37. package/src/src/ast/nodes/class.ts +0 -178
  38. package/src/src/ast/nodes/collection-literal.ts +0 -49
  39. package/src/src/ast/nodes/constructor.ts +0 -126
  40. package/src/src/ast/nodes/doc-tag.ts +0 -138
  41. package/src/src/ast/nodes/doc.ts +0 -111
  42. package/src/src/ast/nodes/enum-value.ts +0 -100
  43. package/src/src/ast/nodes/enum.ts +0 -163
  44. package/src/src/ast/nodes/function.ts +0 -178
  45. package/src/src/ast/nodes/generic-parameter.ts +0 -54
  46. package/src/src/ast/nodes/init-block.ts +0 -38
  47. package/src/src/ast/nodes/interface.ts +0 -133
  48. package/src/src/ast/nodes/lambda-type.ts +0 -73
  49. package/src/src/ast/nodes/lambda.ts +0 -74
  50. package/src/src/ast/nodes/object.ts +0 -102
  51. package/src/src/ast/nodes/parameter.ts +0 -118
  52. package/src/src/ast/nodes/property.ts +0 -225
  53. package/src/src/ast/nodes/reference.ts +0 -178
  54. package/src/src/ast/nodes/string.ts +0 -114
  55. package/src/src/ast/nodes/types.ts +0 -23
  56. package/src/src/ast/references/index.ts +0 -10
  57. package/src/src/ast/references/jackson.ts +0 -59
  58. package/src/src/ast/references/jakarta.ts +0 -14
  59. package/src/src/ast/references/java.ts +0 -27
  60. package/src/src/ast/references/kotlin.ts +0 -41
  61. package/src/src/ast/references/kotlinx.ts +0 -14
  62. package/src/src/ast/references/okhttp3.ts +0 -5
  63. package/src/src/ast/references/reactor.ts +0 -5
  64. package/src/src/ast/references/spring-reactive.ts +0 -33
  65. package/src/src/ast/references/spring.ts +0 -86
  66. package/src/src/ast/references/swagger.ts +0 -23
  67. package/src/src/ast/utils/get-kotlin-builder-options.ts +0 -19
  68. package/src/src/ast/utils/to-kt-node.ts +0 -31
  69. package/src/src/ast/utils/write-kt-annotations.ts +0 -15
  70. package/src/src/ast/utils/write-kt-arguments.ts +0 -45
  71. package/src/src/ast/utils/write-kt-enum-values.ts +0 -27
  72. package/src/src/ast/utils/write-kt-generic-parameters.ts +0 -12
  73. package/src/src/ast/utils/write-kt-members.ts +0 -25
  74. package/src/src/ast/utils/write-kt-node.ts +0 -37
  75. package/src/src/ast/utils/write-kt-parameters.ts +0 -25
  76. package/src/src/common-results.ts +0 -4
  77. package/src/src/config.ts +0 -61
  78. package/src/src/file-builder.ts +0 -112
  79. package/src/src/generators/file-generator.ts +0 -29
  80. package/src/src/generators/index.ts +0 -5
  81. package/src/src/generators/models/args.ts +0 -136
  82. package/src/src/generators/models/index.ts +0 -4
  83. package/src/src/generators/models/model-generator.ts +0 -725
  84. package/src/src/generators/models/models-generator.ts +0 -65
  85. package/src/src/generators/models/models.ts +0 -95
  86. package/src/src/generators/services/okhttp3-clients/args.ts +0 -90
  87. package/src/src/generators/services/okhttp3-clients/index.ts +0 -4
  88. package/src/src/generators/services/okhttp3-clients/models.ts +0 -73
  89. package/src/src/generators/services/okhttp3-clients/okhttp3-client-generator.ts +0 -613
  90. package/src/src/generators/services/okhttp3-clients/okhttp3-clients-generator.ts +0 -188
  91. package/src/src/generators/services/okhttp3-clients/refs.ts +0 -59
  92. package/src/src/generators/services/spring-controllers/args.ts +0 -95
  93. package/src/src/generators/services/spring-controllers/index.ts +0 -4
  94. package/src/src/generators/services/spring-controllers/models.ts +0 -76
  95. package/src/src/generators/services/spring-controllers/refs.ts +0 -17
  96. package/src/src/generators/services/spring-controllers/spring-controller-generator.ts +0 -1109
  97. package/src/src/generators/services/spring-controllers/spring-controllers-generator.ts +0 -140
  98. package/src/src/generators/services/spring-reactive-web-clients/args.ts +0 -103
  99. package/src/src/generators/services/spring-reactive-web-clients/index.ts +0 -4
  100. package/src/src/generators/services/spring-reactive-web-clients/models.ts +0 -62
  101. package/src/src/generators/services/spring-reactive-web-clients/refs.ts +0 -11
  102. package/src/src/generators/services/spring-reactive-web-clients/spring-reactive-web-client-generator.ts +0 -586
  103. package/src/src/generators/services/spring-reactive-web-clients/spring-reactive-web-clients-generator.ts +0 -125
  104. package/src/src/import-collection.ts +0 -98
  105. package/src/src/types.ts +0 -3
  106. package/src/src/utils.ts +0 -47
@@ -1,613 +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 { DefaultKotlinOkHttp3GeneratorArgs as Args } from './index.js';
24
- import type { KotlinOkHttp3ClientGeneratorContext, KotlinOkHttp3ClientGeneratorOutput } from './models.js';
25
-
26
- type Context = KotlinOkHttp3ClientGeneratorContext;
27
- type Output = KotlinOkHttp3ClientGeneratorOutput;
28
- type Builder = KotlinFileBuilder;
29
-
30
- export interface KotlinOkHttp3Generator<TOutput extends Output = Output> {
31
- generate(ctx: Context): MaybePromise<TOutput>;
32
- }
33
-
34
- export class DefaultKotlinOkHttp3Generator extends KotlinFileGenerator<Context, Output>
35
- implements KotlinOkHttp3Generator {
36
- public generate(ctx: KotlinOkHttp3ClientGeneratorContext): MaybePromise<Output> {
37
- const typeName = this.getApiClientName(ctx, {});
38
- const packageName = this.getPackageName(ctx, {});
39
- const filePath = this.getFilePath(ctx, { packageName });
40
-
41
- console.log(`Generating client for service ${ctx.service.name} to ${filePath}...`);
42
- ctx.service.endpoints.forEach((endpoint) => {
43
- console.log(
44
- ` ${getSourceDisplayName(ctx.data, endpoint)} [${toCasing(endpoint.name, ctx.config.functionNameCasing)}]`,
45
- );
46
- });
47
- const builder = new KotlinFileBuilder(packageName, ctx.config);
48
- builder.append(this.getClientFileContent(ctx, {}));
49
- builder.writeToFile(filePath);
50
-
51
- return { typeName, packageName };
52
- }
53
-
54
- protected getClientFileContent(ctx: Context, _args: Args.GetClientFileContent): AppendValueGroup<Builder> {
55
- return appendValueGroup([this.getClientClass(ctx, {})]);
56
- }
57
-
58
- protected getClientClass(ctx: Context, _args: Args.GetClientClass): kt.Class<Builder> {
59
- const serializerAsParameter = ctx.config.serializer === 'parameter';
60
- return kt.class(this.getApiClientName(ctx, {}), {
61
- annotations: [
62
- ctx.service.endpoints.length === 0 || ctx.service.endpoints.some((x) => !x.deprecated)
63
- ? null
64
- : kt.annotation(kt.refs.deprecated(), [kt.argument(kt.string(''))]),
65
- ],
66
- extends: ctx.refs.apiClient(),
67
- primaryConstructor: kt.constructor(
68
- [
69
- serializerAsParameter
70
- ? kt.parameter('objectMapper', kt.refs.jackson.objectMapper(ctx.config.springBootVersion))
71
- : null,
72
- kt.parameter('basePath', kt.refs.string(), { default: 'defaultBasePath' }),
73
- kt.parameter('client', kt.refs.okhttp3.okHttpClient(), {
74
- default: 'defaultClient',
75
- }),
76
- serializerAsParameter
77
- ? null
78
- : kt.parameter('objectMapper', kt.refs.jackson.objectMapper(ctx.config.springBootVersion), {
79
- default: kt.call([ctx.refs.serializer(), 'jacksonObjectMapper']),
80
- }),
81
- ],
82
- null,
83
- {
84
- delegateTarget: 'super',
85
- delegateArguments: ['basePath', 'objectMapper', 'client'],
86
- },
87
- ),
88
- companionObject: this.getClientCompanionObject(ctx, {}),
89
- members: [
90
- ...ctx.service.endpoints.flatMap((endpoint) =>
91
- this.getEndpointClientMembers(ctx, { endpoint, parameters: this.getAllParameters(ctx, { endpoint }) })
92
- ),
93
- ...this.getAdditionalClientMembers(ctx, {}),
94
- ],
95
- });
96
- }
97
-
98
- protected getClientCompanionObject(ctx: Context, _args: Args.GetClientCompanionObject): kt.Object<Builder> {
99
- const result = kt.object<Builder>();
100
-
101
- result.members.push(
102
- kt.property('defaultBasePath', {
103
- annotations: [kt.annotation(kt.refs.jvmStatic())],
104
- type: kt.refs.string(),
105
- delegate: kt.refs.lazyFun.infer(),
106
- delegateArguments: [
107
- kt.lambda(
108
- [],
109
- kt.call(
110
- [kt.call([kt.refs.java.system(), 'getProperties'], []), 'getProperty'],
111
- [kt.call([ctx.refs.apiClient(), 'baseUrlKey']), kt.string(this.getBasePath(ctx, {}))],
112
- ),
113
- ),
114
- ],
115
- }),
116
- );
117
-
118
- return result;
119
- }
120
-
121
- protected getEndpointClientMembers(ctx: Context, args: Args.GetEndpointClientMembers): kt.ClassMember<Builder>[] {
122
- const { endpoint, parameters } = args;
123
- const responseSchema = this.getResponseSchema(ctx, { endpoint });
124
- return [
125
- this.getEndpointClientMethod(ctx, { endpoint, parameters, responseSchema }),
126
- this.getEndpointClientHttpInfoMethod(ctx, { endpoint, parameters, responseSchema }),
127
- this.getEndpointClientRequestConfigMethod(ctx, { endpoint, parameters }),
128
- ];
129
- }
130
-
131
- protected getEndpointClientMethod(ctx: Context, args: Args.GetEndpointClientMethod): kt.Function<Builder> {
132
- const { endpoint, parameters, responseSchema } = args;
133
-
134
- return kt.function(toCasing(endpoint.name, ctx.config.functionNameCasing), {
135
- doc: kt.doc(this.getEndpointDocDescription(ctx, { endpoint }), [
136
- kt.docTag('throws', 'IllegalStateException', 'If the request is not correctly configured'),
137
- kt.docTag('throws', 'IOException', 'Rethrows the OkHttp execute method exception'),
138
- kt.docTag(
139
- 'throws',
140
- 'UnsupportedOperationException',
141
- 'If the API returns an informational or redirection response',
142
- ),
143
- kt.docTag('throws', 'ClientException', 'If the API returns a client error response'),
144
- kt.docTag('throws', 'ServerException', 'If the API returns a server error response'),
145
- ]),
146
- annotations: [
147
- kt.annotation(kt.refs.throws(), [
148
- kt.refs.java.illegalStateException({ classReference: true }),
149
- kt.refs.java.ioException({ classReference: true }),
150
- kt.refs.java.unsupportedOperationException({ classReference: true }),
151
- ctx.refs.clientException({ classReference: true }),
152
- ctx.refs.serverException({ classReference: true }),
153
- ]),
154
- endpoint.deprecated ? kt.annotation(kt.refs.deprecated(), [kt.argument(kt.string(''))]) : null,
155
- ],
156
- parameters: parameters.map((p) => {
157
- return kt.parameter(
158
- toCasing(p.name, ctx.config.parameterNameCasing),
159
- this.getParameterType(ctx, { endpoint, parameter: p }),
160
- {
161
- description: p.description,
162
- default: this.getParameterDefaultValue(ctx, { endpoint, parameter: p }),
163
- },
164
- );
165
- }),
166
- returnType: this.getTypeUsage(ctx, { schema: responseSchema, fallback: kt.refs.unit() }),
167
- body: this.getEndpointClientMethodBody(ctx, { endpoint, parameters, responseSchema }),
168
- });
169
- }
170
-
171
- protected getEndpointClientMethodBody(
172
- ctx: Context,
173
- args: Args.GetEndpointClientMethodBody,
174
- ): AppendValueGroup<Builder> {
175
- const { endpoint, parameters, responseSchema } = args;
176
-
177
- return appendValueGroup(
178
- [
179
- s`val localVarResponse = ${
180
- kt.call(
181
- [toCasing(endpoint.name + '_WithHttpInfo', ctx.config.functionNameCasing)],
182
- parameters.map((x) => toCasing(x.name, ctx.config.parameterNameCasing)),
183
- )
184
- }`,
185
- '',
186
- s`return when (localVarResponse.responseType) {${s.indent`
187
- ${ctx.refs.responseType()}.Success -> ${
188
- responseSchema === undefined
189
- ? kt.refs.unit()
190
- : s`(localVarResponse as ${ctx.refs.success(['*'])}).data as ${
191
- this.getTypeUsage(ctx, {
192
- schema: responseSchema,
193
- })
194
- }`
195
- }
196
- ${ctx.refs.responseType()}.Informational -> throw ${kt.refs.java.unsupportedOperationException()}("Client does not support Informational responses.")
197
- ${ctx.refs.responseType()}.Redirection -> throw ${kt.refs.java.unsupportedOperationException()}("Client does not support Redirection responses.")
198
- ${ctx.refs.responseType()}.ClientError -> {${s.indent`
199
- val localVarError = localVarResponse as ${ctx.refs.clientError(['*'])}
200
- throw ${ctx.refs.clientException()}(${s.indent`
201
- "Client error : \${localVarError.statusCode} \${localVarError.message.orEmpty()}",
202
- localVarError.statusCode,
203
- localVarResponse`}
204
- )`}
205
- }
206
-
207
- ${ctx.refs.responseType()}.ServerError -> {${s.indent`
208
- val localVarError = localVarResponse as ${ctx.refs.serverError(['*'])}
209
- throw ${ctx.refs.serverException()}(${s.indent`
210
- "Server error : \${localVarError.statusCode} \${localVarError.message.orEmpty()}",
211
- localVarError.statusCode,
212
- localVarResponse`}
213
- )`}
214
- }`}
215
- }`,
216
- ],
217
- '\n',
218
- );
219
- }
220
-
221
- protected getEndpointClientHttpInfoMethod(
222
- ctx: Context,
223
- args: Args.GetEndpointClientHttpInfoMethod,
224
- ): kt.Function<Builder> {
225
- const { endpoint, parameters, responseSchema } = args;
226
-
227
- return kt.function(toCasing(args.endpoint.name, ctx.config.functionNameCasing) + 'WithHttpInfo', {
228
- doc: kt.doc(this.getEndpointDocDescription(ctx, { endpoint }), [
229
- kt.docTag('throws', 'IllegalStateException', 'If the request is not correctly configured'),
230
- kt.docTag('throws', 'IOException', 'Rethrows the OkHttp execute method exception'),
231
- ]),
232
- annotations: [
233
- kt.annotation(kt.refs.throws(), [
234
- kt.refs.java.illegalStateException({ classReference: true }),
235
- kt.refs.java.ioException({ classReference: true }),
236
- ]),
237
- endpoint.deprecated ? kt.annotation(kt.refs.deprecated(), [kt.argument(kt.string(''))]) : null,
238
- ],
239
- parameters: parameters.map((p) =>
240
- kt.parameter(
241
- toCasing(p.name, ctx.config.parameterNameCasing),
242
- this.getParameterType(ctx, { endpoint, parameter: p }),
243
- {
244
- description: p.description,
245
- default: this.getParameterDefaultValue(ctx, { endpoint, parameter: p }),
246
- },
247
- )
248
- ),
249
- returnType: ctx.refs.apiResponse([
250
- this.getTypeUsage(ctx, { schema: responseSchema, fallback: kt.refs.unit({ nullable: true }), nullable: true }),
251
- ]),
252
- body: this.getEndpointClientHttpInfoMethodBody(ctx, { endpoint, parameters, responseSchema }),
253
- });
254
- }
255
-
256
- protected getEndpointClientHttpInfoMethodBody(
257
- ctx: Context,
258
- args: Args.GetEndpointClientHttpInfoMethodBody,
259
- ): AppendValueGroup<Builder> {
260
- const { endpoint, parameters, responseSchema } = args;
261
-
262
- return appendValueGroup(
263
- [
264
- s`val localVariableConfig = ${
265
- kt.call(
266
- [toCasing(endpoint.name, 'camel') + 'RequestConfig'],
267
- parameters.map((x) => toCasing(x.name, ctx.config.parameterNameCasing)),
268
- )
269
- }`,
270
- s`return ${
271
- kt.call(
272
- [
273
- kt.reference('request', null, {
274
- generics: [
275
- this.getRequestBodyType(ctx, { endpoint }),
276
- this.getTypeUsage(ctx, { schema: responseSchema, fallback: kt.refs.unit() }),
277
- ],
278
- }),
279
- ],
280
- ['localVariableConfig'],
281
- )
282
- }`,
283
- ],
284
- '\n',
285
- );
286
- }
287
-
288
- protected getEndpointClientRequestConfigMethod(
289
- ctx: Context,
290
- args: Args.GetEndpointClientRequestConfigMethod,
291
- ): kt.Function<Builder> {
292
- const { endpoint, parameters } = args;
293
- const operationName = toCasing(endpoint.name, ctx.config.functionNameCasing);
294
-
295
- return kt.function(toCasing(args.endpoint.name, ctx.config.functionNameCasing) + 'RequestConfig', {
296
- accessModifier: 'private',
297
- doc: kt.doc(`To obtain the request config of the operation ${operationName}`),
298
- annotations: [endpoint.deprecated ? kt.annotation(kt.refs.deprecated(), [kt.argument(kt.string(''))]) : null],
299
- parameters: parameters.map((p) =>
300
- kt.parameter(
301
- toCasing(p.name, ctx.config.parameterNameCasing),
302
- this.getParameterType(ctx, { endpoint, parameter: p }),
303
- {
304
- description: p.description,
305
- default: this.getParameterDefaultValue(ctx, { endpoint, parameter: p }),
306
- },
307
- )
308
- ),
309
- returnType: ctx.refs.requestConfig([this.getRequestBodyType(ctx, { endpoint })]),
310
- body: this.getEndpointClientRequestConfigMethodBody(ctx, { endpoint, parameters }),
311
- });
312
- }
313
-
314
- protected getEndpointClientRequestConfigMethodBody(
315
- ctx: Context,
316
- args: Args.GetEndpointClientRequestConfigMethodBody,
317
- ): AppendValueGroup<Builder> {
318
- const { endpoint, parameters } = args;
319
- const queryParameters = parameters.filter((x) => x.target === 'query');
320
- const headerParameters = parameters.filter((x) => x.target === 'header');
321
- const result = appendValueGroup<Builder>([], '\n');
322
-
323
- if (endpoint.requestBody) {
324
- if (endpoint.requestBody.content[0]?.type === 'multipart/form-data') {
325
- const partConfigs = parameters
326
- .filter((x) => x.multipart)
327
- .map<KtValue<Builder>>((param) => {
328
- const paramName = toCasing(param.name, ctx.config.parameterNameCasing);
329
- return s`"${param.multipart?.name ?? ''}" to ${ctx.refs.partConfig.infer()}(body = ${paramName})`;
330
- });
331
- result.values.push(
332
- s`val localVariableBody = ${
333
- kt.call(kt.refs.mapOf([kt.refs.string(), ctx.refs.partConfig(['*'])]), partConfigs)
334
- }`,
335
- );
336
- } else {
337
- const bodyParamName = toCasing(this.getRequestBodyParamName(ctx, { endpoint }), ctx.config.parameterNameCasing);
338
- result.values.push(`val localVariableBody = ${bodyParamName}`);
339
- }
340
- }
341
-
342
- result.values.push(
343
- s`val localVariableQuery: ${ctx.refs.multiValueMap()} = ${
344
- kt.call(
345
- [kt.refs.mutableMapOf([kt.refs.string(), kt.refs.list([kt.refs.string()])])],
346
- [],
347
- )
348
- }${
349
- queryParameters.length === 0 ? '' : s.indent`
350
- .apply {${s.indent`
351
- ${
352
- appendValueGroup(
353
- queryParameters.map((param) => {
354
- const paramName = toCasing(param.name, ctx.config.parameterNameCasing);
355
- const toString = this.getParameterToString(ctx, { endpoint, parameter: param });
356
- const put = s<Builder>`put(${kt.string(param.name)}, listOf(${paramName}${toString}))`;
357
- return param.required ? put : s<Builder>`if (${paramName} != null) {${s.indent`
358
- ${put}`}
359
- }`;
360
- }),
361
- '\n',
362
- )
363
- }`}
364
- }`
365
- }`,
366
- );
367
-
368
- result.values.push('val localVariableHeaders: MutableMap<String, String> = mutableMapOf()');
369
- if (endpoint.requestBody?.content[0] !== undefined) {
370
- result.values.push(`localVariableHeaders["Content-Type"] = "${endpoint.requestBody?.content[0].type}"`);
371
- }
372
- for (const header of headerParameters) {
373
- const paramName = toCasing(header.name, ctx.config.parameterNameCasing);
374
- const toString = this.getParameterToString(ctx, { endpoint, parameter: header });
375
- result.values.push(
376
- s`if (${paramName} != null) {${s.indent`
377
- localVariableHeaders["${header.name}"] = ${paramName}${toString}`}
378
- }`,
379
- );
380
- }
381
-
382
- result.values.push(
383
- s`return ${
384
- kt.call(
385
- [ctx.refs.requestConfig.infer()],
386
- [
387
- kt.argument.named('method', kt.call([ctx.refs.requestMethod(), endpoint.method.toUpperCase()])),
388
- kt.argument.named('path', kt.string(this.getPathWithInterpolation(ctx, { endpoint }), { template: true })),
389
- kt.argument.named('query', 'localVariableQuery'),
390
- kt.argument.named('headers', 'localVariableHeaders'),
391
- kt.argument.named('requiresAuthentication', 'false'),
392
- endpoint.requestBody ? kt.argument.named('body', 'localVariableBody') : null,
393
- ],
394
- )
395
- }`,
396
- );
397
-
398
- return result;
399
- }
400
-
401
- protected getParameterToString(ctx: Context, args: Args.GetParameterToString): kt.Value<Builder> {
402
- const { parameter } = args;
403
- if (parameter.schema?.kind === 'array') {
404
- return '.joinToString()';
405
- } else if (
406
- parameter.schema?.kind === 'string' && parameter.schema.enum?.length &&
407
- this.getSchemaType(ctx, { schema: parameter.schema })
408
- ) {
409
- return '.value';
410
- } else {
411
- return '.toString()';
412
- }
413
- }
414
-
415
- protected getAdditionalClientMembers(
416
- _ctx: Context,
417
- _args: Args.GetAdditionalClientMembers,
418
- ): kt.ClassMember<Builder>[] {
419
- return [
420
- kt.function('encodeURIComponent', {
421
- accessModifier: 'private',
422
- parameters: [kt.parameter('uriComponent', kt.refs.string())],
423
- returnType: kt.refs.string(),
424
- singleExpression: true,
425
- body:
426
- s`${kt.refs.okhttp3.httpUrl()}.Builder().scheme("http").host("localhost").addPathSegment(uriComponent).build().encodedPathSegments[0]`,
427
- }),
428
- ];
429
- }
430
-
431
- protected getParameterType(ctx: Context, args: Args.GetParameterType): kt.Type<Builder> {
432
- const { parameter } = args;
433
- if (parameter.multipart?.isFile) {
434
- return kt.refs.java.file();
435
- }
436
- return this.getTypeUsage(ctx, {
437
- schema: parameter.schema,
438
- nullable: !parameter.required,
439
- });
440
- }
441
-
442
- protected getRequestBodyType(ctx: Context, args: Args.GetRequestBodyType): kt.Type<Builder> {
443
- const { endpoint } = args;
444
- const content = endpoint.requestBody?.content[0];
445
- return content?.type === 'multipart/form-data'
446
- ? kt.refs.map([kt.refs.string(), ctx.refs.partConfig(['*'])])
447
- : this.getTypeUsage(ctx, { schema: content?.schema, fallback: kt.refs.unit() });
448
- }
449
-
450
- protected getParameterDefaultValue(ctx: Context, args: Args.GetParameterDefaultValue): kt.Value<Builder> | null {
451
- const { parameter } = args;
452
-
453
- return !parameter.required
454
- ? parameter.schema?.kind === 'string' && parameter.schema.enum && parameter.schema.default
455
- ? s`${this.getTypeUsage(ctx, { schema: parameter.schema, nullable: false })}.${
456
- toCasing(String(parameter.schema.default), ctx.config.enumValueNameCasing)
457
- }`
458
- : kt.toNode(parameter.schema?.default)
459
- : null;
460
- }
461
-
462
- protected getTypeUsage(ctx: Context, args: Args.GetTypeUsage<Builder>): kt.Type<Builder> {
463
- const { schema, nullable, fallback } = args;
464
- const type = this.getSchemaType(ctx, { schema });
465
- return type
466
- ? createOverwriteProxy(type, { nullable: nullable ?? type.nullable })
467
- : (fallback ?? kt.refs.any({ nullable }));
468
- }
469
-
470
- protected getPackageName(ctx: Context, _args: Args.GetPackageName): string {
471
- const packageSuffix = typeof ctx.config.packageSuffix === 'string'
472
- ? ctx.config.packageSuffix
473
- : ctx.config.packageSuffix(ctx.service);
474
- return ctx.config.packageName + packageSuffix;
475
- }
476
-
477
- protected getPathWithInterpolation(ctx: Context, args: Args.GetPathWithInterpolation): string {
478
- const { endpoint } = args;
479
- let path = this.getEndpointPath(ctx, { endpoint });
480
- endpoint.parameters
481
- .filter((x) => x.target === 'path')
482
- .forEach((parameter) => {
483
- path = path.replace(
484
- `{${parameter.name}}`,
485
- `\${encodeURIComponent(${toCasing(parameter.name, 'camel')}${
486
- this.getParameterToString(ctx, { endpoint, parameter })
487
- })}`,
488
- );
489
- });
490
- return path;
491
- }
492
-
493
- protected getResponseSchema(_ctx: Context, args: Args.GetResponseSchema): ApiSchema | undefined {
494
- const { endpoint } = args;
495
- return endpoint.responses.find((x) => !x.statusCode || (x.statusCode >= 200 && x.statusCode < 300))
496
- ?.contentOptions[0]?.schema;
497
- }
498
-
499
- protected getSchemaType(ctx: Context, args: Args.GetSchemaType): kt.Reference<SourceBuilder> | undefined {
500
- const { schema } = args;
501
- return schema && ctx.input.kotlin.models[schema.id].type;
502
- }
503
-
504
- protected getAllParameters(ctx: Context, args: Args.GetAllParameters): ApiParameterWithMultipartInfo[] {
505
- const { endpoint } = args;
506
- const parameters = endpoint.parameters.filter(
507
- (parameter) => parameter.target === 'query' || parameter.target === 'path' || parameter.target === 'header',
508
- );
509
- if (endpoint.requestBody) {
510
- const content = endpoint.requestBody.content[0];
511
- let schema = content.schema;
512
-
513
- if (content.type === 'multipart/form-data') {
514
- if (schema && schema.kind === 'object') {
515
- schema = resolveAnyOfAndAllOf(schema, true) ?? schema;
516
- const properties = schema.properties ?? {};
517
- for (const [name, property] of properties.entries()) {
518
- parameters.push(
519
- Object.assign(
520
- this.createApiParameter({
521
- id: `multipart-${name}`,
522
- name,
523
- target: 'body',
524
- schema: property.schema,
525
- required: schema.required.has(name),
526
- description: property.schema.description,
527
- }),
528
- {
529
- multipart: {
530
- name,
531
- isFile: property.schema.kind === 'string' && property.schema.format === 'binary',
532
- },
533
- },
534
- ),
535
- );
536
- }
537
- }
538
- } else {
539
- parameters.push(
540
- this.createApiParameter({
541
- id: 'body',
542
- name: this.getRequestBodyParamName(ctx, { endpoint }),
543
- target: 'body',
544
- schema,
545
- required: endpoint.requestBody.required,
546
- description: endpoint.requestBody.description,
547
- }),
548
- );
549
- }
550
- }
551
-
552
- return parameters.sort((a, b) => (a.required === b.required ? 0 : a.required ? -1 : 1));
553
- }
554
-
555
- protected getRequestBodyParamName(ctx: Context, args: Args.GetRequestBodyParamName): string {
556
- const { endpoint } = args;
557
- const schema = endpoint.requestBody?.content[0].schema;
558
- const schemaInfo = this.getSchemaType(ctx, { schema });
559
- return toCasing(
560
- schemaInfo && schemaInfo.name !== 'Any' ? SourceBuilder.build((b) => kt.reference.write(b, schemaInfo)) : 'body',
561
- ctx.config.parameterNameCasing,
562
- );
563
- }
564
-
565
- protected getEndpointDocDescription(ctx: Context, args: Args.GetEndpointDocDescription): BasicAppendValue<Builder> {
566
- const docSegments = [args.endpoint.description?.trim()];
567
-
568
- if (ctx.config.includeSourceInDocs) {
569
- docSegments.push(getSourceDocLine(args.endpoint));
570
- }
571
-
572
- return docSegments.filter(notNullish).join('\n\n');
573
- }
574
-
575
- protected getBasePath(ctx: Context, _args: Args.GetBasePath): string {
576
- return modifyString(
577
- (ctx.service.$src ?? ctx.service.endpoints[0]?.$src)?.document.servers?.[0]?.url ?? '/',
578
- ctx.config.basePath,
579
- ctx.service,
580
- );
581
- }
582
-
583
- protected getEndpointPath(ctx: Context, args: Args.GetEndpointPath): string {
584
- const { endpoint } = args;
585
- return modifyString(endpoint.path, ctx.config.pathModifier, endpoint);
586
- }
587
-
588
- protected getFilePath(ctx: Context, args: Args.GetFilePath): string {
589
- const { packageName } = args;
590
- return `${ctx.config.outputDir}/${packageName.replace(/\./g, '/')}/${this.getApiClientName(ctx, {})}.kt`;
591
- }
592
-
593
- protected getApiClientName(ctx: Context, _args: Args.GetApiClientName): string {
594
- return toCasing(ctx.service.name, ctx.config.typeNameCasing) + 'ApiClient';
595
- }
596
-
597
- private createApiParameter(data: Partial<ApiParameter> & Pick<ApiParameter, 'id' | 'name' | 'target'>): ApiParameter {
598
- return {
599
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
600
- $src: undefined!,
601
- $ref: undefined,
602
- schema: undefined,
603
- required: false,
604
- description: undefined,
605
- allowEmptyValue: undefined,
606
- allowReserved: undefined,
607
- deprecated: false,
608
- explode: undefined,
609
- style: undefined,
610
- ...data,
611
- };
612
- }
613
- }