@goast/kotlin 0.3.3 → 0.3.5

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/assets/client/okhttp3/ApiClient.kt +2 -1
  2. package/cjs/index.js +3 -2
  3. package/cjs/lib/ast/references/java.js +5 -4
  4. package/cjs/lib/ast/references/reactor.js +2 -1
  5. package/cjs/lib/ast/references/spring.js +15 -12
  6. package/cjs/lib/generators/models/model-generator.js +4 -0
  7. package/cjs/lib/generators/services/okhttp3-clients/okhttp3-client-generator.js +94 -33
  8. package/cjs/lib/generators/services/spring-controllers/spring-controller-generator.js +67 -24
  9. package/cjs/lib/types.js +2 -0
  10. package/esm/index.js +3 -2
  11. package/esm/lib/ast/references/java.js +4 -3
  12. package/esm/lib/ast/references/reactor.js +1 -0
  13. package/esm/lib/ast/references/spring.js +14 -11
  14. package/esm/lib/generators/models/model-generator.js +4 -0
  15. package/esm/lib/generators/services/okhttp3-clients/okhttp3-client-generator.js +95 -34
  16. package/esm/lib/generators/services/spring-controllers/spring-controller-generator.js +68 -25
  17. package/esm/lib/types.js +1 -0
  18. package/package.json +1 -1
  19. package/types/index.d.ts +3 -2
  20. package/types/lib/ast/references/java.d.ts +16 -3
  21. package/types/lib/ast/references/reactor.d.ts +16 -0
  22. package/types/lib/ast/references/spring.d.ts +44 -18
  23. package/types/lib/generators/services/okhttp3-clients/args.d.ts +9 -0
  24. package/types/lib/generators/services/okhttp3-clients/okhttp3-client-generator.d.ts +6 -2
  25. package/types/lib/generators/services/spring-controllers/args.d.ts +3 -2
  26. package/types/lib/generators/services/spring-controllers/spring-controller-generator.d.ts +4 -2
  27. package/types/lib/types.d.ts +7 -0
@@ -85,7 +85,8 @@ open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClie
85
85
  ("Content-Disposition" to "form-data; name=\"$name\"")
86
86
  addPart(
87
87
  partHeaders.toHeaders(),
88
- parameterToString(part.body).toRequestBody(null)
88
+ Serializer.jacksonObjectMapper.writeValueAsString(content)
89
+ .toRequestBody(JsonMediaType.toMediaTypeOrNull())
89
90
  )
90
91
  }
91
92
  }
package/cjs/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./lib/ast"), exports);
4
5
  tslib_1.__exportStar(require("./lib/common-results"), exports);
5
6
  tslib_1.__exportStar(require("./lib/config"), exports);
6
- tslib_1.__exportStar(require("./lib/generators"), exports);
7
7
  tslib_1.__exportStar(require("./lib/file-builder"), exports);
8
+ tslib_1.__exportStar(require("./lib/generators"), exports);
8
9
  tslib_1.__exportStar(require("./lib/import-collection"), exports);
10
+ tslib_1.__exportStar(require("./lib/types"), exports);
9
11
  tslib_1.__exportStar(require("./lib/utils"), exports);
10
- tslib_1.__exportStar(require("./lib/ast"), exports);
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.optional = exports.offsetDateTime = exports.ioException = exports.unsupportedOperationException = exports.illegalStateException = exports.system = void 0;
3
+ exports.optional = exports.offsetDateTime = exports.unsupportedOperationException = exports.system = exports.illegalStateException = exports.ioException = exports.file = void 0;
4
4
  const reference_1 = require("../nodes/reference");
5
+ // java.io
6
+ exports.file = reference_1.ktReference.factory('File', 'java.io');
7
+ exports.ioException = reference_1.ktReference.factory('IOException', 'java.io');
5
8
  // java.lang
6
- exports.system = reference_1.ktReference.factory('System', 'java.lang');
7
9
  exports.illegalStateException = reference_1.ktReference.factory('IllegalStateException', 'java.lang');
10
+ exports.system = reference_1.ktReference.factory('System', 'java.lang');
8
11
  exports.unsupportedOperationException = reference_1.ktReference.factory('UnsupportedOperationException', 'java.lang');
9
- // java.io
10
- exports.ioException = reference_1.ktReference.factory('IOException', 'java.io');
11
12
  // java.time
12
13
  exports.offsetDateTime = reference_1.ktReference.factory('OffsetDateTime', 'java.time');
13
14
  // java.util
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.flux = void 0;
3
+ exports.mono = exports.flux = void 0;
4
4
  const reference_1 = require("../nodes/reference");
5
5
  // reactor.core.publisher
6
6
  exports.flux = reference_1.ktReference.genericFactory('Flux', 'reactor.core.publisher');
7
+ exports.mono = reference_1.ktReference.genericFactory('Mono', 'reactor.core.publisher');
@@ -1,21 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.controller = exports.httpStatus = exports.responseEntity = exports.validated = exports.autowired = exports.nativeWebRequest = exports.pathVariable = exports.requestMethod = exports.requestParam = exports.requestBody = exports.requestMapping = void 0;
3
+ exports.nativeWebRequest = exports.requestPart = exports.requestParam = exports.requestMethod = exports.requestMapping = exports.requestBody = exports.pathVariable = exports.validated = exports.controller = exports.filePart = exports.responseEntity = exports.httpStatus = exports.autowired = void 0;
4
4
  const reference_1 = require("../nodes/reference");
5
- // org.springframework.web.bind.annotation
6
- exports.requestMapping = reference_1.ktReference.factory('RequestMapping', 'org.springframework.web.bind.annotation');
7
- exports.requestBody = reference_1.ktReference.factory('RequestBody', 'org.springframework.web.bind.annotation');
8
- exports.requestParam = reference_1.ktReference.factory('RequestParam', 'org.springframework.web.bind.annotation');
9
- exports.requestMethod = reference_1.ktReference.factory('RequestMethod', 'org.springframework.web.bind.annotation');
10
- exports.pathVariable = reference_1.ktReference.factory('PathVariable', 'org.springframework.web.bind.annotation');
11
- // org.springframework.web.context.request
12
- exports.nativeWebRequest = reference_1.ktReference.factory('NativeWebRequest', 'org.springframework.web.context.request');
13
5
  // org.springframework.beans.factory.annotation
14
6
  exports.autowired = reference_1.ktReference.factory('Autowired', 'org.springframework.beans.factory.annotation');
15
- // org.springframework.validation.annotation
16
- exports.validated = reference_1.ktReference.factory('Validated', 'org.springframework.validation.annotation');
17
7
  // org.springframework.http
18
- exports.responseEntity = reference_1.ktReference.genericFactory('ResponseEntity', 'org.springframework.http');
19
8
  exports.httpStatus = reference_1.ktReference.factory('HttpStatus', 'org.springframework.http');
9
+ exports.responseEntity = reference_1.ktReference.genericFactory('ResponseEntity', 'org.springframework.http');
10
+ // org.springframework.http.codec.multipart
11
+ exports.filePart = reference_1.ktReference.factory('FilePart', 'org.springframework.http.codec.multipart');
20
12
  // org.springframework.stereotype
21
13
  exports.controller = reference_1.ktReference.factory('Controller', 'org.springframework.stereotype');
14
+ // org.springframework.validation.annotation
15
+ exports.validated = reference_1.ktReference.factory('Validated', 'org.springframework.validation.annotation');
16
+ // org.springframework.web.bind.annotation
17
+ exports.pathVariable = reference_1.ktReference.factory('PathVariable', 'org.springframework.web.bind.annotation');
18
+ exports.requestBody = reference_1.ktReference.factory('RequestBody', 'org.springframework.web.bind.annotation');
19
+ exports.requestMapping = reference_1.ktReference.factory('RequestMapping', 'org.springframework.web.bind.annotation');
20
+ exports.requestMethod = reference_1.ktReference.factory('RequestMethod', 'org.springframework.web.bind.annotation');
21
+ exports.requestParam = reference_1.ktReference.factory('RequestParam', 'org.springframework.web.bind.annotation');
22
+ exports.requestPart = reference_1.ktReference.factory('RequestPart', 'org.springframework.web.bind.annotation');
23
+ // org.springframework.web.context.request
24
+ exports.nativeWebRequest = reference_1.ktReference.factory('NativeWebRequest', 'org.springframework.web.context.request');
@@ -352,6 +352,10 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
352
352
  if (!ctx.data.schemas.some((x) => x.id === schema.id)) {
353
353
  return false;
354
354
  }
355
+ // multipart schemas should not have its own type declaration
356
+ if (schema.$src.path.endsWith('/requestBody/content/multipart/form-data/schema')) {
357
+ return false;
358
+ }
355
359
  return true;
356
360
  }
357
361
  getDeclarationTypeName(ctx, args) {
@@ -90,7 +90,7 @@ class DefaultKotlinOkHttp3Generator extends file_generator_1.KotlinFileGenerator
90
90
  ],
91
91
  parameters: parameters.map((p) => {
92
92
  var _a;
93
- return ast_1.kt.parameter((0, core_1.toCasing)(p.name, ctx.config.parameterNameCasing), this.getTypeUsage(ctx, { schema: p.schema, nullable: !p.required }), {
93
+ return ast_1.kt.parameter((0, core_1.toCasing)(p.name, ctx.config.parameterNameCasing), this.getParameterType(ctx, { endpoint, parameter: p }), {
94
94
  description: p.description,
95
95
  default: !p.required ? ast_1.kt.toNode((_a = p.schema) === null || _a === void 0 ? void 0 : _a.default) : null,
96
96
  });
@@ -148,7 +148,7 @@ class DefaultKotlinOkHttp3Generator extends file_generator_1.KotlinFileGenerator
148
148
  ],
149
149
  parameters: parameters.map((p) => {
150
150
  var _a;
151
- return ast_1.kt.parameter((0, core_1.toCasing)(p.name, ctx.config.parameterNameCasing), this.getTypeUsage(ctx, { schema: p.schema, nullable: !p.required }), {
151
+ return ast_1.kt.parameter((0, core_1.toCasing)(p.name, ctx.config.parameterNameCasing), this.getParameterType(ctx, { endpoint, parameter: p }), {
152
152
  description: p.description,
153
153
  default: !p.required ? ast_1.kt.toNode((_a = p.schema) === null || _a === void 0 ? void 0 : _a.default) : null,
154
154
  });
@@ -160,14 +160,13 @@ class DefaultKotlinOkHttp3Generator extends file_generator_1.KotlinFileGenerator
160
160
  });
161
161
  }
162
162
  getEndpointClientHttpInfoMethodBody(ctx, args) {
163
- var _a;
164
163
  const { endpoint, parameters, responseSchema } = args;
165
164
  return (0, core_1.appendValueGroup)([
166
165
  (0, core_1.builderTemplate) `val localVariableConfig = ${ast_1.kt.call([(0, core_1.toCasing)(endpoint.name, 'camel') + 'RequestConfig'], parameters.map((x) => x.name))}`,
167
166
  (0, core_1.builderTemplate) `return ${ast_1.kt.call([
168
167
  ast_1.kt.reference('request', null, {
169
168
  generics: [
170
- this.getTypeUsage(ctx, { schema: (_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0].schema, fallback: ast_1.kt.refs.unit() }),
169
+ this.getRequestBodyType(ctx, { endpoint }),
171
170
  this.getTypeUsage(ctx, { schema: responseSchema, fallback: ast_1.kt.refs.unit() }),
172
171
  ],
173
172
  }),
@@ -175,33 +174,43 @@ class DefaultKotlinOkHttp3Generator extends file_generator_1.KotlinFileGenerator
175
174
  ], '\n');
176
175
  }
177
176
  getEndpointClientRequestConfigMethod(ctx, args) {
178
- var _a;
179
177
  const { endpoint, parameters } = args;
180
178
  const operationName = (0, core_1.toCasing)(endpoint.name, ctx.config.functionNameCasing);
181
- const requestSchema = (_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0].schema;
182
179
  return ast_1.kt.function((0, core_1.toCasing)(args.endpoint.name, ctx.config.functionNameCasing) + 'RequestConfig', {
183
180
  accessModifier: 'private',
184
181
  doc: ast_1.kt.doc(`To obtain the request config of the operation ${operationName}`),
185
182
  annotations: [endpoint.deprecated ? ast_1.kt.annotation(ast_1.kt.refs.deprecated(), [ast_1.kt.argument(ast_1.kt.string(''))]) : null],
186
183
  parameters: parameters.map((p) => {
187
184
  var _a;
188
- return ast_1.kt.parameter((0, core_1.toCasing)(p.name, ctx.config.parameterNameCasing), this.getTypeUsage(ctx, { schema: p.schema, nullable: !p.required }), {
185
+ return ast_1.kt.parameter((0, core_1.toCasing)(p.name, ctx.config.parameterNameCasing), this.getParameterType(ctx, { endpoint, parameter: p }), {
189
186
  description: p.description,
190
187
  default: !p.required ? ast_1.kt.toNode((_a = p.schema) === null || _a === void 0 ? void 0 : _a.default) : null,
191
188
  });
192
189
  }),
193
- returnType: ctx.refs.requestConfig([this.getTypeUsage(ctx, { schema: requestSchema, fallback: ast_1.kt.refs.unit() })]),
194
- body: this.getEndpointClientRequestConfigMethodBody(ctx, { endpoint }),
190
+ returnType: ctx.refs.requestConfig([this.getRequestBodyType(ctx, { endpoint })]),
191
+ body: this.getEndpointClientRequestConfigMethodBody(ctx, { endpoint, parameters }),
195
192
  });
196
193
  }
197
194
  getEndpointClientRequestConfigMethodBody(ctx, args) {
198
- var _a, _b;
199
- const { endpoint } = args;
200
- const queryParameters = endpoint.parameters.filter((x) => x.target === 'query');
195
+ var _a, _b, _c;
196
+ const { endpoint, parameters } = args;
197
+ const queryParameters = parameters.filter((x) => x.target === 'query');
201
198
  const result = (0, core_1.appendValueGroup)([], '\n');
202
199
  if (endpoint.requestBody) {
203
- const bodyParamName = (0, core_1.toCasing)(this.getRequestBodyParamName(ctx, { endpoint }), ctx.config.parameterNameCasing);
204
- result.values.push(`val localVariableBody = ${bodyParamName}`);
200
+ if (((_a = endpoint.requestBody.content[0]) === null || _a === void 0 ? void 0 : _a.type) === 'multipart/form-data') {
201
+ const partConfigs = parameters
202
+ .filter((x) => x.multipart)
203
+ .map((param) => {
204
+ var _a, _b;
205
+ const paramName = (0, core_1.toCasing)(param.name, ctx.config.parameterNameCasing);
206
+ return (0, core_1.builderTemplate) `"${(_b = (_a = param.multipart) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : ''}" to ${ctx.refs.partConfig.infer()}(body = ${paramName})`;
207
+ });
208
+ result.values.push((0, core_1.builderTemplate) `val localVariableBody = ${ast_1.kt.call(ast_1.kt.refs.mapOf([ast_1.kt.refs.string(), ctx.refs.partConfig(['*'])]), partConfigs)}`);
209
+ }
210
+ else {
211
+ const bodyParamName = (0, core_1.toCasing)(this.getRequestBodyParamName(ctx, { endpoint }), ctx.config.parameterNameCasing);
212
+ result.values.push(`val localVariableBody = ${bodyParamName}`);
213
+ }
205
214
  }
206
215
  result.values.push((0, core_1.builderTemplate) `val localVariableQuery: ${ctx.refs.multiValueMap()} = ${ast_1.kt.call([ast_1.kt.refs.mutableMapOf([ast_1.kt.refs.string(), ast_1.kt.refs.list([ast_1.kt.refs.string()])])], [])}${queryParameters.length === 0
207
216
  ? ''
@@ -220,8 +229,8 @@ class DefaultKotlinOkHttp3Generator extends file_generator_1.KotlinFileGenerator
220
229
  }), '\n')}`}
221
230
  }`}`);
222
231
  result.values.push('val localVariableHeaders: MutableMap<String, String> = mutableMapOf()');
223
- if (((_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0]) !== undefined) {
224
- result.values.push(`localVariableHeaders["Content-Type"] = "${(_b = endpoint.requestBody) === null || _b === void 0 ? void 0 : _b.content[0].type}"`);
232
+ if (((_b = endpoint.requestBody) === null || _b === void 0 ? void 0 : _b.content[0]) !== undefined) {
233
+ result.values.push(`localVariableHeaders["Content-Type"] = "${(_c = endpoint.requestBody) === null || _c === void 0 ? void 0 : _c.content[0].type}"`);
225
234
  }
226
235
  result.values.push((0, core_1.builderTemplate) `return ${ast_1.kt.call([ctx.refs.requestConfig.infer()], [
227
236
  ast_1.kt.argument.named('method', ast_1.kt.call([ctx.refs.requestMethod(), endpoint.method.toUpperCase()])),
@@ -244,6 +253,25 @@ class DefaultKotlinOkHttp3Generator extends file_generator_1.KotlinFileGenerator
244
253
  }),
245
254
  ];
246
255
  }
256
+ getParameterType(ctx, args) {
257
+ var _a;
258
+ const { parameter } = args;
259
+ if ((_a = parameter.multipart) === null || _a === void 0 ? void 0 : _a.isFile) {
260
+ return ast_1.kt.refs.java.file();
261
+ }
262
+ return this.getTypeUsage(ctx, {
263
+ schema: parameter.schema,
264
+ nullable: !parameter.required,
265
+ });
266
+ }
267
+ getRequestBodyType(ctx, args) {
268
+ var _a;
269
+ const { endpoint } = args;
270
+ const content = (_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0];
271
+ return (content === null || content === void 0 ? void 0 : content.type) === 'multipart/form-data'
272
+ ? ast_1.kt.refs.map([ast_1.kt.refs.string(), ctx.refs.partConfig(['*'])])
273
+ : this.getTypeUsage(ctx, { schema: content === null || content === void 0 ? void 0 : content.schema, fallback: ast_1.kt.refs.unit() });
274
+ }
247
275
  getTypeUsage(ctx, args) {
248
276
  const { schema, nullable, fallback } = args;
249
277
  const type = this.getSchemaType(ctx, { schema });
@@ -275,26 +303,43 @@ class DefaultKotlinOkHttp3Generator extends file_generator_1.KotlinFileGenerator
275
303
  return schema && ctx.input.kotlin.models[schema.id].type;
276
304
  }
277
305
  getAllParameters(ctx, args) {
306
+ var _a, _b;
278
307
  const { endpoint } = args;
279
308
  const parameters = endpoint.parameters.filter((parameter) => parameter.target === 'query' || parameter.target === 'path');
280
309
  if (endpoint.requestBody) {
281
- const schema = endpoint.requestBody.content[0].schema;
282
- parameters.push({
283
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
284
- $src: undefined,
285
- $ref: undefined,
286
- id: 'body',
287
- name: this.getRequestBodyParamName(ctx, { endpoint }),
288
- target: 'body',
289
- schema,
290
- required: endpoint.requestBody.required,
291
- description: endpoint.requestBody.description,
292
- allowEmptyValue: undefined,
293
- allowReserved: undefined,
294
- deprecated: false,
295
- explode: undefined,
296
- style: undefined,
297
- });
310
+ const content = endpoint.requestBody.content[0];
311
+ let schema = content.schema;
312
+ if (content.type === 'multipart/form-data') {
313
+ if (schema && schema.kind === 'object') {
314
+ schema = (_a = (0, core_1.resolveAnyOfAndAllOf)(schema, true)) !== null && _a !== void 0 ? _a : schema;
315
+ const properties = (_b = schema.properties) !== null && _b !== void 0 ? _b : {};
316
+ for (const [name, property] of properties.entries()) {
317
+ parameters.push(Object.assign(this.createApiParameter({
318
+ id: `multipart-${name}`,
319
+ name,
320
+ target: 'body',
321
+ schema: property.schema,
322
+ required: schema.required.has(name),
323
+ description: property.schema.description,
324
+ }), {
325
+ multipart: {
326
+ name,
327
+ isFile: property.schema.kind === 'string' && property.schema.format === 'binary',
328
+ },
329
+ }));
330
+ }
331
+ }
332
+ }
333
+ else {
334
+ parameters.push(this.createApiParameter({
335
+ id: 'body',
336
+ name: this.getRequestBodyParamName(ctx, { endpoint }),
337
+ target: 'body',
338
+ schema,
339
+ required: endpoint.requestBody.required,
340
+ description: endpoint.requestBody.description,
341
+ }));
342
+ }
298
343
  }
299
344
  return parameters.sort((a, b) => (a.required === b.required ? 0 : a.required ? -1 : 1));
300
345
  }
@@ -320,5 +365,21 @@ class DefaultKotlinOkHttp3Generator extends file_generator_1.KotlinFileGenerator
320
365
  getApiClientName(ctx, args) {
321
366
  return (0, core_1.toCasing)(ctx.service.name, ctx.config.typeNameCasing) + 'ApiClient';
322
367
  }
368
+ createApiParameter(data) {
369
+ return {
370
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
371
+ $src: undefined,
372
+ $ref: undefined,
373
+ schema: undefined,
374
+ required: false,
375
+ description: undefined,
376
+ allowEmptyValue: undefined,
377
+ allowReserved: undefined,
378
+ deprecated: false,
379
+ explode: undefined,
380
+ style: undefined,
381
+ ...data,
382
+ };
383
+ }
323
384
  }
324
385
  exports.DefaultKotlinOkHttp3Generator = DefaultKotlinOkHttp3Generator;
@@ -107,6 +107,7 @@ class DefaultKotlinSpringControllerGenerator extends file_generator_1.KotlinFile
107
107
  const result = ast_1.kt.parameter((0, core_1.toCasing)(parameter.name, ctx.config.parameterNameCasing), this.getParameterType(ctx, { endpoint, parameter }), {});
108
108
  if (ctx.config.addSwaggerAnnotations) {
109
109
  const annotation = ast_1.kt.annotation(ast_1.kt.refs.swagger.parameter(), [
110
+ parameter.multipart ? ast_1.kt.argument.named('name', ast_1.kt.string(parameter.multipart.name)) : null,
110
111
  parameter.description ? ast_1.kt.argument.named('description', ast_1.kt.string((_a = parameter.description) === null || _a === void 0 ? void 0 : _a.trim())) : null,
111
112
  ast_1.kt.argument.named('required', parameter.required),
112
113
  ]);
@@ -119,7 +120,7 @@ class DefaultKotlinSpringControllerGenerator extends file_generator_1.KotlinFile
119
120
  if (!isCorePackage && ctx.config.addJakartaValidationAnnotations) {
120
121
  result.annotations.push(ast_1.kt.annotation(ast_1.kt.refs.jakarta.valid()));
121
122
  }
122
- if (parameter.target === 'body') {
123
+ if (parameter.target === 'body' && !parameter.multipart) {
123
124
  result.annotations.push(ast_1.kt.annotation(ast_1.kt.refs.spring.requestBody()));
124
125
  }
125
126
  if (parameter.target === 'query') {
@@ -135,6 +136,12 @@ class DefaultKotlinSpringControllerGenerator extends file_generator_1.KotlinFile
135
136
  if (parameter.target === 'path') {
136
137
  result.annotations.push(ast_1.kt.annotation(ast_1.kt.refs.spring.pathVariable(), [ast_1.kt.string(parameter.name)]));
137
138
  }
139
+ if (parameter.multipart) {
140
+ result.annotations.push(ast_1.kt.annotation(ast_1.kt.refs.spring.requestPart(), [
141
+ ast_1.kt.argument.named('value', ast_1.kt.string(parameter.multipart.name)),
142
+ ast_1.kt.argument.named('required', parameter.required),
143
+ ]));
144
+ }
138
145
  return result;
139
146
  }
140
147
  getApiInterfaceEndpointMethodBody(ctx, endpoint, parameters) {
@@ -259,11 +266,14 @@ class DefaultKotlinSpringControllerGenerator extends file_generator_1.KotlinFile
259
266
  }
260
267
  // #endregion
261
268
  getParameterType(ctx, args) {
262
- var _a;
269
+ var _a, _b;
263
270
  const { parameter } = args;
271
+ if ((_a = parameter.multipart) === null || _a === void 0 ? void 0 : _a.isFile) {
272
+ return ast_1.kt.refs.reactor.mono([ast_1.kt.refs.spring.filePart()]);
273
+ }
264
274
  const type = this.getTypeUsage(ctx, {
265
275
  schema: parameter.schema,
266
- nullable: (!parameter.required && ((_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.default) === undefined) || undefined,
276
+ nullable: (!parameter.required && ((_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.default) === undefined) || undefined,
267
277
  });
268
278
  return parameter.target === 'body' ? listToFlux(type) : type;
269
279
  }
@@ -330,33 +340,66 @@ class DefaultKotlinSpringControllerGenerator extends file_generator_1.KotlinFile
330
340
  return (0, core_1.toCasing)(ctx.service.name + '_ApiDelegate', ctx.config.typeNameCasing);
331
341
  }
332
342
  getAllParameters(ctx, args) {
343
+ var _a, _b;
333
344
  const { endpoint } = args;
334
345
  const parameters = endpoint.parameters.filter((parameter) => parameter.target === 'query' || parameter.target === 'path');
335
346
  if (endpoint.requestBody) {
336
- const schema = endpoint.requestBody.content[0].schema;
337
- const schemaType = this.getSchemaType(ctx, { schema });
338
- const name = !schemaType || /^Any\??$/.test(schemaType.name)
339
- ? 'body'
340
- : core_1.SourceBuilder.build((b) => ast_1.kt.reference.write(b, schemaType));
341
- parameters.push({
342
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
343
- $src: undefined,
344
- $ref: undefined,
345
- id: 'body',
346
- name,
347
- target: 'body',
348
- schema,
349
- required: endpoint.requestBody.required,
350
- description: endpoint.requestBody.description,
351
- allowEmptyValue: undefined,
352
- allowReserved: undefined,
353
- deprecated: false,
354
- explode: undefined,
355
- style: undefined,
356
- });
347
+ const content = endpoint.requestBody.content[0];
348
+ let schema = content.schema;
349
+ if (content.type === 'multipart/form-data') {
350
+ if (schema && schema.kind === 'object') {
351
+ schema = (_a = (0, core_1.resolveAnyOfAndAllOf)(schema, true)) !== null && _a !== void 0 ? _a : schema;
352
+ const properties = (_b = schema.properties) !== null && _b !== void 0 ? _b : {};
353
+ for (const [name, property] of properties.entries()) {
354
+ parameters.push(Object.assign(this.createApiParameter({
355
+ id: `multipart-${name}`,
356
+ name,
357
+ target: 'body',
358
+ schema: property.schema,
359
+ required: schema.required.has(name),
360
+ description: property.schema.description,
361
+ }), {
362
+ multipart: {
363
+ name,
364
+ isFile: property.schema.kind === 'string' && property.schema.format === 'binary',
365
+ },
366
+ }));
367
+ }
368
+ }
369
+ }
370
+ else {
371
+ const schemaType = this.getSchemaType(ctx, { schema });
372
+ const name = !schemaType || /^Any\??$/.test(schemaType.name)
373
+ ? 'body'
374
+ : core_1.SourceBuilder.build((b) => ast_1.kt.reference.write(b, schemaType));
375
+ parameters.push(this.createApiParameter({
376
+ id: 'body',
377
+ name,
378
+ target: 'body',
379
+ schema,
380
+ required: endpoint.requestBody.required,
381
+ description: endpoint.requestBody.description,
382
+ }));
383
+ }
357
384
  }
358
385
  return parameters;
359
386
  }
387
+ createApiParameter(data) {
388
+ return {
389
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
390
+ $src: undefined,
391
+ $ref: undefined,
392
+ schema: undefined,
393
+ required: false,
394
+ description: undefined,
395
+ allowEmptyValue: undefined,
396
+ allowReserved: undefined,
397
+ deprecated: false,
398
+ explode: undefined,
399
+ style: undefined,
400
+ ...data,
401
+ };
402
+ }
360
403
  }
361
404
  exports.DefaultKotlinSpringControllerGenerator = DefaultKotlinSpringControllerGenerator;
362
405
  function listToFlux(type) {
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/esm/index.js CHANGED
@@ -1,7 +1,8 @@
1
+ export * from './lib/ast';
1
2
  export * from './lib/common-results';
2
3
  export * from './lib/config';
3
- export * from './lib/generators';
4
4
  export * from './lib/file-builder';
5
+ export * from './lib/generators';
5
6
  export * from './lib/import-collection';
7
+ export * from './lib/types';
6
8
  export * from './lib/utils';
7
- export * from './lib/ast';
@@ -1,10 +1,11 @@
1
1
  import { ktReference } from '../nodes/reference';
2
+ // java.io
3
+ export const file = ktReference.factory('File', 'java.io');
4
+ export const ioException = ktReference.factory('IOException', 'java.io');
2
5
  // java.lang
3
- export const system = ktReference.factory('System', 'java.lang');
4
6
  export const illegalStateException = ktReference.factory('IllegalStateException', 'java.lang');
7
+ export const system = ktReference.factory('System', 'java.lang');
5
8
  export const unsupportedOperationException = ktReference.factory('UnsupportedOperationException', 'java.lang');
6
- // java.io
7
- export const ioException = ktReference.factory('IOException', 'java.io');
8
9
  // java.time
9
10
  export const offsetDateTime = ktReference.factory('OffsetDateTime', 'java.time');
10
11
  // java.util
@@ -1,3 +1,4 @@
1
1
  import { ktReference } from '../nodes/reference';
2
2
  // reactor.core.publisher
3
3
  export const flux = ktReference.genericFactory('Flux', 'reactor.core.publisher');
4
+ export const mono = ktReference.genericFactory('Mono', 'reactor.core.publisher');
@@ -1,18 +1,21 @@
1
1
  import { ktReference } from '../nodes/reference';
2
- // org.springframework.web.bind.annotation
3
- export const requestMapping = ktReference.factory('RequestMapping', 'org.springframework.web.bind.annotation');
4
- export const requestBody = ktReference.factory('RequestBody', 'org.springframework.web.bind.annotation');
5
- export const requestParam = ktReference.factory('RequestParam', 'org.springframework.web.bind.annotation');
6
- export const requestMethod = ktReference.factory('RequestMethod', 'org.springframework.web.bind.annotation');
7
- export const pathVariable = ktReference.factory('PathVariable', 'org.springframework.web.bind.annotation');
8
- // org.springframework.web.context.request
9
- export const nativeWebRequest = ktReference.factory('NativeWebRequest', 'org.springframework.web.context.request');
10
2
  // org.springframework.beans.factory.annotation
11
3
  export const autowired = ktReference.factory('Autowired', 'org.springframework.beans.factory.annotation');
12
- // org.springframework.validation.annotation
13
- export const validated = ktReference.factory('Validated', 'org.springframework.validation.annotation');
14
4
  // org.springframework.http
15
- export const responseEntity = ktReference.genericFactory('ResponseEntity', 'org.springframework.http');
16
5
  export const httpStatus = ktReference.factory('HttpStatus', 'org.springframework.http');
6
+ export const responseEntity = ktReference.genericFactory('ResponseEntity', 'org.springframework.http');
7
+ // org.springframework.http.codec.multipart
8
+ export const filePart = ktReference.factory('FilePart', 'org.springframework.http.codec.multipart');
17
9
  // org.springframework.stereotype
18
10
  export const controller = ktReference.factory('Controller', 'org.springframework.stereotype');
11
+ // org.springframework.validation.annotation
12
+ export const validated = ktReference.factory('Validated', 'org.springframework.validation.annotation');
13
+ // org.springframework.web.bind.annotation
14
+ export const pathVariable = ktReference.factory('PathVariable', 'org.springframework.web.bind.annotation');
15
+ export const requestBody = ktReference.factory('RequestBody', 'org.springframework.web.bind.annotation');
16
+ export const requestMapping = ktReference.factory('RequestMapping', 'org.springframework.web.bind.annotation');
17
+ export const requestMethod = ktReference.factory('RequestMethod', 'org.springframework.web.bind.annotation');
18
+ export const requestParam = ktReference.factory('RequestParam', 'org.springframework.web.bind.annotation');
19
+ export const requestPart = ktReference.factory('RequestPart', 'org.springframework.web.bind.annotation');
20
+ // org.springframework.web.context.request
21
+ export const nativeWebRequest = ktReference.factory('NativeWebRequest', 'org.springframework.web.context.request');
@@ -349,6 +349,10 @@ export class DefaultKotlinModelGenerator extends KotlinFileGenerator {
349
349
  if (!ctx.data.schemas.some((x) => x.id === schema.id)) {
350
350
  return false;
351
351
  }
352
+ // multipart schemas should not have its own type declaration
353
+ if (schema.$src.path.endsWith('/requestBody/content/multipart/form-data/schema')) {
354
+ return false;
355
+ }
352
356
  return true;
353
357
  }
354
358
  getDeclarationTypeName(ctx, args) {