@odata2ts/odata2ts 0.23.1 → 0.25.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 (78) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/lib/FactoryFunctionModel.d.ts +13 -13
  3. package/lib/FactoryFunctionModel.js +2 -2
  4. package/lib/FactoryFunctionModel.js.map +1 -1
  5. package/lib/NamingModel.d.ts +182 -182
  6. package/lib/NamingModel.js +11 -11
  7. package/lib/NamingModel.js.map +1 -1
  8. package/lib/OptionModel.d.ts +228 -223
  9. package/lib/OptionModel.js +23 -23
  10. package/lib/OptionModel.js.map +1 -1
  11. package/lib/app.d.ts +8 -8
  12. package/lib/app.js +67 -63
  13. package/lib/app.js.map +1 -1
  14. package/lib/cli.d.ts +3 -3
  15. package/lib/cli.js +153 -153
  16. package/lib/data-model/DataModel.d.ts +88 -85
  17. package/lib/data-model/DataModel.js +141 -134
  18. package/lib/data-model/DataModel.js.map +1 -1
  19. package/lib/data-model/DataModelDigestion.d.ts +48 -44
  20. package/lib/data-model/DataModelDigestion.js +299 -274
  21. package/lib/data-model/DataModelDigestion.js.map +1 -1
  22. package/lib/data-model/DataModelDigestionV2.d.ts +10 -10
  23. package/lib/data-model/DataModelDigestionV2.js +210 -200
  24. package/lib/data-model/DataModelDigestionV2.js.map +1 -1
  25. package/lib/data-model/DataModelDigestionV4.d.ts +3 -3
  26. package/lib/data-model/DataModelDigestionV4.js +197 -195
  27. package/lib/data-model/DataModelDigestionV4.js.map +1 -1
  28. package/lib/data-model/DataTypeModel.d.ts +102 -102
  29. package/lib/data-model/DataTypeModel.js +8 -8
  30. package/lib/data-model/DataTypeModel.js.map +1 -1
  31. package/lib/data-model/NamingHelper.d.ts +57 -55
  32. package/lib/data-model/NamingHelper.js +231 -214
  33. package/lib/data-model/NamingHelper.js.map +1 -1
  34. package/lib/data-model/ServiceConfigHelper.d.ts +21 -21
  35. package/lib/data-model/ServiceConfigHelper.js +113 -113
  36. package/lib/data-model/edmx/ODataEdmxModelBase.d.ts +92 -80
  37. package/lib/data-model/edmx/ODataEdmxModelBase.js +2 -2
  38. package/lib/data-model/edmx/ODataEdmxModelBase.js.map +1 -1
  39. package/lib/data-model/edmx/ODataEdmxModelV3.d.ts +63 -63
  40. package/lib/data-model/edmx/ODataEdmxModelV3.js +2 -2
  41. package/lib/data-model/edmx/ODataEdmxModelV4.d.ts +67 -67
  42. package/lib/data-model/edmx/ODataEdmxModelV4.js +2 -2
  43. package/lib/defaultConfig.d.ts +9 -9
  44. package/lib/defaultConfig.js +165 -164
  45. package/lib/defaultConfig.js.map +1 -1
  46. package/lib/evaluateConfig.d.ts +25 -25
  47. package/lib/evaluateConfig.js +82 -82
  48. package/lib/generator/ImportContainer.d.ts +16 -16
  49. package/lib/generator/ImportContainer.js +91 -91
  50. package/lib/generator/ModelGenerator.d.ts +2 -2
  51. package/lib/generator/ModelGenerator.js +211 -183
  52. package/lib/generator/ModelGenerator.js.map +1 -1
  53. package/lib/generator/QueryObjectGenerator.d.ts +2 -2
  54. package/lib/generator/QueryObjectGenerator.js +239 -239
  55. package/lib/generator/ServiceGenerator.d.ts +8 -8
  56. package/lib/generator/ServiceGenerator.js +422 -422
  57. package/lib/generator/index.d.ts +3 -3
  58. package/lib/generator/index.js +9 -9
  59. package/lib/index.d.ts +3 -3
  60. package/lib/index.js +6 -6
  61. package/lib/project/ProjectManager.d.ts +30 -30
  62. package/lib/project/ProjectManager.js +177 -175
  63. package/lib/project/ProjectManager.js.map +1 -1
  64. package/lib/project/formatter/BaseFormatter.d.ts +49 -49
  65. package/lib/project/formatter/BaseFormatter.js +30 -30
  66. package/lib/project/formatter/FileFormatter.d.ts +16 -16
  67. package/lib/project/formatter/FileFormatter.js +2 -2
  68. package/lib/project/formatter/NoopFormatter.d.ts +29 -29
  69. package/lib/project/formatter/NoopFormatter.js +42 -42
  70. package/lib/project/formatter/PrettierFormatter.d.ts +46 -46
  71. package/lib/project/formatter/PrettierFormatter.js +92 -92
  72. package/lib/project/formatter/index.d.ts +2 -2
  73. package/lib/project/formatter/index.js +14 -14
  74. package/lib/project/logger/logFilePath.d.ts +1 -1
  75. package/lib/project/logger/logFilePath.js +12 -12
  76. package/lib/run-cli.d.ts +2 -2
  77. package/lib/run-cli.js +6 -6
  78. package/package.json +27 -28
@@ -1,275 +1,300 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Digester = void 0;
4
- const tslib_1 = require("tslib");
5
- const DataModel_1 = require("./DataModel");
6
- const ServiceConfigHelper_1 = require("./ServiceConfigHelper");
7
- class Digester {
8
- constructor(version, schema, options, namingHelper, converters) {
9
- this.version = version;
10
- this.schema = schema;
11
- this.options = options;
12
- this.namingHelper = namingHelper;
13
- this.model2Type = new Map();
14
- this.mapProp = (p) => {
15
- if (!p.$.Type) {
16
- throw new Error(`No type information given for property [${p.$.Name}]!`);
17
- }
18
- const isCollection = !!p.$.Type.match(/^Collection\(/);
19
- const dataType = p.$.Type.replace(/^Collection\(([^\)]+)\)/, "$1");
20
- const configProp = this.serviceConfigHelper.findConfigPropByName(p.$.Name);
21
- const name = this.namingHelper.getModelPropName((configProp === null || configProp === void 0 ? void 0 : configProp.mappedName) || p.$.Name);
22
- let result;
23
- // domain object known from service:
24
- // EntityType, ComplexType or EnumType
25
- if (dataType.startsWith(this.namingHelper.getServicePrefix())) {
26
- const resultDt = this.model2Type.get(dataType);
27
- if (!resultDt) {
28
- throw new Error(`Couldn't determine model type for data type with name '${dataType}'`);
29
- }
30
- // special handling for enums
31
- if (resultDt === "EnumType" /* DataTypes.EnumType */) {
32
- result = {
33
- dataType: resultDt,
34
- type: this.namingHelper.getEnumName(dataType),
35
- qPath: "QEnumPath",
36
- qObject: isCollection ? "QEnumCollection" : undefined,
37
- qParam: "QEnumParam",
38
- };
39
- }
40
- // handling of complex & entity types
41
- else {
42
- result = {
43
- dataType: resultDt,
44
- type: this.namingHelper.getModelName(dataType),
45
- qPath: "QEntityPath",
46
- qObject: this.namingHelper.getQName(dataType),
47
- qParam: "QComplexParam",
48
- };
49
- }
50
- }
51
- // OData built-in data types
52
- else if (dataType.startsWith(Digester.EDM_PREFIX)) {
53
- const { outputType, qPath, qParam, qCollection } = this.mapODataType(dataType);
54
- const { to, toModule: typeModule, converters } = this.dataModel.getConverter(dataType) || {};
55
- const type = !to ? outputType : to.startsWith(Digester.EDM_PREFIX) ? this.mapODataType(to).outputType : to;
56
- result = {
57
- dataType: "PrimitiveType" /* DataTypes.PrimitiveType */,
58
- type,
59
- typeModule,
60
- qPath,
61
- qParam,
62
- qObject: isCollection ? qCollection : undefined,
63
- converters,
64
- };
65
- }
66
- else {
67
- throw new Error(`Unknown type [${dataType}]: Not 'Collection(...)', not '${this.namingHelper.getServicePrefix()}*', not OData type 'Edm.*'`);
68
- }
69
- return Object.assign({ odataName: p.$.Name, name, odataType: p.$.Type, required: p.$.Nullable === "false", isCollection: isCollection, managed: configProp === null || configProp === void 0 ? void 0 : configProp.managed }, result);
70
- };
71
- this.dataModel = new DataModel_1.DataModel(version, converters);
72
- this.serviceConfigHelper = new ServiceConfigHelper_1.ServiceConfigHelper(options);
73
- this.collectModelTypes(this.schema);
74
- }
75
- digest() {
76
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
77
- this.digestSchema(this.schema);
78
- return this.dataModel;
79
- });
80
- }
81
- collectModelTypes(schema) {
82
- var _a, _b, _c;
83
- const servicePrefix = this.namingHelper.getServicePrefix();
84
- (_a = schema.EnumType) === null || _a === void 0 ? void 0 : _a.forEach((et) => {
85
- this.model2Type.set(servicePrefix + et.$.Name, "EnumType" /* DataTypes.EnumType */);
86
- });
87
- (_b = schema.ComplexType) === null || _b === void 0 ? void 0 : _b.forEach((ct) => {
88
- this.model2Type.set(servicePrefix + ct.$.Name, "ComplexType" /* DataTypes.ComplexType */);
89
- });
90
- (_c = schema.EntityType) === null || _c === void 0 ? void 0 : _c.forEach((et) => {
91
- this.model2Type.set(servicePrefix + et.$.Name, "ModelType" /* DataTypes.ModelType */);
92
- });
93
- }
94
- digestSchema(schema) {
95
- // enums
96
- if (schema.EnumType) {
97
- for (const et of schema.EnumType) {
98
- const name = et.$.Name;
99
- this.dataModel.addEnum(name, {
100
- odataName: name,
101
- name: this.namingHelper.getEnumName(name),
102
- members: et.Member.map((m) => m.$.Name),
103
- });
104
- }
105
- }
106
- // entity types
107
- this.addEntityType(schema.EntityType);
108
- // complex types
109
- this.addComplexType(schema.ComplexType);
110
- this.postProcessModel();
111
- // delegate to concrete entity container digestion
112
- this.digestEntityContainer();
113
- }
114
- getBaseModel(model) {
115
- var _a;
116
- const entityConfig = this.serviceConfigHelper.findConfigEntityByName(model.$.Name);
117
- const entityName = (entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.mappedName) || model.$.Name;
118
- const name = this.namingHelper.getModelName(entityName);
119
- const qName = this.namingHelper.getQName(entityName);
120
- const editableName = this.namingHelper.getEditableModelName(entityName);
121
- const odataName = model.$.Name;
122
- const bType = model.$.BaseType;
123
- const props = [...((_a = model.Property) !== null && _a !== void 0 ? _a : []), ...this.getNavigationProps(model)];
124
- // support for base types, i.e. extends clause of interfaces
125
- const baseClasses = [];
126
- if (bType) {
127
- baseClasses.push(this.namingHelper.getModelName(bType));
128
- }
129
- return {
130
- name,
131
- qName,
132
- odataName,
133
- editableName,
134
- baseClasses,
135
- props: props.map(this.mapProp),
136
- baseProps: [], // postprocess required
137
- };
138
- }
139
- addComplexType(models) {
140
- if (!models || !models.length) {
141
- return;
142
- }
143
- for (const model of models) {
144
- const baseModel = this.getBaseModel(model);
145
- this.dataModel.addComplexType(baseModel.name, baseModel);
146
- }
147
- }
148
- addEntityType(models) {
149
- var _a;
150
- if (!models || !models.length) {
151
- return;
152
- }
153
- for (const model of models) {
154
- const baseModel = this.getBaseModel(model);
155
- const entityConfig = this.serviceConfigHelper.findConfigEntityByName(model.$.Name);
156
- const entityName = (entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.mappedName) || model.$.Name;
157
- // key support: we add keys from this entity,
158
- // but not keys stemming from base classes (postprocess required)
159
- const keyNames = [];
160
- if ((_a = entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.keys) === null || _a === void 0 ? void 0 : _a.length) {
161
- keyNames.push(...entityConfig.keys);
162
- }
163
- else {
164
- const entity = model;
165
- if (entity.Key && entity.Key.length && entity.Key[0].PropertyRef.length) {
166
- const propNames = entity.Key[0].PropertyRef.map((key) => key.$.Name);
167
- keyNames.push(...propNames);
168
- }
169
- }
170
- this.dataModel.addModel(baseModel.name, Object.assign(Object.assign({}, baseModel), { idModelName: this.namingHelper.getIdModelName(entityName), qIdFunctionName: this.namingHelper.getQIdFunctionName(entityName), generateId: true, keyNames: keyNames, keys: [], getKeyUnion: () => keyNames.join(" | ") }));
171
- }
172
- }
173
- postProcessModel() {
174
- // complex types
175
- const complexTypes = this.dataModel.getComplexTypes();
176
- complexTypes.forEach((model) => {
177
- const [baseProps] = this.collectBaseClassPropsAndKeys(model, []);
178
- model.baseProps = baseProps;
179
- });
180
- const modelTypes = this.dataModel.getModels();
181
- // entity types
182
- modelTypes.forEach((model) => {
183
- const [baseProps, baseKeys, idName, qIdName] = this.collectBaseClassPropsAndKeys(model, []);
184
- model.baseProps = baseProps;
185
- if (!model.keyNames.length && idName) {
186
- model.idModelName = idName;
187
- model.qIdFunctionName = qIdName;
188
- model.generateId = false;
189
- }
190
- model.keyNames.unshift(...baseKeys);
191
- // sanity check: entity types require key specification
192
- if (!model.keyNames.length) {
193
- throw new Error(`Key property is missing from Entity "${model.name}" (${model.odataName})!`);
194
- }
195
- const isSingleKey = model.keyNames.length === 1;
196
- const props = [...model.baseProps, ...model.props];
197
- model.keys = model.keyNames.map((keyName) => {
198
- const prop = props.find((p) => p.odataName === keyName);
199
- if (!prop) {
200
- throw new Error(`Key with name [${keyName}] not found in props!`);
201
- }
202
- // automatically set key prop to managed, if this is the only key of the given entity
203
- if (prop.managed === undefined) {
204
- prop.managed = !this.options.disableAutoManagedKey && isSingleKey;
205
- }
206
- return prop;
207
- });
208
- });
209
- const sortedModelTypes = this.sortModelsByInheritance(modelTypes);
210
- this.dataModel.setModels(sortedModelTypes);
211
- const sortedComplexTypes = this.sortModelsByInheritance(complexTypes);
212
- this.dataModel.setComplexTypes(sortedComplexTypes);
213
- }
214
- sortModelsByInheritance(models) {
215
- // recursively visit all models and sort them by inheritance such that base classes
216
- // are always before derived classes
217
- const sortedModels = {};
218
- const visitedModels = new Set();
219
- const inProgressModels = new Set();
220
- function visit(model) {
221
- if (inProgressModels.has(model)) {
222
- throw new Error("Cyclic dependencies detected!");
223
- }
224
- if (!visitedModels.has(model)) {
225
- inProgressModels.add(model);
226
- for (const baseClassName of model.baseClasses) {
227
- const baseClass = models.find((e) => e.name === baseClassName);
228
- if (baseClass) {
229
- visit(baseClass);
230
- }
231
- }
232
- visitedModels.add(model);
233
- inProgressModels.delete(model);
234
- sortedModels[model.name] = model;
235
- }
236
- }
237
- for (const model of models) {
238
- visit(model);
239
- }
240
- return sortedModels;
241
- }
242
- collectBaseClassPropsAndKeys(model, visitedModels) {
243
- if (visitedModels.includes(model.name)) {
244
- throw new Error(`Cyclic inheritance detected for model ${model.name}!`);
245
- }
246
- visitedModels.push(model.name);
247
- return model.baseClasses.reduce(([props, keys, idName, qIdName], bc) => {
248
- var _a;
249
- const baseModel = this.dataModel.getModel(bc) || this.dataModel.getComplexType(bc);
250
- let idNameResult = idName;
251
- let qIdNameResult = qIdName;
252
- // recursive
253
- if (baseModel.baseClasses.length) {
254
- const [parentProps, parentKeys, parentIdName, parentQIdName] = this.collectBaseClassPropsAndKeys(baseModel, visitedModels);
255
- props.unshift(...parentProps);
256
- keys.unshift(...parentKeys);
257
- if (parentIdName) {
258
- idNameResult = parentIdName;
259
- qIdNameResult = parentQIdName;
260
- }
261
- }
262
- props.push(...baseModel.props);
263
- if ((_a = baseModel.keyNames) === null || _a === void 0 ? void 0 : _a.length) {
264
- keys.push(...baseModel.keyNames.filter((kn) => !keys.includes(kn)));
265
- idNameResult = baseModel.idModelName;
266
- qIdNameResult = baseModel.qIdFunctionName;
267
- }
268
- return [props, keys, idNameResult, qIdNameResult];
269
- }, [[], [], "", ""]);
270
- }
271
- }
272
- exports.Digester = Digester;
273
- Digester.EDM_PREFIX = "Edm.";
274
- Digester.ROOT_OPERATION = "/";
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Digester = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const DataModel_1 = require("./DataModel");
6
+ const ServiceConfigHelper_1 = require("./ServiceConfigHelper");
7
+ class Digester {
8
+ constructor(version, schemas, options, namingHelper, converters) {
9
+ this.version = version;
10
+ this.schemas = schemas;
11
+ this.options = options;
12
+ this.namingHelper = namingHelper;
13
+ this.model2Type = new Map();
14
+ this.mapProp = (p) => {
15
+ if (!p.$.Type) {
16
+ throw new Error(`No type information given for property [${p.$.Name}]!`);
17
+ }
18
+ const configProp = this.serviceConfigHelper.findConfigPropByName(p.$.Name);
19
+ const name = this.namingHelper.getModelPropName((configProp === null || configProp === void 0 ? void 0 : configProp.mappedName) || p.$.Name);
20
+ const isCollection = !!p.$.Type.match(/^Collection\(/);
21
+ let dataType = p.$.Type.replace(/^Collection\(([^\)]+)\)/, "$1");
22
+ if (this.namingHelper.includesServicePrefix(dataType)) {
23
+ const dtName = this.namingHelper.stripServicePrefix(dataType);
24
+ if (this.dataModel.getPrimitiveType(dtName) !== undefined) {
25
+ dataType = this.dataModel.getPrimitiveType(dtName);
26
+ }
27
+ }
28
+ let result;
29
+ // domain object known from service:
30
+ // EntityType, ComplexType, EnumType or TypeDefinition
31
+ if (this.namingHelper.includesServicePrefix(dataType)) {
32
+ const resultDt = this.model2Type.get(dataType);
33
+ if (!resultDt) {
34
+ throw new Error(`Couldn't determine model type for data type with name '${dataType}'`);
35
+ }
36
+ // special handling for enums
37
+ if (resultDt === "EnumType" /* DataTypes.EnumType */) {
38
+ result = {
39
+ dataType: resultDt,
40
+ type: this.namingHelper.getEnumName(dataType),
41
+ qPath: "QEnumPath",
42
+ qObject: isCollection ? "QEnumCollection" : undefined,
43
+ qParam: "QEnumParam",
44
+ };
45
+ }
46
+ // handling of complex & entity types
47
+ else {
48
+ result = {
49
+ dataType: resultDt,
50
+ type: this.namingHelper.getModelName(dataType),
51
+ qPath: "QEntityPath",
52
+ qObject: this.namingHelper.getQName(dataType),
53
+ qParam: "QComplexParam",
54
+ };
55
+ }
56
+ }
57
+ // OData built-in data types
58
+ else if (dataType.startsWith(Digester.EDM_PREFIX)) {
59
+ const { outputType, qPath, qParam, qCollection } = this.mapODataType(dataType);
60
+ const { to, toModule: typeModule, converters } = this.dataModel.getConverter(dataType) || {};
61
+ const type = !to ? outputType : to.startsWith(Digester.EDM_PREFIX) ? this.mapODataType(to).outputType : to;
62
+ result = {
63
+ dataType: "PrimitiveType" /* DataTypes.PrimitiveType */,
64
+ type,
65
+ typeModule,
66
+ qPath,
67
+ qParam,
68
+ qObject: isCollection ? qCollection : undefined,
69
+ converters,
70
+ };
71
+ }
72
+ else {
73
+ throw new Error(`Unknown type [${dataType}]: Not 'Collection(...)', not OData type 'Edm.*', not starting with one of the namespaces!W`);
74
+ }
75
+ return Object.assign({ odataName: p.$.Name, name, odataType: p.$.Type, required: p.$.Nullable === "false", isCollection: isCollection, managed: configProp === null || configProp === void 0 ? void 0 : configProp.managed }, result);
76
+ };
77
+ this.dataModel = new DataModel_1.DataModel(version, converters);
78
+ this.serviceConfigHelper = new ServiceConfigHelper_1.ServiceConfigHelper(options);
79
+ this.collectModelTypes(schemas);
80
+ }
81
+ digest() {
82
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
83
+ this.digestEntityTypesAndOperations();
84
+ // delegate to version specific entity container digestion
85
+ this.schemas.forEach((schema) => this.digestEntityContainer(schema));
86
+ return this.dataModel;
87
+ });
88
+ }
89
+ collectModelTypes(schemas) {
90
+ schemas.forEach((schema) => {
91
+ var _a, _b, _c;
92
+ const servicePrefix = schema.$.Namespace + ".";
93
+ (_a = schema.EnumType) === null || _a === void 0 ? void 0 : _a.forEach((et) => {
94
+ this.model2Type.set(servicePrefix + et.$.Name, "EnumType" /* DataTypes.EnumType */);
95
+ });
96
+ (_b = schema.ComplexType) === null || _b === void 0 ? void 0 : _b.forEach((ct) => {
97
+ this.model2Type.set(servicePrefix + ct.$.Name, "ComplexType" /* DataTypes.ComplexType */);
98
+ });
99
+ (_c = schema.EntityType) === null || _c === void 0 ? void 0 : _c.forEach((et) => {
100
+ this.model2Type.set(servicePrefix + et.$.Name, "ModelType" /* DataTypes.ModelType */);
101
+ });
102
+ });
103
+ }
104
+ digestEntityTypesAndOperations() {
105
+ this.schemas.forEach((schema) => {
106
+ // type definitions: alias for primitive types
107
+ this.addTypeDefinition(schema.TypeDefinition);
108
+ // enums
109
+ if (schema.EnumType) {
110
+ for (const et of schema.EnumType) {
111
+ const name = et.$.Name;
112
+ this.dataModel.addEnum(name, {
113
+ odataName: name,
114
+ name: this.namingHelper.getEnumName(name),
115
+ members: et.Member.map((m) => m.$.Name),
116
+ });
117
+ }
118
+ }
119
+ // entity types
120
+ this.addEntityType(schema.EntityType);
121
+ // complex types
122
+ this.addComplexType(schema.ComplexType);
123
+ // V4 only: function & action types
124
+ this.digestOperations(schema);
125
+ });
126
+ this.postProcessModel();
127
+ }
128
+ getBaseModel(model) {
129
+ var _a;
130
+ const entityConfig = this.serviceConfigHelper.findConfigEntityByName(model.$.Name);
131
+ const entityName = (entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.mappedName) || model.$.Name;
132
+ const name = this.namingHelper.getModelName(entityName);
133
+ const qName = this.namingHelper.getQName(entityName);
134
+ const editableName = this.namingHelper.getEditableModelName(entityName);
135
+ const odataName = model.$.Name;
136
+ const bType = model.$.BaseType;
137
+ const props = [...((_a = model.Property) !== null && _a !== void 0 ? _a : []), ...this.getNavigationProps(model)];
138
+ // support for base types, i.e. extends clause of interfaces
139
+ const baseClasses = [];
140
+ if (bType) {
141
+ baseClasses.push(this.namingHelper.getModelName(bType));
142
+ }
143
+ return {
144
+ name,
145
+ qName,
146
+ odataName,
147
+ editableName,
148
+ baseClasses,
149
+ props: props.map(this.mapProp),
150
+ baseProps: [], // postprocess required
151
+ };
152
+ }
153
+ addTypeDefinition(types) {
154
+ if (!types || !types.length) {
155
+ return;
156
+ }
157
+ for (const t of types) {
158
+ this.dataModel.addTypeDefinition(t.$.Name, t.$.UnderlyingType);
159
+ }
160
+ }
161
+ addComplexType(models) {
162
+ if (!models || !models.length) {
163
+ return;
164
+ }
165
+ for (const model of models) {
166
+ const baseModel = this.getBaseModel(model);
167
+ this.dataModel.addComplexType(baseModel.name, baseModel);
168
+ }
169
+ }
170
+ addEntityType(models) {
171
+ var _a;
172
+ if (!models || !models.length) {
173
+ return;
174
+ }
175
+ for (const model of models) {
176
+ const baseModel = this.getBaseModel(model);
177
+ const entityConfig = this.serviceConfigHelper.findConfigEntityByName(model.$.Name);
178
+ const entityName = (entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.mappedName) || model.$.Name;
179
+ // key support: we add keys from this entity,
180
+ // but not keys stemming from base classes (postprocess required)
181
+ const keyNames = [];
182
+ if ((_a = entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.keys) === null || _a === void 0 ? void 0 : _a.length) {
183
+ keyNames.push(...entityConfig.keys);
184
+ }
185
+ else {
186
+ const entity = model;
187
+ if (entity.Key && entity.Key.length && entity.Key[0].PropertyRef.length) {
188
+ const propNames = entity.Key[0].PropertyRef.map((key) => key.$.Name);
189
+ keyNames.push(...propNames);
190
+ }
191
+ }
192
+ this.dataModel.addModel(baseModel.name, Object.assign(Object.assign({}, baseModel), { idModelName: this.namingHelper.getIdModelName(entityName), qIdFunctionName: this.namingHelper.getQIdFunctionName(entityName), generateId: true, keyNames: keyNames, keys: [], getKeyUnion: () => keyNames.join(" | ") }));
193
+ }
194
+ }
195
+ postProcessModel() {
196
+ // complex types
197
+ const complexTypes = this.dataModel.getComplexTypes();
198
+ complexTypes.forEach((model) => {
199
+ const [baseProps] = this.collectBaseClassPropsAndKeys(model, []);
200
+ model.baseProps = baseProps;
201
+ });
202
+ const modelTypes = this.dataModel.getModels();
203
+ // entity types
204
+ modelTypes.forEach((model) => {
205
+ const [baseProps, baseKeys, idName, qIdName] = this.collectBaseClassPropsAndKeys(model, []);
206
+ model.baseProps = baseProps;
207
+ if (!model.keyNames.length && idName) {
208
+ model.idModelName = idName;
209
+ model.qIdFunctionName = qIdName;
210
+ model.generateId = false;
211
+ }
212
+ model.keyNames.unshift(...baseKeys);
213
+ // sanity check: entity types require key specification
214
+ if (!model.keyNames.length) {
215
+ throw new Error(`Key property is missing from Entity "${model.name}" (${model.odataName})!`);
216
+ }
217
+ const isSingleKey = model.keyNames.length === 1;
218
+ const props = [...model.baseProps, ...model.props];
219
+ model.keys = model.keyNames.map((keyName) => {
220
+ const prop = props.find((p) => p.odataName === keyName);
221
+ if (!prop) {
222
+ throw new Error(`Key with name [${keyName}] not found in props!`);
223
+ }
224
+ // automatically set key prop to managed, if this is the only key of the given entity
225
+ if (prop.managed === undefined) {
226
+ prop.managed = !this.options.disableAutoManagedKey && isSingleKey;
227
+ }
228
+ return prop;
229
+ });
230
+ });
231
+ const sortedModelTypes = this.sortModelsByInheritance(modelTypes);
232
+ this.dataModel.setModels(sortedModelTypes);
233
+ const sortedComplexTypes = this.sortModelsByInheritance(complexTypes);
234
+ this.dataModel.setComplexTypes(sortedComplexTypes);
235
+ }
236
+ sortModelsByInheritance(models) {
237
+ // recursively visit all models and sort them by inheritance such that base classes
238
+ // are always before derived classes
239
+ const sortedModels = {};
240
+ const visitedModels = new Set();
241
+ const inProgressModels = new Set();
242
+ function visit(model) {
243
+ if (inProgressModels.has(model)) {
244
+ throw new Error("Cyclic dependencies detected!");
245
+ }
246
+ if (!visitedModels.has(model)) {
247
+ inProgressModels.add(model);
248
+ for (const baseClassName of model.baseClasses) {
249
+ const baseClass = models.find((e) => e.name === baseClassName);
250
+ if (baseClass) {
251
+ visit(baseClass);
252
+ }
253
+ }
254
+ visitedModels.add(model);
255
+ inProgressModels.delete(model);
256
+ sortedModels[model.name] = model;
257
+ }
258
+ }
259
+ for (const model of models) {
260
+ visit(model);
261
+ }
262
+ return sortedModels;
263
+ }
264
+ collectBaseClassPropsAndKeys(model, visitedModels) {
265
+ if (visitedModels.includes(model.name)) {
266
+ throw new Error(`Cyclic inheritance detected for model ${model.name}!`);
267
+ }
268
+ visitedModels.push(model.name);
269
+ return model.baseClasses.reduce(([props, keys, idName, qIdName], bc) => {
270
+ var _a;
271
+ const baseModel = this.dataModel.getModel(bc) || this.dataModel.getComplexType(bc);
272
+ if (!baseModel) {
273
+ throw new Error(`BaseModel "${bc}" doesn't exist!`);
274
+ }
275
+ let idNameResult = idName;
276
+ let qIdNameResult = qIdName;
277
+ // recursive
278
+ if (baseModel.baseClasses.length) {
279
+ const [parentProps, parentKeys, parentIdName, parentQIdName] = this.collectBaseClassPropsAndKeys(baseModel, visitedModels);
280
+ props.unshift(...parentProps);
281
+ keys.unshift(...parentKeys);
282
+ if (parentIdName) {
283
+ idNameResult = parentIdName;
284
+ qIdNameResult = parentQIdName;
285
+ }
286
+ }
287
+ props.push(...baseModel.props);
288
+ if ((_a = baseModel.keyNames) === null || _a === void 0 ? void 0 : _a.length) {
289
+ keys.push(...baseModel.keyNames.filter((kn) => !keys.includes(kn)));
290
+ idNameResult = baseModel.idModelName;
291
+ qIdNameResult = baseModel.qIdFunctionName;
292
+ }
293
+ return [props, keys, idNameResult, qIdNameResult];
294
+ }, [[], [], "", ""]);
295
+ }
296
+ }
297
+ exports.Digester = Digester;
298
+ Digester.EDM_PREFIX = "Edm.";
299
+ Digester.ROOT_OPERATION = "/";
275
300
  //# sourceMappingURL=DataModelDigestion.js.map