swagger-typescript-api 12.0.4 → 13.0.0

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 (75) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1 -1
  3. package/cli/constants.js +3 -3
  4. package/cli/execute.js +52 -31
  5. package/cli/index.d.ts +1 -2
  6. package/cli/index.js +18 -17
  7. package/cli/operations/display-help.js +51 -29
  8. package/cli/parse-args.js +3 -3
  9. package/cli/process-option.js +28 -20
  10. package/index.d.ts +99 -7
  11. package/index.js +158 -136
  12. package/package.json +35 -30
  13. package/src/code-formatter.js +28 -13
  14. package/src/code-gen-process.js +367 -264
  15. package/src/commands/generate-templates/configuration.js +2 -2
  16. package/src/commands/generate-templates/index.js +1 -2
  17. package/src/commands/generate-templates/templates-gen-process.js +62 -35
  18. package/src/component-type-name-resolver.js +44 -0
  19. package/src/configuration.js +166 -98
  20. package/src/constants.js +28 -22
  21. package/src/index.js +3 -4
  22. package/src/schema-components-map.js +39 -23
  23. package/src/schema-parser/base-schema-parsers/array.js +43 -0
  24. package/src/schema-parser/base-schema-parsers/complex.js +51 -0
  25. package/src/schema-parser/base-schema-parsers/discriminator.js +301 -0
  26. package/src/schema-parser/base-schema-parsers/enum.js +158 -0
  27. package/src/schema-parser/base-schema-parsers/object.js +105 -0
  28. package/src/schema-parser/base-schema-parsers/primitive.js +63 -0
  29. package/src/schema-parser/complex-schema-parsers/all-of.js +26 -0
  30. package/src/schema-parser/complex-schema-parsers/any-of.js +34 -0
  31. package/src/schema-parser/complex-schema-parsers/not.js +9 -0
  32. package/src/schema-parser/complex-schema-parsers/one-of.js +27 -0
  33. package/src/schema-parser/mono-schema-parser.js +48 -0
  34. package/src/schema-parser/schema-formatters.js +58 -44
  35. package/src/schema-parser/schema-parser-fabric.js +131 -0
  36. package/src/schema-parser/schema-parser.js +212 -361
  37. package/src/schema-parser/schema-utils.js +158 -33
  38. package/src/schema-parser/util/enum-key-resolver.js +26 -0
  39. package/src/{schema-parser → schema-routes}/schema-routes.js +472 -203
  40. package/src/schema-routes/util/specific-arg-name-resolver.js +26 -0
  41. package/src/schema-walker.js +93 -0
  42. package/src/swagger-schema-resolver.js +61 -28
  43. package/src/templates-worker.js +240 -0
  44. package/src/translators/javascript.js +83 -0
  45. package/src/translators/translator.js +35 -0
  46. package/src/{type-name.js → type-name-formatter.js} +35 -20
  47. package/src/util/file-system.js +30 -14
  48. package/src/util/id.js +2 -2
  49. package/src/util/internal-case.js +1 -1
  50. package/src/util/logger.js +46 -20
  51. package/src/util/name-resolver.js +50 -58
  52. package/src/util/object-assign.js +7 -3
  53. package/src/util/pascal-case.js +1 -1
  54. package/src/util/request.js +5 -5
  55. package/src/util/sort-by-property.js +17 -0
  56. package/templates/base/data-contract-jsdoc.ejs +37 -37
  57. package/templates/base/data-contracts.ejs +40 -28
  58. package/templates/base/enum-data-contract.ejs +12 -12
  59. package/templates/base/http-client.ejs +2 -2
  60. package/templates/base/http-clients/axios-http-client.ejs +139 -138
  61. package/templates/base/http-clients/fetch-http-client.ejs +224 -224
  62. package/templates/base/interface-data-contract.ejs +10 -10
  63. package/templates/base/object-field-jsdoc.ejs +28 -28
  64. package/templates/base/route-docs.ejs +30 -30
  65. package/templates/base/route-name.ejs +42 -42
  66. package/templates/base/route-type.ejs +22 -21
  67. package/templates/base/type-data-contract.ejs +15 -15
  68. package/templates/default/api.ejs +69 -65
  69. package/templates/default/procedure-call.ejs +100 -100
  70. package/templates/default/route-types.ejs +32 -28
  71. package/templates/modular/api.ejs +28 -28
  72. package/templates/modular/procedure-call.ejs +100 -100
  73. package/templates/modular/route-types.ejs +18 -18
  74. package/src/templates.js +0 -177
  75. package/src/translators/JavaScript.js +0 -60
@@ -1,32 +1,34 @@
1
- const { objectAssign } = require("./util/object-assign");
2
- const _ = require("lodash");
3
- const CONSTANTS = require("./constants");
4
- const { ComponentTypeNameResolver } = require("./util/name-resolver");
5
- const { cosmiconfigSync } = require("cosmiconfig");
1
+ /* eslint-disable no-unused-vars */
2
+ const { objectAssign } = require('./util/object-assign');
3
+ const _ = require('lodash');
4
+ const CONSTANTS = require('./constants');
5
+ const { ComponentTypeNameResolver } = require('./component-type-name-resolver');
6
+ const { cosmiconfigSync } = require('cosmiconfig');
7
+ const ts = require('typescript');
6
8
 
7
9
  const TsKeyword = {
8
- Number: "number",
9
- String: "string",
10
- Boolean: "boolean",
11
- Any: "any",
12
- Void: "void",
13
- Unknown: "unknown",
14
- Null: "null",
15
- Undefined: "undefined",
16
- Object: "object",
17
- File: "File",
18
- Date: "Date",
19
- Type: "type",
20
- Enum: "enum",
21
- Interface: "interface",
22
- Array: "Array",
23
- Record: "Record",
24
- Intersection: "&",
25
- Union: "|",
10
+ Number: 'number',
11
+ String: 'string',
12
+ Boolean: 'boolean',
13
+ Any: 'any',
14
+ Void: 'void',
15
+ Unknown: 'unknown',
16
+ Null: 'null',
17
+ Undefined: 'undefined',
18
+ Object: 'object',
19
+ File: 'File',
20
+ Date: 'Date',
21
+ Type: 'type',
22
+ Enum: 'enum',
23
+ Interface: 'interface',
24
+ Array: 'Array',
25
+ Record: 'Record',
26
+ Intersection: '&',
27
+ Union: '|',
26
28
  };
27
29
 
28
30
  const TsCodeGenKeyword = {
29
- UtilRequiredKeys: "UtilRequiredKeys",
31
+ UtilRequiredKeys: 'UtilRequiredKeys',
30
32
  };
31
33
 
32
34
  /**
@@ -35,7 +37,7 @@ const TsCodeGenKeyword = {
35
37
  class CodeGenConfig {
36
38
  version = CONSTANTS.PROJECT_VERSION;
37
39
  /** CLI flag */
38
- templates = "../templates/default";
40
+ templates = '';
39
41
  /** CLI flag */
40
42
  generateResponses = false;
41
43
  /** CLI flag */
@@ -74,10 +76,10 @@ class CodeGenConfig {
74
76
  extractResponseError = false;
75
77
  extractEnums = false;
76
78
  fileNames = {
77
- dataContracts: "data-contracts",
78
- routeTypes: "route-types",
79
- httpClient: "http-client",
80
- outOfModuleApi: "Common",
79
+ dataContracts: 'data-contracts',
80
+ routeTypes: 'route-types',
81
+ httpClient: 'http-client',
82
+ outOfModuleApi: 'Common',
81
83
  };
82
84
  routeNameDuplicatesMap = new Map();
83
85
  prettierOptions = { ...CONSTANTS.PRETTIER_OPTIONS };
@@ -89,7 +91,7 @@ class CodeGenConfig {
89
91
  onPreParseSchema: (originalSchema, typeName, schemaType) => void 0,
90
92
  onParseSchema: (originalSchema, parsedSchema) => parsedSchema,
91
93
  onCreateRoute: (routeData) => routeData,
92
- onInit: (config) => config,
94
+ onInit: (config, codeGenProcess) => config,
93
95
  onPrepareConfig: (apiConfig) => apiConfig,
94
96
  onCreateRequestParams: (rawType) => {},
95
97
  onCreateRouteName: () => {},
@@ -102,72 +104,114 @@ class CodeGenConfig {
102
104
  unwrapResponseData = false;
103
105
  disableThrowOnError = false;
104
106
  sortTypes = false;
107
+ sortRoutes = false;
105
108
  templatePaths = {
106
109
  /** `templates/base` */
107
- base: "",
110
+ base: '',
108
111
  /** `templates/default` */
109
- default: "",
112
+ default: '',
110
113
  /** `templates/modular` */
111
- modular: "",
114
+ modular: '',
112
115
  /** usage path if `--templates` option is not set */
113
- original: "",
116
+ original: '',
114
117
  /** custom path to templates (`--templates`) */
115
- custom: "",
118
+ custom: '',
116
119
  };
117
120
  /** Record<templateName, templateContent> */
118
121
  templatesToRender = {
119
- api: "",
120
- dataContracts: "",
121
- dataContractJsDoc: "",
122
- interfaceDataContract: "",
123
- typeDataContract: "",
124
- enumDataContract: "",
125
- objectFieldJsDoc: "",
126
- httpClient: "",
127
- routeTypes: "",
128
- routeName: "",
122
+ api: '',
123
+ dataContracts: '',
124
+ dataContractJsDoc: '',
125
+ interfaceDataContract: '',
126
+ typeDataContract: '',
127
+ enumDataContract: '',
128
+ objectFieldJsDoc: '',
129
+ httpClient: '',
130
+ routeTypes: '',
131
+ routeName: '',
129
132
  };
133
+ /**
134
+ * @type {Record<string, (...args: any[]) => MonoSchemaParser>}
135
+ */
136
+ schemaParsers = {};
130
137
  toJS = false;
131
138
  silent = false;
132
- typePrefix = "";
133
- typeSuffix = "";
134
- enumKeyPrefix = "";
135
- enumKeySuffix = "";
139
+ typePrefix = '';
140
+ typeSuffix = '';
141
+ enumKeyPrefix = '';
142
+ enumKeySuffix = '';
136
143
  patch = false;
137
- componentTypeNameResolver = new ComponentTypeNameResolver(null, []);
144
+ /** @type {ComponentTypeNameResolver} */
145
+ componentTypeNameResolver;
138
146
  /** name of the main exported class */
139
- apiClassName = "Api";
147
+ apiClassName = 'Api';
140
148
  debug = false;
141
149
  anotherArrayType = false;
142
150
  internalTemplateOptions = {
143
151
  addUtilRequiredKeysType: false,
144
152
  };
145
153
  extraTemplates = [];
146
- input = "";
154
+ input = '';
147
155
  modular = false;
148
- output = "";
149
- url = "";
156
+ output = '';
157
+ url = '';
150
158
  cleanOutput = false;
151
159
  spec = null;
152
- fileName = "Api.ts";
160
+ fileName = 'Api.ts';
153
161
  authorizationToken = void 0;
154
162
  requestOptions = null;
155
163
 
156
164
  jsPrimitiveTypes = [];
157
165
  jsEmptyTypes = [];
158
- fixInvalidTypeNamePrefix = "Type";
159
- fixInvalidEnumKeyPrefix = "Value";
166
+ fixInvalidTypeNamePrefix = 'Type';
167
+ fixInvalidEnumKeyPrefix = 'Value';
168
+
169
+ enumKeyResolverName = 'Value';
170
+ typeNameResolverName = 'ComponentType';
171
+ specificArgNameResolverName = 'arg';
160
172
 
161
173
  successResponseStatusRange = [200, 299];
162
174
 
163
175
  /** @type {ExtractingOptions} */
164
176
  extractingOptions = {
165
- requestBodySuffix: ["Payload", "Body", "Input"],
166
- requestParamsSuffix: ["Params"],
167
- responseBodySuffix: ["Data", "Result", "Output"],
168
- responseErrorSuffix: ["Error", "Fail", "Fails", "ErrorData", "HttpError", "BadResponse"],
177
+ requestBodySuffix: ['Payload', 'Body', 'Input'],
178
+ requestParamsSuffix: ['Params'],
179
+ responseBodySuffix: ['Data', 'Result', 'Output'],
180
+ responseErrorSuffix: [
181
+ 'Error',
182
+ 'Fail',
183
+ 'Fails',
184
+ 'ErrorData',
185
+ 'HttpError',
186
+ 'BadResponse',
187
+ ],
188
+ enumSuffix: ['Enum'],
189
+ discriminatorMappingSuffix: ['Mapping', 'Mapper', 'MapType'],
190
+ discriminatorAbstractPrefix: [
191
+ 'Base',
192
+ 'Abstract',
193
+ 'Discriminator',
194
+ 'Internal',
195
+ 'Polymorph',
196
+ ],
169
197
  };
170
198
 
199
+ compilerTsConfig = {
200
+ module: 'ESNext',
201
+ noImplicitReturns: true,
202
+ alwaysStrict: true,
203
+ target: ts.ScriptTarget.ESNext,
204
+ declaration: true,
205
+ noImplicitAny: false,
206
+ sourceMap: false,
207
+ removeComments: false,
208
+ disableSizeLimit: true,
209
+ esModuleInterop: true,
210
+ emitDecoratorMetadata: true,
211
+ skipLibCheck: true,
212
+ };
213
+ customTranslator;
214
+
171
215
  Ts = {
172
216
  Keyword: _.cloneDeep(TsKeyword),
173
217
  CodeGenKeyword: _.cloneDeep(TsCodeGenKeyword),
@@ -200,28 +244,39 @@ class CodeGenConfig {
200
244
  /**
201
245
  * $A1 | $A2
202
246
  */
203
- UnionType: (contents) => _.join(_.uniq(contents), ` ${this.Ts.Keyword.Union} `),
247
+ UnionType: (contents) =>
248
+ _.join(_.uniq(contents), ` ${this.Ts.Keyword.Union} `),
204
249
  /**
205
250
  * ($A1)
206
251
  */
207
- ExpressionGroup: (content) => (content ? `(${content})` : ""),
252
+ ExpressionGroup: (content) => (content ? `(${content})` : ''),
208
253
  /**
209
254
  * $A1 & $A2
210
255
  */
211
- IntersectionType: (contents) => _.join(_.uniq(contents), ` ${this.Ts.Keyword.Intersection} `),
256
+ IntersectionType: (contents) =>
257
+ _.join(_.uniq(contents), ` ${this.Ts.Keyword.Intersection} `),
212
258
  /**
213
259
  * Record<$A1, $A2>
214
260
  */
215
- RecordType: (key, value) => this.Ts.TypeWithGeneric(this.Ts.Keyword.Record, [key, value]),
261
+ RecordType: (key, value) =>
262
+ this.Ts.TypeWithGeneric(this.Ts.Keyword.Record, [key, value]),
216
263
  /**
217
264
  * readonly $key?:$value
218
265
  */
219
266
  TypeField: ({ readonly, key, optional, value }) =>
220
- _.compact([readonly && "readonly ", key, optional && "?", ": ", value]).join(""),
267
+ _.compact([
268
+ readonly && 'readonly ',
269
+ key,
270
+ optional && '?',
271
+ ': ',
272
+ value,
273
+ ]).join(''),
221
274
  /**
222
275
  * [key: $A1]: $A2
223
276
  */
224
277
  InterfaceDynamicField: (key, value) => `[key: ${key}]: ${value}`,
278
+
279
+ EnumUsageKey: (enumStruct, key) => `${enumStruct}.${key}`,
225
280
  /**
226
281
  * $A1 = $A2
227
282
  */
@@ -232,7 +287,10 @@ class CodeGenConfig {
232
287
  * $AN.key = $AN.value,
233
288
  */
234
289
  EnumFieldsWrapper: (contents) =>
235
- _.map(contents, ({ key, value }) => ` ${this.Ts.EnumField(key, value)}`).join(",\n"),
290
+ _.map(
291
+ contents,
292
+ ({ key, value }) => ` ${this.Ts.EnumField(key, value)}`,
293
+ ).join(',\n'),
236
294
  /**
237
295
  * {\n $A \n}
238
296
  */
@@ -244,19 +302,21 @@ class CodeGenConfig {
244
302
  [
245
303
  ...(contents.length === 1
246
304
  ? [`/** ${contents[0]} */`]
247
- : ["/**", ...contents.map((content) => ` * ${content}`), " */"]),
305
+ : ['/**', ...contents.map((content) => ` * ${content}`), ' */']),
248
306
  ].map((part) => `${formatFn ? formatFn(part) : part}\n`),
249
307
  /**
250
308
  * $A1<...$A2.join(,)>
251
309
  */
252
310
  TypeWithGeneric: (typeName, genericArgs) => {
253
- return `${typeName}${genericArgs.length ? `<${genericArgs.join(",")}>` : ""}`;
311
+ return `${typeName}${
312
+ genericArgs.length ? `<${genericArgs.join(',')}>` : ''
313
+ }`;
254
314
  },
255
315
  /**
256
316
  * [$A1, $A2, ...$AN]
257
317
  */
258
318
  Tuple: (values) => {
259
- return `[${values.join(", ")}]`;
319
+ return `[${values.join(', ')}]`;
260
320
  },
261
321
  };
262
322
 
@@ -277,43 +337,39 @@ class CodeGenConfig {
277
337
  /** formats */
278
338
  binary: () => this.Ts.Keyword.File,
279
339
  file: () => this.Ts.Keyword.File,
280
- "date-time": () => this.Ts.Keyword.String,
340
+ 'date-time': () => this.Ts.Keyword.String,
281
341
  time: () => this.Ts.Keyword.String,
282
342
  date: () => this.Ts.Keyword.String,
283
343
  duration: () => this.Ts.Keyword.String,
284
344
  email: () => this.Ts.Keyword.String,
285
- "idn-email": () => this.Ts.Keyword.String,
286
- "idn-hostname": () => this.Ts.Keyword.String,
345
+ 'idn-email': () => this.Ts.Keyword.String,
346
+ 'idn-hostname': () => this.Ts.Keyword.String,
287
347
  ipv4: () => this.Ts.Keyword.String,
288
348
  ipv6: () => this.Ts.Keyword.String,
289
349
  uuid: () => this.Ts.Keyword.String,
290
350
  uri: () => this.Ts.Keyword.String,
291
- "uri-reference": () => this.Ts.Keyword.String,
292
- "uri-template": () => this.Ts.Keyword.String,
293
- "json-pointer": () => this.Ts.Keyword.String,
294
- "relative-json-pointer": () => this.Ts.Keyword.String,
351
+ 'uri-reference': () => this.Ts.Keyword.String,
352
+ 'uri-template': () => this.Ts.Keyword.String,
353
+ 'json-pointer': () => this.Ts.Keyword.String,
354
+ 'relative-json-pointer': () => this.Ts.Keyword.String,
295
355
  regex: () => this.Ts.Keyword.String,
296
356
  },
297
- array: ({ items, ...schemaPart }, parser) => {
298
- const content = parser.getInlineParseContent(items);
299
- return parser.schemaUtils.safeAddNullToType(schemaPart, this.Ts.ArrayType(content));
300
- },
301
357
  };
302
358
 
303
359
  templateInfos = [
304
- { name: "api", fileName: "api" },
305
- { name: "dataContracts", fileName: "data-contracts" },
306
- { name: "dataContractJsDoc", fileName: "data-contract-jsdoc" },
307
- { name: "interfaceDataContract", fileName: "interface-data-contract" },
308
- { name: "typeDataContract", fileName: "type-data-contract" },
309
- { name: "enumDataContract", fileName: "enum-data-contract" },
310
- { name: "objectFieldJsDoc", fileName: "object-field-jsdoc" },
311
- { name: "httpClient", fileName: "http-client" },
312
- { name: "routeTypes", fileName: "route-types" },
313
- { name: "routeName", fileName: "route-name" },
360
+ { name: 'api', fileName: 'api' },
361
+ { name: 'dataContracts', fileName: 'data-contracts' },
362
+ { name: 'dataContractJsDoc', fileName: 'data-contract-jsdoc' },
363
+ { name: 'interfaceDataContract', fileName: 'interface-data-contract' },
364
+ { name: 'typeDataContract', fileName: 'type-data-contract' },
365
+ { name: 'enumDataContract', fileName: 'enum-data-contract' },
366
+ { name: 'objectFieldJsDoc', fileName: 'object-field-jsdoc' },
367
+ { name: 'httpClient', fileName: 'http-client' },
368
+ { name: 'routeTypes', fileName: 'route-types' },
369
+ { name: 'routeName', fileName: 'route-name' },
314
370
  ];
315
371
 
316
- templateExtensions = [".eta", ".ejs"];
372
+ templateExtensions = ['.eta', '.ejs'];
317
373
 
318
374
  /**
319
375
  * @param config {Partial<GenerateApiConfiguration['config']>}
@@ -325,7 +381,7 @@ class CodeGenConfig {
325
381
  constants,
326
382
  templateInfos,
327
383
  hooks,
328
- ...params
384
+ ...otherConfig
329
385
  }) {
330
386
  objectAssign(this.Ts, codeGenConstructs);
331
387
  objectAssign(this.primitiveTypes, primitiveTypeConstructs);
@@ -333,8 +389,11 @@ class CodeGenConfig {
333
389
  this.defaultResponseType = this.Ts.Keyword.Void;
334
390
 
335
391
  this.update({
336
- ...params,
337
- prettierOptions: prettierOptions === undefined ? getDefaultPrettierOptions() : prettierOptions,
392
+ ...otherConfig,
393
+ prettierOptions:
394
+ prettierOptions === undefined
395
+ ? getDefaultPrettierOptions()
396
+ : prettierOptions,
338
397
  hooks: _.merge(this.hooks, hooks || {}),
339
398
  constants: {
340
399
  ...CONSTANTS,
@@ -343,8 +402,17 @@ class CodeGenConfig {
343
402
  templateInfos: templateInfos || this.templateInfos,
344
403
  });
345
404
 
346
- this.jsPrimitiveTypes = [this.Ts.Keyword.Number, this.Ts.Keyword.String, this.Ts.Keyword.Boolean];
405
+ this.jsPrimitiveTypes = [
406
+ this.Ts.Keyword.Number,
407
+ this.Ts.Keyword.String,
408
+ this.Ts.Keyword.Boolean,
409
+ ];
347
410
  this.jsEmptyTypes = [this.Ts.Keyword.Null, this.Ts.Keyword.Undefined];
411
+ this.componentTypeNameResolver = new ComponentTypeNameResolver(
412
+ this,
413
+ null,
414
+ [],
415
+ );
348
416
  }
349
417
 
350
418
  /**
@@ -357,12 +425,12 @@ class CodeGenConfig {
357
425
  }
358
426
 
359
427
  const getDefaultPrettierOptions = () => {
360
- const prettier = cosmiconfigSync("prettier").search();
428
+ const prettier = cosmiconfigSync('prettier').search();
361
429
 
362
430
  if (prettier) {
363
431
  return {
364
432
  ...prettier.config,
365
- parser: "typescript",
433
+ parser: 'typescript',
366
434
  };
367
435
  }
368
436
 
package/src/constants.js CHANGED
@@ -1,27 +1,33 @@
1
- const packageJson = require("../package.json");
2
- const RESERVED_QUERY_ARG_NAMES = ["query", "queryParams", "queryArg"];
3
- const RESERVED_BODY_ARG_NAMES = ["data", "body", "reqBody"];
4
- const RESERVED_REQ_PARAMS_ARG_NAMES = ["params", "requestParams", "reqParams", "httpParams"];
5
- const RESERVED_PATH_ARG_NAMES = ["path", "pathParams"];
6
- const RESERVED_HEADER_ARG_NAMES = ["headers", "headersParams"];
1
+ const packageJson = require('../package.json');
2
+ const RESERVED_QUERY_ARG_NAMES = ['query', 'queryParams', 'queryArg'];
3
+ const RESERVED_BODY_ARG_NAMES = ['data', 'body', 'reqBody'];
4
+ const RESERVED_REQ_PARAMS_ARG_NAMES = [
5
+ 'params',
6
+ 'requestParams',
7
+ 'reqParams',
8
+ 'httpParams',
9
+ ];
10
+ const RESERVED_PATH_ARG_NAMES = ['path', 'pathParams'];
11
+ const RESERVED_HEADER_ARG_NAMES = ['headers', 'headersParams'];
7
12
 
8
13
  const SCHEMA_TYPES = {
9
- ARRAY: "array",
10
- OBJECT: "object",
11
- ENUM: "enum",
12
- REF: "$ref",
13
- PRIMITIVE: "primitive",
14
- COMPLEX: "complex",
15
- COMPLEX_ONE_OF: "oneOf",
16
- COMPLEX_ANY_OF: "anyOf",
17
- COMPLEX_ALL_OF: "allOf",
18
- COMPLEX_NOT: "not",
19
- COMPLEX_UNKNOWN: "__unknown",
14
+ ARRAY: 'array',
15
+ OBJECT: 'object',
16
+ ENUM: 'enum',
17
+ REF: '$ref',
18
+ PRIMITIVE: 'primitive',
19
+ COMPLEX: 'complex',
20
+ DISCRIMINATOR: 'discriminator',
21
+ COMPLEX_ONE_OF: 'oneOf',
22
+ COMPLEX_ANY_OF: 'anyOf',
23
+ COMPLEX_ALL_OF: 'allOf',
24
+ COMPLEX_NOT: 'not',
25
+ COMPLEX_UNKNOWN: '__unknown',
20
26
  };
21
27
 
22
28
  const HTTP_CLIENT = {
23
- FETCH: "fetch",
24
- AXIOS: "axios",
29
+ FETCH: 'fetch',
30
+ AXIOS: 'axios',
25
31
  };
26
32
 
27
33
  const PROJECT_VERSION = packageJson.version;
@@ -41,7 +47,7 @@ const FILE_PREFIX = `/* eslint-disable */
41
47
 
42
48
  module.exports = {
43
49
  FILE_PREFIX,
44
- DEFAULT_BODY_ARG_NAME: "data",
50
+ DEFAULT_BODY_ARG_NAME: 'data',
45
51
  PROJECT_VERSION,
46
52
  SCHEMA_TYPES,
47
53
  HTTP_CLIENT,
@@ -53,7 +59,7 @@ module.exports = {
53
59
  PRETTIER_OPTIONS: {
54
60
  printWidth: 120,
55
61
  tabWidth: 2,
56
- trailingComma: "all",
57
- parser: "typescript",
62
+ trailingComma: 'all',
63
+ parser: 'typescript',
58
64
  },
59
65
  };
package/src/index.js CHANGED
@@ -6,10 +6,9 @@
6
6
  // License text available at https://opensource.org/licenses/MIT
7
7
  // Repository https://github.com/acacode/swagger-typescript-api
8
8
 
9
- const _ = require("lodash");
10
- const constants = require("./constants");
11
- const { CodeGenProcess } = require("./code-gen-process.js");
12
- const { generateTemplates } = require("./commands/generate-templates");
9
+ const constants = require('./constants');
10
+ const { CodeGenProcess } = require('./code-gen-process.js');
11
+ const { generateTemplates } = require('./commands/generate-templates');
13
12
 
14
13
  module.exports = {
15
14
  constants: constants,
@@ -1,31 +1,31 @@
1
- const _ = require("lodash");
1
+ const _ = require('lodash');
2
2
 
3
3
  class SchemaComponentsMap {
4
- /**
5
- * @type {Record<string, SchemaComponent>}
6
- */
7
- data = {};
8
- /**
9
- * @type {CodeGenConfig}
10
- */
4
+ /** @type {SchemaComponent[]} */
5
+ _data = [];
6
+ /** @type {CodeGenConfig} */
11
7
  config;
12
8
 
13
- constructor(config, schema) {
9
+ constructor({ config }) {
14
10
  this.config = config;
15
- this.processSchema(schema);
16
11
  }
17
12
 
18
- processSchema(schema) {
19
- this.data = {};
20
- if (!schema) return;
21
- _.each(schema.components, (component, componentName) =>
22
- _.each(component, (rawTypeData, typeName) => this.createComponent(componentName, typeName, rawTypeData)),
23
- );
13
+ clear() {
14
+ this._data = [];
24
15
  }
25
16
 
26
- createComponent(componentName, typeName, rawTypeData) {
27
- const $ref = `#/components/${componentName}/${typeName}`;
17
+ createRef = (paths) => {
18
+ return ['#', ...paths].join('/');
19
+ };
20
+
21
+ parseRef = (ref) => {
22
+ return ref.split('/');
23
+ };
28
24
 
25
+ createComponent($ref, rawTypeData) {
26
+ const parsed = this.parseRef($ref);
27
+ const typeName = parsed[parsed.length - 1];
28
+ const componentName = parsed[parsed.length - 2];
29
29
  const componentSchema = {
30
30
  $ref,
31
31
  typeName,
@@ -35,23 +35,39 @@ class SchemaComponentsMap {
35
35
  typeData: null,
36
36
  };
37
37
 
38
- const usageComponent = this.config.hooks.onCreateComponent(componentSchema) || componentSchema;
38
+ const usageComponent =
39
+ this.config.hooks.onCreateComponent(componentSchema) || componentSchema;
40
+
41
+ const refIndex = this._data.findIndex((c) => c.$ref === $ref);
39
42
 
40
- this.data[$ref] = usageComponent;
43
+ if (refIndex === -1) {
44
+ this._data.push(usageComponent);
45
+ } else {
46
+ this._data[refIndex] = usageComponent;
47
+ }
41
48
 
42
49
  return usageComponent;
43
50
  }
44
51
 
52
+ /**
53
+ * @returns {SchemaComponent[]}
54
+ */
55
+ getComponents() {
56
+ return this._data;
57
+ }
58
+
45
59
  /**
46
60
  * @param componentName {string}
47
61
  * @returns {SchemaComponent[]}
48
62
  */
49
63
  filter(componentName) {
50
- return _.filter(this.data, (v, ref) => _.startsWith(ref, `#/components/${componentName}`));
64
+ return _.filter(this._data, (v) =>
65
+ _.startsWith(v.$ref, `#/components/${componentName}`),
66
+ );
51
67
  }
52
68
 
53
- get(ref) {
54
- return this.data[ref] || null;
69
+ get($ref) {
70
+ return this._data.find((c) => c.$ref === $ref) || null;
55
71
  }
56
72
  }
57
73
 
@@ -0,0 +1,43 @@
1
+ const { MonoSchemaParser } = require('../mono-schema-parser');
2
+ const _ = require('lodash');
3
+ const { SCHEMA_TYPES } = require('../../constants');
4
+
5
+ class ArraySchemaParser extends MonoSchemaParser {
6
+ parse() {
7
+ let contentType;
8
+ const { type, description, items } = this.schema || {};
9
+
10
+ if (_.isArray(items) && type === SCHEMA_TYPES.ARRAY) {
11
+ const tupleContent = [];
12
+ for (const item of items) {
13
+ tupleContent.push(
14
+ this.schemaParserFabric
15
+ .createSchemaParser({ schema: item, schemaPath: this.schemaPath })
16
+ .getInlineParseContent(),
17
+ );
18
+ }
19
+ contentType = this.config.Ts.Tuple(tupleContent);
20
+ } else {
21
+ const content = this.schemaParserFabric
22
+ .createSchemaParser({ schema: items, schemaPath: this.schemaPath })
23
+ .getInlineParseContent();
24
+ contentType = this.config.Ts.ArrayType(content);
25
+ }
26
+
27
+ return {
28
+ ...(_.isObject(this.schema) ? this.schema : {}),
29
+ $schemaPath: this.schemaPath.slice(),
30
+ $parsedSchema: true,
31
+ schemaType: SCHEMA_TYPES.PRIMITIVE,
32
+ type: SCHEMA_TYPES.PRIMITIVE,
33
+ typeIdentifier: this.config.Ts.Keyword.Type,
34
+ name: this.typeName,
35
+ description: this.schemaFormatters.formatDescription(description),
36
+ content: this.schemaUtils.safeAddNullToType(this.schema, contentType),
37
+ };
38
+ }
39
+ }
40
+
41
+ module.exports = {
42
+ ArraySchemaParser,
43
+ };