@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.
Files changed (52) hide show
  1. package/.vscode/launch.json +6 -0
  2. package/README.md +4 -2
  3. package/autogen/identity/api/identity_api.dart +82 -0
  4. package/autogen/identity/models/auth_activate_command.dart +14 -0
  5. package/autogen/identity/models/auth_app_authenticate_command.dart +16 -0
  6. package/autogen/identity/models/auth_generate_reset_password_code_command.dart +15 -0
  7. package/autogen/identity/models/auth_refresh_token_command.dart +15 -0
  8. package/autogen/identity/models/auth_reset_password_command.dart +16 -0
  9. package/autogen/identity/models/auth_user_authenticate_command.dart +15 -0
  10. package/autogen/identity/models/auth_user_dto.dart +18 -0
  11. package/autogen/identity/models/auth_verify_reset_password_code_command.dart +14 -0
  12. package/autogen/identity/models/authentication_token.dart +17 -0
  13. package/autogen/mvc/models/problem_details.dart +17 -0
  14. package/autogen/service_defaults/models/application_exception.dart +14 -0
  15. package/autogen/service_defaults/models/result.dart +17 -0
  16. package/autogen/user_profile/api/user_profile_api.dart +46 -0
  17. package/autogen/user_profile/models/test_list_query.dart +13 -0
  18. package/autogen/user_profile/models/test_read_query.dart +13 -0
  19. package/autogen/user_profile/models/test_save_command.dart +13 -0
  20. package/autogen/user_profile/models/user_general_info_save_command.dart +13 -0
  21. package/dist/generator.js +63 -31
  22. package/dist/generators-writers/angular/api-angular-writer.js +1 -1
  23. package/dist/generators-writers/dart/api-dart-writer.js +110 -0
  24. package/dist/generators-writers/dart/model-dart-writer.js +124 -0
  25. package/dist/generators-writers/dart/models/import-definition-dart.js +1 -0
  26. package/dist/generators-writers/dart/normalizator.js +35 -0
  27. package/dist/generators-writers/nextjs/api-nextjs-writer.js +1 -1
  28. package/dist/generators-writers/utils.js +43 -2
  29. package/dist/index.js +72 -16
  30. package/dist/models/swagger/swagger-component-property.js +10 -0
  31. package/dist/models/swagger/swagger-component.js +1 -0
  32. package/dist/models/swagger/swagger-schema.js +1 -0
  33. package/package.json +11 -5
  34. package/src/generator.ts +67 -38
  35. package/src/generators-writers/angular/api-angular-writer.ts +1 -1
  36. package/src/generators-writers/dart/api-dart-writer.ts +164 -0
  37. package/src/generators-writers/dart/model-dart-writer.ts +176 -0
  38. package/src/generators-writers/dart/models/import-definition-dart.ts +6 -0
  39. package/src/generators-writers/dart/normalizator.ts +44 -0
  40. package/src/generators-writers/dart/templates/api.mustache +29 -0
  41. package/src/generators-writers/dart/templates/model.mustache +18 -0
  42. package/src/generators-writers/nextjs/api-nextjs-writer.ts +1 -1
  43. package/src/generators-writers/utils.ts +54 -2
  44. package/src/index.ts +80 -16
  45. package/src/models/api-dto.ts +1 -0
  46. package/src/models/model-dto.ts +1 -0
  47. package/src/models/swagger/swagger-component-property.ts +10 -9
  48. package/src/models/swagger/swagger-component.ts +11 -2
  49. package/src/models/swagger/swagger-schema.ts +18 -6
  50. package/src/models/swagger/swagger.ts +1 -0
  51. package/autogeneration/output/api.autogenerated.ts +0 -95
  52. 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 args = process.argv.slice(2);
5
- if (args.length !== 4) {
6
- console.log("Warning: Requires 3 arguments");
7
- console.log("node index.js [swaggerJsonUrl] [outputDirectory] [angular|next] [moment|date-fns]");
8
- process.exit();
9
- }
10
- const swaggerJsonUrl = args[0];
11
- const outputDirectory = args[1];
12
- const outputFormat = args[2] == 'next' ? 'next' : 'angular';
13
- const dateLib = args[3] == 'moment' ? 'moment' : 'date-fns';
14
- //const excludedModels = ['Type', 'MethodBase', 'Assembly', 'MethodInfo']
15
- // const apiUrl = args[0]//"http://localhost:5208";
16
- // const version = args[1]; //"1";
17
- // const swaggerJsonUrl = `${apiUrl}/swagger/v${version}/swagger.json`;
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, outputDirectory, outputFormat, dateLib);
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
+ // }
@@ -1 +1,2 @@
1
+ // import { SwaggerComponentProperty } from "./swagger-component-property.js";
1
2
  export {};
@@ -1 +1,2 @@
1
+ // import { SwaggerComponentProperty } from "./swagger-component-property.js";
1
2
  export {};
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@devlearning/swagger-generator",
3
- "version": "1.0.11",
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
- "dev": "ts-node --esm ./src/index.ts http://localhost:7550/swagger/ApiGateway/swagger.json autogeneration/output",
9
- "debug-angular": "npx tsx src/index.ts http://localhost:7550/swagger/ApiGateway/swagger.json autogeneration/output angular moment",
10
- "debug-nextjs": "npx tsx src/index.ts http://localhost:7550/swagger/ApiGateway/swagger.json autogeneration/output next date-fns",
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
- "node-fetch": "^3.3.2"
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 _outputDirectory: string;
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, outputDirectory: string, outputFormat: 'angular' | 'next', dateLibrary: 'moment' | 'date-fns') {
49
+ constructor(swagger: Swagger, commandLineArgs: CommandLineArgs) {
49
50
  this._swagger = swagger;
50
- this._outputDirectory = outputDirectory;
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.computeApi();
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._outputFormat == 'angular') {
179
- const apiWriter = new ApiAngularWriter(this._outputDirectory);
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._outputFormat == 'next') {
182
- const apiWriter = new ApiNextJsWriter(this._outputDirectory);
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 gerated` });
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._outputFormat == 'angular') {
196
- const apiWriter = new ModelAngularWriter(this._outputDirectory);
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._outputFormat == 'next') {
199
- const apiWriter = new ModelNextJsWriter(this._outputDirectory);
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.$ref != null) {
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: SwaggerComponentProperty): TypeDto {
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.type != null && swaggerComponentProperty.type == 'array')
359
- if (swaggerComponentProperty.items.$ref != null)
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
- else
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].$ref != null) {
487
- nestedUsedType = swaggerComponent.properties[propertyName].$ref.replace('#/components/schemas/', '');
488
- } else if (swaggerComponent.properties[propertyName].type == 'array' && swaggerComponent.properties[propertyName].items.$ref != null) {
489
- nestedUsedType = swaggerComponent.properties[propertyName].items.$ref.replace('#/components/schemas/', '');
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._dateLibrary == 'moment' ? 'moment.Moment' : 'Date';
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.getApiNameNormalized(api.name);
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
+ }