swagger-typescript-api 13.0.0-experimental-1 → 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 (81) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +22 -12
  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 +113 -8
  11. package/index.js +158 -135
  12. package/package.json +35 -30
  13. package/src/code-formatter.js +28 -13
  14. package/src/code-gen-process.js +357 -259
  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 +167 -95
  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 +69 -60
  35. package/src/schema-parser/schema-parser-fabric.js +131 -0
  36. package/src/schema-parser/schema-parser.js +208 -427
  37. package/src/schema-parser/schema-utils.js +123 -58
  38. package/src/schema-parser/util/enum-key-resolver.js +26 -0
  39. package/src/schema-routes/schema-routes.js +1225 -0
  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-formatter.js +33 -18
  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 +52 -60
  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/README.md +17 -17
  57. package/templates/base/README.md +7 -7
  58. package/templates/base/data-contract-jsdoc.ejs +37 -37
  59. package/templates/base/data-contracts.ejs +40 -27
  60. package/templates/base/enum-data-contract.ejs +12 -12
  61. package/templates/base/http-client.ejs +3 -3
  62. package/templates/base/http-clients/axios-http-client.ejs +139 -138
  63. package/templates/base/http-clients/fetch-http-client.ejs +224 -224
  64. package/templates/base/interface-data-contract.ejs +10 -10
  65. package/templates/base/object-field-jsdoc.ejs +28 -28
  66. package/templates/base/route-docs.ejs +30 -30
  67. package/templates/base/route-name.ejs +42 -42
  68. package/templates/base/route-type.ejs +22 -21
  69. package/templates/base/type-data-contract.ejs +15 -15
  70. package/templates/default/README.md +6 -6
  71. package/templates/default/api.ejs +69 -68
  72. package/templates/default/procedure-call.ejs +100 -100
  73. package/templates/default/route-types.ejs +32 -32
  74. package/templates/modular/README.md +6 -6
  75. package/templates/modular/api.ejs +28 -28
  76. package/templates/modular/procedure-call.ejs +100 -100
  77. package/templates/modular/route-types.ejs +18 -18
  78. package/src/schema-parser/schema-processor.js +0 -79
  79. package/src/schema-parser/schema-routes.js +0 -950
  80. package/src/templates.js +0 -182
  81. package/src/translators/JavaScript.js +0 -60
@@ -1,415 +1,249 @@
1
- const { SchemaFormatters } = require("./schema-formatters");
2
- const { SchemaUtils } = require("./schema-utils");
3
- const { SCHEMA_TYPES } = require("../constants");
4
- const _ = require("lodash");
5
- const { internalCase } = require("../util/internal-case");
6
- const { camelCase } = require("lodash");
1
+ /* eslint-disable no-unused-vars */
2
+ const { SCHEMA_TYPES } = require('../constants.js');
3
+ const _ = require('lodash');
4
+ const { SchemaFormatters } = require('./schema-formatters');
5
+ const { SchemaUtils } = require('./schema-utils');
6
+ const {
7
+ DiscriminatorSchemaParser,
8
+ } = require('./base-schema-parsers/discriminator');
9
+ const { EnumSchemaParser } = require('./base-schema-parsers/enum');
10
+ const { ObjectSchemaParser } = require('./base-schema-parsers/object');
11
+ const { PrimitiveSchemaParser } = require('./base-schema-parsers/primitive');
12
+ const { ComplexSchemaParser } = require('./base-schema-parsers/complex');
13
+ const { OneOfSchemaParser } = require('./complex-schema-parsers/one-of');
14
+ const { AllOfSchemaParser } = require('./complex-schema-parsers/all-of');
15
+ const { AnyOfSchemaParser } = require('./complex-schema-parsers/any-of');
16
+ const { NotSchemaParser } = require('./complex-schema-parsers/not');
17
+ const { ArraySchemaParser } = require('./base-schema-parsers/array');
18
+ const { sortByProperty } = require('../util/sort-by-property');
7
19
 
8
20
  class SchemaParser {
9
- /**
10
- * @type {CodeGenConfig}
11
- */
21
+ /** @type {SchemaParserFabric} */
22
+ schemaParserFabric;
23
+ /** @type {CodeGenConfig} */
12
24
  config;
13
- /**
14
- * @type {SchemaComponentsMap}
15
- */
25
+ /** @type {Logger} */
26
+ logger;
27
+ /** @type {SchemaComponentsMap} */
16
28
  schemaComponentsMap;
17
- /**
18
- * @type {TypeNameFormatter}
19
- */
29
+ /** @type {TypeNameFormatter} */
20
30
  typeNameFormatter;
21
- /**
22
- * @type {SchemaFormatters}
23
- */
31
+ /** @type {SchemaFormatters} */
24
32
  schemaFormatters;
25
-
26
- /**
27
- * @type {SchemaUtils}
28
- */
33
+ /** @type {SchemaUtils} */
29
34
  schemaUtils;
30
-
31
- schemaPath = [];
35
+ /** @type {TemplatesWorker} */
36
+ templatesWorker;
37
+ /** @type {SchemaWalker} */
38
+ schemaWalker;
32
39
 
33
40
  typeName;
34
41
  schema;
42
+ schemaPath = [];
35
43
 
36
- constructor(
37
- config,
38
- schemaComponentsMap,
39
- typeNameFormatter,
40
- schemaFormatters,
41
- schemaUtils,
42
- schema,
43
- typeName = null,
44
- schemaPath = [],
45
- ) {
46
- this.config = config;
47
- this.schemaComponentsMap = schemaComponentsMap;
48
- this.typeNameFormatter = typeNameFormatter;
49
- this.schemaFormatters = schemaFormatters;
50
- this.schemaUtils = schemaUtils;
44
+ constructor(schemaParserFabric, { typeName, schema, schemaPath } = {}) {
45
+ this.schemaParserFabric = schemaParserFabric;
46
+ this.config = schemaParserFabric.config;
47
+ this.logger = schemaParserFabric.logger;
48
+ this.templatesWorker = schemaParserFabric.templatesWorker;
49
+ this.schemaComponentsMap = schemaParserFabric.schemaComponentsMap;
50
+ this.typeNameFormatter = schemaParserFabric.typeNameFormatter;
51
+ this.schemaWalker = schemaParserFabric.schemaWalker;
52
+ this.schemaFormatters = schemaParserFabric.schemaFormatters;
53
+ this.schemaUtils = schemaParserFabric.schemaUtils;
54
+
55
+ this.typeName = typeName || null;
51
56
  this.schema = schema;
52
- this.typeName = typeName;
53
- this.schemaPath = schemaPath;
57
+ this.schemaPath = [...(schemaPath || [])];
54
58
  }
55
59
 
56
60
  _complexSchemaParsers = {
57
- // T1 | T2
58
- [SCHEMA_TYPES.COMPLEX_ONE_OF]: async (schema) => {
59
- const ignoreTypes = [this.config.Ts.Keyword.Any];
60
- const combined = await Promise.all(
61
- _.map(schema.oneOf, (childSchema) =>
62
- this.createParser(
63
- this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema),
64
- undefined,
65
- this.schemaPath,
66
- ).getInlineContent(),
67
- ),
61
+ [SCHEMA_TYPES.COMPLEX_ONE_OF]: (schema) => {
62
+ const SchemaParser =
63
+ this.config.schemaParsers.complexOneOf || OneOfSchemaParser;
64
+ const schemaParser = new SchemaParser(
65
+ this,
66
+ schema,
67
+ null,
68
+ this.schemaPath,
68
69
  );
69
- const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
70
-
71
- const type = this.config.Ts.UnionType(filtered);
72
-
73
- return this.schemaUtils.safeAddNullToType(schema, type);
70
+ return schemaParser.parse();
74
71
  },
75
- // T1 & T2
76
- [SCHEMA_TYPES.COMPLEX_ALL_OF]: async (schema) => {
77
- const ignoreTypes = [...this.config.jsPrimitiveTypes, this.config.Ts.Keyword.Any];
78
- const combined = await Promise.all(
79
- _.map(schema.allOf, (childSchema) =>
80
- this.createParser(
81
- this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema),
82
- undefined,
83
- this.schemaPath,
84
- ).getInlineContent(),
85
- ),
72
+ [SCHEMA_TYPES.COMPLEX_ALL_OF]: (schema) => {
73
+ const SchemaParser =
74
+ this.config.schemaParsers.complexAllOf || AllOfSchemaParser;
75
+ const schemaParser = new SchemaParser(
76
+ this,
77
+ schema,
78
+ null,
79
+ this.schemaPath,
86
80
  );
87
- const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
88
-
89
- const type = this.config.Ts.IntersectionType(filtered);
90
-
91
- return this.schemaUtils.safeAddNullToType(schema, type);
81
+ return schemaParser.parse();
92
82
  },
93
- // T1 | T2 | (T1 & T2)
94
- [SCHEMA_TYPES.COMPLEX_ANY_OF]: async (schema) => {
95
- const ignoreTypes = [...this.config.jsPrimitiveTypes, this.config.Ts.Keyword.Any];
96
- const combined = await Promise.all(
97
- _.map(schema.anyOf, (childSchema) =>
98
- this.createParser(
99
- this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema),
100
- undefined,
101
- this.schemaPath,
102
- ).getInlineContent(),
103
- ),
83
+ [SCHEMA_TYPES.COMPLEX_ANY_OF]: (schema) => {
84
+ const SchemaParser =
85
+ this.config.schemaParsers.complexAnyOf || AnyOfSchemaParser;
86
+ const schemaParser = new SchemaParser(
87
+ this,
88
+ schema,
89
+ null,
90
+ this.schemaPath,
104
91
  );
105
- const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
106
-
107
- const type = this.config.Ts.UnionType(
108
- _.compact([
109
- ...filtered,
110
- filtered.length > 1 && this.config.Ts.ExpressionGroup(this.config.Ts.IntersectionType(filtered)),
111
- ]),
112
- );
113
-
114
- return this.schemaUtils.safeAddNullToType(schema, type);
92
+ return schemaParser.parse();
115
93
  },
116
- // TODO
117
94
  [SCHEMA_TYPES.COMPLEX_NOT]: (schema) => {
118
- // TODO
119
- return this.config.Ts.Keyword.Any;
95
+ const SchemaParser =
96
+ this.config.schemaParsers.complexNot || NotSchemaParser;
97
+ const schemaParser = new SchemaParser(
98
+ this,
99
+ schema,
100
+ null,
101
+ this.schemaPath,
102
+ );
103
+ return schemaParser.parse();
120
104
  },
121
105
  };
122
- _baseSchemaParsers = {
123
- [SCHEMA_TYPES.ENUM]: async (schema, typeName) => {
124
- if (this.config.extractEnums && !typeName) {
125
- const generatedTypeName = this.config.componentTypeNameResolver.resolve([this.buildTypeNameFromPath()]);
126
- const schemaComponent = this.schemaComponentsMap.createComponent("schemas", generatedTypeName, { ...schema });
127
- const parser = this.createParser(schemaComponent, generatedTypeName);
128
- return await parser.parse();
129
- }
130
-
131
- const refType = this.schemaUtils.getSchemaRefType(schema);
132
- const $ref = (refType && refType.$ref) || null;
133
-
134
- if (Array.isArray(schema.enum) && Array.isArray(schema.enum[0])) {
135
- return await this.createParser(
136
- {
137
- oneOf: schema.enum.map((enumNames) => ({
138
- type: "array",
139
- items: enumNames.map((enumName) => ({ type: "string", enum: [enumName] })),
140
- })),
141
- },
142
- typeName,
143
- this.schemaPath,
144
- ).parse();
145
- }
146
-
147
- const keyType = await this.schemaUtils.getSchemaType(schema);
148
- const enumNames = this.schemaUtils.getEnumNames(schema);
149
- let content = null;
150
-
151
- const formatValue = async (value) => {
152
- if (value === null) {
153
- return this.config.Ts.NullValue(value);
154
- }
155
- if (keyType === (await this.schemaUtils.getSchemaType({ type: "number" }))) {
156
- return this.config.Ts.NumberValue(value);
157
- }
158
- if (keyType === (await this.schemaUtils.getSchemaType({ type: "boolean" }))) {
159
- return this.config.Ts.BooleanValue(value);
160
- }
161
-
162
- return this.config.Ts.StringValue(value);
163
- };
164
-
165
- if (_.isArray(enumNames) && _.size(enumNames)) {
166
- content = await Promise.all(
167
- _.map(enumNames, async (enumName, index) => {
168
- const enumValue = _.get(schema.enum, index);
169
- const formattedKey =
170
- (enumName &&
171
- this.typeNameFormatter.format(enumName, {
172
- type: "enum-key",
173
- })) ||
174
- this.typeNameFormatter.format(`${enumValue}`, {
175
- type: "enum-key",
176
- });
177
-
178
- if (this.config.enumNamesAsValues || _.isUndefined(enumValue)) {
179
- return {
180
- key: formattedKey,
181
- type: this.config.Ts.Keyword.String,
182
- value: this.config.Ts.StringValue(enumName),
183
- };
184
- }
185
-
186
- return {
187
- key: formattedKey,
188
- type: keyType,
189
- value: await formatValue(enumValue),
190
- };
191
- }),
192
- );
193
- } else {
194
- content = await Promise.all(
195
- _.map(schema.enum, async (key) => {
196
- return {
197
- key: this.typeNameFormatter.format(`${key}`, {
198
- type: "enum-key",
199
- }),
200
- type: keyType,
201
- value: await formatValue(key),
202
- };
203
- }),
204
- );
205
- }
206
106
 
207
- return {
208
- ...(_.isObject(schema) ? schema : {}),
209
- $ref: $ref,
210
- typeName: typeName || ($ref && refType.typeName) || null,
211
- $parsedSchema: true,
212
- schemaType: SCHEMA_TYPES.ENUM,
213
- type: SCHEMA_TYPES.ENUM,
214
- keyType: keyType,
215
- typeIdentifier: this.config.generateUnionEnums ? this.config.Ts.Keyword.Type : this.config.Ts.Keyword.Enum,
216
- name: typeName,
217
- description: this.schemaFormatters.formatDescription(schema.description),
218
- content,
219
- };
107
+ _baseSchemaParsers = {
108
+ [SCHEMA_TYPES.ENUM]: (schema, typeName) => {
109
+ const SchemaParser = this.config.schemaParsers.enum || EnumSchemaParser;
110
+ const schemaParser = new SchemaParser(
111
+ this,
112
+ schema,
113
+ typeName,
114
+ this.schemaPath,
115
+ );
116
+ return schemaParser.parse();
220
117
  },
221
- [SCHEMA_TYPES.OBJECT]: async (schema, typeName) => {
222
- const { properties, additionalProperties } = schema || {};
223
- const contentProperties = [];
224
-
225
- const propertyEntries = _.entries(properties);
226
-
227
- for await (const [name, property] of propertyEntries) {
228
- this.schemaPath.push(name);
229
- const required = this.schemaUtils.isPropertyRequired(name, property, schema);
230
- const rawTypeData = _.get(this.schemaUtils.getSchemaRefType(property), "rawTypeData", {});
231
- const nullable = !!(rawTypeData.nullable || property.nullable);
232
- const fieldName = this.typeNameFormatter.isValidName(name) ? name : this.config.Ts.StringValue(name);
233
- const fieldValue = await this.createParser(property, null, this.schemaPath).getInlineContent();
234
- const readOnly = property.readOnly;
235
-
236
- this.schemaPath.pop();
237
-
238
- contentProperties.push({
239
- ...property,
240
- $$raw: property,
241
- title: property.title,
242
- description:
243
- property.description ||
244
- _.compact(_.map(property[this.schemaUtils.getComplexType(property)], "description"))[0] ||
245
- rawTypeData.description ||
246
- _.compact(_.map(rawTypeData[this.schemaUtils.getComplexType(rawTypeData)], "description"))[0] ||
247
- "",
248
- isRequired: required,
249
- isNullable: nullable,
250
- name: fieldName,
251
- value: fieldValue,
252
- field: this.config.Ts.TypeField({
253
- readonly: readOnly && this.config.addReadonly,
254
- optional: !required,
255
- key: fieldName,
256
- value: fieldValue,
257
- }),
258
- });
259
- }
260
-
261
- if (additionalProperties) {
262
- contentProperties.push({
263
- $$raw: { additionalProperties },
264
- description: "",
265
- isRequired: false,
266
- field: this.config.Ts.InterfaceDynamicField(this.config.Ts.Keyword.String, this.config.Ts.Keyword.Any),
267
- });
268
- }
269
-
270
- return {
271
- ...(_.isObject(schema) ? schema : {}),
272
- $parsedSchema: true,
273
- schemaType: SCHEMA_TYPES.OBJECT,
274
- type: SCHEMA_TYPES.OBJECT,
275
- typeIdentifier: this.config.Ts.Keyword.Interface,
276
- name: typeName,
277
- description: this.schemaFormatters.formatDescription(schema.description),
278
- allFieldsAreOptional: !_.some(_.values(contentProperties), (part) => part.isRequired),
279
- content: contentProperties,
280
- };
118
+ [SCHEMA_TYPES.OBJECT]: (schema, typeName) => {
119
+ const SchemaParser =
120
+ this.config.schemaParsers.object || ObjectSchemaParser;
121
+ const schemaParser = new SchemaParser(
122
+ this,
123
+ schema,
124
+ typeName,
125
+ this.schemaPath,
126
+ );
127
+ return schemaParser.parse();
281
128
  },
282
- [SCHEMA_TYPES.COMPLEX]: async (schema, typeName) => {
283
- const complexType = this.schemaUtils.getComplexType(schema);
284
- const simpleSchema = _.omit(_.clone(schema), _.keys(this._complexSchemaParsers));
285
- const complexSchemaContent = await this._complexSchemaParsers[complexType](schema);
286
-
287
- return {
288
- ...(_.isObject(schema) ? schema : {}),
289
- $parsedSchema: true,
290
- schemaType: SCHEMA_TYPES.COMPLEX,
291
- type: SCHEMA_TYPES.PRIMITIVE,
292
- typeIdentifier: this.config.Ts.Keyword.Type,
293
- name: typeName,
294
- description: this.schemaFormatters.formatDescription(
295
- schema.description || _.compact(_.map(schema[complexType], "description"))[0] || "",
296
- ),
297
- content:
298
- this.config.Ts.IntersectionType(
299
- _.compact([
300
- this.config.Ts.ExpressionGroup(complexSchemaContent),
301
- this.schemaUtils.getInternalSchemaType(simpleSchema) === SCHEMA_TYPES.OBJECT &&
302
- this.config.Ts.ExpressionGroup(
303
- await this.createParser(simpleSchema, null, this.schemaPath).getInlineContent(),
304
- ),
305
- ]),
306
- ) || this.config.Ts.Keyword.Any,
307
- };
129
+ [SCHEMA_TYPES.COMPLEX]: (schema, typeName) => {
130
+ const SchemaParser =
131
+ this.config.schemaParsers.complex || ComplexSchemaParser;
132
+ const schemaParser = new SchemaParser(
133
+ this,
134
+ schema,
135
+ typeName,
136
+ this.schemaPath,
137
+ );
138
+ return schemaParser.parse();
308
139
  },
309
- [SCHEMA_TYPES.ARRAY]: async (schema, typeName) => {
310
- let contentType;
311
- const { type, description, items } = schema || {};
312
-
313
- if (_.isArray(items) && type === SCHEMA_TYPES.ARRAY) {
314
- const tupleContent = await Promise.all(
315
- items.map((item) => this.createParser(item, null, this.schemaPath).getInlineContent()),
316
- );
317
- contentType = this.config.Ts.Tuple(tupleContent);
318
- } else {
319
- const content = await this.createParser(items, null, this.schemaPath).getInlineContent();
320
- contentType = this.config.Ts.ArrayType(content);
321
- }
322
-
323
- return {
324
- ...(_.isObject(schema) ? schema : {}),
325
- $parsedSchema: true,
326
- schemaType: SCHEMA_TYPES.PRIMITIVE,
327
- type: SCHEMA_TYPES.PRIMITIVE,
328
- typeIdentifier: this.config.Ts.Keyword.Type,
329
- name: typeName,
330
- description: this.schemaFormatters.formatDescription(description),
331
- content: this.schemaUtils.safeAddNullToType(schema, contentType),
332
- };
140
+ [SCHEMA_TYPES.PRIMITIVE]: (schema, typeName) => {
141
+ const SchemaParser =
142
+ this.config.schemaParsers.primitive || PrimitiveSchemaParser;
143
+ const schemaParser = new SchemaParser(
144
+ this,
145
+ schema,
146
+ typeName,
147
+ this.schemaPath,
148
+ );
149
+ return schemaParser.parse();
333
150
  },
334
- [SCHEMA_TYPES.PRIMITIVE]: async (schema, typeName) => {
335
- let contentType = null;
336
- const { additionalProperties, type, description, items } = schema || {};
337
-
338
- if (type === this.config.Ts.Keyword.Object && additionalProperties) {
339
- const fieldType = _.isObject(additionalProperties)
340
- ? await this.createParser(additionalProperties, null, this.schemaPath).getInlineContent()
341
- : this.config.Ts.Keyword.Any;
342
- contentType = this.config.Ts.RecordType(this.config.Ts.Keyword.String, fieldType);
343
- }
344
-
345
- if (_.isArray(type) && type.length) {
346
- contentType = await this._complexSchemaParsers.oneOf({
347
- ...(_.isObject(schema) ? schema : {}),
348
- oneOf: type.map((type) => ({ type })),
349
- });
350
- }
351
-
352
- if (_.isArray(items) && type === SCHEMA_TYPES.ARRAY) {
353
- contentType = this.config.Ts.Tuple(
354
- await Promise.all(items.map((item) => this.createParser(item, null, this.schemaPath).getInlineContent())),
355
- );
356
- }
357
-
358
- return {
359
- ...(_.isObject(schema) ? schema : {}),
360
- $parsedSchema: true,
361
- schemaType: SCHEMA_TYPES.PRIMITIVE,
362
- type: SCHEMA_TYPES.PRIMITIVE,
363
- typeIdentifier: this.config.Ts.Keyword.Type,
364
- name: typeName,
365
- description: this.schemaFormatters.formatDescription(description),
366
- // TODO: probably it should be refactored. `type === 'null'` is not flexible
367
- content:
368
- type === this.config.Ts.Keyword.Null ? type : contentType || (await this.schemaUtils.getSchemaType(schema)),
369
- };
151
+ [SCHEMA_TYPES.DISCRIMINATOR]: (schema, typeName) => {
152
+ const SchemaParser =
153
+ this.config.schemaParsers.discriminator || DiscriminatorSchemaParser;
154
+ const schemaParser = new SchemaParser(
155
+ this,
156
+ schema,
157
+ typeName,
158
+ this.schemaPath,
159
+ );
160
+ return schemaParser.parse();
161
+ },
162
+ [SCHEMA_TYPES.ARRAY]: (schema, typeName) => {
163
+ const SchemaParser = this.config.schemaParsers.array || ArraySchemaParser;
164
+ const schemaParser = new SchemaParser(
165
+ this,
166
+ schema,
167
+ typeName,
168
+ this.schemaPath,
169
+ );
170
+ return schemaParser.parse();
370
171
  },
371
- };
372
-
373
- buildTypeNameFromPath = () => {
374
- const schemaPath = _.uniq(_.compact(this.schemaPath));
375
-
376
- if (!schemaPath || !schemaPath[0]) return null;
377
-
378
- return internalCase(camelCase(`${schemaPath[0]}_${schemaPath[schemaPath.length - 1]}`));
379
172
  };
380
173
 
381
174
  /**
382
- *
383
- * @param schema {any}
384
- * @param typeName {null | string}
385
- * @param formatter {"inline" | "base"}
386
- * @return {Promise<Record<string, any>>}
175
+ * @return {Record<string, any>}
387
176
  */
388
- parse = async () => {
389
- if (!this.schema) return await this._baseSchemaParsers[SCHEMA_TYPES.PRIMITIVE](null, this.typeName);
177
+ parseSchema = () => {
178
+ if (!this.schema)
179
+ return this._baseSchemaParsers[SCHEMA_TYPES.PRIMITIVE](
180
+ null,
181
+ this.typeName,
182
+ );
390
183
 
391
184
  let schemaType = null;
392
185
  let parsedSchema = null;
393
186
 
394
- if (typeof this.schema === "string") {
187
+ if (typeof this.schema === 'string') {
395
188
  return this.schema;
396
189
  }
397
190
 
398
191
  if (!this.schema.$parsed) {
399
192
  if (!this.typeName && this.schemaUtils.isRefSchema(this.schema)) {
400
- this.typeName = await this.schemaUtils.getSchemaType(this.schema);
193
+ this.typeName = this.schemaUtils.getSchemaType(this.schema);
401
194
  }
402
195
 
403
- if (this.schema.items && !Array.isArray(this.schema.items) && !this.schema.type) {
196
+ /**
197
+ * swagger schemas fixes
198
+ * ---->
199
+ */
200
+ if (
201
+ this.schema.items &&
202
+ !Array.isArray(this.schema.items) &&
203
+ !this.schema.type
204
+ ) {
404
205
  this.schema.type = SCHEMA_TYPES.ARRAY;
405
206
  }
207
+ if (
208
+ Array.isArray(this.schema.enum) &&
209
+ this.schema.enum.length === 1 &&
210
+ this.schema.enum[0] == null
211
+ ) {
212
+ this.logger.debug('invalid enum schema', this.schema);
213
+ this.schema = { type: this.config.Ts.Keyword.Null };
214
+ }
215
+ /**
216
+ * <----
217
+ */
218
+
406
219
  schemaType = this.schemaUtils.getInternalSchemaType(this.schema);
407
220
 
408
221
  this.schemaPath.push(this.typeName);
409
222
 
410
- _.merge(this.schema, this.config.hooks.onPreParseSchema(this.schema, this.typeName, schemaType));
411
- parsedSchema = await this._baseSchemaParsers[schemaType](this.schema, this.typeName);
412
- this.schema.$parsed = this.config.hooks.onParseSchema(this.schema, parsedSchema) || parsedSchema;
223
+ _.merge(
224
+ this.schema,
225
+ this.config.hooks.onPreParseSchema(
226
+ this.schema,
227
+ this.typeName,
228
+ schemaType,
229
+ ),
230
+ );
231
+ parsedSchema = this._baseSchemaParsers[schemaType](
232
+ this.schema,
233
+ this.typeName,
234
+ );
235
+ this.schema.$parsed =
236
+ this.config.hooks.onParseSchema(this.schema, parsedSchema) ||
237
+ parsedSchema;
238
+
239
+ if (
240
+ this.config.sortTypes &&
241
+ Array.isArray(this.schema.$parsed?.content)
242
+ ) {
243
+ this.schema.$parsed.content = this.schema.$parsed.content.sort(
244
+ sortByProperty('name'),
245
+ );
246
+ }
413
247
  }
414
248
 
415
249
  this.schemaPath.pop();
@@ -417,76 +251,23 @@ class SchemaParser {
417
251
  return this.schema.$parsed;
418
252
  };
419
253
 
420
- /**
421
- * @param cfg {{ formatType?: "base" | "inline", schemaType?: string } }
422
- * @return {Promise<Record<string, any>>}
423
- */
424
- format = async (cfg) => {
425
- const parsedSchema = await this.parse();
426
- return await this.schemaFormatters.formatSchema(parsedSchema, cfg);
427
- };
428
-
429
- getInlineContent = async () => {
430
- const schema = await this.format({ formatType: "inline" });
431
- return schema.content;
432
- };
433
-
434
- getContent = async () => {
435
- const schema = await this.format({ formatType: "base" });
436
- return schema.content;
437
- };
438
-
439
- /**
440
- * @param {Record<string, any>} [schema]
441
- * @param {string | null | undefined} [typeName]
442
- * @param {string[] | undefined} [schemaPath]
443
- * @return {SchemaParser}
444
- */
445
- createParser = (schema, typeName, schemaPath) => {
446
- return new SchemaParser(
447
- this.config,
448
- this.schemaComponentsMap,
449
- this.typeNameFormatter,
450
- this.schemaFormatters,
451
- this.schemaUtils,
452
- schema,
453
- typeName,
454
- schemaPath,
254
+ getInlineParseContent = () => {
255
+ const parsedSchema = this.parseSchema();
256
+ const formattedSchema = this.schemaFormatters.formatSchema(
257
+ parsedSchema,
258
+ 'inline',
455
259
  );
260
+ return formattedSchema.content;
456
261
  };
457
262
 
458
- /**
459
- * @param config {CodeGenConfig}
460
- * @param schemaComponentsMap {SchemaComponentsMap}
461
- * @param typeNameFormatter {TypeNameFormatter}
462
- * @param schemaFormatters {SchemaFormatters}
463
- * @param schemaUtils {SchemaUtils}
464
- * @param {Record<string, any>} [schema]
465
- * @param {string | null | undefined} [typeName]
466
- * @param {string[] | undefined} [schemaPath]
467
- * @return {SchemaParser}
468
- */
469
- static create(
470
- config,
471
- schemaComponentsMap,
472
- typeNameFormatter,
473
- schemaFormatters,
474
- schemaUtils,
475
- schema,
476
- typeName,
477
- schemaPath,
478
- ) {
479
- return new SchemaParser(
480
- config,
481
- schemaComponentsMap,
482
- typeNameFormatter,
483
- schemaFormatters,
484
- schemaUtils,
485
- schema,
486
- typeName,
487
- schemaPath,
263
+ getParseContent = () => {
264
+ const parsedSchema = this.parseSchema();
265
+ const formattedSchema = this.schemaFormatters.formatSchema(
266
+ parsedSchema,
267
+ 'base',
488
268
  );
489
- }
269
+ return formattedSchema.content;
270
+ };
490
271
  }
491
272
 
492
273
  module.exports = {