@goast/kotlin 0.3.2 → 0.3.4
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.
- package/cjs/index.js +3 -2
- package/cjs/lib/ast/references/java.js +5 -4
- package/cjs/lib/ast/references/reactor.js +2 -1
- package/cjs/lib/ast/references/spring.js +15 -12
- package/cjs/lib/generators/models/model-generator.js +9 -18
- package/cjs/lib/generators/models/models.js +1 -0
- package/cjs/lib/generators/services/okhttp3-clients/okhttp3-client-generator.js +94 -33
- package/cjs/lib/generators/services/spring-controllers/spring-controller-generator.js +67 -24
- package/cjs/lib/types.js +2 -0
- package/esm/index.js +3 -2
- package/esm/lib/ast/references/java.js +4 -3
- package/esm/lib/ast/references/reactor.js +1 -0
- package/esm/lib/ast/references/spring.js +14 -11
- package/esm/lib/generators/models/model-generator.js +9 -18
- package/esm/lib/generators/models/models.js +1 -0
- package/esm/lib/generators/services/okhttp3-clients/okhttp3-client-generator.js +95 -34
- package/esm/lib/generators/services/spring-controllers/spring-controller-generator.js +68 -25
- package/esm/lib/types.js +1 -0
- package/package.json +2 -2
- package/types/index.d.ts +3 -2
- package/types/lib/ast/references/java.d.ts +16 -3
- package/types/lib/ast/references/reactor.d.ts +16 -0
- package/types/lib/ast/references/spring.d.ts +44 -18
- package/types/lib/generators/models/models.d.ts +33 -0
- package/types/lib/generators/services/okhttp3-clients/args.d.ts +9 -0
- package/types/lib/generators/services/okhttp3-clients/okhttp3-client-generator.d.ts +6 -2
- package/types/lib/generators/services/spring-controllers/args.d.ts +3 -2
- package/types/lib/generators/services/spring-controllers/spring-controller-generator.d.ts +4 -2
- package/types/lib/types.d.ts +7 -0
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.
|
|
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.
|
|
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');
|
|
@@ -14,24 +14,6 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
|
|
|
14
14
|
// Do not generate types that are only used for anyOf and/or allOf
|
|
15
15
|
return { type: ast_1.kt.refs.any({ nullable: true }) };
|
|
16
16
|
}
|
|
17
|
-
if (ctx.schema.id === ctx.schema.name) {
|
|
18
|
-
// TODO: Add this to @goast/core
|
|
19
|
-
const match = ctx.schema.$src.path.match(/\/components\/responses\/([^/]+)\/content\/.+\/schema/);
|
|
20
|
-
if (match) {
|
|
21
|
-
ctx.schema.name = match[1].toLowerCase().endsWith('response') ? match[1] : match[1] + 'Response';
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (ctx.schema.isNameGenerated) {
|
|
25
|
-
// TODO: Change this in @goast/core
|
|
26
|
-
const match = ctx.schema.$src.path.match(/\/paths\/(?<path>.+)\/(?<method>.+)\/responses\/(?<status>\d+)\//);
|
|
27
|
-
if (match && match.groups) {
|
|
28
|
-
const { path, method, status } = match.groups;
|
|
29
|
-
const endpoint = ctx.data.endpoints.find((e) => e.path === path && e.method === method);
|
|
30
|
-
if (endpoint) {
|
|
31
|
-
ctx.schema.name = `${endpoint.name}${status}Response`;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
17
|
if (this.shouldGenerateTypeDeclaration(ctx, { schema: ctx.schema })) {
|
|
36
18
|
const typeName = this.getDeclarationTypeName(ctx, { schema: ctx.schema });
|
|
37
19
|
const packageName = this.getPackageName(ctx, { schema: ctx.schema });
|
|
@@ -187,6 +169,8 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
|
|
|
187
169
|
return schema.enum && schema.enum.length > 0
|
|
188
170
|
? ast_1.kt.call([this.getType(ctx, { schema }), (0, core_1.toCasing)(String(schema.default), ctx.config.enumValueNameCasing)])
|
|
189
171
|
: ast_1.kt.string(String(schema.default));
|
|
172
|
+
case 'array':
|
|
173
|
+
return ast_1.kt.call(ast_1.kt.refs.listOf.infer(), Array.isArray(schema.default) ? schema.default.map((x) => ast_1.kt.toNode(x)) : []);
|
|
190
174
|
default:
|
|
191
175
|
return 'null';
|
|
192
176
|
}
|
|
@@ -361,10 +345,17 @@ class DefaultKotlinModelGenerator extends file_generator_1.KotlinFileGenerator {
|
|
|
361
345
|
if (schema.kind === 'object' && schema.properties.size === 0 && schema.additionalProperties) {
|
|
362
346
|
return false;
|
|
363
347
|
}
|
|
348
|
+
if (schema.kind === 'object' && ctx.config.emptyObjectTypeBehavior === 'use-any' && schema.properties.size === 0) {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
364
351
|
// Dynamically generated schemas do not have its own type declaration
|
|
365
352
|
if (!ctx.data.schemas.some((x) => x.id === schema.id)) {
|
|
366
353
|
return false;
|
|
367
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
|
+
}
|
|
368
359
|
return true;
|
|
369
360
|
}
|
|
370
361
|
getDeclarationTypeName(ctx, args) {
|
|
@@ -7,6 +7,7 @@ exports.defaultKotlinModelsGeneratorConfig = {
|
|
|
7
7
|
packageName: 'com.openapi.generated',
|
|
8
8
|
packageSuffix: '.model',
|
|
9
9
|
oneOfBehavior: 'treat-as-any-of',
|
|
10
|
+
emptyObjectTypeBehavior: 'generate-empty-class',
|
|
10
11
|
addJacksonAnnotations: true,
|
|
11
12
|
addJakartaValidationAnnotations: true,
|
|
12
13
|
addSwaggerAnnotations: true,
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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 =
|
|
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
|
-
|
|
204
|
-
|
|
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 (((
|
|
224
|
-
result.values.push(`localVariableHeaders["Content-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
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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 && ((
|
|
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
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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) {
|
package/cjs/lib/types.js
ADDED
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,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');
|
|
@@ -11,24 +11,6 @@ export class DefaultKotlinModelGenerator extends KotlinFileGenerator {
|
|
|
11
11
|
// Do not generate types that are only used for anyOf and/or allOf
|
|
12
12
|
return { type: kt.refs.any({ nullable: true }) };
|
|
13
13
|
}
|
|
14
|
-
if (ctx.schema.id === ctx.schema.name) {
|
|
15
|
-
// TODO: Add this to @goast/core
|
|
16
|
-
const match = ctx.schema.$src.path.match(/\/components\/responses\/([^/]+)\/content\/.+\/schema/);
|
|
17
|
-
if (match) {
|
|
18
|
-
ctx.schema.name = match[1].toLowerCase().endsWith('response') ? match[1] : match[1] + 'Response';
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
if (ctx.schema.isNameGenerated) {
|
|
22
|
-
// TODO: Change this in @goast/core
|
|
23
|
-
const match = ctx.schema.$src.path.match(/\/paths\/(?<path>.+)\/(?<method>.+)\/responses\/(?<status>\d+)\//);
|
|
24
|
-
if (match && match.groups) {
|
|
25
|
-
const { path, method, status } = match.groups;
|
|
26
|
-
const endpoint = ctx.data.endpoints.find((e) => e.path === path && e.method === method);
|
|
27
|
-
if (endpoint) {
|
|
28
|
-
ctx.schema.name = `${endpoint.name}${status}Response`;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
14
|
if (this.shouldGenerateTypeDeclaration(ctx, { schema: ctx.schema })) {
|
|
33
15
|
const typeName = this.getDeclarationTypeName(ctx, { schema: ctx.schema });
|
|
34
16
|
const packageName = this.getPackageName(ctx, { schema: ctx.schema });
|
|
@@ -184,6 +166,8 @@ export class DefaultKotlinModelGenerator extends KotlinFileGenerator {
|
|
|
184
166
|
return schema.enum && schema.enum.length > 0
|
|
185
167
|
? kt.call([this.getType(ctx, { schema }), toCasing(String(schema.default), ctx.config.enumValueNameCasing)])
|
|
186
168
|
: kt.string(String(schema.default));
|
|
169
|
+
case 'array':
|
|
170
|
+
return kt.call(kt.refs.listOf.infer(), Array.isArray(schema.default) ? schema.default.map((x) => kt.toNode(x)) : []);
|
|
187
171
|
default:
|
|
188
172
|
return 'null';
|
|
189
173
|
}
|
|
@@ -358,10 +342,17 @@ export class DefaultKotlinModelGenerator extends KotlinFileGenerator {
|
|
|
358
342
|
if (schema.kind === 'object' && schema.properties.size === 0 && schema.additionalProperties) {
|
|
359
343
|
return false;
|
|
360
344
|
}
|
|
345
|
+
if (schema.kind === 'object' && ctx.config.emptyObjectTypeBehavior === 'use-any' && schema.properties.size === 0) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
361
348
|
// Dynamically generated schemas do not have its own type declaration
|
|
362
349
|
if (!ctx.data.schemas.some((x) => x.id === schema.id)) {
|
|
363
350
|
return false;
|
|
364
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
|
+
}
|
|
365
356
|
return true;
|
|
366
357
|
}
|
|
367
358
|
getDeclarationTypeName(ctx, args) {
|
|
@@ -4,6 +4,7 @@ export const defaultKotlinModelsGeneratorConfig = {
|
|
|
4
4
|
packageName: 'com.openapi.generated',
|
|
5
5
|
packageSuffix: '.model',
|
|
6
6
|
oneOfBehavior: 'treat-as-any-of',
|
|
7
|
+
emptyObjectTypeBehavior: 'generate-empty-class',
|
|
7
8
|
addJacksonAnnotations: true,
|
|
8
9
|
addJakartaValidationAnnotations: true,
|
|
9
10
|
addSwaggerAnnotations: true,
|