swagger-typescript-api 12.0.1 → 13.0.0-experimental-1
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/README.md +8 -9
- package/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/code-gen-process.js +76 -71
- package/src/configuration.js +1 -5
- package/src/schema-parser/schema-formatters.js +28 -23
- package/src/schema-parser/schema-parser.js +270 -200
- package/src/schema-parser/schema-processor.js +79 -0
- package/src/schema-parser/schema-routes.js +96 -82
- package/src/schema-parser/schema-utils.js +62 -1
- package/src/templates.js +19 -14
- package/src/{type-name.js → type-name-formatter.js} +2 -2
- package/templates/base/data-contracts.ejs +4 -5
- package/templates/base/http-client.ejs +1 -1
- package/templates/base/interface-data-contract.ejs +3 -3
- package/templates/base/route-type.ejs +1 -1
- package/templates/base/type-data-contract.ejs +3 -3
- package/templates/default/api.ejs +12 -9
- package/templates/default/procedure-call.ejs +2 -2
- package/templates/default/route-types.ejs +15 -11
- package/templates/modular/api.ejs +3 -3
- package/templates/modular/procedure-call.ejs +2 -2
- package/templates/modular/route-types.ejs +3 -3
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
const { SCHEMA_TYPES } = require("../constants.js");
|
|
2
|
-
const _ = require("lodash");
|
|
3
1
|
const { SchemaFormatters } = require("./schema-formatters");
|
|
4
|
-
const { internalCase } = require("../util/internal-case");
|
|
5
2
|
const { SchemaUtils } = require("./schema-utils");
|
|
3
|
+
const { SCHEMA_TYPES } = require("../constants");
|
|
4
|
+
const _ = require("lodash");
|
|
5
|
+
const { internalCase } = require("../util/internal-case");
|
|
6
6
|
const { camelCase } = require("lodash");
|
|
7
|
-
const { pascalCase } = require("../util/pascal-case");
|
|
8
7
|
|
|
9
8
|
class SchemaParser {
|
|
10
9
|
/**
|
|
11
10
|
* @type {CodeGenConfig}
|
|
12
11
|
*/
|
|
13
12
|
config;
|
|
14
|
-
|
|
15
13
|
/**
|
|
16
14
|
* @type {SchemaComponentsMap}
|
|
17
15
|
*/
|
|
18
16
|
schemaComponentsMap;
|
|
19
17
|
/**
|
|
20
|
-
* @type {
|
|
18
|
+
* @type {TypeNameFormatter}
|
|
21
19
|
*/
|
|
22
|
-
|
|
20
|
+
typeNameFormatter;
|
|
23
21
|
/**
|
|
24
22
|
* @type {SchemaFormatters}
|
|
25
23
|
*/
|
|
@@ -30,22 +28,43 @@ class SchemaParser {
|
|
|
30
28
|
*/
|
|
31
29
|
schemaUtils;
|
|
32
30
|
|
|
33
|
-
|
|
31
|
+
schemaPath = [];
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
typeName;
|
|
34
|
+
schema;
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
config,
|
|
38
|
+
schemaComponentsMap,
|
|
39
|
+
typeNameFormatter,
|
|
40
|
+
schemaFormatters,
|
|
41
|
+
schemaUtils,
|
|
42
|
+
schema,
|
|
43
|
+
typeName = null,
|
|
44
|
+
schemaPath = [],
|
|
45
|
+
) {
|
|
36
46
|
this.config = config;
|
|
37
47
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
48
|
+
this.typeNameFormatter = typeNameFormatter;
|
|
49
|
+
this.schemaFormatters = schemaFormatters;
|
|
50
|
+
this.schemaUtils = schemaUtils;
|
|
51
|
+
this.schema = schema;
|
|
38
52
|
this.typeName = typeName;
|
|
39
|
-
this.
|
|
40
|
-
this.schemaUtils = new SchemaUtils(config, schemaComponentsMap);
|
|
53
|
+
this.schemaPath = schemaPath;
|
|
41
54
|
}
|
|
42
55
|
|
|
43
|
-
|
|
56
|
+
_complexSchemaParsers = {
|
|
44
57
|
// T1 | T2
|
|
45
|
-
[SCHEMA_TYPES.COMPLEX_ONE_OF]: (schema) => {
|
|
58
|
+
[SCHEMA_TYPES.COMPLEX_ONE_OF]: async (schema) => {
|
|
46
59
|
const ignoreTypes = [this.config.Ts.Keyword.Any];
|
|
47
|
-
const combined =
|
|
48
|
-
|
|
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
|
+
),
|
|
49
68
|
);
|
|
50
69
|
const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
|
|
51
70
|
|
|
@@ -54,10 +73,16 @@ class SchemaParser {
|
|
|
54
73
|
return this.schemaUtils.safeAddNullToType(schema, type);
|
|
55
74
|
},
|
|
56
75
|
// T1 & T2
|
|
57
|
-
[SCHEMA_TYPES.COMPLEX_ALL_OF]: (schema) => {
|
|
76
|
+
[SCHEMA_TYPES.COMPLEX_ALL_OF]: async (schema) => {
|
|
58
77
|
const ignoreTypes = [...this.config.jsPrimitiveTypes, this.config.Ts.Keyword.Any];
|
|
59
|
-
const combined =
|
|
60
|
-
|
|
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
|
+
),
|
|
61
86
|
);
|
|
62
87
|
const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
|
|
63
88
|
|
|
@@ -66,10 +91,16 @@ class SchemaParser {
|
|
|
66
91
|
return this.schemaUtils.safeAddNullToType(schema, type);
|
|
67
92
|
},
|
|
68
93
|
// T1 | T2 | (T1 & T2)
|
|
69
|
-
[SCHEMA_TYPES.COMPLEX_ANY_OF]: (schema) => {
|
|
94
|
+
[SCHEMA_TYPES.COMPLEX_ANY_OF]: async (schema) => {
|
|
70
95
|
const ignoreTypes = [...this.config.jsPrimitiveTypes, this.config.Ts.Keyword.Any];
|
|
71
|
-
const combined =
|
|
72
|
-
|
|
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
|
+
),
|
|
73
104
|
);
|
|
74
105
|
const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
|
|
75
106
|
|
|
@@ -88,20 +119,20 @@ class SchemaParser {
|
|
|
88
119
|
return this.config.Ts.Keyword.Any;
|
|
89
120
|
},
|
|
90
121
|
};
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
[SCHEMA_TYPES.ENUM]: (schema, typeName) => {
|
|
122
|
+
_baseSchemaParsers = {
|
|
123
|
+
[SCHEMA_TYPES.ENUM]: async (schema, typeName) => {
|
|
94
124
|
if (this.config.extractEnums && !typeName) {
|
|
95
125
|
const generatedTypeName = this.config.componentTypeNameResolver.resolve([this.buildTypeNameFromPath()]);
|
|
96
126
|
const schemaComponent = this.schemaComponentsMap.createComponent("schemas", generatedTypeName, { ...schema });
|
|
97
|
-
|
|
127
|
+
const parser = this.createParser(schemaComponent, generatedTypeName);
|
|
128
|
+
return await parser.parse();
|
|
98
129
|
}
|
|
99
130
|
|
|
100
131
|
const refType = this.schemaUtils.getSchemaRefType(schema);
|
|
101
132
|
const $ref = (refType && refType.$ref) || null;
|
|
102
133
|
|
|
103
134
|
if (Array.isArray(schema.enum) && Array.isArray(schema.enum[0])) {
|
|
104
|
-
return this.
|
|
135
|
+
return await this.createParser(
|
|
105
136
|
{
|
|
106
137
|
oneOf: schema.enum.map((enumNames) => ({
|
|
107
138
|
type: "array",
|
|
@@ -109,21 +140,22 @@ class SchemaParser {
|
|
|
109
140
|
})),
|
|
110
141
|
},
|
|
111
142
|
typeName,
|
|
112
|
-
|
|
143
|
+
this.schemaPath,
|
|
144
|
+
).parse();
|
|
113
145
|
}
|
|
114
146
|
|
|
115
|
-
const keyType = this.getSchemaType(schema);
|
|
147
|
+
const keyType = await this.schemaUtils.getSchemaType(schema);
|
|
116
148
|
const enumNames = this.schemaUtils.getEnumNames(schema);
|
|
117
149
|
let content = null;
|
|
118
150
|
|
|
119
|
-
const formatValue = (value) => {
|
|
151
|
+
const formatValue = async (value) => {
|
|
120
152
|
if (value === null) {
|
|
121
153
|
return this.config.Ts.NullValue(value);
|
|
122
154
|
}
|
|
123
|
-
if (keyType === this.getSchemaType({ type: "number" })) {
|
|
155
|
+
if (keyType === (await this.schemaUtils.getSchemaType({ type: "number" }))) {
|
|
124
156
|
return this.config.Ts.NumberValue(value);
|
|
125
157
|
}
|
|
126
|
-
if (keyType === this.getSchemaType({ type: "boolean" })) {
|
|
158
|
+
if (keyType === (await this.schemaUtils.getSchemaType({ type: "boolean" }))) {
|
|
127
159
|
return this.config.Ts.BooleanValue(value);
|
|
128
160
|
}
|
|
129
161
|
|
|
@@ -131,41 +163,45 @@ class SchemaParser {
|
|
|
131
163
|
};
|
|
132
164
|
|
|
133
165
|
if (_.isArray(enumNames) && _.size(enumNames)) {
|
|
134
|
-
content =
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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}`, {
|
|
139
175
|
type: "enum-key",
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
+
}
|
|
144
185
|
|
|
145
|
-
if (this.config.enumNamesAsValues || _.isUndefined(enumValue)) {
|
|
146
186
|
return {
|
|
147
187
|
key: formattedKey,
|
|
148
|
-
type:
|
|
149
|
-
value:
|
|
188
|
+
type: keyType,
|
|
189
|
+
value: await formatValue(enumValue),
|
|
150
190
|
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return {
|
|
154
|
-
key: formattedKey,
|
|
155
|
-
type: keyType,
|
|
156
|
-
value: formatValue(enumValue),
|
|
157
|
-
};
|
|
158
|
-
});
|
|
191
|
+
}),
|
|
192
|
+
);
|
|
159
193
|
} else {
|
|
160
|
-
content =
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
+
);
|
|
169
205
|
}
|
|
170
206
|
|
|
171
207
|
return {
|
|
@@ -182,8 +218,54 @@ class SchemaParser {
|
|
|
182
218
|
content,
|
|
183
219
|
};
|
|
184
220
|
},
|
|
185
|
-
[SCHEMA_TYPES.OBJECT]: (schema, typeName) => {
|
|
186
|
-
const
|
|
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
|
+
}
|
|
187
269
|
|
|
188
270
|
return {
|
|
189
271
|
...(_.isObject(schema) ? schema : {}),
|
|
@@ -197,10 +279,10 @@ class SchemaParser {
|
|
|
197
279
|
content: contentProperties,
|
|
198
280
|
};
|
|
199
281
|
},
|
|
200
|
-
[SCHEMA_TYPES.COMPLEX]: (schema, typeName) => {
|
|
201
|
-
const complexType = this.getComplexType(schema);
|
|
202
|
-
const simpleSchema = _.omit(_.clone(schema), _.keys(this.
|
|
203
|
-
const complexSchemaContent = this.
|
|
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);
|
|
204
286
|
|
|
205
287
|
return {
|
|
206
288
|
...(_.isObject(schema) ? schema : {}),
|
|
@@ -216,32 +298,61 @@ class SchemaParser {
|
|
|
216
298
|
this.config.Ts.IntersectionType(
|
|
217
299
|
_.compact([
|
|
218
300
|
this.config.Ts.ExpressionGroup(complexSchemaContent),
|
|
219
|
-
this.getInternalSchemaType(simpleSchema) === SCHEMA_TYPES.OBJECT &&
|
|
220
|
-
this.config.Ts.ExpressionGroup(
|
|
301
|
+
this.schemaUtils.getInternalSchemaType(simpleSchema) === SCHEMA_TYPES.OBJECT &&
|
|
302
|
+
this.config.Ts.ExpressionGroup(
|
|
303
|
+
await this.createParser(simpleSchema, null, this.schemaPath).getInlineContent(),
|
|
304
|
+
),
|
|
221
305
|
]),
|
|
222
306
|
) || this.config.Ts.Keyword.Any,
|
|
223
307
|
};
|
|
224
308
|
},
|
|
225
|
-
[SCHEMA_TYPES.
|
|
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
|
+
};
|
|
333
|
+
},
|
|
334
|
+
[SCHEMA_TYPES.PRIMITIVE]: async (schema, typeName) => {
|
|
226
335
|
let contentType = null;
|
|
227
336
|
const { additionalProperties, type, description, items } = schema || {};
|
|
228
337
|
|
|
229
338
|
if (type === this.config.Ts.Keyword.Object && additionalProperties) {
|
|
230
339
|
const fieldType = _.isObject(additionalProperties)
|
|
231
|
-
? this.
|
|
340
|
+
? await this.createParser(additionalProperties, null, this.schemaPath).getInlineContent()
|
|
232
341
|
: this.config.Ts.Keyword.Any;
|
|
233
342
|
contentType = this.config.Ts.RecordType(this.config.Ts.Keyword.String, fieldType);
|
|
234
343
|
}
|
|
235
344
|
|
|
236
345
|
if (_.isArray(type) && type.length) {
|
|
237
|
-
contentType = this.
|
|
346
|
+
contentType = await this._complexSchemaParsers.oneOf({
|
|
238
347
|
...(_.isObject(schema) ? schema : {}),
|
|
239
348
|
oneOf: type.map((type) => ({ type })),
|
|
240
349
|
});
|
|
241
350
|
}
|
|
242
351
|
|
|
243
352
|
if (_.isArray(items) && type === SCHEMA_TYPES.ARRAY) {
|
|
244
|
-
contentType = this.config.Ts.Tuple(
|
|
353
|
+
contentType = this.config.Ts.Tuple(
|
|
354
|
+
await Promise.all(items.map((item) => this.createParser(item, null, this.schemaPath).getInlineContent())),
|
|
355
|
+
);
|
|
245
356
|
}
|
|
246
357
|
|
|
247
358
|
return {
|
|
@@ -253,110 +364,18 @@ class SchemaParser {
|
|
|
253
364
|
name: typeName,
|
|
254
365
|
description: this.schemaFormatters.formatDescription(description),
|
|
255
366
|
// TODO: probably it should be refactored. `type === 'null'` is not flexible
|
|
256
|
-
content:
|
|
367
|
+
content:
|
|
368
|
+
type === this.config.Ts.Keyword.Null ? type : contentType || (await this.schemaUtils.getSchemaType(schema)),
|
|
257
369
|
};
|
|
258
370
|
},
|
|
259
371
|
};
|
|
260
372
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
if (schema.allOf || schema.oneOf || schema.anyOf || schema.not) return SCHEMA_TYPES.COMPLEX;
|
|
264
|
-
if (!_.isEmpty(schema.properties)) return SCHEMA_TYPES.OBJECT;
|
|
265
|
-
|
|
266
|
-
return SCHEMA_TYPES.PRIMITIVE;
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
getSchemaType = (schema) => {
|
|
270
|
-
if (!schema) return this.config.Ts.Keyword.Any;
|
|
271
|
-
|
|
272
|
-
const refTypeInfo = this.schemaUtils.getSchemaRefType(schema);
|
|
273
|
-
|
|
274
|
-
if (refTypeInfo) {
|
|
275
|
-
return this.schemaUtils.checkAndAddRequiredKeys(
|
|
276
|
-
schema,
|
|
277
|
-
this.schemaUtils.safeAddNullToType(schema, this.typeName.format(refTypeInfo.typeName)),
|
|
278
|
-
);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
const primitiveType = this.schemaUtils.getSchemaPrimitiveType(schema);
|
|
282
|
-
|
|
283
|
-
if (primitiveType == null) return this.config.Ts.Keyword.Any;
|
|
284
|
-
|
|
285
|
-
let resultType;
|
|
286
|
-
|
|
287
|
-
const typeAlias =
|
|
288
|
-
_.get(this.config.primitiveTypes, [primitiveType, schema.format]) ||
|
|
289
|
-
_.get(this.config.primitiveTypes, [primitiveType, "$default"]) ||
|
|
290
|
-
this.config.primitiveTypes[primitiveType];
|
|
291
|
-
|
|
292
|
-
if (_.isFunction(typeAlias)) {
|
|
293
|
-
resultType = typeAlias(schema, this);
|
|
294
|
-
} else {
|
|
295
|
-
resultType = typeAlias || primitiveType;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (!resultType) return this.config.Ts.Keyword.Any;
|
|
299
|
-
|
|
300
|
-
return this.schemaUtils.checkAndAddRequiredKeys(schema, this.schemaUtils.safeAddNullToType(schema, resultType));
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
getObjectSchemaContent = (schema) => {
|
|
304
|
-
const { properties, additionalProperties } = schema || {};
|
|
305
|
-
|
|
306
|
-
const propertiesContent = _.map(properties, (property, name) => {
|
|
307
|
-
this.$processingSchemaPath.push(name);
|
|
308
|
-
const required = this.schemaUtils.isPropertyRequired(name, property, schema);
|
|
309
|
-
const rawTypeData = _.get(this.schemaUtils.getSchemaRefType(property), "rawTypeData", {});
|
|
310
|
-
const nullable = !!(rawTypeData.nullable || property.nullable);
|
|
311
|
-
const fieldName = this.typeName.isValidName(name) ? name : this.config.Ts.StringValue(name);
|
|
312
|
-
const fieldValue = this.getInlineParseContent(property);
|
|
313
|
-
const readOnly = property.readOnly;
|
|
314
|
-
|
|
315
|
-
this.$processingSchemaPath.pop();
|
|
316
|
-
|
|
317
|
-
return {
|
|
318
|
-
...property,
|
|
319
|
-
$$raw: property,
|
|
320
|
-
title: property.title,
|
|
321
|
-
description:
|
|
322
|
-
property.description ||
|
|
323
|
-
_.compact(_.map(property[this.getComplexType(property)], "description"))[0] ||
|
|
324
|
-
rawTypeData.description ||
|
|
325
|
-
_.compact(_.map(rawTypeData[this.getComplexType(rawTypeData)], "description"))[0] ||
|
|
326
|
-
"",
|
|
327
|
-
isRequired: required,
|
|
328
|
-
isNullable: nullable,
|
|
329
|
-
name: fieldName,
|
|
330
|
-
value: fieldValue,
|
|
331
|
-
field: this.config.Ts.TypeField({
|
|
332
|
-
readonly: readOnly && this.config.addReadonly,
|
|
333
|
-
optional: !required,
|
|
334
|
-
key: fieldName,
|
|
335
|
-
value: fieldValue,
|
|
336
|
-
}),
|
|
337
|
-
};
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
if (additionalProperties) {
|
|
341
|
-
propertiesContent.push({
|
|
342
|
-
$$raw: { additionalProperties },
|
|
343
|
-
description: "",
|
|
344
|
-
isRequired: false,
|
|
345
|
-
field: this.config.Ts.InterfaceDynamicField(this.config.Ts.Keyword.String, this.config.Ts.Keyword.Any),
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
return propertiesContent;
|
|
350
|
-
};
|
|
373
|
+
buildTypeNameFromPath = () => {
|
|
374
|
+
const schemaPath = _.uniq(_.compact(this.schemaPath));
|
|
351
375
|
|
|
352
|
-
|
|
353
|
-
if (schema.oneOf) return SCHEMA_TYPES.COMPLEX_ONE_OF;
|
|
354
|
-
if (schema.allOf) return SCHEMA_TYPES.COMPLEX_ALL_OF;
|
|
355
|
-
if (schema.anyOf) return SCHEMA_TYPES.COMPLEX_ANY_OF;
|
|
356
|
-
// TODO :(
|
|
357
|
-
if (schema.not) return SCHEMA_TYPES.COMPLEX_NOT;
|
|
376
|
+
if (!schemaPath || !schemaPath[0]) return null;
|
|
358
377
|
|
|
359
|
-
return
|
|
378
|
+
return internalCase(camelCase(`${schemaPath[0]}_${schemaPath[schemaPath.length - 1]}`));
|
|
360
379
|
};
|
|
361
380
|
|
|
362
381
|
/**
|
|
@@ -364,59 +383,110 @@ class SchemaParser {
|
|
|
364
383
|
* @param schema {any}
|
|
365
384
|
* @param typeName {null | string}
|
|
366
385
|
* @param formatter {"inline" | "base"}
|
|
367
|
-
* @return {Record<string, any
|
|
386
|
+
* @return {Promise<Record<string, any>>}
|
|
368
387
|
*/
|
|
369
|
-
|
|
370
|
-
if (!schema) return this.
|
|
388
|
+
parse = async () => {
|
|
389
|
+
if (!this.schema) return await this._baseSchemaParsers[SCHEMA_TYPES.PRIMITIVE](null, this.typeName);
|
|
371
390
|
|
|
372
391
|
let schemaType = null;
|
|
373
392
|
let parsedSchema = null;
|
|
374
393
|
|
|
375
|
-
if (typeof schema === "string") {
|
|
376
|
-
return schema;
|
|
394
|
+
if (typeof this.schema === "string") {
|
|
395
|
+
return this.schema;
|
|
377
396
|
}
|
|
378
397
|
|
|
379
|
-
if (!schema.$parsed) {
|
|
380
|
-
if (!typeName && this.schemaUtils.isRefSchema(schema)) {
|
|
381
|
-
typeName = this.getSchemaType(schema);
|
|
398
|
+
if (!this.schema.$parsed) {
|
|
399
|
+
if (!this.typeName && this.schemaUtils.isRefSchema(this.schema)) {
|
|
400
|
+
this.typeName = await this.schemaUtils.getSchemaType(this.schema);
|
|
382
401
|
}
|
|
383
402
|
|
|
384
|
-
if (schema.items && !Array.isArray(schema.items) && !schema.type) {
|
|
385
|
-
schema.type = SCHEMA_TYPES.ARRAY;
|
|
403
|
+
if (this.schema.items && !Array.isArray(this.schema.items) && !this.schema.type) {
|
|
404
|
+
this.schema.type = SCHEMA_TYPES.ARRAY;
|
|
386
405
|
}
|
|
387
|
-
schemaType = this.getInternalSchemaType(schema);
|
|
406
|
+
schemaType = this.schemaUtils.getInternalSchemaType(this.schema);
|
|
388
407
|
|
|
389
|
-
this
|
|
408
|
+
this.schemaPath.push(this.typeName);
|
|
390
409
|
|
|
391
|
-
_.merge(schema, this.config.hooks.onPreParseSchema(schema, typeName, schemaType));
|
|
392
|
-
parsedSchema = this.
|
|
393
|
-
schema.$parsed = this.config.hooks.onParseSchema(schema, parsedSchema) || parsedSchema;
|
|
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;
|
|
394
413
|
}
|
|
395
414
|
|
|
396
|
-
this
|
|
415
|
+
this.schemaPath.pop();
|
|
397
416
|
|
|
398
|
-
return schema.$parsed;
|
|
417
|
+
return this.schema.$parsed;
|
|
399
418
|
};
|
|
400
419
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
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);
|
|
405
427
|
};
|
|
406
428
|
|
|
407
|
-
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
return formattedSchema.content;
|
|
429
|
+
getInlineContent = async () => {
|
|
430
|
+
const schema = await this.format({ formatType: "inline" });
|
|
431
|
+
return schema.content;
|
|
411
432
|
};
|
|
412
433
|
|
|
413
|
-
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
434
|
+
getContent = async () => {
|
|
435
|
+
const schema = await this.format({ formatType: "base" });
|
|
436
|
+
return schema.content;
|
|
437
|
+
};
|
|
417
438
|
|
|
418
|
-
|
|
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,
|
|
455
|
+
);
|
|
419
456
|
};
|
|
457
|
+
|
|
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,
|
|
488
|
+
);
|
|
489
|
+
}
|
|
420
490
|
}
|
|
421
491
|
|
|
422
492
|
module.exports = {
|