@goast/kotlin 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/cjs/lib/generators/index.js +1 -0
  2. package/cjs/lib/generators/models/model-generator.js +77 -25
  3. package/cjs/lib/generators/services/okhttp3-clients/index.js +6 -0
  4. package/cjs/lib/generators/services/okhttp3-clients/models.js +5 -0
  5. package/cjs/lib/generators/services/okhttp3-clients/okhttp3-client-generator.js +411 -0
  6. package/cjs/lib/generators/services/okhttp3-clients/okhttp3-clients-generator.js +68 -0
  7. package/cjs/lib/generators/services/spring-controllers/spring-controller-generator.js +25 -45
  8. package/cjs/lib/utils.js +16 -1
  9. package/esm/lib/generators/index.js +1 -0
  10. package/esm/lib/generators/models/model-generator.js +77 -25
  11. package/esm/lib/generators/services/okhttp3-clients/index.js +3 -0
  12. package/esm/lib/generators/services/okhttp3-clients/models.js +2 -0
  13. package/esm/lib/generators/services/okhttp3-clients/okhttp3-client-generator.js +407 -0
  14. package/esm/lib/generators/services/okhttp3-clients/okhttp3-clients-generator.js +64 -0
  15. package/esm/lib/generators/services/spring-controllers/spring-controller-generator.js +25 -45
  16. package/esm/lib/utils.js +14 -0
  17. package/package.json +2 -2
  18. package/types/lib/file-builder.d.ts +1 -1
  19. package/types/lib/generators/index.d.ts +1 -0
  20. package/types/lib/generators/models/model-generator.d.ts +9 -3
  21. package/types/lib/generators/services/okhttp3-clients/index.d.ts +3 -0
  22. package/types/lib/generators/services/okhttp3-clients/models.d.ts +29 -0
  23. package/types/lib/generators/services/okhttp3-clients/okhttp3-client-generator.d.ts +60 -0
  24. package/types/lib/generators/services/okhttp3-clients/okhttp3-clients-generator.d.ts +22 -0
  25. package/types/lib/generators/services/spring-controllers/models.d.ts +3 -1
  26. package/types/lib/generators/services/spring-controllers/spring-controller-generator.d.ts +2 -0
  27. package/types/lib/utils.d.ts +1 -0
@@ -3,4 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./file-generator"), exports);
5
5
  tslib_1.__exportStar(require("./models"), exports);
6
+ tslib_1.__exportStar(require("./services/okhttp3-clients"), exports);
6
7
  tslib_1.__exportStar(require("./services/spring-controllers"), exports);
@@ -77,26 +77,77 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
77
77
  }
78
78
  }
79
79
  else {
80
- this.generateDataClass(ctx, builder, schema);
80
+ this.generateObjectPackageMember(ctx, builder, schema);
81
81
  }
82
82
  }
83
- generateDataClass(ctx, builder, schema) {
83
+ generateObjectPackageMember(ctx, builder, schema) {
84
+ if (schema.discriminator) {
85
+ this.generateObjectInterface(ctx, builder, schema);
86
+ }
87
+ else {
88
+ this.generateObjectDataClass(ctx, builder, schema);
89
+ }
90
+ }
91
+ generateObjectInterface(ctx, builder, schema) {
92
+ builder
93
+ .apply((builder) => this.generateDocumentation(ctx, builder, schema))
94
+ .ensureCurrentLineEmpty()
95
+ .apply((builder) => this.generateObjectInterfaceAnnotations(ctx, builder, schema))
96
+ .ensureCurrentLineEmpty()
97
+ .apply((builder) => this.generateObjectInterfaceSignature(ctx, builder, schema))
98
+ .append(' ')
99
+ .parenthesizeMultiline('{}', (builder) => this.generateObjectInterfaceMembers(ctx, builder, schema));
100
+ }
101
+ generateObjectInterfaceAnnotations(ctx, builder, schema) {
102
+ if (schema.discriminator) {
103
+ builder.appendAnnotation('JsonTypeInfo', 'com.fasterxml.jackson.annotation', [
104
+ ['use', 'JsonTypeInfo.Id.NAME'],
105
+ ['include', 'JsonTypeInfo.As.PROPERTY'],
106
+ ['property', this.toStringLiteral(ctx, schema.discriminator.propertyName)],
107
+ ['visible', 'true'],
108
+ ]);
109
+ const entries = Object.entries(schema.discriminator.mapping);
110
+ if (entries.length > 0) {
111
+ builder.appendAnnotation('JsonSubTypes', 'com.fasterxml.jackson.annotation', entries.map(([value, schema]) => (builder) => {
112
+ const schemaResult = ctx.getSchemaResult(schema);
113
+ builder
114
+ .append(`JsonSubTypes.Type(value = ${schemaResult.typeName}::class, name = ${this.toStringLiteral(ctx, value)})`)
115
+ .addImport(schemaResult.typeName, schemaResult.packageName);
116
+ }));
117
+ }
118
+ }
119
+ }
120
+ generateObjectInterfaceSignature(ctx, builder, schema) {
121
+ builder.append('interface ').append(this.getDeclarationTypeName(ctx));
122
+ }
123
+ generateObjectInterfaceMembers(ctx, builder, schema) {
124
+ builder.forEach(this.sortProperties(ctx, schema, schema.properties.values()), (builder, property) => builder
125
+ .ensurePreviousLineEmpty()
126
+ .apply((builder) => this.generateJsonPropertyAnnotation(ctx, builder, schema, property, 'get'))
127
+ .ensureCurrentLineEmpty()
128
+ .append(`val ${(0, core_1.toCasing)(property.name, 'camel')}: `)
129
+ .apply((builder) => this.generateType(ctx, builder, property.schema))
130
+ .applyIf(!schema.required.has(property.name), (builder) => builder.appendIf(!property.schema.nullable, '?').append(' = null')));
131
+ }
132
+ generateObjectDataClass(ctx, builder, schema) {
133
+ const inheritedSchemas = schema.inheritedSchemas.filter((x) => this.shouldGenerateTypeDeclaration(ctx, x) && !x.isNameGenerated);
84
134
  builder
85
135
  .apply((builder) => this.generateDocumentation(ctx, builder, schema))
86
136
  .append('data class ')
87
137
  .append(this.getDeclarationTypeName(ctx))
88
- .parenthesizeIf(schema.properties.size > 0, '()', (builder) => builder
89
- .appendLine()
90
- .forEachSeparated(this.sortProperties(ctx, schema, schema.properties.values()), ',\n', (builder, property) => builder
138
+ .parenthesizeMultilineIf(schema.properties.size > 0, '()', (builder) => builder.forEachSeparated(this.sortProperties(ctx, schema, schema.properties.values()), ',\n', (builder, property) => builder
91
139
  .ensurePreviousLineEmpty()
92
- .apply((builder) => this.generatePropertyAnnotations(ctx, builder, schema, property))
140
+ .apply((builder) => this.generateObjectDataClassParameterAnnotations(ctx, builder, schema, property))
141
+ .appendIf(inheritedSchemas.some((x) => this.hasProperty(ctx, x, property.name)), 'override ')
93
142
  .append(`val ${(0, core_1.toCasing)(property.name, 'camel')}: `)
94
143
  .apply((builder) => this.generateType(ctx, builder, property.schema))
95
- .applyIf(!schema.required.has(property.name), (builder) => builder.appendIf(!property.schema.nullable, '?').append(' = null')))
96
- .appendLineIf(schema.properties.size > 0))
97
- .parenthesizeIf(schema.additionalProperties !== undefined && schema.additionalProperties !== false, '{}', (builder) => builder
98
- .appendLine()
99
- .applyIf(schema.additionalProperties !== undefined && schema.additionalProperties !== false, (builder) => builder
144
+ .applyIf(!schema.required.has(property.name), (builder) => builder.appendIf(!property.schema.nullable, '?').append(' = null'))))
145
+ .applyIf(inheritedSchemas.length > 0, (builder) => builder
146
+ .append(' : ')
147
+ .forEachSeparated(inheritedSchemas, ', ', (builder, schema) => builder.append((0, core_1.toCasing)(schema.name, 'pascal'))) // TODO: Calling generateType here will lead to endless loop
148
+ )
149
+ .append(' ')
150
+ .parenthesizeMultilineIf(schema.additionalProperties !== undefined && schema.additionalProperties !== false, '{}', (builder) => builder.applyIf(schema.additionalProperties !== undefined && schema.additionalProperties !== false, (builder) => builder
100
151
  .appendLine('@JsonIgnore')
101
152
  .addImport('JsonIgnore', 'com.fasterxml.jackson.annotation')
102
153
  .append('val additionalProperties: Mutable')
@@ -108,7 +159,7 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
108
159
  .append('fun set')
109
160
  .parenthesize('()', (builder) => builder.append('name: String, value: ').applyIfElse(schema.additionalProperties === true, (builder) => builder.append('Any?'), (builder) => this.generateType(ctx, builder, schema.additionalProperties)))
110
161
  .append(' ')
111
- .parenthesize('{}', (builder) => builder.appendLine().appendLine('this.additionalProperties[name] = value'))
162
+ .parenthesizeMultiline('{}', 'this.additionalProperties[name] = value')
112
163
  .appendLine()
113
164
  .appendLine()
114
165
  .appendLine('@JsonAnyGetter')
@@ -116,10 +167,9 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
116
167
  .append('fun getMap(): ')
117
168
  .apply((builder) => this.generateMapType(ctx, builder, schema))
118
169
  .append(' ')
119
- .parenthesize('{}', (builder) => builder.appendLine().appendLine('return this.additionalProperties'))
120
- .appendLine()));
170
+ .parenthesizeMultiline('{}', 'return this.additionalProperties')));
121
171
  }
122
- generatePropertyAnnotations(ctx, builder, schema, property) {
172
+ generateObjectDataClassParameterAnnotations(ctx, builder, schema, property) {
123
173
  this.generatePropertyValidationAnnotations(ctx, builder, schema, property);
124
174
  this.generatePropertySchemaAnnotation(ctx, builder, schema, property);
125
175
  this.generateJsonPropertyAnnotation(ctx, builder, schema, property);
@@ -154,9 +204,9 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
154
204
  .parenthesizeIf(parts.size > 0, '()', (builder) => builder.forEachSeparated(parts.entries(), ', ', (builder, [key, value]) => builder.append(`${key} = ${value}`)))
155
205
  .appendLine();
156
206
  }
157
- generateJsonPropertyAnnotation(ctx, builder, schema, property) {
207
+ generateJsonPropertyAnnotation(ctx, builder, schema, property, scope) {
158
208
  builder
159
- .append('@JsonProperty')
209
+ .append(`@${scope ? scope + ':' : ''}JsonProperty`)
160
210
  .addImport('JsonProperty', 'com.fasterxml.jackson.annotation')
161
211
  .parenthesize('()', (builder) => builder
162
212
  .append(this.toStringLiteral(ctx, property.name))
@@ -165,7 +215,7 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
165
215
  .applyIf(property.schema.custom['exclude-when-null'] === true, (builder) => builder
166
216
  .append('@get:JsonInclude')
167
217
  .addImport('JsonInclude', 'com.fasterxml.jackson.annotation')
168
- .parenthesize('()', (builder) => builder.append('JsonInclude.Include.NON_NULL'))
218
+ .parenthesize('()', 'JsonInclude.Include.NON_NULL')
169
219
  .appendLine());
170
220
  }
171
221
  generateMapType(ctx, builder, schema) {
@@ -272,18 +322,15 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
272
322
  .append('enum class ')
273
323
  .append(this.getDeclarationTypeName(ctx))
274
324
  .append('(val value: String) ')
275
- .parenthesize('{}', (builder) => {
325
+ .parenthesizeMultiline('{}', (builder) => {
276
326
  var _a;
277
- return builder
278
- .appendLine()
279
- .forEachSeparated((_a = schema.enum) !== null && _a !== void 0 ? _a : [], (builder) => builder.appendLine(',').appendLine(), (builder, value) => builder
327
+ return builder.forEachSeparated((_a = schema.enum) !== null && _a !== void 0 ? _a : [], (builder) => builder.appendLine(',').appendLine(), (builder, value) => builder
280
328
  .append('@JsonProperty')
281
329
  .addImport('JsonProperty', 'com.fasterxml.jackson.annotation')
282
- .parenthesize('()', (builder) => builder.append(this.toStringLiteral(ctx, String(value))))
330
+ .parenthesize('()', this.toStringLiteral(ctx, String(value)))
283
331
  .appendLine()
284
332
  .append((0, core_1.toCasing)(String(value), 'snake'))
285
- .parenthesize('()', (builder) => builder.append(this.toStringLiteral(ctx, String(value)))))
286
- .appendLine();
333
+ .parenthesize('()', this.toStringLiteral(ctx, String(value))));
287
334
  });
288
335
  }
289
336
  generateArrayType(ctx, builder, schema) {
@@ -333,5 +380,10 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
333
380
  return bRequired - aRequired;
334
381
  });
335
382
  }
383
+ hasProperty(ctx, schema, name) {
384
+ return (('properties' in schema && schema.properties.has(name)) ||
385
+ ('anyOf' in schema && schema.anyOf.some((x) => this.hasProperty(ctx, x, name))) ||
386
+ ('allOf' in schema && schema.allOf.some((x) => this.hasProperty(ctx, x, name))));
387
+ }
336
388
  }
337
389
  exports.DefaultKotlinModelGenerator = DefaultKotlinModelGenerator;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./models"), exports);
5
+ tslib_1.__exportStar(require("./okhttp3-client-generator"), exports);
6
+ tslib_1.__exportStar(require("./okhttp3-clients-generator"), exports);
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultKotlinOkHttp3ClientsGeneratorConfig = void 0;
4
+ const config_1 = require("../../../config");
5
+ exports.defaultKotlinOkHttp3ClientsGeneratorConfig = Object.assign(Object.assign({}, config_1.defaultKotlinGeneratorConfig), { packageName: 'com.openapi.generated', packageSuffix: '.api.client', infrastructurePackageName: { mode: 'append-full-package-name', value: '.infrastructure' } });
@@ -0,0 +1,411 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultKotlinOkHttp3Generator = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const fs_extra_1 = require("fs-extra");
7
+ const core_1 = require("@goast/core");
8
+ const file_builder_1 = require("../../../file-builder");
9
+ const utils_1 = require("../../../utils");
10
+ const file_generator_1 = require("../../file-generator");
11
+ class DefaultKotlinOkHttp3Generator extends file_generator_1.KotlinFileGenerator {
12
+ generate(ctx) {
13
+ const typeName = this.getApiClientName(ctx);
14
+ const filePath = this.getFilePath(ctx);
15
+ (0, fs_extra_1.ensureDirSync)((0, path_1.dirname)(filePath));
16
+ console.log(`Generating client for service ${ctx.service.name} to ${filePath}...`);
17
+ const builder = new file_builder_1.KotlinFileBuilder(ctx.packageName, ctx.config);
18
+ this.generateApiClientFileContent(ctx, builder);
19
+ (0, fs_1.writeFileSync)(filePath, builder.toString());
20
+ return { typeName, packageName: ctx.packageName };
21
+ }
22
+ generateApiClientFileContent(ctx, builder) {
23
+ builder
24
+ .apply((builder) => this.generateApiClientClassAnnotations(ctx, builder))
25
+ .ensureCurrentLineEmpty()
26
+ .apply((builder) => this.generateApiClientClassSignature(ctx, builder))
27
+ .append(' ')
28
+ .parenthesizeMultiline('{}', (builder) => this.generateApiClientClassContent(ctx, builder));
29
+ }
30
+ generateApiClientClassAnnotations(ctx, builder) {
31
+ // None for now
32
+ }
33
+ generateApiClientClassSignature(ctx, builder) {
34
+ builder
35
+ .append('class ')
36
+ .append(this.getApiClientName(ctx))
37
+ .parenthesizeMultiline('()', (builder) => builder
38
+ .appendLine('basePath: String = defaultBasePath,')
39
+ .appendLine('client: OkHttpClient = ApiClient.defaultClient')
40
+ .addImport('OkHttpClient', 'okhttp3')
41
+ .addImport('ApiClient', ctx.infrastructurePackageName))
42
+ .append(' : ')
43
+ .append('ApiClient(basePath, client)');
44
+ }
45
+ generateApiClientClassContent(ctx, builder) {
46
+ builder
47
+ .apply((builder) => this.generateApiClientCompanionObject(ctx, builder))
48
+ .forEach(ctx.service.endpoints, (builder, endpoint) => builder
49
+ .ensurePreviousLineEmpty()
50
+ .apply((builder) => this.generateApiClientMethod(ctx, builder, endpoint))
51
+ .ensurePreviousLineEmpty()
52
+ .apply((builder) => this.generateApiClientHttpInfoMethod(ctx, builder, endpoint))
53
+ .ensurePreviousLineEmpty()
54
+ .apply((builder) => this.generateApiClientRequestConfigMethod(ctx, builder, endpoint)))
55
+ .ensurePreviousLineEmpty()
56
+ .apply((builder) => this.generateAdditionalMethods(ctx, builder));
57
+ }
58
+ generateApiClientCompanionObject(ctx, builder) {
59
+ builder
60
+ .append('companion object ')
61
+ .parenthesizeMultiline('{}', (builder) => this.generateApiClientCompanionObjectContent(ctx, builder));
62
+ }
63
+ generateApiClientCompanionObjectContent(ctx, builder) {
64
+ this.generateApiClientCompanionObjectDefaultBasePathProperty(ctx, builder);
65
+ }
66
+ generateApiClientCompanionObjectDefaultBasePathProperty(ctx, builder) {
67
+ builder
68
+ .appendAnnotation('JvmStatic')
69
+ .append('val defaultBasePath: String by lazy ')
70
+ .parenthesizeMultiline('{}', (builder) => builder
71
+ .appendLine(`System.getProperties().getProperty(ApiClient.baseUrlKey, ${this.toStringLiteral(ctx, this.getBasePath(ctx))})`)
72
+ .addImport('ApiClient', ctx.infrastructurePackageName));
73
+ }
74
+ generateApiClientMethod(ctx, builder, endpoint) {
75
+ builder
76
+ .apply((builder) => this.generateApiClientMethodDocumentation(ctx, builder, endpoint))
77
+ .ensureCurrentLineEmpty()
78
+ .apply((builder) => this.generateApiClientMethodAnnotations(ctx, builder, endpoint))
79
+ .ensureCurrentLineEmpty()
80
+ .apply((builder) => this.generateApiClientMethodSignature(ctx, builder, endpoint))
81
+ .append(' ')
82
+ .parenthesizeMultiline('{}', (builder) => this.generateApiClientMethodContent(ctx, builder, endpoint));
83
+ }
84
+ generateApiClientMethodDocumentation(ctx, builder, endpoint) {
85
+ builder
86
+ .appendLine('/**')
87
+ .applyWithLinePrefix(' * ', (builder) => {
88
+ var _a;
89
+ return builder
90
+ .appendLine(`${(_a = endpoint.summary) !== null && _a !== void 0 ? _a : 'TODO: Provide summary'}`)
91
+ .apply((builder) => this.generateParamDocEntries(ctx, builder, endpoint))
92
+ .append('@return ')
93
+ .apply((builder) => this.generateApiClientMethodReturnType(ctx, builder, endpoint))
94
+ .appendLine()
95
+ .appendLine('@throws IllegalStateException If the request is not correctly configured')
96
+ .appendLine('@throws IOException Rethrows the OkHttp execute method exception')
97
+ .appendLine('@throws UnsupportedOperationException If the API returns an informational or redirection response')
98
+ .appendLine('@throws ClientException If the API returns a client error response')
99
+ .appendLine('@throws ServerException If the API returns a server error response');
100
+ })
101
+ .appendLine(' */');
102
+ }
103
+ generateApiClientMethodAnnotations(ctx, builder, endpoint) {
104
+ builder
105
+ .appendAnnotation('Throws', undefined, [
106
+ 'IllegalStateException::class',
107
+ 'IOException::class',
108
+ 'UnsupportedOperationException::class',
109
+ 'ClientException::class',
110
+ 'ServerException::class',
111
+ ])
112
+ .addImport('IOException', 'java.io')
113
+ .addImport('ClientException', ctx.infrastructurePackageName)
114
+ .addImport('ServerException', ctx.infrastructurePackageName);
115
+ }
116
+ generateApiClientMethodSignature(ctx, builder, endpoint) {
117
+ builder
118
+ .append('fun ')
119
+ .append((0, core_1.toCasing)(endpoint.name, 'camel'))
120
+ .parenthesize('()', (builder) => this.generateApiClientMethodParameters(ctx, builder, endpoint))
121
+ .append(': ')
122
+ .apply((builder) => this.generateApiClientMethodReturnType(ctx, builder, endpoint));
123
+ }
124
+ generateApiClientMethodParameters(ctx, builder, endpoint) {
125
+ this.generateParams(ctx, builder, endpoint, true);
126
+ }
127
+ generateApiClientMethodReturnType(ctx, builder, endpoint) {
128
+ this.generateTypeUsage(ctx, builder, this.getResponseSchema(ctx, endpoint), 'Unit');
129
+ }
130
+ generateApiClientMethodContent(ctx, builder, endpoint) {
131
+ const responseSchema = this.getResponseSchema(ctx, endpoint);
132
+ builder
133
+ .append(`val localVarResponse = ${(0, core_1.toCasing)(endpoint.name, 'camel')}WithHttpInfo`)
134
+ .parenthesize('()', (builder) => this.generateParams(ctx, builder, endpoint, false))
135
+ .appendLine()
136
+ .appendLine()
137
+ .append('return when (localVarResponse.responseType) ')
138
+ .parenthesizeMultiline('{}', (builder) => builder
139
+ .append('ResponseType.Success -> ')
140
+ .applyIfElse(responseSchema === undefined, (builder) => builder.append('Unit'), (builder) => builder
141
+ .append('(localVarResponse as Success<*>).data as ')
142
+ .addImport('Success', ctx.infrastructurePackageName)
143
+ .apply((builder) => this.generateTypeUsage(ctx, builder, responseSchema)))
144
+ .ensureCurrentLineEmpty()
145
+ .appendLine(responseErrorHandlingCode)
146
+ .addImport('ClientError', ctx.infrastructurePackageName)
147
+ .addImport('ServerError', ctx.infrastructurePackageName)
148
+ .addImport('ResponseType', ctx.infrastructurePackageName));
149
+ }
150
+ generateApiClientHttpInfoMethod(ctx, builder, endpoint) {
151
+ builder
152
+ .apply((builder) => this.generateApiClientHttpInfoMethodDocumentation(ctx, builder, endpoint))
153
+ .ensureCurrentLineEmpty()
154
+ .apply((builder) => this.generateApiClientHttpInfoMethodAnnotations(ctx, builder, endpoint))
155
+ .ensureCurrentLineEmpty()
156
+ .apply((builder) => this.generateApiClientHttpInfoMethodSignature(ctx, builder, endpoint))
157
+ .append(' ')
158
+ .parenthesizeMultiline('{}', (builder) => this.generateApiClientHttpInfoMethodContent(ctx, builder, endpoint));
159
+ }
160
+ generateApiClientHttpInfoMethodDocumentation(ctx, builder, endpoint) {
161
+ builder
162
+ .appendLine('/**')
163
+ .applyWithLinePrefix(' * ', (builder) => {
164
+ var _a;
165
+ return builder
166
+ .appendLine(`${(_a = endpoint.summary) !== null && _a !== void 0 ? _a : 'TODO: Provide summary'}`)
167
+ .apply((builder) => this.generateParamDocEntries(ctx, builder, endpoint))
168
+ .append('@return ')
169
+ .apply((builder) => this.generateApiClientHttpInfoMethodReturnType(ctx, builder, endpoint))
170
+ .appendLine()
171
+ .appendLine('@throws IllegalStateException If the request is not correctly configured')
172
+ .appendLine('@throws IOException Rethrows the OkHttp execute method exception')
173
+ .appendLine('@throws UnsupportedOperationException If the API returns an informational or redirection response')
174
+ .appendLine('@throws ClientException If the API returns a client error response')
175
+ .appendLine('@throws ServerException If the API returns a server error response');
176
+ })
177
+ .appendLine(' */');
178
+ }
179
+ generateApiClientHttpInfoMethodAnnotations(ctx, builder, endpoint) {
180
+ builder
181
+ .appendAnnotation('Throws', undefined, ['IllegalStateException::class', 'IOException::class'])
182
+ .addImport('IOException', 'java.io');
183
+ }
184
+ generateApiClientHttpInfoMethodSignature(ctx, builder, endpoint) {
185
+ builder
186
+ .append('fun ')
187
+ .append((0, core_1.toCasing)(endpoint.name, 'camel'), 'WithHttpInfo')
188
+ .parenthesize('()', (builder) => this.generateApiClientHttpInfoMethodSignatureParameters(ctx, builder, endpoint))
189
+ .append(': ')
190
+ .apply((builder) => this.generateApiClientHttpInfoMethodReturnType(ctx, builder, endpoint));
191
+ }
192
+ generateApiClientHttpInfoMethodSignatureParameters(ctx, builder, endpoint) {
193
+ this.generateParams(ctx, builder, endpoint, true);
194
+ }
195
+ generateApiClientHttpInfoMethodReturnType(ctx, builder, endpoint) {
196
+ builder
197
+ .append('ApiResponse')
198
+ .addImport('ApiResponse', ctx.infrastructurePackageName)
199
+ .parenthesize('<>', (builder) => this.generateTypeUsage(ctx, builder, this.getResponseSchema(ctx, endpoint), 'Unit', true));
200
+ }
201
+ generateApiClientHttpInfoMethodContent(ctx, builder, endpoint) {
202
+ builder
203
+ .append(`val localVariableConfig = ${(0, core_1.toCasing)(endpoint.name, 'camel')}RequestConfig`)
204
+ .parenthesize('()', (builder) => this.generateParams(ctx, builder, endpoint, false))
205
+ .appendLine()
206
+ .appendLine()
207
+ .append('return request')
208
+ .parenthesize('<>', (builder) => builder
209
+ .apply((builder) => { var _a; return this.generateTypeUsage(ctx, builder, (_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0].schema, 'Unit'); })
210
+ .append(', ')
211
+ .apply((builder) => this.generateTypeUsage(ctx, builder, this.getResponseSchema(ctx, endpoint), 'Unit')))
212
+ .parenthesizeMultiline('()', (builder) => builder.append('localVariableConfig'));
213
+ }
214
+ generateApiClientRequestConfigMethod(ctx, builder, endpoint) {
215
+ builder
216
+ .apply((builder) => this.generateApiClientRequestConfigMethodDocumentation(ctx, builder, endpoint))
217
+ .ensureCurrentLineEmpty()
218
+ .apply((builder) => this.generateApiClientRequestConfigMethodAnnotations(ctx, builder, endpoint))
219
+ .ensureCurrentLineEmpty()
220
+ .apply((builder) => this.generateApiClientRequestConfigMethodSignature(ctx, builder, endpoint))
221
+ .append(' ')
222
+ .parenthesizeMultiline('{}', (builder) => this.generateApiClientRequestConfigMethodContent(ctx, builder, endpoint));
223
+ }
224
+ generateApiClientRequestConfigMethodDocumentation(ctx, builder, endpoint) {
225
+ builder
226
+ .appendLine('/**')
227
+ .applyWithLinePrefix(' * ', (builder) => builder
228
+ .appendLine(`To obtain the request config of the operation ${(0, core_1.toCasing)(endpoint.name, 'camel')}`)
229
+ .apply((builder) => this.generateParamDocEntries(ctx, builder, endpoint))
230
+ .append('@return RequestConfig'))
231
+ .appendLine(' */');
232
+ }
233
+ generateApiClientRequestConfigMethodAnnotations(ctx, builder, endpoint) {
234
+ // No annotations needed
235
+ }
236
+ generateApiClientRequestConfigMethodSignature(ctx, builder, endpoint) {
237
+ builder
238
+ .append('private fun ')
239
+ .append((0, core_1.toCasing)(endpoint.name, 'camel'), 'RequestConfig')
240
+ .parenthesize('()', (builder) => this.generateApiClientRequestConfigMethodSignatureParameters(ctx, builder, endpoint))
241
+ .append(': ')
242
+ .apply((builder) => this.generateApiClientRequestConfigMethodReturnType(ctx, builder, endpoint));
243
+ }
244
+ generateApiClientRequestConfigMethodSignatureParameters(ctx, builder, endpoint) {
245
+ this.generateParams(ctx, builder, endpoint, true);
246
+ }
247
+ generateApiClientRequestConfigMethodReturnType(ctx, builder, endpoint) {
248
+ builder
249
+ .append('RequestConfig')
250
+ .addImport('RequestConfig', ctx.infrastructurePackageName)
251
+ .parenthesize('<>', (builder) => { var _a; return this.generateTypeUsage(ctx, builder, (_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0].schema, 'Unit'); });
252
+ }
253
+ generateApiClientRequestConfigMethodContent(ctx, builder, endpoint) {
254
+ var _a, _b;
255
+ const queryParameters = endpoint.parameters.filter((x) => x.target === 'query');
256
+ builder
257
+ .appendLineIf(!!endpoint.requestBody, `val localVariableBody = ${(0, core_1.toCasing)(this.getRequestBodyParamName(ctx, endpoint), 'camel')}`)
258
+ .appendLine('val localVariableQuery: MultiValueMap = mutableMapOf<String, List<String>>()')
259
+ .addImport('MultiValueMap', ctx.infrastructurePackageName)
260
+ .applyIf(queryParameters.length > 0, (builder) => builder.indent((builder) => builder.append('.apply ').parenthesizeMultiline('{}', (builder) => builder.forEach(queryParameters, (builder, param) => builder
261
+ .appendIf(!param.required, `if (${(0, core_1.toCasing)(param.name, 'camel')} != null) `)
262
+ .parenthesizeMultilineIf(!param.required, '{}', (builder) => builder.appendLine(`put(${this.toStringLiteral(ctx, (0, core_1.toCasing)(param.name, 'camel'))}, listOf(${(0, core_1.toCasing)(param.name, 'camel')}.toString()))`))
263
+ .appendLine()))))
264
+ .ensureCurrentLineEmpty()
265
+ .appendLine('val localVariableHeaders: MutableMap<String, String> = mutableMapOf()')
266
+ .appendLineIf(((_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0]) !== undefined, `localVariableHeaders["Content-Type"] = "${(_b = endpoint.requestBody) === null || _b === void 0 ? void 0 : _b.content[0].type}"`)
267
+ .appendLine()
268
+ .append('return RequestConfig')
269
+ .addImport('RequestConfig', ctx.infrastructurePackageName)
270
+ .parenthesizeMultiline('()', (builder) => builder
271
+ .appendLine(`method = RequestMethod.${endpoint.method.toUpperCase()},`)
272
+ .addImport('RequestMethod', ctx.infrastructurePackageName)
273
+ .appendLine(`path = "${this.getPathWithInterpolation(ctx, endpoint)}",`)
274
+ .appendLine('query = localVariableQuery,')
275
+ .appendLine('headers = localVariableHeaders,')
276
+ .appendLine('requiresAuthentication = false,')
277
+ .appendLineIf(!!endpoint.requestBody, 'body = localVariableBody'));
278
+ }
279
+ generateAdditionalMethods(ctx, builder) {
280
+ this.generateEncodeUriComponentMethod(ctx, builder);
281
+ }
282
+ generateEncodeUriComponentMethod(ctx, builder) {
283
+ builder
284
+ .appendLine('private fun encodeURIComponent(uriComponent: String): String =')
285
+ .indent('HttpUrl.Builder().scheme("http").host("localhost").addPathSegment(uriComponent).build().encodedPathSegments[0]')
286
+ .addImport('HttpUrl', 'okhttp3');
287
+ }
288
+ generateParamDocEntries(ctx, builder, endpoint) {
289
+ const parameters = this.getAllParameters(ctx, endpoint);
290
+ builder.forEach(parameters, (builder, parameter) => { var _a; return builder.appendLine(`@param ${parameter.name} ${(_a = parameter.description) !== null && _a !== void 0 ? _a : 'TODO: Provide description'}`); });
291
+ }
292
+ generateParams(ctx, builder, endpoint, includeTypeDefinition) {
293
+ const parameters = this.getAllParameters(ctx, endpoint);
294
+ builder.forEachSeparated(parameters, ', ', (builder, parameter) => builder.append((0, core_1.toCasing)(parameter.name, 'camel')).applyIf(includeTypeDefinition, (builder) => builder
295
+ .append(': ')
296
+ .apply((builder) => this.generateTypeUsage(ctx, builder, parameter.schema))
297
+ .appendIf(!parameter.required, '? = ', this.getDefaultValue(ctx, parameter.schema))));
298
+ }
299
+ generateTypeUsage(ctx, builder, schema, fallback, nullable) {
300
+ if (schema && schema.kind === 'array') {
301
+ const schemaInfo = this.getSchemaInfo(ctx, schema.items);
302
+ builder.append(this.getTypeNameWithNullability(`List<${schemaInfo.typeName}>`, nullable));
303
+ builder.imports.addImports([schemaInfo, ...schemaInfo.additionalImports]);
304
+ }
305
+ else if (schema || !fallback) {
306
+ const schemaInfo = this.getSchemaInfo(ctx, schema);
307
+ builder.append(this.getTypeNameWithNullability(schemaInfo.typeName, nullable));
308
+ builder.imports.addImports([schemaInfo, ...schemaInfo.additionalImports]);
309
+ }
310
+ else {
311
+ builder.append(this.getTypeNameWithNullability(fallback, nullable));
312
+ }
313
+ }
314
+ getTypeNameWithNullability(typeName, nullable) {
315
+ if (nullable === undefined)
316
+ return typeName;
317
+ return nullable ? `${typeName}?` : typeName.match(/^(.*?)\??$/)[1];
318
+ }
319
+ getDefaultValue(ctx, schema) {
320
+ if (!(schema === null || schema === void 0 ? void 0 : schema.default)) {
321
+ return 'null';
322
+ }
323
+ if (typeof schema.default === 'string') {
324
+ return (0, utils_1.toKotlinStringLiteral)(schema.default);
325
+ }
326
+ else if (typeof schema.default === 'number' || typeof schema.default === 'boolean') {
327
+ return schema.default.toString();
328
+ }
329
+ else {
330
+ return 'null';
331
+ }
332
+ }
333
+ getPathWithInterpolation(ctx, endpoint) {
334
+ let path = this.getEndpointPath(ctx, endpoint);
335
+ endpoint.parameters
336
+ .filter((x) => x.target === 'path')
337
+ .forEach((parameter) => {
338
+ path = path.replace(`{${parameter.name}}`, `\${encodeURIComponent(${(0, core_1.toCasing)(parameter.name, 'camel')}.toString())}`);
339
+ });
340
+ return path;
341
+ }
342
+ getResponseSchema(ctx, endpoint) {
343
+ var _a, _b;
344
+ return (_b = (_a = endpoint.responses.find((x) => !x.statusCode || (x.statusCode >= 200 && x.statusCode < 300))) === null || _a === void 0 ? void 0 : _a.contentOptions[0]) === null || _b === void 0 ? void 0 : _b.schema;
345
+ }
346
+ getSchemaInfo(ctx, schema) {
347
+ var _a;
348
+ return ((_a = (schema && ctx.input.models[schema.id])) !== null && _a !== void 0 ? _a : { typeName: 'Any?', packageName: undefined, additionalImports: [] });
349
+ }
350
+ getAllParameters(ctx, endpoint) {
351
+ const parameters = endpoint.parameters.filter((parameter) => parameter.target === 'query' || parameter.target === 'path');
352
+ if (endpoint.requestBody) {
353
+ const schema = endpoint.requestBody.content[0].schema;
354
+ parameters.push({
355
+ $src: undefined,
356
+ $ref: undefined,
357
+ id: 'body',
358
+ name: this.getRequestBodyParamName(ctx, endpoint),
359
+ target: 'body',
360
+ schema,
361
+ required: endpoint.requestBody.required,
362
+ description: endpoint.requestBody.description,
363
+ allowEmptyValue: undefined,
364
+ allowReserved: undefined,
365
+ deprecated: false,
366
+ explode: undefined,
367
+ style: undefined,
368
+ });
369
+ }
370
+ return parameters.sort((a, b) => (a.required === b.required ? 0 : a.required ? -1 : 1));
371
+ }
372
+ getRequestBodyParamName(ctx, endpoint) {
373
+ var _a;
374
+ const schema = (_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0].schema;
375
+ const schemaInfo = this.getSchemaInfo(ctx, schema);
376
+ return /^Any\??$/.test(schemaInfo.typeName) ? 'body' : schemaInfo.typeName;
377
+ }
378
+ getBasePath(ctx) {
379
+ var _a, _b, _c, _d, _e, _f;
380
+ return (0, utils_1.modifyString)((_f = (_e = (_d = (_c = ((_a = ctx.service.$src) !== null && _a !== void 0 ? _a : (_b = ctx.service.endpoints[0]) === null || _b === void 0 ? void 0 : _b.$src)) === null || _c === void 0 ? void 0 : _c.document.servers) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.url) !== null && _f !== void 0 ? _f : '/', ctx.config.basePath, ctx.service);
381
+ }
382
+ getEndpointPath(ctx, endpoint) {
383
+ return (0, utils_1.modifyString)(endpoint.path, ctx.config.pathModifier, endpoint);
384
+ }
385
+ getFilePath(ctx) {
386
+ return `${ctx.config.outputDir}/${ctx.packageName.replace(/\./g, '/')}/${this.getApiClientName(ctx)}.kt`;
387
+ }
388
+ getApiClientName(ctx) {
389
+ return (0, core_1.toCasing)(ctx.service.name, 'pascal') + 'ApiClient';
390
+ }
391
+ }
392
+ exports.DefaultKotlinOkHttp3Generator = DefaultKotlinOkHttp3Generator;
393
+ const responseErrorHandlingCode = `ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.")
394
+ ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.")
395
+ ResponseType.ClientError -> {
396
+ val localVarError = localVarResponse as ClientError<*>
397
+ throw ClientException(
398
+ "Client error : \${localVarError.statusCode} \${localVarError.message.orEmpty()}",
399
+ localVarError.statusCode,
400
+ localVarResponse
401
+ )
402
+ }
403
+
404
+ ResponseType.ServerError -> {
405
+ val localVarError = localVarResponse as ServerError<*>
406
+ throw ServerException(
407
+ "Server error : \${localVarError.statusCode} \${localVarError.message.orEmpty()}",
408
+ localVarError.statusCode,
409
+ localVarResponse
410
+ )
411
+ }`;