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