@odata2ts/odata2ts 0.29.1 → 0.31.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 (42) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +81 -81
  3. package/lib/FactoryFunctionModel.d.ts +1 -1
  4. package/lib/FactoryFunctionModel.js.map +1 -1
  5. package/lib/OptionModel.d.ts +54 -4
  6. package/lib/OptionModel.js.map +1 -1
  7. package/lib/app.js +1 -8
  8. package/lib/app.js.map +1 -1
  9. package/lib/data-model/DataModel.d.ts +48 -37
  10. package/lib/data-model/DataModel.js +130 -61
  11. package/lib/data-model/DataModel.js.map +1 -1
  12. package/lib/data-model/DataModelDigestion.d.ts +2 -3
  13. package/lib/data-model/DataModelDigestion.js +74 -96
  14. package/lib/data-model/DataModelDigestion.js.map +1 -1
  15. package/lib/data-model/DataModelDigestionV2.d.ts +1 -1
  16. package/lib/data-model/DataModelDigestionV2.js +30 -15
  17. package/lib/data-model/DataModelDigestionV2.js.map +1 -1
  18. package/lib/data-model/DataModelDigestionV4.js +65 -43
  19. package/lib/data-model/DataModelDigestionV4.js.map +1 -1
  20. package/lib/data-model/DataTypeModel.d.ts +10 -1
  21. package/lib/data-model/DataTypeModel.js.map +1 -1
  22. package/lib/data-model/NamingHelper.d.ts +6 -6
  23. package/lib/data-model/NamingHelper.js +14 -7
  24. package/lib/data-model/NamingHelper.js.map +1 -1
  25. package/lib/data-model/ServiceConfigHelper.d.ts +12 -3
  26. package/lib/data-model/ServiceConfigHelper.js +73 -11
  27. package/lib/data-model/ServiceConfigHelper.js.map +1 -1
  28. package/lib/defaultConfig.js +1 -0
  29. package/lib/defaultConfig.js.map +1 -1
  30. package/lib/generator/ImportContainer.d.ts +0 -1
  31. package/lib/generator/ImportContainer.js +2 -17
  32. package/lib/generator/ImportContainer.js.map +1 -1
  33. package/lib/generator/ModelGenerator.js +9 -6
  34. package/lib/generator/ModelGenerator.js.map +1 -1
  35. package/lib/generator/QueryObjectGenerator.js +12 -6
  36. package/lib/generator/QueryObjectGenerator.js.map +1 -1
  37. package/lib/generator/ServiceGenerator.js +19 -27
  38. package/lib/generator/ServiceGenerator.js.map +1 -1
  39. package/lib/project/ProjectManager.d.ts +0 -5
  40. package/lib/project/ProjectManager.js +1 -21
  41. package/lib/project/ProjectManager.js.map +1 -1
  42. package/package.json +2 -2
@@ -1,19 +1,43 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DataModel = void 0;
3
+ exports.DataModel = exports.withNamespace = void 0;
4
4
  const DataTypeModel_1 = require("./DataTypeModel");
5
- const ROOT_OPERATION_BINDING = "/";
5
+ function withNamespace(ns, name) {
6
+ // this supports the edge case of an empty string as namespace which isn't really valid according to spec (see CSDL)
7
+ return ns ? `${ns}.${name}` : name;
8
+ }
9
+ exports.withNamespace = withNamespace;
6
10
  class DataModel {
7
- constructor(version, converters = new Map()) {
11
+ constructor(namespaces, version, converters = new Map()) {
8
12
  this.version = version;
9
- this.modelTypes = {};
10
- this.complexTypes = {};
11
- this.enumTypes = {};
12
- // combines functions & actions
13
- this.operationTypes = {};
14
- this.typeDefinitions = {};
13
+ this.models = new Map();
14
+ /**
15
+ * Stores unbound operations by their fully qualified name.
16
+ * @private
17
+ */
18
+ this.unboundOperationTypes = new Map();
19
+ /**
20
+ * Stores operations bound to an entity type by the fully qualified name of the binding entity, e.g.
21
+ * "Trippin.Person".
22
+ * @private
23
+ */
24
+ this.entityBoundOperationTypes = new Map();
25
+ /**
26
+ * Stores operations bound to an entity collection by the fully qualified name of the binding entity, e.g.
27
+ * "Trippin.Person".
28
+ * @private
29
+ */
30
+ this.entityCollectionBoundOperationTypes = new Map();
31
+ this.typeDefinitions = new Map();
32
+ this.aliases = {};
15
33
  this.container = { entitySets: {}, singletons: {}, functions: {}, actions: {} };
16
34
  this.converters = converters;
35
+ this.namespace2Alias = namespaces.reduce((col, [ns, alias]) => {
36
+ if (alias) {
37
+ col[ns] = alias;
38
+ }
39
+ return col;
40
+ }, {});
17
41
  }
18
42
  /**
19
43
  * OData version: 2.0 or 4.0.
@@ -28,51 +52,62 @@ class DataModel {
28
52
  isV4() {
29
53
  return this.version === DataTypeModel_1.ODataVersion.V4;
30
54
  }
31
- addTypeDefinition(name, type) {
32
- this.typeDefinitions[name] = type;
55
+ retrieveType(fqName, haystack) {
56
+ return haystack.get(fqName) || (this.aliases[fqName] ? haystack.get(this.aliases[fqName]) : undefined);
57
+ }
58
+ addAlias(namespace, name) {
59
+ const alias = this.namespace2Alias[namespace];
60
+ if (alias) {
61
+ this.aliases[withNamespace(alias, name)] = withNamespace(namespace, name);
62
+ }
63
+ }
64
+ addTypeDefinition(namespace, name, type) {
65
+ const fqName = withNamespace(namespace, name);
66
+ this.typeDefinitions.set(fqName, type);
67
+ this.addAlias(namespace, name);
68
+ }
69
+ getPrimitiveType(fqName) {
70
+ return this.retrieveType(fqName, this.typeDefinitions);
33
71
  }
34
- getPrimitiveType(name) {
35
- return this.typeDefinitions[name];
72
+ getModel(fqName) {
73
+ return this.retrieveType(fqName, this.models);
36
74
  }
37
- addModel(name, model) {
38
- this.modelTypes[name] = model;
75
+ addEntityType(namespace, name, model) {
76
+ const fqName = withNamespace(namespace, name);
77
+ this.models.set(fqName, Object.assign(Object.assign({}, model), { dataType: "ModelType" /* DataTypes.ModelType */ }));
78
+ this.addAlias(namespace, name);
39
79
  }
40
80
  /**
41
- * Get a specific model by its name.
81
+ * Get a specific model by its fully qualified name.
42
82
  *
43
- * @param modelName the final model name that is generated
83
+ * @param fqName the fully qualified name of the entity
44
84
  * @returns the model type
45
85
  */
46
- getModel(modelName) {
47
- return this.modelTypes[modelName];
86
+ getEntityType(fqName) {
87
+ return this.retrieveType(fqName, this.models);
48
88
  }
49
89
  /**
50
90
  * Retrieve all known EntityType models from the EDMX model.
51
91
  *
52
92
  * @returns list of model types
53
93
  */
54
- getModels() {
55
- return Object.values(this.modelTypes);
94
+ getEntityTypes() {
95
+ const ets = [...this.models.values()].filter((m) => m.dataType === "ModelType" /* DataTypes.ModelType */);
96
+ return this.sortModelsByInheritance(ets);
56
97
  }
57
- /**
58
- * Set all model entity types
59
- *
60
- * @param models new model types
61
- */
62
- setModels(models) {
63
- this.modelTypes = models;
64
- }
65
- addComplexType(name, model) {
66
- this.complexTypes[name] = model;
98
+ addComplexType(namespace, name, model) {
99
+ const fqName = withNamespace(namespace, name);
100
+ this.models.set(fqName, Object.assign(Object.assign({}, model), { dataType: "ComplexType" /* DataTypes.ComplexType */ }));
101
+ this.addAlias(namespace, name);
67
102
  }
68
103
  /**
69
- * Get a specific model by its name.
104
+ * Get a specific model by its fully qualified name.
70
105
  *
71
- * @param name the final model name that is generated
106
+ * @param fqName the final model name that is generated
72
107
  * @returns the model type
73
108
  */
74
- getComplexType(name) {
75
- return this.complexTypes[name];
109
+ getComplexType(fqName) {
110
+ return this.retrieveType(fqName, this.models);
76
111
  }
77
112
  /**
78
113
  * Retrieve all known ComplexType models from the EDMX model.
@@ -80,44 +115,49 @@ class DataModel {
80
115
  * @returns list of model types
81
116
  */
82
117
  getComplexTypes() {
83
- return Object.values(this.complexTypes);
118
+ const types = [...this.models.values()].filter((m) => m.dataType === "ComplexType" /* DataTypes.ComplexType */);
119
+ return this.sortModelsByInheritance(types);
84
120
  }
85
- /**
86
- * Set all complex types
87
- *
88
- * @param models new complex types
89
- */
90
- setComplexTypes(complexTypes) {
91
- this.complexTypes = complexTypes;
92
- }
93
- addEnum(name, type) {
94
- this.enumTypes[name] = type;
121
+ addEnum(namespace, name, type) {
122
+ const fqName = withNamespace(namespace, name);
123
+ this.models.set(fqName, Object.assign(Object.assign({}, type), { dataType: "EnumType" /* DataTypes.EnumType */ }));
124
+ this.addAlias(namespace, name);
95
125
  }
96
126
  /**
97
127
  * Get list of all known enums, i.e. EnumType nodes from the EDMX model.
98
128
  * @returns list of enum types
99
129
  */
100
130
  getEnums() {
101
- return Object.values(this.enumTypes);
131
+ return [...this.models.values()].filter((m) => m.dataType === "EnumType" /* DataTypes.EnumType */);
102
132
  }
103
- addOperationType(binding, operationType) {
104
- if (!this.operationTypes[binding]) {
105
- this.operationTypes[binding] = [];
106
- }
107
- this.operationTypes[binding].push(operationType);
133
+ addUnboundOperationType(namespace, operationType) {
134
+ this.unboundOperationTypes.set(operationType.fqName, operationType);
135
+ this.addAlias(namespace, operationType.odataName);
108
136
  }
109
137
  getUnboundOperationTypes() {
110
- const operations = this.operationTypes[ROOT_OPERATION_BINDING];
111
- return !operations ? [] : [...operations];
138
+ return [...this.unboundOperationTypes.values()];
139
+ }
140
+ getUnboundOperationType(fqOpName) {
141
+ return this.retrieveType(fqOpName, this.unboundOperationTypes);
142
+ }
143
+ addBoundOperationType(namespace, bindingProp, operationType) {
144
+ const fqEntityType = bindingProp.fqType;
145
+ const store = bindingProp.isCollection ? this.entityCollectionBoundOperationTypes : this.entityBoundOperationTypes;
146
+ const list = store.get(fqEntityType);
147
+ if (list) {
148
+ list.push(operationType);
149
+ }
150
+ else {
151
+ store.set(fqEntityType, [operationType]);
152
+ }
112
153
  }
113
- getOperationTypeByBinding(binding) {
114
- const operations = this.operationTypes[binding];
115
- return !operations ? [] : [...operations];
154
+ getEntityTypeOperations(fqEntityName) {
155
+ const operations = this.retrieveType(fqEntityName, this.entityBoundOperationTypes);
156
+ return operations || [];
116
157
  }
117
- getOperationTypeByEntityOrCollectionBinding(binding) {
118
- const entityOps = this.operationTypes[binding] || [];
119
- const collOps = this.operationTypes[`Collection(${binding})`] || [];
120
- return [...collOps, ...entityOps];
158
+ getEntitySetOperations(fqEntityName) {
159
+ const operations = this.retrieveType(fqEntityName, this.entityCollectionBoundOperationTypes);
160
+ return operations || [];
121
161
  }
122
162
  addAction(name, action) {
123
163
  this.container.actions[name] = action;
@@ -137,6 +177,35 @@ class DataModel {
137
177
  getConverter(dataType) {
138
178
  return this.converters.get(dataType);
139
179
  }
180
+ sortModelsByInheritance(models) {
181
+ // recursively visit all models and sort them by inheritance such that base classes
182
+ // are always before derived classes
183
+ const sorted = [];
184
+ const visitedModels = new Set();
185
+ const inProgressModels = new Set();
186
+ function visit(model) {
187
+ const fqName = model.fqName;
188
+ if (inProgressModels.has(fqName)) {
189
+ throw new Error(`Cyclic inheritance detected for model "${fqName}"!`);
190
+ }
191
+ if (!visitedModels.has(fqName)) {
192
+ inProgressModels.add(fqName);
193
+ for (const baseClassName of model.baseClasses) {
194
+ const baseClass = models.find((e) => e.fqName === baseClassName);
195
+ if (baseClass) {
196
+ visit(baseClass);
197
+ }
198
+ }
199
+ visitedModels.add(fqName);
200
+ inProgressModels.delete(fqName);
201
+ sorted.push(model);
202
+ }
203
+ }
204
+ for (const model of models) {
205
+ visit(model);
206
+ }
207
+ return sorted;
208
+ }
140
209
  }
141
210
  exports.DataModel = DataModel;
142
211
  //# sourceMappingURL=DataModel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataModel.js","sourceRoot":"","sources":["../../src/data-model/DataModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { MappedConverterChains } from \"@odata2ts/converter-runtime\";\r\nimport { ODataTypesV2, ODataTypesV4 } from \"@odata2ts/odata-core\";\r\n\r\nimport {\r\n ActionImportType,\r\n ComplexType,\r\n EntityContainerModel,\r\n EntitySetType,\r\n EnumType,\r\n FunctionImportType,\r\n ModelType,\r\n ODataVersion,\r\n OperationType,\r\n SingletonType,\r\n} from \"./DataTypeModel\";\r\n\r\nexport interface ProjectFiles {\r\n model: string;\r\n qObject: string;\r\n service: string;\r\n}\r\n\r\nconst ROOT_OPERATION_BINDING = \"/\";\r\n\r\nexport class DataModel {\r\n private readonly converters: MappedConverterChains;\r\n\r\n private modelTypes: { [name: string]: ModelType } = {};\r\n private complexTypes: { [name: string]: ComplexType } = {};\r\n private enumTypes: { [name: string]: EnumType } = {};\r\n // combines functions & actions\r\n private operationTypes: { [binding: string]: Array<OperationType> } = {};\r\n private typeDefinitions: { [name: string]: string } = {};\r\n private container: EntityContainerModel = { entitySets: {}, singletons: {}, functions: {}, actions: {} };\r\n\r\n constructor(private version: ODataVersion, converters: MappedConverterChains = new Map()) {\r\n this.converters = converters;\r\n }\r\n\r\n /**\r\n * OData version: 2.0 or 4.0.\r\n * @returns\r\n */\r\n public getODataVersion() {\r\n return this.version;\r\n }\r\n\r\n public isV2() {\r\n return this.version === ODataVersion.V2;\r\n }\r\n\r\n public isV4() {\r\n return this.version === ODataVersion.V4;\r\n }\r\n\r\n public addTypeDefinition(name: string, type: string) {\r\n this.typeDefinitions[name] = type;\r\n }\r\n\r\n public getPrimitiveType(name: string): string | undefined {\r\n return this.typeDefinitions[name];\r\n }\r\n\r\n public addModel(name: string, model: ModelType) {\r\n this.modelTypes[name] = model;\r\n }\r\n\r\n /**\r\n * Get a specific model by its name.\r\n *\r\n * @param modelName the final model name that is generated\r\n * @returns the model type\r\n */\r\n public getModel(modelName: string) {\r\n return this.modelTypes[modelName];\r\n }\r\n\r\n /**\r\n * Retrieve all known EntityType models from the EDMX model.\r\n *\r\n * @returns list of model types\r\n */\r\n public getModels() {\r\n return Object.values(this.modelTypes);\r\n }\r\n\r\n /**\r\n * Set all model entity types\r\n *\r\n * @param models new model types\r\n */\r\n public setModels(models: { [name: string]: ModelType }) {\r\n this.modelTypes = models;\r\n }\r\n\r\n public addComplexType(name: string, model: ComplexType) {\r\n this.complexTypes[name] = model;\r\n }\r\n\r\n /**\r\n * Get a specific model by its name.\r\n *\r\n * @param name the final model name that is generated\r\n * @returns the model type\r\n */\r\n public getComplexType(name: string) {\r\n return this.complexTypes[name];\r\n }\r\n\r\n /**\r\n * Retrieve all known ComplexType models from the EDMX model.\r\n *\r\n * @returns list of model types\r\n */\r\n public getComplexTypes() {\r\n return Object.values(this.complexTypes);\r\n }\r\n\r\n /**\r\n * Set all complex types\r\n *\r\n * @param models new complex types\r\n */\r\n public setComplexTypes(complexTypes: { [name: string]: ComplexType }) {\r\n this.complexTypes = complexTypes;\r\n }\r\n\r\n public addEnum(name: string, type: EnumType) {\r\n this.enumTypes[name] = type;\r\n }\r\n\r\n /**\r\n * Get list of all known enums, i.e. EnumType nodes from the EDMX model.\r\n * @returns list of enum types\r\n */\r\n public getEnums() {\r\n return Object.values(this.enumTypes);\r\n }\r\n\r\n public addOperationType(binding: string, operationType: OperationType) {\r\n if (!this.operationTypes[binding]) {\r\n this.operationTypes[binding] = [];\r\n }\r\n\r\n this.operationTypes[binding].push(operationType);\r\n }\r\n\r\n public getUnboundOperationTypes(): Array<OperationType> {\r\n const operations = this.operationTypes[ROOT_OPERATION_BINDING];\r\n return !operations ? [] : [...operations];\r\n }\r\n\r\n public getOperationTypeByBinding(binding: string): Array<OperationType> {\r\n const operations = this.operationTypes[binding];\r\n return !operations ? [] : [...operations];\r\n }\r\n\r\n public getOperationTypeByEntityOrCollectionBinding(binding: string): Array<OperationType> {\r\n const entityOps = this.operationTypes[binding] || [];\r\n const collOps = this.operationTypes[`Collection(${binding})`] || [];\r\n return [...collOps, ...entityOps];\r\n }\r\n\r\n public addAction(name: string, action: ActionImportType) {\r\n this.container.actions[name] = action;\r\n }\r\n\r\n public addFunction(name: string, func: FunctionImportType) {\r\n this.container.functions[name] = func;\r\n }\r\n\r\n public addSingleton(name: string, singleton: SingletonType) {\r\n this.container.singletons[name] = singleton;\r\n }\r\n\r\n public addEntitySet(name: string, entitySet: EntitySetType) {\r\n this.container.entitySets[name] = entitySet;\r\n }\r\n\r\n public getEntityContainer() {\r\n return this.container;\r\n }\r\n\r\n public getConverter(dataType: ODataTypesV2 | ODataTypesV4 | string) {\r\n return this.converters.get(dataType);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"DataModel.js","sourceRoot":"","sources":["../../src/data-model/DataModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { MappedConverterChains } from \"@odata2ts/converter-runtime\";\r\nimport { ODataTypesV2, ODataTypesV4 } from \"@odata2ts/odata-core\";\r\n\r\nimport {\r\n ActionImportType,\r\n ComplexType,\r\n DataTypes,\r\n EntityContainerModel,\r\n EntitySetType,\r\n EnumType,\r\n FunctionImportType,\r\n ModelType,\r\n ODataVersion,\r\n OperationType,\r\n PropertyModel,\r\n SingletonType,\r\n} from \"./DataTypeModel\";\r\n\r\nexport interface ProjectFiles {\r\n model: string;\r\n qObject: string;\r\n service: string;\r\n}\r\n\r\n/**\r\n * Each namespace is represented as tuple: 1. the namespace 2. the alias, if any.\r\n */\r\nexport type NamespaceWithAlias = [string, string?];\r\n\r\nexport function withNamespace(ns: string, name: string) {\r\n // this supports the edge case of an empty string as namespace which isn't really valid according to spec (see CSDL)\r\n return ns ? `${ns}.${name}` : name;\r\n}\r\n\r\nexport class DataModel {\r\n private readonly converters: MappedConverterChains;\r\n\r\n private models = new Map<string, ModelType | ComplexType | EnumType>();\r\n /**\r\n * Stores unbound operations by their fully qualified name.\r\n * @private\r\n */\r\n private unboundOperationTypes = new Map<string, OperationType>();\r\n /**\r\n * Stores operations bound to an entity type by the fully qualified name of the binding entity, e.g.\r\n * \"Trippin.Person\".\r\n * @private\r\n */\r\n private entityBoundOperationTypes = new Map<string, Array<OperationType>>();\r\n /**\r\n * Stores operations bound to an entity collection by the fully qualified name of the binding entity, e.g.\r\n * \"Trippin.Person\".\r\n * @private\r\n */\r\n private entityCollectionBoundOperationTypes = new Map<string, Array<OperationType>>();\r\n private readonly namespace2Alias: { [ns: string]: string };\r\n private typeDefinitions = new Map<string, string>();\r\n private aliases: Record<string, string> = {};\r\n private container: EntityContainerModel = { entitySets: {}, singletons: {}, functions: {}, actions: {} };\r\n\r\n constructor(\r\n namespaces: Array<NamespaceWithAlias>,\r\n private version: ODataVersion,\r\n converters: MappedConverterChains = new Map()\r\n ) {\r\n this.converters = converters;\r\n this.namespace2Alias = namespaces.reduce<Record<string, string>>((col, [ns, alias]) => {\r\n if (alias) {\r\n col[ns] = alias;\r\n }\r\n return col;\r\n }, {});\r\n }\r\n\r\n /**\r\n * OData version: 2.0 or 4.0.\r\n * @returns\r\n */\r\n public getODataVersion() {\r\n return this.version;\r\n }\r\n\r\n public isV2() {\r\n return this.version === ODataVersion.V2;\r\n }\r\n\r\n public isV4() {\r\n return this.version === ODataVersion.V4;\r\n }\r\n\r\n private retrieveType<T>(fqName: string, haystack: Map<string, T>): T | undefined {\r\n return haystack.get(fqName) || (this.aliases[fqName] ? haystack.get(this.aliases[fqName]) : undefined);\r\n }\r\n\r\n private addAlias(namespace: string, name: string) {\r\n const alias = this.namespace2Alias[namespace];\r\n if (alias) {\r\n this.aliases[withNamespace(alias, name)] = withNamespace(namespace, name);\r\n }\r\n }\r\n\r\n public addTypeDefinition(namespace: string, name: string, type: string) {\r\n const fqName = withNamespace(namespace, name);\r\n this.typeDefinitions.set(fqName, type);\r\n this.addAlias(namespace, name);\r\n }\r\n\r\n public getPrimitiveType(fqName: string): string | undefined {\r\n return this.retrieveType(fqName, this.typeDefinitions);\r\n }\r\n\r\n public getModel(fqName: string) {\r\n return this.retrieveType(fqName, this.models);\r\n }\r\n\r\n public addEntityType(namespace: string, name: string, model: Omit<ModelType, \"dataType\">) {\r\n const fqName = withNamespace(namespace, name);\r\n this.models.set(fqName, { ...model, dataType: DataTypes.ModelType });\r\n this.addAlias(namespace, name);\r\n }\r\n\r\n /**\r\n * Get a specific model by its fully qualified name.\r\n *\r\n * @param fqName the fully qualified name of the entity\r\n * @returns the model type\r\n */\r\n public getEntityType(fqName: string) {\r\n return this.retrieveType(fqName, this.models) as ModelType;\r\n }\r\n\r\n /**\r\n * Retrieve all known EntityType models from the EDMX model.\r\n *\r\n * @returns list of model types\r\n */\r\n public getEntityTypes() {\r\n const ets = [...this.models.values()].filter((m): m is ModelType => m.dataType === DataTypes.ModelType);\r\n return this.sortModelsByInheritance(ets);\r\n }\r\n\r\n public addComplexType(namespace: string, name: string, model: Omit<ComplexType, \"dataType\">) {\r\n const fqName = withNamespace(namespace, name);\r\n this.models.set(fqName, { ...model, dataType: DataTypes.ComplexType });\r\n this.addAlias(namespace, name);\r\n }\r\n\r\n /**\r\n * Get a specific model by its fully qualified name.\r\n *\r\n * @param fqName the final model name that is generated\r\n * @returns the model type\r\n */\r\n public getComplexType(fqName: string) {\r\n return this.retrieveType(fqName, this.models) as ComplexType;\r\n }\r\n\r\n /**\r\n * Retrieve all known ComplexType models from the EDMX model.\r\n *\r\n * @returns list of model types\r\n */\r\n public getComplexTypes() {\r\n const types = [...this.models.values()].filter((m): m is ComplexType => m.dataType === DataTypes.ComplexType);\r\n return this.sortModelsByInheritance(types);\r\n }\r\n\r\n public addEnum(namespace: string, name: string, type: Omit<EnumType, \"dataType\">) {\r\n const fqName = withNamespace(namespace, name);\r\n this.models.set(fqName, { ...type, dataType: DataTypes.EnumType });\r\n this.addAlias(namespace, name);\r\n }\r\n\r\n /**\r\n * Get list of all known enums, i.e. EnumType nodes from the EDMX model.\r\n * @returns list of enum types\r\n */\r\n public getEnums() {\r\n return [...this.models.values()].filter((m): m is EnumType => m.dataType === DataTypes.EnumType);\r\n }\r\n\r\n public addUnboundOperationType(namespace: string, operationType: OperationType) {\r\n this.unboundOperationTypes.set(operationType.fqName, operationType);\r\n this.addAlias(namespace, operationType.odataName);\r\n }\r\n\r\n public getUnboundOperationTypes(): Array<OperationType> {\r\n return [...this.unboundOperationTypes.values()];\r\n }\r\n\r\n public getUnboundOperationType(fqOpName: string): OperationType | undefined {\r\n return this.retrieveType(fqOpName, this.unboundOperationTypes);\r\n }\r\n\r\n public addBoundOperationType(namespace: string, bindingProp: PropertyModel, operationType: OperationType) {\r\n const fqEntityType = bindingProp.fqType;\r\n\r\n const store = bindingProp.isCollection ? this.entityCollectionBoundOperationTypes : this.entityBoundOperationTypes;\r\n const list = store.get(fqEntityType);\r\n if (list) {\r\n list.push(operationType);\r\n } else {\r\n store.set(fqEntityType, [operationType]);\r\n }\r\n }\r\n\r\n public getEntityTypeOperations(fqEntityName: string): Array<OperationType> {\r\n const operations = this.retrieveType(fqEntityName, this.entityBoundOperationTypes);\r\n return operations || [];\r\n }\r\n\r\n public getEntitySetOperations(fqEntityName: string): Array<OperationType> {\r\n const operations = this.retrieveType(fqEntityName, this.entityCollectionBoundOperationTypes);\r\n return operations || [];\r\n }\r\n\r\n public addAction(name: string, action: ActionImportType) {\r\n this.container.actions[name] = action;\r\n }\r\n\r\n public addFunction(name: string, func: FunctionImportType) {\r\n this.container.functions[name] = func;\r\n }\r\n\r\n public addSingleton(name: string, singleton: SingletonType) {\r\n this.container.singletons[name] = singleton;\r\n }\r\n\r\n public addEntitySet(name: string, entitySet: EntitySetType) {\r\n this.container.entitySets[name] = entitySet;\r\n }\r\n\r\n public getEntityContainer() {\r\n return this.container;\r\n }\r\n\r\n public getConverter(dataType: ODataTypesV2 | ODataTypesV4 | string) {\r\n return this.converters.get(dataType);\r\n }\r\n\r\n private sortModelsByInheritance<Type extends Omit<ComplexType, \"dataType\">>(models: Array<Type>): Array<Type> {\r\n // recursively visit all models and sort them by inheritance such that base classes\r\n // are always before derived classes\r\n const sorted: Array<Type> = [];\r\n const visitedModels = new Set<string>();\r\n const inProgressModels = new Set<string>();\r\n\r\n function visit(model: Type) {\r\n const fqName = model.fqName;\r\n if (inProgressModels.has(fqName)) {\r\n throw new Error(`Cyclic inheritance detected for model \"${fqName}\"!`);\r\n }\r\n\r\n if (!visitedModels.has(fqName)) {\r\n inProgressModels.add(fqName);\r\n\r\n for (const baseClassName of model.baseClasses) {\r\n const baseClass = models.find((e) => e.fqName === baseClassName);\r\n if (baseClass) {\r\n visit(baseClass);\r\n }\r\n }\r\n visitedModels.add(fqName);\r\n inProgressModels.delete(fqName);\r\n sorted.push(model);\r\n }\r\n }\r\n\r\n for (const model of models) {\r\n visit(model);\r\n }\r\n return sorted;\r\n }\r\n}\r\n"]}
@@ -20,11 +20,12 @@ export declare abstract class Digester<S extends Schema<ET, CT>, ET extends Enti
20
20
  protected options: DigestionOptions;
21
21
  protected namingHelper: NamingHelper;
22
22
  protected static EDM_PREFIX: string;
23
- protected static ROOT_OPERATION: string;
24
23
  protected readonly dataModel: DataModel;
25
24
  protected readonly serviceConfigHelper: ServiceConfigHelper;
26
25
  private model2Type;
27
26
  protected constructor(version: ODataVersion, schemas: Array<S>, options: DigestionOptions, namingHelper: NamingHelper, converters?: MappedConverterChains);
27
+ private collectModelTypes;
28
+ private addModel2Type;
28
29
  protected abstract getNavigationProps(entityType: ET | ComplexType): Array<Property>;
29
30
  protected abstract digestOperations(schema: SchemaV3 | SchemaV4): void;
30
31
  protected abstract digestEntityContainer(schema: SchemaV3 | SchemaV4): void;
@@ -36,14 +37,12 @@ export declare abstract class Digester<S extends Schema<ET, CT>, ET extends Enti
36
37
  */
37
38
  protected abstract mapODataType(type: string): TypeModel;
38
39
  digest(): Promise<DataModel>;
39
- private collectModelTypes;
40
40
  private digestEntityTypesAndOperations;
41
41
  private getBaseModel;
42
42
  private addTypeDefinition;
43
43
  private addComplexType;
44
44
  private addEntityType;
45
45
  private postProcessModel;
46
- private sortModelsByInheritance;
47
46
  private collectBaseClassPropsAndKeys;
48
47
  protected mapProp: (p: Property, entityPropConfig?: PropertyGenerationOptions | undefined) => PropertyModel;
49
48
  }
@@ -15,14 +15,15 @@ class Digester {
15
15
  if (!p.$.Type) {
16
16
  throw new Error(`No type information given for property [${p.$.Name}]!`);
17
17
  }
18
- const configProp = this.serviceConfigHelper.findConfigPropByName(p.$.Name);
18
+ const configProp = this.serviceConfigHelper.findPropConfigByName(p.$.Name);
19
19
  const name = this.namingHelper.getModelPropName((entityPropConfig === null || entityPropConfig === void 0 ? void 0 : entityPropConfig.mappedName) || (configProp === null || configProp === void 0 ? void 0 : configProp.mappedName) || p.$.Name);
20
20
  const isCollection = !!p.$.Type.match(/^Collection\(/);
21
21
  let dataType = p.$.Type.replace(/^Collection\(([^\)]+)\)/, "$1");
22
+ // support for primitive type mapping
22
23
  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);
24
+ const dt = this.dataModel.getPrimitiveType(dataType);
25
+ if (dt !== undefined) {
26
+ dataType = dt;
26
27
  }
27
28
  }
28
29
  let result;
@@ -31,7 +32,7 @@ class Digester {
31
32
  if (this.namingHelper.includesServicePrefix(dataType)) {
32
33
  const resultDt = this.model2Type.get(dataType);
33
34
  if (!resultDt) {
34
- throw new Error(`Couldn't determine model type for data type with name '${dataType}'`);
35
+ throw new Error(`Couldn't determine model data type for property "${p.$.Name}"! Given data type: "${dataType}".`);
35
36
  }
36
37
  // special handling for enums
37
38
  if (resultDt === "EnumType" /* DataTypes.EnumType */) {
@@ -72,113 +73,122 @@ class Digester {
72
73
  else {
73
74
  throw new Error(`Unknown type [${dataType}]: Not 'Collection(...)', not OData type 'Edm.*', not starting with one of the namespaces!W`);
74
75
  }
75
- return Object.assign({ odataName: p.$.Name, name, odataType: p.$.Type, required: p.$.Nullable === "false", isCollection: isCollection, managed: typeof (entityPropConfig === null || entityPropConfig === void 0 ? void 0 : entityPropConfig.managed) !== "undefined" ? entityPropConfig.managed : configProp === null || configProp === void 0 ? void 0 : configProp.managed }, result);
76
+ return Object.assign({ odataName: p.$.Name, name, odataType: p.$.Type, fqType: dataType, required: p.$.Nullable === "false", isCollection: isCollection, managed: typeof (entityPropConfig === null || entityPropConfig === void 0 ? void 0 : entityPropConfig.managed) !== "undefined" ? entityPropConfig.managed : configProp === null || configProp === void 0 ? void 0 : configProp.managed }, result);
76
77
  };
77
- this.dataModel = new DataModel_1.DataModel(version, converters);
78
+ const namespaces = schemas.map((s) => [s.$.Namespace, s.$.Alias]);
79
+ this.dataModel = new DataModel_1.DataModel(namespaces, version, converters);
78
80
  this.serviceConfigHelper = new ServiceConfigHelper_1.ServiceConfigHelper(options);
79
81
  this.collectModelTypes(schemas);
80
82
  }
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
83
  collectModelTypes(schemas) {
90
84
  schemas.forEach((schema) => {
91
85
  var _a, _b, _c;
92
- const servicePrefix = schema.$.Namespace + ".";
86
+ const { Namespace: ns, Alias: alias } = schema.$;
93
87
  (_a = schema.EnumType) === null || _a === void 0 ? void 0 : _a.forEach((et) => {
94
- this.model2Type.set(servicePrefix + et.$.Name, "EnumType" /* DataTypes.EnumType */);
88
+ this.addModel2Type(ns, alias, et.$.Name, "EnumType" /* DataTypes.EnumType */);
95
89
  });
96
90
  (_b = schema.ComplexType) === null || _b === void 0 ? void 0 : _b.forEach((ct) => {
97
- this.model2Type.set(servicePrefix + ct.$.Name, "ComplexType" /* DataTypes.ComplexType */);
91
+ this.addModel2Type(ns, alias, ct.$.Name, "ComplexType" /* DataTypes.ComplexType */);
98
92
  });
99
93
  (_c = schema.EntityType) === null || _c === void 0 ? void 0 : _c.forEach((et) => {
100
- this.model2Type.set(servicePrefix + et.$.Name, "ModelType" /* DataTypes.ModelType */);
94
+ this.addModel2Type(ns, alias, et.$.Name, "ModelType" /* DataTypes.ModelType */);
101
95
  });
102
96
  });
103
97
  }
98
+ addModel2Type(ns, alias, name, dt) {
99
+ this.model2Type.set((0, DataModel_1.withNamespace)(ns, name), dt);
100
+ if (alias) {
101
+ this.model2Type.set((0, DataModel_1.withNamespace)(alias, name), dt);
102
+ }
103
+ }
104
+ digest() {
105
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
106
+ this.digestEntityTypesAndOperations();
107
+ // delegate to version specific entity container digestion
108
+ this.schemas.forEach((schema) => this.digestEntityContainer(schema));
109
+ return this.dataModel;
110
+ });
111
+ }
104
112
  digestEntityTypesAndOperations() {
105
113
  this.schemas.forEach((schema) => {
114
+ const ns = [schema.$.Namespace, schema.$.Alias];
106
115
  // type definitions: alias for primitive types
107
- this.addTypeDefinition(schema.TypeDefinition);
116
+ this.addTypeDefinition(schema.$.Namespace, schema.TypeDefinition);
108
117
  // enums
109
118
  if (schema.EnumType) {
110
119
  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),
120
+ const odataName = et.$.Name;
121
+ const fqName = (0, DataModel_1.withNamespace)(ns[0], odataName);
122
+ this.dataModel.addEnum(ns[0], odataName, {
123
+ fqName,
124
+ odataName,
125
+ name: this.namingHelper.getEnumName(odataName),
115
126
  members: et.Member.map((m) => m.$.Name),
116
127
  });
117
128
  }
118
129
  }
119
- // entity types
120
- this.addEntityType(schema.EntityType);
121
130
  // complex types
122
- this.addComplexType(schema.ComplexType);
131
+ this.addComplexType(ns, schema.ComplexType);
132
+ // entity types
133
+ this.addEntityType(ns, schema.EntityType);
123
134
  // V4 only: function & action types
124
135
  this.digestOperations(schema);
125
136
  });
126
137
  this.postProcessModel();
127
138
  }
128
- getBaseModel(model) {
139
+ getBaseModel(namespace, model) {
129
140
  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
141
  const odataName = model.$.Name;
136
- const bType = model.$.BaseType;
137
- const props = [...((_a = model.Property) !== null && _a !== void 0 ? _a : []), ...this.getNavigationProps(model)];
142
+ const fqName = (0, DataModel_1.withNamespace)(namespace[0], odataName);
143
+ const entityConfig = this.serviceConfigHelper.findEntityConfigByName(namespace, odataName);
144
+ const entityName = (entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.mappedName) || model.$.Name;
145
+ // map properties respecting the config
146
+ const props = [...((_a = model.Property) !== null && _a !== void 0 ? _a : []), ...this.getNavigationProps(model)].map((p) => {
147
+ var _a;
148
+ const epConfig = (_a = entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.properties) === null || _a === void 0 ? void 0 : _a.find((ep) => ep.name === p.$.Name);
149
+ return this.mapProp(p, epConfig);
150
+ });
138
151
  // support for base types, i.e. extends clause of interfaces
139
152
  const baseClasses = [];
140
- if (bType) {
141
- baseClasses.push(this.namingHelper.getModelName(bType));
153
+ if (model.$.BaseType) {
154
+ baseClasses.push(model.$.BaseType);
142
155
  }
143
156
  return {
144
- name,
145
- qName,
157
+ fqName,
146
158
  odataName,
147
- editableName,
159
+ name: this.namingHelper.getModelName(entityName),
160
+ qName: this.namingHelper.getQName(entityName),
161
+ editableName: this.namingHelper.getEditableModelName(entityName),
148
162
  baseClasses,
149
- props: props.map((p) => {
150
- var _a;
151
- const epConfig = (_a = entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.properties) === null || _a === void 0 ? void 0 : _a.find((ep) => ep.name === p.$.Name);
152
- return this.mapProp(p, epConfig);
153
- }),
163
+ props,
154
164
  baseProps: [], // postprocess required
155
165
  };
156
166
  }
157
- addTypeDefinition(types) {
167
+ addTypeDefinition(ns, types) {
158
168
  if (!types || !types.length) {
159
169
  return;
160
170
  }
161
171
  for (const t of types) {
162
- this.dataModel.addTypeDefinition(t.$.Name, t.$.UnderlyingType);
172
+ this.dataModel.addTypeDefinition(ns, t.$.Name, t.$.UnderlyingType);
163
173
  }
164
174
  }
165
- addComplexType(models) {
175
+ addComplexType(namespace, models) {
166
176
  if (!models || !models.length) {
167
177
  return;
168
178
  }
169
179
  for (const model of models) {
170
- const baseModel = this.getBaseModel(model);
171
- this.dataModel.addComplexType(baseModel.name, baseModel);
180
+ const baseModel = this.getBaseModel(namespace, model);
181
+ this.dataModel.addComplexType(namespace[0], baseModel.odataName, baseModel);
172
182
  }
173
183
  }
174
- addEntityType(models) {
184
+ addEntityType(namespace, models) {
175
185
  var _a;
176
186
  if (!models || !models.length) {
177
187
  return;
178
188
  }
179
189
  for (const model of models) {
180
- const baseModel = this.getBaseModel(model);
181
- const entityConfig = this.serviceConfigHelper.findConfigEntityByName(model.$.Name);
190
+ const baseModel = this.getBaseModel(namespace, model);
191
+ const entityConfig = this.serviceConfigHelper.findEntityConfigByName(namespace, model.$.Name);
182
192
  const entityName = (entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.mappedName) || model.$.Name;
183
193
  // key support: we add keys from this entity,
184
194
  // but not keys stemming from base classes (postprocess required)
@@ -193,7 +203,7 @@ class Digester {
193
203
  keyNames.push(...propNames);
194
204
  }
195
205
  }
196
- 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(" | ") }));
206
+ this.dataModel.addEntityType(namespace[0], baseModel.odataName, Object.assign(Object.assign({}, baseModel), { idModelName: this.namingHelper.getIdModelName(entityName), qIdFunctionName: this.namingHelper.getQIdFunctionName(entityName), generateId: true, keyNames: keyNames, keys: [], getKeyUnion: () => keyNames.join(" | ") }));
197
207
  }
198
208
  }
199
209
  postProcessModel() {
@@ -203,8 +213,8 @@ class Digester {
203
213
  const [baseProps] = this.collectBaseClassPropsAndKeys(model, []);
204
214
  model.baseProps = baseProps;
205
215
  });
206
- const modelTypes = this.dataModel.getModels();
207
216
  // entity types
217
+ const modelTypes = this.dataModel.getEntityTypes();
208
218
  modelTypes.forEach((model) => {
209
219
  const [baseProps, baseKeys, idName, qIdName] = this.collectBaseClassPropsAndKeys(model, []);
210
220
  model.baseProps = baseProps;
@@ -232,47 +242,15 @@ class Digester {
232
242
  return prop;
233
243
  });
234
244
  });
235
- const sortedModelTypes = this.sortModelsByInheritance(modelTypes);
236
- this.dataModel.setModels(sortedModelTypes);
237
- const sortedComplexTypes = this.sortModelsByInheritance(complexTypes);
238
- this.dataModel.setComplexTypes(sortedComplexTypes);
239
- }
240
- sortModelsByInheritance(models) {
241
- // recursively visit all models and sort them by inheritance such that base classes
242
- // are always before derived classes
243
- const sortedModels = {};
244
- const visitedModels = new Set();
245
- const inProgressModels = new Set();
246
- function visit(model) {
247
- if (inProgressModels.has(model)) {
248
- throw new Error("Cyclic dependencies detected!");
249
- }
250
- if (!visitedModels.has(model)) {
251
- inProgressModels.add(model);
252
- for (const baseClassName of model.baseClasses) {
253
- const baseClass = models.find((e) => e.name === baseClassName);
254
- if (baseClass) {
255
- visit(baseClass);
256
- }
257
- }
258
- visitedModels.add(model);
259
- inProgressModels.delete(model);
260
- sortedModels[model.name] = model;
261
- }
262
- }
263
- for (const model of models) {
264
- visit(model);
265
- }
266
- return sortedModels;
267
245
  }
268
246
  collectBaseClassPropsAndKeys(model, visitedModels) {
269
- if (visitedModels.includes(model.name)) {
270
- throw new Error(`Cyclic inheritance detected for model ${model.name}!`);
247
+ if (visitedModels.includes(model.fqName)) {
248
+ throw new Error(`Cyclic inheritance detected for model ${model.fqName}!`);
271
249
  }
272
- visitedModels.push(model.name);
250
+ visitedModels.push(model.fqName);
273
251
  return model.baseClasses.reduce(([props, keys, idName, qIdName], bc) => {
274
252
  var _a;
275
- const baseModel = this.dataModel.getModel(bc) || this.dataModel.getComplexType(bc);
253
+ const baseModel = this.dataModel.getEntityType(bc) || this.dataModel.getComplexType(bc);
276
254
  if (!baseModel) {
277
255
  throw new Error(`BaseModel "${bc}" doesn't exist!`);
278
256
  }
@@ -289,10 +267,11 @@ class Digester {
289
267
  }
290
268
  }
291
269
  props.push(...baseModel.props);
292
- if ((_a = baseModel.keyNames) === null || _a === void 0 ? void 0 : _a.length) {
293
- keys.push(...baseModel.keyNames.filter((kn) => !keys.includes(kn)));
294
- idNameResult = baseModel.idModelName;
295
- qIdNameResult = baseModel.qIdFunctionName;
270
+ const entityModel = baseModel;
271
+ if ((_a = entityModel.keyNames) === null || _a === void 0 ? void 0 : _a.length) {
272
+ keys.push(...entityModel.keyNames.filter((kn) => !keys.includes(kn)));
273
+ idNameResult = entityModel.idModelName;
274
+ qIdNameResult = entityModel.qIdFunctionName;
296
275
  }
297
276
  return [props, keys, idNameResult, qIdNameResult];
298
277
  }, [[], [], "", ""]);
@@ -300,5 +279,4 @@ class Digester {
300
279
  }
301
280
  exports.Digester = Digester;
302
281
  Digester.EDM_PREFIX = "Edm.";
303
- Digester.ROOT_OPERATION = "/";
304
282
  //# sourceMappingURL=DataModelDigestion.js.map