@devlearning/swagger-generator 1.0.11 → 1.0.13
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/.vscode/launch.json +6 -0
- package/README.md +4 -2
- package/autogen/identity/api/identity_api.dart +82 -0
- package/autogen/identity/models/auth_activate_command.dart +14 -0
- package/autogen/identity/models/auth_app_authenticate_command.dart +16 -0
- package/autogen/identity/models/auth_generate_reset_password_code_command.dart +15 -0
- package/autogen/identity/models/auth_refresh_token_command.dart +15 -0
- package/autogen/identity/models/auth_reset_password_command.dart +16 -0
- package/autogen/identity/models/auth_user_authenticate_command.dart +15 -0
- package/autogen/identity/models/auth_user_dto.dart +18 -0
- package/autogen/identity/models/auth_verify_reset_password_code_command.dart +14 -0
- package/autogen/identity/models/authentication_token.dart +17 -0
- package/autogen/mvc/models/problem_details.dart +17 -0
- package/autogen/service_defaults/models/application_exception.dart +14 -0
- package/autogen/service_defaults/models/result.dart +17 -0
- package/autogen/user_profile/api/user_profile_api.dart +46 -0
- package/autogen/user_profile/models/test_list_query.dart +13 -0
- package/autogen/user_profile/models/test_read_query.dart +13 -0
- package/autogen/user_profile/models/test_save_command.dart +13 -0
- package/autogen/user_profile/models/user_general_info_save_command.dart +13 -0
- package/dist/generator.js +63 -31
- package/dist/generators-writers/angular/api-angular-writer.js +1 -1
- package/dist/generators-writers/dart/api-dart-writer.js +110 -0
- package/dist/generators-writers/dart/model-dart-writer.js +124 -0
- package/dist/generators-writers/dart/models/import-definition-dart.js +1 -0
- package/dist/generators-writers/dart/normalizator.js +35 -0
- package/dist/generators-writers/nextjs/api-nextjs-writer.js +1 -1
- package/dist/generators-writers/utils.js +43 -2
- package/dist/index.js +72 -16
- package/dist/models/swagger/swagger-component-property.js +10 -0
- package/dist/models/swagger/swagger-component.js +1 -0
- package/dist/models/swagger/swagger-schema.js +1 -0
- package/package.json +11 -5
- package/src/generator.ts +67 -38
- package/src/generators-writers/angular/api-angular-writer.ts +1 -1
- package/src/generators-writers/dart/api-dart-writer.ts +164 -0
- package/src/generators-writers/dart/model-dart-writer.ts +176 -0
- package/src/generators-writers/dart/models/import-definition-dart.ts +6 -0
- package/src/generators-writers/dart/normalizator.ts +44 -0
- package/src/generators-writers/dart/templates/api.mustache +29 -0
- package/src/generators-writers/dart/templates/model.mustache +18 -0
- package/src/generators-writers/nextjs/api-nextjs-writer.ts +1 -1
- package/src/generators-writers/utils.ts +54 -2
- package/src/index.ts +80 -16
- package/src/models/api-dto.ts +1 -0
- package/src/models/model-dto.ts +1 -0
- package/src/models/swagger/swagger-component-property.ts +10 -9
- package/src/models/swagger/swagger-component.ts +11 -2
- package/src/models/swagger/swagger-schema.ts +18 -6
- package/src/models/swagger/swagger.ts +1 -0
- package/autogeneration/output/api.autogenerated.ts +0 -95
- package/autogeneration/output/model.autogenerated.ts +0 -69
package/dist/index.js
CHANGED
|
@@ -1,24 +1,80 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import yargs from 'yargs';
|
|
3
|
+
import { hideBin } from 'yargs/helpers';
|
|
2
4
|
import { Generator } from './generator.js';
|
|
3
5
|
import { SwaggerDownloader } from './swagger-downloader.js';
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
export var DateTimeLibrary;
|
|
7
|
+
(function (DateTimeLibrary) {
|
|
8
|
+
DateTimeLibrary["Moment"] = "moment";
|
|
9
|
+
DateTimeLibrary["DateFns"] = "date-fn";
|
|
10
|
+
})(DateTimeLibrary || (DateTimeLibrary = {}));
|
|
11
|
+
export var TargetGeneration;
|
|
12
|
+
(function (TargetGeneration) {
|
|
13
|
+
TargetGeneration["Angular"] = "angular";
|
|
14
|
+
TargetGeneration["Next"] = "next";
|
|
15
|
+
TargetGeneration["Dart"] = "dart";
|
|
16
|
+
})(TargetGeneration || (TargetGeneration = {}));
|
|
17
|
+
const argv = yargs(hideBin(process.argv))
|
|
18
|
+
.scriptName("swagger-gen")
|
|
19
|
+
.usage('Usage: $0 --url <swaggerJsonUrl> --output <outputDirectory> --target <target> [--dateTimeLibrary <dateTimeLibrary>] [--package <name>]')
|
|
20
|
+
.option('url', {
|
|
21
|
+
alias: 'u',
|
|
22
|
+
type: 'string',
|
|
23
|
+
demandOption: true,
|
|
24
|
+
describe: 'URL of swagger.json file',
|
|
25
|
+
})
|
|
26
|
+
.option('output', {
|
|
27
|
+
alias: 'o',
|
|
28
|
+
type: 'string',
|
|
29
|
+
demandOption: true,
|
|
30
|
+
describe: 'Output directory for generated code',
|
|
31
|
+
})
|
|
32
|
+
.option('target', {
|
|
33
|
+
alias: 't',
|
|
34
|
+
type: 'string',
|
|
35
|
+
choices: ['angular', 'next', 'dart'],
|
|
36
|
+
demandOption: true,
|
|
37
|
+
describe: 'Target format for the generated code',
|
|
38
|
+
})
|
|
39
|
+
.option('dateTimeLibrary', {
|
|
40
|
+
alias: 'd',
|
|
41
|
+
type: 'string',
|
|
42
|
+
choices: ['moment', 'date-fns'],
|
|
43
|
+
default: 'date-fns',
|
|
44
|
+
describe: 'Date library to use for date handling',
|
|
45
|
+
})
|
|
46
|
+
.option('package', {
|
|
47
|
+
alias: 'p',
|
|
48
|
+
type: 'string',
|
|
49
|
+
describe: 'For Dart: package name for Dart project',
|
|
50
|
+
})
|
|
51
|
+
.help()
|
|
52
|
+
.parseSync();
|
|
53
|
+
const commandLineArgs = {
|
|
54
|
+
swaggerJsonUrl: argv.url,
|
|
55
|
+
outputDirectory: argv.output,
|
|
56
|
+
target: parseTargetGeneration(argv.target),
|
|
57
|
+
dateTimeLibrary: parseDateTimeLibrary(argv.dateTimeLibrary),
|
|
58
|
+
package: argv.package ?? '',
|
|
59
|
+
};
|
|
18
60
|
const swaggerDownloader = new SwaggerDownloader();
|
|
19
|
-
swaggerDownloader.download(new URL(swaggerJsonUrl))
|
|
61
|
+
swaggerDownloader.download(new URL(commandLineArgs.swaggerJsonUrl))
|
|
20
62
|
.then(swaggerDoc => {
|
|
21
|
-
return new Generator(swaggerDoc,
|
|
63
|
+
return new Generator(swaggerDoc, commandLineArgs);
|
|
22
64
|
})
|
|
23
65
|
.then(generator => { generator.generate(); });
|
|
24
66
|
// require('./index.js')({swaggerDownloader});
|
|
67
|
+
function parseDateTimeLibrary(value) {
|
|
68
|
+
const values = Object.values(DateTimeLibrary);
|
|
69
|
+
if (values.includes(value)) {
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
function parseTargetGeneration(value) {
|
|
75
|
+
const values = Object.values(TargetGeneration);
|
|
76
|
+
if (values.includes(value)) {
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
throw new Error(`Invalid OutputFormat: ${value}`);
|
|
80
|
+
}
|
|
@@ -1 +1,11 @@
|
|
|
1
1
|
export {};
|
|
2
|
+
// export interface SwaggerComponentProperty {
|
|
3
|
+
// type: string;
|
|
4
|
+
// $ref: string;
|
|
5
|
+
// allOf: SwaggerComponentProperty[];
|
|
6
|
+
// format: string;
|
|
7
|
+
// items: SwaggerSchema;
|
|
8
|
+
// properties: { [key: string]: SwaggerComponentProperty; };
|
|
9
|
+
// nullable: boolean;
|
|
10
|
+
// minLength: number;
|
|
11
|
+
// }
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devlearning/swagger-generator",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Swagger generator apis and models for Angular and NextJS",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"
|
|
9
|
-
"debug-
|
|
10
|
-
"debug-
|
|
8
|
+
"debug-angular": "npx tsx src/index.ts --url http://localhost:7550/swagger/ApiGateway/swagger.json --output autogeneration/output --target angular --dateTimeLibrary moment",
|
|
9
|
+
"debug-nextjs": "npx tsx src/index.ts --url http://localhost:7550/swagger/ApiGateway/swagger.json --output autogeneration/output --target next --dateTimeLibrary date-fns",
|
|
10
|
+
"debug-flutter": "npx tsx src/index.ts --url http://localhost:7550/swagger/ApiGateway/swagger.json --output autogen --target flutter --package coqudo_app",
|
|
11
11
|
"deploy": "npx tsc && npm publish"
|
|
12
12
|
},
|
|
13
13
|
"bin": {
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
"swagger",
|
|
18
18
|
"angular",
|
|
19
19
|
"nextjs",
|
|
20
|
+
"dart",
|
|
21
|
+
"flutter",
|
|
20
22
|
"api",
|
|
21
23
|
"generator"
|
|
22
24
|
],
|
|
@@ -24,12 +26,16 @@
|
|
|
24
26
|
"license": "ISC",
|
|
25
27
|
"dependencies": {
|
|
26
28
|
"cli-progress": "^3.12.0",
|
|
27
|
-
"
|
|
29
|
+
"mustache": "^4.2.0",
|
|
30
|
+
"node-fetch": "^3.3.2",
|
|
31
|
+
"yargs": "^18.0.0"
|
|
28
32
|
},
|
|
29
33
|
"node-fetch": "^3.3.2",
|
|
30
34
|
"devDependencies": {
|
|
31
35
|
"@types/cli-progress": "^3.11.6",
|
|
36
|
+
"@types/mustache": "^4.2.6",
|
|
32
37
|
"@types/node": "^18.15.0",
|
|
38
|
+
"@types/yargs": "^17.0.33",
|
|
33
39
|
"ts-node": "^10.9.1",
|
|
34
40
|
"tsconfig-paths": "^4.2.0",
|
|
35
41
|
"typescript": "^5.1.6"
|
package/src/generator.ts
CHANGED
|
@@ -2,7 +2,6 @@ import fs from 'fs';
|
|
|
2
2
|
import { SwaggerComponent } from './models/swagger/swagger-component.js';
|
|
3
3
|
import { Swagger } from './models/swagger/swagger.js';
|
|
4
4
|
import { SwaggerMethod } from './models/swagger/swagger-method.js';
|
|
5
|
-
import { SwaggerComponentProperty } from './models/swagger/swagger-component-property.js';
|
|
6
5
|
import { SwaggerSchema } from './models/swagger/swagger-schema.js';
|
|
7
6
|
import { ApiDto } from './models/api-dto.js';
|
|
8
7
|
import { TypeDto } from './models/type-dto.js';
|
|
@@ -16,15 +15,17 @@ import { ModelAngularWriter } from './generators-writers/angular/model-angular-w
|
|
|
16
15
|
import { PropertyDto } from './models/property-dto.js';
|
|
17
16
|
import { EnumValueDto } from './models/enum-value-dto.js';
|
|
18
17
|
import { SwaggerContent } from './models/swagger/swagger-content.js';
|
|
18
|
+
import { CommandLineArgs, DateTimeLibrary, TargetGeneration } from './index.js';
|
|
19
|
+
import { ApiDartWriter } from './generators-writers/dart/api-dart-writer.js';
|
|
20
|
+
import { ModelDartWriter } from './generators-writers/dart/model-dart-writer.js';
|
|
21
|
+
import { Utils } from './generators-writers/utils.js';
|
|
19
22
|
|
|
20
23
|
const contentTypeApplicationJson = 'application/json';
|
|
21
24
|
const contentTypeMultipartFormData = 'multipart/form-data';
|
|
22
25
|
|
|
23
26
|
export class Generator {
|
|
24
27
|
private _swagger: Swagger;
|
|
25
|
-
private
|
|
26
|
-
private _outputFormat: 'angular' | 'next';
|
|
27
|
-
private _dateLibrary: 'moment' | 'date-fns';
|
|
28
|
+
private _commandLineArgs: CommandLineArgs;
|
|
28
29
|
|
|
29
30
|
private _apis: ApiDto[] = [];
|
|
30
31
|
private _models: ModelDto[] = [];
|
|
@@ -45,21 +46,21 @@ export class Generator {
|
|
|
45
46
|
barsize: 20,
|
|
46
47
|
}, Presets.shades_classic);
|
|
47
48
|
|
|
48
|
-
constructor(swagger: Swagger,
|
|
49
|
+
constructor(swagger: Swagger, commandLineArgs: CommandLineArgs) {
|
|
49
50
|
this._swagger = swagger;
|
|
50
|
-
this.
|
|
51
|
-
this._outputFormat = outputFormat;
|
|
52
|
-
this._dateLibrary = dateLibrary;
|
|
51
|
+
this._commandLineArgs = commandLineArgs;
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
generate() {
|
|
56
55
|
console.info('%c[Swagger API Generator] %cStarting to parse Swagger JSON file...', 'color: #4CAF50; font-weight: bold;', 'color: #2196F3;');
|
|
57
56
|
|
|
58
|
-
this.
|
|
59
|
-
this.generateApi();
|
|
57
|
+
Utils.clearDirectory(this._commandLineArgs.outputDirectory);
|
|
60
58
|
|
|
59
|
+
this.computeApi();
|
|
61
60
|
this.computeModel();
|
|
61
|
+
|
|
62
62
|
this.generateModel();
|
|
63
|
+
this.generateApi();
|
|
63
64
|
|
|
64
65
|
console.info('%c[Swagger Generator] %cSwagger file generated successfully!', 'color: #4CAF50; font-weight: bold;', 'color: #00C853;');
|
|
65
66
|
}
|
|
@@ -85,6 +86,7 @@ export class Generator {
|
|
|
85
86
|
swaggerMethod: apiSwaggerMethod,
|
|
86
87
|
haveRequest: apiSwaggerMethod.requestBody != null,
|
|
87
88
|
isMultiPart: apiSwaggerMethod.requestBody != null && apiSwaggerMethod.requestBody.content[contentTypeMultipartFormData] != null,
|
|
89
|
+
tag: apiSwaggerMethod.tags && apiSwaggerMethod.tags.length > 0 ? apiSwaggerMethod.tags[0] : 'default',
|
|
88
90
|
};
|
|
89
91
|
this._apis.push(apiDto);
|
|
90
92
|
}
|
|
@@ -149,6 +151,7 @@ export class Generator {
|
|
|
149
151
|
|
|
150
152
|
// console.debug(`\tModel - ${modelName}`);
|
|
151
153
|
this._models.push({
|
|
154
|
+
typeName: modelName,
|
|
152
155
|
modelType: swaggerComponent.type == 'integer' ? 'enum' : 'class',
|
|
153
156
|
name: modelName,
|
|
154
157
|
properties: (swaggerComponent.type == 'object') ? this.retrieveComponentProperties(swaggerComponent) : [],
|
|
@@ -164,6 +167,7 @@ export class Generator {
|
|
|
164
167
|
const swaggerMethodInfo = swaggerMethod[method];
|
|
165
168
|
|
|
166
169
|
this._models.push({
|
|
170
|
+
typeName: this.getApiNameNormalized(apiName),
|
|
167
171
|
modelType: 'class',
|
|
168
172
|
name: this.getApiNameNormalized(apiName),
|
|
169
173
|
properties: this.retrieveComponentProperties(swaggerMethodInfo.requestBody.content[contentTypeMultipartFormData].schema),
|
|
@@ -175,15 +179,18 @@ export class Generator {
|
|
|
175
179
|
generateApi() {
|
|
176
180
|
this._barApis.update(this._apis.length, { message: `Api generating...` });
|
|
177
181
|
|
|
178
|
-
if (this.
|
|
179
|
-
const apiWriter = new ApiAngularWriter(this.
|
|
182
|
+
if (this._commandLineArgs.target == TargetGeneration.Angular) {
|
|
183
|
+
const apiWriter = new ApiAngularWriter(this._commandLineArgs.outputDirectory);
|
|
180
184
|
apiWriter.write(this._apis);
|
|
181
|
-
} else if (this.
|
|
182
|
-
const apiWriter = new ApiNextJsWriter(this.
|
|
185
|
+
} else if (this._commandLineArgs.target == TargetGeneration.Next) {
|
|
186
|
+
const apiWriter = new ApiNextJsWriter(this._commandLineArgs.outputDirectory);
|
|
183
187
|
apiWriter.write(this._apis);
|
|
188
|
+
} else if (this._commandLineArgs.target == TargetGeneration.Dart) {
|
|
189
|
+
const apiWriter = new ApiDartWriter(this._commandLineArgs);
|
|
190
|
+
apiWriter.write(this._apis, this._models);
|
|
184
191
|
}
|
|
185
192
|
|
|
186
|
-
this._barApis.update(this._apis.length, { message: `Api
|
|
193
|
+
this._barApis.update(this._apis.length, { message: `Api was generated successfully` });
|
|
187
194
|
|
|
188
195
|
this._barApis.stop();
|
|
189
196
|
}
|
|
@@ -192,15 +199,18 @@ export class Generator {
|
|
|
192
199
|
generateModel() {
|
|
193
200
|
this._barModels.update(this._apis.length, { message: `Model generation...` });
|
|
194
201
|
|
|
195
|
-
if (this.
|
|
196
|
-
const apiWriter = new ModelAngularWriter(this.
|
|
202
|
+
if (this._commandLineArgs.target == TargetGeneration.Angular) {
|
|
203
|
+
const apiWriter = new ModelAngularWriter(this._commandLineArgs.outputDirectory);
|
|
197
204
|
apiWriter.write(this._models);
|
|
198
|
-
} else if (this.
|
|
199
|
-
const apiWriter = new ModelNextJsWriter(this.
|
|
205
|
+
} else if (this._commandLineArgs.target == TargetGeneration.Next) {
|
|
206
|
+
const apiWriter = new ModelNextJsWriter(this._commandLineArgs.outputDirectory);
|
|
207
|
+
apiWriter.write(this._models);
|
|
208
|
+
} else if (this._commandLineArgs.target == TargetGeneration.Dart) {
|
|
209
|
+
const apiWriter = new ModelDartWriter(this._commandLineArgs);
|
|
200
210
|
apiWriter.write(this._models);
|
|
201
211
|
}
|
|
202
212
|
|
|
203
|
-
this._barModels.update(this._apis.length, { message: `Model generated` });
|
|
213
|
+
this._barModels.update(this._apis.length, { message: `Model was generated successfully` });
|
|
204
214
|
|
|
205
215
|
this._barModels.stop();
|
|
206
216
|
}
|
|
@@ -226,9 +236,10 @@ export class Generator {
|
|
|
226
236
|
});
|
|
227
237
|
} else {
|
|
228
238
|
if (swaggerMethod.requestBody != null) {
|
|
239
|
+
const type = this.retrieveType(swaggerMethod.requestBody.content[contentTypeApplicationJson].schema);
|
|
229
240
|
parameters.push({
|
|
230
241
|
name: 'request',
|
|
231
|
-
typeName: swaggerMethod.requestBody.content[contentTypeApplicationJson].schema.$ref.replace('#/components/schemas/', ''),
|
|
242
|
+
typeName: type.typeName, //swaggerMethod.requestBody.content[contentTypeApplicationJson].schema.$ref.replace('#/components/schemas/', ''),
|
|
232
243
|
nullable: false,
|
|
233
244
|
isQuery: false,
|
|
234
245
|
isEnum: false,
|
|
@@ -240,9 +251,10 @@ export class Generator {
|
|
|
240
251
|
} else {
|
|
241
252
|
swaggerMethod.parameters?.filter(x => x.in == 'query').forEach(parameter => {
|
|
242
253
|
if (parameter.schema.$ref != null) {
|
|
254
|
+
const type = this.retrieveType(parameter.schema);
|
|
243
255
|
parameters.push({
|
|
244
256
|
name: this.toFirstLetterLowercase(parameter.name),
|
|
245
|
-
typeName: parameter.schema.$ref.replace('#/components/schemas/', ''),
|
|
257
|
+
typeName: type.typeName, //parameter.schema.$ref.replace('#/components/schemas/', ''),
|
|
246
258
|
nullable: !parameter.required,
|
|
247
259
|
swaggerParameter: parameter,
|
|
248
260
|
isQuery: true,
|
|
@@ -316,7 +328,7 @@ export class Generator {
|
|
|
316
328
|
if (swaggerContent.schema.type != null) {
|
|
317
329
|
let schema = swaggerContent.schema;
|
|
318
330
|
if (schema.type == 'array') {
|
|
319
|
-
if (schema.items
|
|
331
|
+
if (schema.items?.$ref != null) {
|
|
320
332
|
return <TypeDto>{
|
|
321
333
|
typeName: `${this.getObjectName(schema.items.$ref)}`,
|
|
322
334
|
nullable: false,
|
|
@@ -344,8 +356,8 @@ export class Generator {
|
|
|
344
356
|
}
|
|
345
357
|
}
|
|
346
358
|
|
|
347
|
-
retrieveType(swaggerComponentProperty:
|
|
348
|
-
if (swaggerComponentProperty.$ref != null)
|
|
359
|
+
retrieveType(swaggerComponentProperty: SwaggerSchema): TypeDto {
|
|
360
|
+
if (swaggerComponentProperty.$ref != null) {
|
|
349
361
|
return {
|
|
350
362
|
typeName: swaggerComponentProperty.$ref.replace('#/components/schemas/', ''),
|
|
351
363
|
isTypeReference: true,
|
|
@@ -354,9 +366,18 @@ export class Generator {
|
|
|
354
366
|
isArray: false,
|
|
355
367
|
isVoid: false,
|
|
356
368
|
};
|
|
369
|
+
}
|
|
357
370
|
|
|
358
|
-
if (swaggerComponentProperty.
|
|
359
|
-
|
|
371
|
+
if (swaggerComponentProperty.allOf != null) {
|
|
372
|
+
const type = this.retrieveType(swaggerComponentProperty.allOf[0]); //TODO per ora prendo solo il primo, ma potrebbe essere un array di tipi
|
|
373
|
+
return {
|
|
374
|
+
...type,
|
|
375
|
+
nullable: swaggerComponentProperty.nullable ?? false,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (swaggerComponentProperty.type != null && swaggerComponentProperty.type == 'array') {
|
|
380
|
+
if (swaggerComponentProperty.items?.$ref != null) {
|
|
360
381
|
return {
|
|
361
382
|
typeName: `${this.getObjectName(swaggerComponentProperty.items.$ref)}`,
|
|
362
383
|
isTypeReference: true,
|
|
@@ -365,7 +386,8 @@ export class Generator {
|
|
|
365
386
|
isArray: true,
|
|
366
387
|
isVoid: false,
|
|
367
388
|
};
|
|
368
|
-
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
369
391
|
return {
|
|
370
392
|
typeName: this.getNativeType(swaggerComponentProperty),
|
|
371
393
|
isTypeReference: false,
|
|
@@ -374,8 +396,10 @@ export class Generator {
|
|
|
374
396
|
isArray: false,
|
|
375
397
|
isVoid: false,
|
|
376
398
|
};
|
|
399
|
+
}
|
|
400
|
+
}
|
|
377
401
|
|
|
378
|
-
if (swaggerComponentProperty.type != null)
|
|
402
|
+
if (swaggerComponentProperty.type != null) {
|
|
379
403
|
return {
|
|
380
404
|
typeName: this.getNativeType(swaggerComponentProperty),
|
|
381
405
|
isTypeReference: false,
|
|
@@ -384,8 +408,8 @@ export class Generator {
|
|
|
384
408
|
isArray: false,
|
|
385
409
|
isVoid: false,
|
|
386
410
|
};
|
|
387
|
-
|
|
388
|
-
if (swaggerComponentProperty.type == null)
|
|
411
|
+
}
|
|
412
|
+
if (swaggerComponentProperty.type == null) {
|
|
389
413
|
return {
|
|
390
414
|
typeName: 'void',
|
|
391
415
|
isTypeReference: false,
|
|
@@ -394,7 +418,7 @@ export class Generator {
|
|
|
394
418
|
isArray: false,
|
|
395
419
|
isVoid: true,
|
|
396
420
|
};
|
|
397
|
-
|
|
421
|
+
}
|
|
398
422
|
console.error("unmanaged swaggerMethodInfo", swaggerComponentProperty);
|
|
399
423
|
throw new Error("unmanaged swaggerMethodInfo");
|
|
400
424
|
}
|
|
@@ -428,6 +452,7 @@ export class Generator {
|
|
|
428
452
|
let properties: PropertyDto[] = [];
|
|
429
453
|
for (let index = 0; index < Object.getOwnPropertyNames(swaggerCopmponent.properties).length; index++) {
|
|
430
454
|
const propertyName = Object.getOwnPropertyNames(swaggerCopmponent.properties)[index];
|
|
455
|
+
|
|
431
456
|
const type = this.retrieveType(swaggerCopmponent.properties[propertyName]);
|
|
432
457
|
properties.push({
|
|
433
458
|
...type,
|
|
@@ -483,10 +508,14 @@ export class Generator {
|
|
|
483
508
|
|
|
484
509
|
let nestedUsedType = '';
|
|
485
510
|
|
|
486
|
-
if (swaggerComponent.properties[propertyName]
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
nestedUsedType = swaggerComponent.properties[propertyName]
|
|
511
|
+
if (!swaggerComponent.properties[propertyName]) continue;
|
|
512
|
+
|
|
513
|
+
if (swaggerComponent.properties[propertyName].$ref) {
|
|
514
|
+
nestedUsedType = swaggerComponent.properties[propertyName].$ref!.replace('#/components/schemas/', '');
|
|
515
|
+
}else if (swaggerComponent.properties[propertyName].allOf && swaggerComponent.properties[propertyName].allOf![0] && swaggerComponent.properties[propertyName].allOf![0]!.$ref) {
|
|
516
|
+
nestedUsedType = swaggerComponent.properties[propertyName].allOf![0]!.$ref!.replace('#/components/schemas/', ''); //TODO Assuming allOf contains a single $ref
|
|
517
|
+
} else if (swaggerComponent.properties[propertyName].type == 'array' && swaggerComponent.properties[propertyName].items?.$ref) {
|
|
518
|
+
nestedUsedType = swaggerComponent.properties[propertyName].items!.$ref!.replace('#/components/schemas/', '');
|
|
490
519
|
}
|
|
491
520
|
|
|
492
521
|
if (nestedUsedType != '' && usedTypes.findIndex(x => x.typeName == nestedUsedType) == -1) {
|
|
@@ -513,13 +542,13 @@ export class Generator {
|
|
|
513
542
|
|
|
514
543
|
if (schema.$ref != null) {
|
|
515
544
|
debugger
|
|
516
|
-
} else if (schema.type == 'array') {
|
|
545
|
+
} else if (schema.type == 'array' && schema.items != null) {
|
|
517
546
|
nativeType = this.getNativeType(schema.items);
|
|
518
547
|
nativeType += '[]';
|
|
519
548
|
} else {
|
|
520
549
|
if (schema.type == 'integer') nativeType = 'number';
|
|
521
550
|
if (schema.type == 'string' && schema.format == null) nativeType = 'string';
|
|
522
|
-
if (schema.type == 'string' && schema.format == 'date-time') nativeType = this.
|
|
551
|
+
if (schema.type == 'string' && schema.format == 'date-time') nativeType = this._commandLineArgs.dateTimeLibrary == DateTimeLibrary.Moment ? 'moment.Moment' : 'Date';
|
|
523
552
|
if (schema.type == 'string' && schema.format == 'uuid') nativeType = 'string';
|
|
524
553
|
if (schema.type == 'string' && schema.format == 'binary') nativeType = 'File';
|
|
525
554
|
if (schema.type == 'number') nativeType = 'number';
|
|
@@ -24,7 +24,7 @@ export class ApiAngularWriter {
|
|
|
24
24
|
|
|
25
25
|
private _apiString(api: ApiDto) {
|
|
26
26
|
|
|
27
|
-
let apiNameNormalized = Utils.
|
|
27
|
+
let apiNameNormalized = Utils.getNormalizedApiPath(api.name);
|
|
28
28
|
let parametersString = this._parameters(api);
|
|
29
29
|
let queryParametersPreparation = this._queryParametersPreparation(api);
|
|
30
30
|
let requestPreparation = this._requestPreparation(api);
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import fs, { writeFileSync } from 'fs';
|
|
2
|
+
import { ApiDto } from '@src/models/api-dto.js';
|
|
3
|
+
import { Utils } from '../utils.js';
|
|
4
|
+
import { ParameterDto } from '@src/models/parameter-dto.js';
|
|
5
|
+
import * as Mustache from 'mustache';
|
|
6
|
+
import { CommandLineArgs } from '@src/index.js';
|
|
7
|
+
import { ModelDto } from '@src/models/model-dto.js';
|
|
8
|
+
import { TypeDto } from '@src/models/type-dto.js';
|
|
9
|
+
import { ImportDefinitionDart } from './models/import-definition-dart.js';
|
|
10
|
+
import { Normalizator } from './normalizator.js';
|
|
11
|
+
|
|
12
|
+
interface ApiDefinitionDart {
|
|
13
|
+
package: string;
|
|
14
|
+
outputDirectory: string;
|
|
15
|
+
filename: string;
|
|
16
|
+
apiClassName: string;
|
|
17
|
+
imports: string[];
|
|
18
|
+
endpoints: EndpointDefinitionDart[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface EndpointDefinitionDart {
|
|
22
|
+
methodName: string;
|
|
23
|
+
httpMethod: HttpMethodDart;
|
|
24
|
+
path: string;
|
|
25
|
+
responseType: string;
|
|
26
|
+
haveRequest?: boolean;
|
|
27
|
+
requestType?: string; // solo se haveRequest è true
|
|
28
|
+
isGet?: boolean; // per indicare se è un metodo GET
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type HttpMethodDart = 'get' | 'post' | 'put' | 'delete' | 'patch';
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
export class ApiDartWriter {
|
|
35
|
+
private _commandLineArgs: CommandLineArgs;
|
|
36
|
+
|
|
37
|
+
constructor(commandLineArgs: CommandLineArgs) {
|
|
38
|
+
this._commandLineArgs = commandLineArgs;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
write(apis: ApiDto[], models: ModelDto[]) {
|
|
42
|
+
|
|
43
|
+
const template = fs.readFileSync('src/generators-writers/dart/templates/api.mustache', 'utf-8');
|
|
44
|
+
|
|
45
|
+
const grouped = this._groupByTag(apis);
|
|
46
|
+
|
|
47
|
+
for (const [tag, apis] of Object.entries(grouped)) {
|
|
48
|
+
console.log(`Api: ${tag}`);
|
|
49
|
+
|
|
50
|
+
let subPath = '';
|
|
51
|
+
let filename = '';
|
|
52
|
+
let apiClassName = '';
|
|
53
|
+
|
|
54
|
+
subPath = Utils.toDartFileName(tag);
|
|
55
|
+
filename = `${Utils.toDartFileName(tag + 'Api')}`;
|
|
56
|
+
apiClassName = `${Utils.toDartClassName(tag + 'Api')}`;
|
|
57
|
+
|
|
58
|
+
var apiDefinition = <ApiDefinitionDart>{
|
|
59
|
+
package: this._commandLineArgs.package,
|
|
60
|
+
outputDirectory: this._commandLineArgs.outputDirectory,
|
|
61
|
+
filename: filename,
|
|
62
|
+
apiClassName: apiClassName,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
var endpoints = <EndpointDefinitionDart[]>[];
|
|
66
|
+
var imports = <ImportDefinitionDart[]>[];
|
|
67
|
+
|
|
68
|
+
for (const api of apis) {
|
|
69
|
+
var requestType: string | undefined = undefined;
|
|
70
|
+
requestType = api.haveRequest ? api.parameters[0]?.typeName || 'void' : undefined;
|
|
71
|
+
requestType = requestType?.split('.').pop()!
|
|
72
|
+
requestType = Utils.toDartClassName(requestType);
|
|
73
|
+
|
|
74
|
+
var responseType: string = 'void';
|
|
75
|
+
responseType = api.returnType ? api.returnType.typeName : 'void';
|
|
76
|
+
responseType = responseType?.split('.').pop()!;
|
|
77
|
+
responseType = Utils.toDartClassName(responseType) ?? responseType;
|
|
78
|
+
|
|
79
|
+
var methodName = Utils.getNormalizedApiPath(api.name);
|
|
80
|
+
if (methodName.startsWith(Utils.toFirstLetterLowercase(tag))) {
|
|
81
|
+
methodName = methodName.slice(tag.length);
|
|
82
|
+
methodName = Utils.toFirstLetterLowercase(methodName);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const endpoint = <EndpointDefinitionDart>{
|
|
86
|
+
methodName: methodName,
|
|
87
|
+
httpMethod: api.method.toLowerCase() as HttpMethodDart,
|
|
88
|
+
path: api.url,
|
|
89
|
+
responseType: responseType,
|
|
90
|
+
haveRequest: api.haveRequest,
|
|
91
|
+
requestType: requestType,
|
|
92
|
+
isGet: api.method.toLowerCase() === 'get'
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
if (api.haveRequest && api.parameters[0]?.typeName) {
|
|
96
|
+
if (imports.findIndex(x => x.type.typeName == api.parameters[0]?.typeName) == -1) {
|
|
97
|
+
models.forEach(model => {
|
|
98
|
+
if (model.typeName === api.parameters[0]?.typeName) {
|
|
99
|
+
const normalizedInfo = Normalizator.getNormalizedInfo(model);
|
|
100
|
+
imports.push({
|
|
101
|
+
type: api.parameters[0],
|
|
102
|
+
import: `import 'package:${this._commandLineArgs.package}/${this._commandLineArgs.outputDirectory}/${normalizedInfo.subPath}/${normalizedInfo.filename}.dart';`
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (api.returnType && !api.returnType.isNativeType) {
|
|
110
|
+
if (imports.findIndex(x => x.type.typeName == api.returnType!.typeName) == -1) {
|
|
111
|
+
models.forEach(model => {
|
|
112
|
+
if (model.typeName === api.returnType!.typeName) {
|
|
113
|
+
const normalizedInfo = Normalizator.getNormalizedInfo(model);
|
|
114
|
+
imports.push({
|
|
115
|
+
type: api.returnType!,
|
|
116
|
+
import: `import 'package:${this._commandLineArgs.package}/${this._commandLineArgs.outputDirectory}/${normalizedInfo.subPath}/${normalizedInfo.filename}.dart';`
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
endpoints.push(endpoint);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
apiDefinition.endpoints = endpoints;
|
|
127
|
+
apiDefinition.imports = imports.map(i => i.import);
|
|
128
|
+
|
|
129
|
+
let destinationPath = `${this._commandLineArgs.outputDirectory}/${subPath}/api`;
|
|
130
|
+
|
|
131
|
+
Utils.ensureDirectorySync(`${destinationPath}`);
|
|
132
|
+
|
|
133
|
+
var result = Mustache.default.render(template, apiDefinition);
|
|
134
|
+
writeFileSync(`${destinationPath}/${apiDefinition.filename}.dart`, result, 'utf-8');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private _toPascalCase(input: string): string {
|
|
139
|
+
return input
|
|
140
|
+
.replace(/[_\- ]+/g, ' ') // sostituisce underscore, dash e spazi con uno spazio singolo
|
|
141
|
+
.trim() // rimuove spazi iniziali/finali
|
|
142
|
+
.split(' ') // divide in parole
|
|
143
|
+
.map(word =>
|
|
144
|
+
word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
|
|
145
|
+
)
|
|
146
|
+
.join('');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private _normalizeApiClassName(input: string): string {
|
|
150
|
+
return input
|
|
151
|
+
.replace(/\./g, '');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private _groupByTag(apis: ApiDto[]) {
|
|
155
|
+
const groupedByRole = apis.reduce<Record<string, ApiDto[]>>((acc, api) => {
|
|
156
|
+
if (!acc[api.tag]) {
|
|
157
|
+
acc[api.tag] = [];
|
|
158
|
+
}
|
|
159
|
+
acc[api.tag].push(api);
|
|
160
|
+
return acc;
|
|
161
|
+
}, {});
|
|
162
|
+
return groupedByRole;
|
|
163
|
+
}
|
|
164
|
+
}
|