Skip to content

Commit 614aac2

Browse files
committed
fix: try to fix problem with extracting enums
1 parent 00d77f9 commit 614aac2

File tree

12 files changed

+408
-238
lines changed

12 files changed

+408
-238
lines changed

src/code-gen-process.js

Lines changed: 24 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const { CodeFormatter } = require("./code-formatter");
1616
const { pascalCase } = require("./util/pascal-case");
1717
const { internalCase } = require("./util/internal-case");
1818
const { sortByProperty } = require("./util/sort-by-property");
19+
const { DataContracts } = require("./data-contracts");
1920

2021
const PATCHABLE_INSTANCES = [
2122
"schemaWalker",
@@ -52,6 +53,8 @@ class CodeGenProcess {
5253
templatesWorker;
5354
/** @type {SchemaWalker} */
5455
schemaWalker;
56+
/** @type {DataContracts} */
57+
dataContracts;
5558
/** @type {JavascriptTranslator} */
5659
javascriptTranslator;
5760

@@ -70,9 +73,13 @@ class CodeGenProcess {
7073
this.templatesWorker = new TemplatesWorker(this);
7174
this.codeFormatter = new CodeFormatter(this);
7275
this.schemaParserFabric = new SchemaParserFabric(this);
76+
this.dataContracts = new DataContracts(this);
7377
this.schemaRoutes = new SchemaRoutes(this);
7478
this.javascriptTranslator = new JavascriptTranslator(this);
79+
7580
this.config.componentTypeNameResolver.logger = this.logger;
81+
this.schemaParserFabric.dataContracts = this.dataContracts;
82+
this.schemaParserFabric.schemaUtils.dataContracts = this.dataContracts;
7683
}
7784

7885
async start() {
@@ -99,24 +106,16 @@ class CodeGenProcess {
99106

100107
_.each(swagger.usageSchema.components, (component, componentName) =>
101108
_.each(component, (rawTypeData, typeName) => {
102-
this.schemaComponentsMap.createComponent(
103-
this.schemaComponentsMap.createRef(["components", componentName, typeName]),
104-
rawTypeData,
105-
);
109+
this.dataContracts.add({
110+
schema: rawTypeData,
111+
name: typeName,
112+
contractType: componentName,
113+
});
106114
}),
107115
);
108116

109-
const schemaComponents = this.schemaComponentsMap.filter("schemas");
110-
111-
const parsedSchemas = schemaComponents.map((schemaComponent) => {
112-
const parsed = this.schemaParserFabric.parseSchema(schemaComponent.rawTypeData, schemaComponent.typeName);
113-
schemaComponent.typeData = parsed;
114-
return parsed;
115-
});
116-
117117
this.schemaRoutes.attachSchema({
118118
usageSchema: swagger.usageSchema,
119-
parsedSchemas,
120119
});
121120

122121
const rawConfiguration = {
@@ -206,65 +205,22 @@ class CodeGenProcess {
206205
};
207206

208207
collectModelTypes = () => {
209-
const components = this.schemaComponentsMap.getComponents();
210-
let modelTypes = [];
211-
212-
const getSchemaComponentsCount = () => components.filter((c) => c.componentName === "schemas").length;
213-
214-
let schemaComponentsCount = getSchemaComponentsCount();
215-
let processedCount = 0;
216-
217-
while (processedCount < schemaComponentsCount) {
218-
modelTypes = [];
219-
processedCount = 0;
220-
for (const component of components) {
221-
if (component.componentName === "schemas") {
222-
const modelType = this.prepareModelType(component);
223-
if (modelType) {
224-
modelTypes.push(modelType);
225-
}
226-
processedCount++;
227-
}
228-
}
229-
schemaComponentsCount = getSchemaComponentsCount();
230-
}
208+
let dataContracts = [...this.dataContracts.values];
231209

232210
if (this.config.sortTypes) {
233-
return modelTypes.sort(sortByProperty("name"));
211+
return dataContracts.sort(sortByProperty("name"));
234212
}
235213

236-
return modelTypes;
237-
};
238-
239-
prepareModelType = (typeInfo) => {
240-
if (typeInfo.$prepared) return typeInfo.$prepared;
241-
242-
if (!typeInfo.typeData) {
243-
typeInfo.typeData = this.schemaParserFabric.parseSchema(typeInfo.rawTypeData, typeInfo.typeName);
244-
}
245-
const rawTypeData = typeInfo.typeData;
246-
const typeData = this.schemaParserFabric.schemaFormatters.base[rawTypeData.type]
247-
? this.schemaParserFabric.schemaFormatters.base[rawTypeData.type](rawTypeData)
248-
: rawTypeData;
249-
let { typeIdentifier, name: originalName, content, description } = typeData;
250-
const name = this.typeNameFormatter.format(originalName);
251-
252-
if (name === null) return null;
253-
254-
const preparedModelType = {
255-
...typeData,
256-
typeIdentifier,
257-
name,
258-
description,
259-
$content: rawTypeData.content,
260-
rawContent: rawTypeData.content,
261-
content: content,
262-
typeData,
263-
};
264-
265-
typeInfo.$prepared = preparedModelType;
266-
267-
return preparedModelType;
214+
return dataContracts.map((dataContract) => {
215+
return {
216+
...dataContract.schemas.parsed,
217+
name: dataContract.name,
218+
$content: dataContract.schemas.parsed.content,
219+
rawContent: dataContract.schemas.parsed.content,
220+
content: dataContract.content,
221+
typeData: dataContract.schemas.parsed,
222+
};
223+
});
268224
};
269225

270226
/**

src/data-contracts.js

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
const _ = require("lodash");
2+
3+
/**
4+
* @typedef {{
5+
* $ref: string,
6+
* schemas: { original: Record<string, any>, parsed: Record<string, any>, ref: Record<string, any> },
7+
* content: Record<string, any> | string,
8+
* inlineContent: string,
9+
* refContent: string,
10+
* name: string,
11+
* typeName: string,
12+
* linkers: string[],
13+
* }} DataContract
14+
*/
15+
16+
class DataContracts {
17+
/** @type {CodeGenConfig} */
18+
config;
19+
/** @type {Logger} */
20+
logger;
21+
/** @type {SchemaParserFabric} */
22+
schemaParserFabric;
23+
/** @type {TypeNameFormatter} */
24+
typeNameFormatter;
25+
/** @type {SchemaUtils} */
26+
schemaUtils;
27+
/** @type {SchemaComponentsMap} */
28+
schemaComponentsMap;
29+
30+
/** @type {DataContract[]} */
31+
values;
32+
33+
constructor({ config, logger, schemaParserFabric }) {
34+
this.values = [];
35+
this.config = config;
36+
this.logger = logger;
37+
this.schemaParserFabric = schemaParserFabric;
38+
this.schemaUtils = this.schemaParserFabric.schemaUtils;
39+
this.typeNameFormatter = this.schemaParserFabric.typeNameFormatter;
40+
this.schemaComponentsMap = this.schemaParserFabric.schemaComponentsMap;
41+
}
42+
43+
_createDataContractNames = (name, builder) => {
44+
if (!builder) {
45+
const formatted = this.typeNameFormatter.format(name);
46+
const usageName = this.config.componentTypeNameResolver.resolve([formatted]);
47+
48+
return { formatted, usageName, originalName: name };
49+
}
50+
51+
const { usageName, original, formatted } = builder();
52+
53+
return { formatted: formatted || usageName, usageName, originalName: original || null };
54+
};
55+
56+
/**
57+
*
58+
* @param schema
59+
* @param name
60+
* @param $ref
61+
* @param {() => ({ usageName: string, formatted: string, original: string })} [nameBuilder]
62+
* @returns {DataContract}
63+
*/
64+
add = ({ schema, name, nameBuilder, contractType = "schemas", schemaPath }) => {
65+
const { formatted, usageName, originalName } = this._createDataContractNames(name, nameBuilder);
66+
const parser = this.schemaParserFabric.createSchemaParser({
67+
schema,
68+
typeName: originalName,
69+
schemaPath,
70+
});
71+
const parsed = parser.parseSchema();
72+
const $ref = this.schemaComponentsMap.createRef(["components", contractType, usageName]);
73+
74+
const refContent = usageName;
75+
76+
const linkers = _.uniq(
77+
_.compact([
78+
originalName,
79+
usageName,
80+
formatted,
81+
$ref,
82+
originalName && this.typeNameFormatter.format(originalName, { onlyFormat: true }),
83+
originalName && this.schemaComponentsMap.createRef(["components", "schemas", originalName]),
84+
this.schemaComponentsMap.createRef(["components", "schemas", formatted]),
85+
refContent,
86+
]),
87+
);
88+
89+
/**
90+
* @type {DataContract}
91+
*/
92+
const dataContract = {
93+
$ref: $ref,
94+
schemas: {
95+
original: schema,
96+
parsed,
97+
},
98+
refContent,
99+
content: parser.getParseContent(),
100+
inlineContent: parser.getInlineParseContent(),
101+
name: usageName,
102+
typeName: usageName,
103+
linkers: linkers,
104+
};
105+
106+
this.values.push(dataContract);
107+
108+
dataContract.schemas.ref = this.schemaParserFabric.parseSchema({ $ref: $ref });
109+
110+
return dataContract;
111+
};
112+
113+
/**
114+
* @param name
115+
* @returns {DataContract | null}
116+
*/
117+
findByLinker = (name) => {
118+
return this.values.find((value) => value.linkers.includes(name)) || null;
119+
};
120+
121+
/**
122+
* @param content
123+
* @returns {DataContract | null}
124+
*/
125+
findByContent = (content) => {
126+
return (
127+
this.values.find(
128+
(value) =>
129+
_.isEqual(value.content, content) ||
130+
_.isEqual(value.inlineContent, content) ||
131+
_.isEqual(value.refContent, content),
132+
) || null
133+
);
134+
};
135+
}
136+
137+
module.exports = {
138+
DataContracts,
139+
};

src/schema-parser/base-schema-parsers/discriminator.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,19 @@ class DiscriminatorSchemaParser extends MonoSchemaParser {
210210
prefixes: this.config.extractingOptions.discriminatorAbstractPrefix,
211211
resolver: this.config.extractingOptions.discriminatorAbstractResolver,
212212
});
213+
this.dataContracts.add({
214+
schema: { ...schema, internal: true },
215+
nameBuilder: () => {
216+
const usageName = this.schemaUtils.resolveTypeName(this.typeName, {
217+
prefixes: this.config.extractingOptions.discriminatorAbstractPrefix,
218+
resolver: this.config.extractingOptions.discriminatorAbstractResolver,
219+
});
220+
return {
221+
usageName,
222+
original: this.typeName,
223+
};
224+
},
225+
});
213226
const component = this.schemaComponentsMap.createComponent(
214227
this.schemaComponentsMap.createRef(["components", "schemas", typeName]),
215228
{

src/schema-parser/base-schema-parsers/enum.js

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,21 @@ class EnumSchemaParser extends MonoSchemaParser {
1414
}
1515

1616
extractEnum = (pathTypeName) => {
17-
const generatedTypeName = this.schemaUtils.resolveTypeName(pathTypeName, {
18-
suffixes: this.config.extractingOptions.enumSuffix,
19-
resolver: this.config.extractingOptions.enumNameResolver,
20-
});
21-
const customComponent = this.schemaComponentsMap.createComponent(
22-
this.schemaComponentsMap.createRef(["components", "schemas", generatedTypeName]),
23-
{
24-
...this.schema,
17+
const dataContract = this.dataContracts.add({
18+
schema: { ...this.schema },
19+
nameBuilder: () => {
20+
const usageName = this.schemaUtils.resolveTypeName(pathTypeName, {
21+
suffixes: this.config.extractingOptions.enumSuffix,
22+
resolver: this.config.extractingOptions.enumNameResolver,
23+
});
24+
25+
return {
26+
usageName,
27+
original: pathTypeName,
28+
};
2529
},
26-
);
27-
return this.schemaParserFabric.parseSchema(customComponent);
30+
});
31+
return dataContract.schemas.ref;
2832
};
2933

3034
parse() {
@@ -34,8 +38,7 @@ class EnumSchemaParser extends MonoSchemaParser {
3438
return this.extractEnum(pathTypeName);
3539
}
3640

37-
const refType = this.schemaUtils.getSchemaRefType(this.schema);
38-
const $ref = (refType && refType.$ref) || null;
41+
const dc = this.schemaUtils.findDataContract(this.schema);
3942

4043
// fix schema when enum has length 1+ but value is []
4144
if (Array.isArray(this.schema.enum)) {
@@ -104,8 +107,8 @@ class EnumSchemaParser extends MonoSchemaParser {
104107

105108
return {
106109
...(_.isObject(this.schema) ? this.schema : {}),
107-
$ref: $ref,
108-
typeName: this.typeName || ($ref && refType.typeName) || null,
110+
$ref: dc?.$ref,
111+
typeName: this.typeName || (dc?.$ref && dc?.name) || null,
109112
$parsedSchema: true,
110113
schemaType: SCHEMA_TYPES.ENUM,
111114
type: SCHEMA_TYPES.ENUM,

src/schema-parser/base-schema-parsers/object.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ class ObjectSchemaParser extends MonoSchemaParser {
2424
const { properties, additionalProperties } = schema || {};
2525

2626
const propertiesContent = _.map(properties, (property, name) => {
27+
/** @type {DataContract|null} */
28+
const propDc = this.schemaUtils.findDataContract(property);
2729
const required = this.schemaUtils.isPropertyRequired(name, property, schema);
28-
const rawTypeData = _.get(this.schemaUtils.getSchemaRefType(property), "rawTypeData", {});
29-
const nullable = !!(rawTypeData.nullable || property.nullable);
30+
const parsedDcSchema = propDc?.schemas.parsed || {};
31+
const nullable = !!(parsedDcSchema.nullable || property.nullable);
3032
const fieldName = this.typeNameFormatter.isValidName(name) ? name : this.config.Ts.StringValue(name);
3133
const fieldValue = this.schemaParserFabric
3234
.createSchemaParser({ schema: property, schemaPath: [...this.schemaPath, name] })
@@ -40,8 +42,8 @@ class ObjectSchemaParser extends MonoSchemaParser {
4042
description:
4143
property.description ||
4244
_.compact(_.map(property[this.schemaUtils.getComplexType(property)], "description"))[0] ||
43-
rawTypeData.description ||
44-
_.compact(_.map(rawTypeData[this.schemaUtils.getComplexType(rawTypeData)], "description"))[0] ||
45+
parsedDcSchema.description ||
46+
_.compact(_.map(parsedDcSchema[this.schemaUtils.getComplexType(parsedDcSchema)], "description"))[0] ||
4547
"",
4648
isRequired: required,
4749
isNullable: nullable,

src/schema-parser/mono-schema-parser.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class MonoSchemaParser {
2121
config;
2222
/** @type {SchemaFormatters} */
2323
schemaFormatters;
24+
/** @type {DataContracts} */
25+
dataContracts;
2426

2527
constructor(schemaParser, schema, typeName = null, schemaPath = []) {
2628
this.schemaParser = schemaParser;
@@ -34,6 +36,7 @@ class MonoSchemaParser {
3436
this.schemaUtils = this.schemaParser.schemaUtils;
3537
this.config = this.schemaParser.config;
3638
this.schemaFormatters = this.schemaParser.schemaFormatters;
39+
this.dataContracts = this.schemaParser.dataContracts;
3740
}
3841

3942
parse() {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy