@itwin/ecschema-editing 4.6.0-dev.6 → 4.6.0-dev.8

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 (156) hide show
  1. package/lib/cjs/Differencing/SchemaConflicts.d.ts +2 -2
  2. package/lib/cjs/Differencing/SchemaConflicts.js +1 -1
  3. package/lib/cjs/Differencing/SchemaConflicts.js.map +1 -1
  4. package/lib/cjs/Differencing/SchemaDiagnosticVisitor.d.ts +9 -6
  5. package/lib/cjs/Differencing/SchemaDiagnosticVisitor.d.ts.map +1 -1
  6. package/lib/cjs/Differencing/SchemaDiagnosticVisitor.js +213 -161
  7. package/lib/cjs/Differencing/SchemaDiagnosticVisitor.js.map +1 -1
  8. package/lib/cjs/Differencing/SchemaDifference.d.ts +354 -78
  9. package/lib/cjs/Differencing/SchemaDifference.d.ts.map +1 -1
  10. package/lib/cjs/Differencing/SchemaDifference.js +184 -11
  11. package/lib/cjs/Differencing/SchemaDifference.js.map +1 -1
  12. package/lib/cjs/Editing/Constants.js.map +1 -1
  13. package/lib/cjs/Editing/CustomAttributes.js.map +1 -1
  14. package/lib/cjs/Editing/ECClasses.js.map +1 -1
  15. package/lib/cjs/Editing/Editor.js.map +1 -1
  16. package/lib/cjs/Editing/Entities.js.map +1 -1
  17. package/lib/cjs/Editing/Enumerations.js.map +1 -1
  18. package/lib/cjs/Editing/Formats.js.map +1 -1
  19. package/lib/cjs/Editing/InvertedUnits.js.map +1 -1
  20. package/lib/cjs/Editing/KindOfQuantities.js.map +1 -1
  21. package/lib/cjs/Editing/Mixins.js.map +1 -1
  22. package/lib/cjs/Editing/Mutable/MutableArrayProperty.js.map +1 -1
  23. package/lib/cjs/Editing/Mutable/MutableCAClass.js.map +1 -1
  24. package/lib/cjs/Editing/Mutable/MutableClass.js.map +1 -1
  25. package/lib/cjs/Editing/Mutable/MutableConstant.d.ts +1 -0
  26. package/lib/cjs/Editing/Mutable/MutableConstant.d.ts.map +1 -1
  27. package/lib/cjs/Editing/Mutable/MutableConstant.js.map +1 -1
  28. package/lib/cjs/Editing/Mutable/MutableEntityClass.js.map +1 -1
  29. package/lib/cjs/Editing/Mutable/MutableEnumeration.d.ts +1 -0
  30. package/lib/cjs/Editing/Mutable/MutableEnumeration.d.ts.map +1 -1
  31. package/lib/cjs/Editing/Mutable/MutableEnumeration.js.map +1 -1
  32. package/lib/cjs/Editing/Mutable/MutableFormat.js.map +1 -1
  33. package/lib/cjs/Editing/Mutable/MutableInvertedUnit.js.map +1 -1
  34. package/lib/cjs/Editing/Mutable/MutableKindOfQuantity.d.ts +2 -0
  35. package/lib/cjs/Editing/Mutable/MutableKindOfQuantity.d.ts.map +1 -1
  36. package/lib/cjs/Editing/Mutable/MutableKindOfQuantity.js.map +1 -1
  37. package/lib/cjs/Editing/Mutable/MutableMixin.js.map +1 -1
  38. package/lib/cjs/Editing/Mutable/MutablePhenomenon.d.ts +1 -0
  39. package/lib/cjs/Editing/Mutable/MutablePhenomenon.d.ts.map +1 -1
  40. package/lib/cjs/Editing/Mutable/MutablePhenomenon.js.map +1 -1
  41. package/lib/cjs/Editing/Mutable/MutablePrimitiveOrEnumProperty.js.map +1 -1
  42. package/lib/cjs/Editing/Mutable/MutableProperty.js.map +1 -1
  43. package/lib/cjs/Editing/Mutable/MutablePropertyCategory.d.ts +1 -0
  44. package/lib/cjs/Editing/Mutable/MutablePropertyCategory.d.ts.map +1 -1
  45. package/lib/cjs/Editing/Mutable/MutablePropertyCategory.js.map +1 -1
  46. package/lib/cjs/Editing/Mutable/MutableRelationshipClass.js.map +1 -1
  47. package/lib/cjs/Editing/Mutable/MutableSchema.d.ts +2 -0
  48. package/lib/cjs/Editing/Mutable/MutableSchema.d.ts.map +1 -1
  49. package/lib/cjs/Editing/Mutable/MutableSchema.js.map +1 -1
  50. package/lib/cjs/Editing/Mutable/MutableUnit.js.map +1 -1
  51. package/lib/cjs/Editing/Mutable/MutableUnitSystem.d.ts +1 -0
  52. package/lib/cjs/Editing/Mutable/MutableUnitSystem.d.ts.map +1 -1
  53. package/lib/cjs/Editing/Mutable/MutableUnitSystem.js.map +1 -1
  54. package/lib/cjs/Editing/Phenomena.js.map +1 -1
  55. package/lib/cjs/Editing/PropertyCategories.js.map +1 -1
  56. package/lib/cjs/Editing/RelationshipClasses.js.map +1 -1
  57. package/lib/cjs/Editing/SchemaItems.js.map +1 -1
  58. package/lib/cjs/Editing/Structs.js.map +1 -1
  59. package/lib/cjs/Editing/UnitSystems.js.map +1 -1
  60. package/lib/cjs/Editing/Units.js.map +1 -1
  61. package/lib/cjs/Merging/CAClassMerger.d.ts +4 -7
  62. package/lib/cjs/Merging/CAClassMerger.d.ts.map +1 -1
  63. package/lib/cjs/Merging/CAClassMerger.js +26 -23
  64. package/lib/cjs/Merging/CAClassMerger.js.map +1 -1
  65. package/lib/cjs/Merging/ClassMerger.d.ts +10 -18
  66. package/lib/cjs/Merging/ClassMerger.d.ts.map +1 -1
  67. package/lib/cjs/Merging/ClassMerger.js +148 -155
  68. package/lib/cjs/Merging/ClassMerger.js.map +1 -1
  69. package/lib/cjs/Merging/ConstantMerger.d.ts +4 -8
  70. package/lib/cjs/Merging/ConstantMerger.d.ts.map +1 -1
  71. package/lib/cjs/Merging/ConstantMerger.js +59 -40
  72. package/lib/cjs/Merging/ConstantMerger.js.map +1 -1
  73. package/lib/cjs/Merging/CustomAttributeMerger.d.ts +16 -13
  74. package/lib/cjs/Merging/CustomAttributeMerger.d.ts.map +1 -1
  75. package/lib/cjs/Merging/CustomAttributeMerger.js +66 -34
  76. package/lib/cjs/Merging/CustomAttributeMerger.js.map +1 -1
  77. package/lib/cjs/Merging/EntityClassMerger.d.ts +10 -7
  78. package/lib/cjs/Merging/EntityClassMerger.d.ts.map +1 -1
  79. package/lib/cjs/Merging/EntityClassMerger.js +41 -29
  80. package/lib/cjs/Merging/EntityClassMerger.js.map +1 -1
  81. package/lib/cjs/Merging/EnumerationMerger.d.ts +9 -9
  82. package/lib/cjs/Merging/EnumerationMerger.d.ts.map +1 -1
  83. package/lib/cjs/Merging/EnumerationMerger.js +77 -48
  84. package/lib/cjs/Merging/EnumerationMerger.js.map +1 -1
  85. package/lib/cjs/Merging/KindOfQuantityMerger.d.ts +4 -11
  86. package/lib/cjs/Merging/KindOfQuantityMerger.d.ts.map +1 -1
  87. package/lib/cjs/Merging/KindOfQuantityMerger.js +57 -53
  88. package/lib/cjs/Merging/KindOfQuantityMerger.js.map +1 -1
  89. package/lib/cjs/Merging/MixinMerger.d.ts +4 -7
  90. package/lib/cjs/Merging/MixinMerger.d.ts.map +1 -1
  91. package/lib/cjs/Merging/MixinMerger.js +24 -25
  92. package/lib/cjs/Merging/MixinMerger.js.map +1 -1
  93. package/lib/cjs/Merging/PhenomenonMerger.d.ts +8 -0
  94. package/lib/cjs/Merging/PhenomenonMerger.d.ts.map +1 -0
  95. package/lib/cjs/Merging/PhenomenonMerger.js +37 -0
  96. package/lib/cjs/Merging/PhenomenonMerger.js.map +1 -0
  97. package/lib/cjs/Merging/PropertyCategoryMerger.d.ts +8 -0
  98. package/lib/cjs/Merging/PropertyCategoryMerger.d.ts.map +1 -0
  99. package/lib/cjs/Merging/PropertyCategoryMerger.js +34 -0
  100. package/lib/cjs/Merging/PropertyCategoryMerger.js.map +1 -0
  101. package/lib/cjs/Merging/PropertyMerger.d.ts +6 -14
  102. package/lib/cjs/Merging/PropertyMerger.d.ts.map +1 -1
  103. package/lib/cjs/Merging/PropertyMerger.js +212 -287
  104. package/lib/cjs/Merging/PropertyMerger.js.map +1 -1
  105. package/lib/cjs/Merging/RelationshipClassMerger.d.ts +16 -10
  106. package/lib/cjs/Merging/RelationshipClassMerger.d.ts.map +1 -1
  107. package/lib/cjs/Merging/RelationshipClassMerger.js +121 -112
  108. package/lib/cjs/Merging/RelationshipClassMerger.js.map +1 -1
  109. package/lib/cjs/Merging/SchemaItemMerger.d.ts +26 -51
  110. package/lib/cjs/Merging/SchemaItemMerger.d.ts.map +1 -1
  111. package/lib/cjs/Merging/SchemaItemMerger.js +106 -88
  112. package/lib/cjs/Merging/SchemaItemMerger.js.map +1 -1
  113. package/lib/cjs/Merging/SchemaMerger.d.ts +21 -9
  114. package/lib/cjs/Merging/SchemaMerger.d.ts.map +1 -1
  115. package/lib/cjs/Merging/SchemaMerger.js +74 -88
  116. package/lib/cjs/Merging/SchemaMerger.js.map +1 -1
  117. package/lib/cjs/Merging/SchemaReferenceMerger.d.ts +5 -5
  118. package/lib/cjs/Merging/SchemaReferenceMerger.d.ts.map +1 -1
  119. package/lib/cjs/Merging/SchemaReferenceMerger.js +33 -15
  120. package/lib/cjs/Merging/SchemaReferenceMerger.js.map +1 -1
  121. package/lib/cjs/Merging/UnitSystemMerger.d.ts +8 -0
  122. package/lib/cjs/Merging/UnitSystemMerger.d.ts.map +1 -0
  123. package/lib/cjs/Merging/UnitSystemMerger.js +26 -0
  124. package/lib/cjs/Merging/UnitSystemMerger.js.map +1 -0
  125. package/lib/cjs/Validation/Diagnostic.js.map +1 -1
  126. package/lib/cjs/Validation/DiagnosticReporter.js.map +1 -1
  127. package/lib/cjs/Validation/ECRules.d.ts +23 -23
  128. package/lib/cjs/Validation/ECRules.d.ts.map +1 -1
  129. package/lib/cjs/Validation/ECRules.js +1 -1
  130. package/lib/cjs/Validation/ECRules.js.map +1 -1
  131. package/lib/cjs/Validation/LoggingDiagnosticReporter.js.map +1 -1
  132. package/lib/cjs/Validation/RuleSuppressionSet.js.map +1 -1
  133. package/lib/cjs/Validation/Rules.js.map +1 -1
  134. package/lib/cjs/Validation/SchemaChanges.js +1 -1
  135. package/lib/cjs/Validation/SchemaChanges.js.map +1 -1
  136. package/lib/cjs/Validation/SchemaCompareDiagnostics.js.map +1 -1
  137. package/lib/cjs/Validation/SchemaCompareReporter.js.map +1 -1
  138. package/lib/cjs/Validation/SchemaCompareResultDelegate.js.map +1 -1
  139. package/lib/cjs/Validation/SchemaCompareVisitor.js.map +1 -1
  140. package/lib/cjs/Validation/SchemaComparer.d.ts.map +1 -1
  141. package/lib/cjs/Validation/SchemaComparer.js +3 -3
  142. package/lib/cjs/Validation/SchemaComparer.js.map +1 -1
  143. package/lib/cjs/Validation/SchemaValidater.js.map +1 -1
  144. package/lib/cjs/Validation/SchemaValidationVisitor.js.map +1 -1
  145. package/lib/cjs/Validation/SchemaWalker.js.map +1 -1
  146. package/lib/cjs/ecschema-editing.js.map +1 -1
  147. package/package.json +9 -9
  148. package/public/locales/en/ECSchemaEditing.json +26 -26
  149. package/lib/cjs/Merging/SchemaItemFactory.d.ts +0 -15
  150. package/lib/cjs/Merging/SchemaItemFactory.d.ts.map +0 -1
  151. package/lib/cjs/Merging/SchemaItemFactory.js +0 -82
  152. package/lib/cjs/Merging/SchemaItemFactory.js.map +0 -1
  153. package/lib/cjs/Merging/StructClassMerger.d.ts +0 -10
  154. package/lib/cjs/Merging/StructClassMerger.d.ts.map +0 -1
  155. package/lib/cjs/Merging/StructClassMerger.js +0 -13
  156. package/lib/cjs/Merging/StructClassMerger.js.map +0 -1
@@ -1,102 +1,120 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SchemaItemMerger = void 0;
4
- /*---------------------------------------------------------------------------------------------
5
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
- * See LICENSE.md in the project root for license terms and full copyright notice.
7
- *--------------------------------------------------------------------------------------------*/
3
+ exports.updateSchemaItemKey = exports.updateSchemaItemFullName = exports.mergeSchemaItems = exports.locateSchemaItem = void 0;
4
+ const SchemaDifference_1 = require("../Differencing/SchemaDifference");
8
5
  const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
9
- const SchemaChanges_1 = require("../Validation/SchemaChanges");
10
- const SchemaItemFactory_1 = require("./SchemaItemFactory");
6
+ const EnumerationMerger_1 = require("./EnumerationMerger");
7
+ const PhenomenonMerger_1 = require("./PhenomenonMerger");
8
+ const PropertyCategoryMerger_1 = require("./PropertyCategoryMerger");
9
+ const UnitSystemMerger_1 = require("./UnitSystemMerger");
10
+ const KindOfQuantityMerger_1 = require("./KindOfQuantityMerger");
11
+ const ConstantMerger_1 = require("./ConstantMerger");
12
+ const ClassMerger_1 = require("./ClassMerger");
11
13
  /**
12
- * The SchemaItemMerger is an base class for several other mergers with the actual logic
13
- * to perform merging for a certain schema item type. The class provides the shared logics
14
- * that is shared for all schema item mergers and custom logic can be applied by overriding
15
- * the protected class members.
14
+ * Handles the merging logic for everything that is same for all schema items such as labels or descriptions
16
15
  * @internal
17
16
  */
18
- class SchemaItemMerger {
19
- /**
20
- * Constructor of the SchemaItemMerger class. This should not be overriden or extended
21
- * by sub-implementations.
22
- * @param context The current merging context.
23
- */
24
- constructor(context) {
25
- this.context = context;
17
+ async function mergeSchemaItem(context, change, merger) {
18
+ if (change.changeType === "add") {
19
+ return merger.add(context, change);
26
20
  }
27
- /**
28
- * This overridable method allows to create a property value resolver that gets defines
29
- * a handler function for every possible property change. This allows adding complex handing
30
- * if a property value requires complicated merging.
31
- * @returns A resolver map with resolvers for the property.
32
- */
33
- async createPropertyValueResolver() {
34
- // Can be overriden for complex property value merging
35
- return {};
21
+ if (change.changeType === "modify") {
22
+ const schemaItem = await locateSchemaItem(context, change.itemName, change.schemaType);
23
+ return merger.modify(context, change, schemaItem.key, schemaItem);
36
24
  }
37
- /**
38
- * This overridable method gets called for more complex merging.
39
- * @param _itemKey The key of the current schema item.
40
- * @param _source The source item that shall gets merged into.
41
- * @param _change The schema item change to be applied.
42
- */
43
- async merge(_itemKey, _source, _change) {
44
- // Can be overriden for complex merging
25
+ return { errorMessage: `The merger does not support ${change.changeType} of ${change.schemaType}.` };
26
+ }
27
+ /**
28
+ * @internal
29
+ */
30
+ async function locateSchemaItem(context, itemName, schemaType) {
31
+ const schemaItemKey = new ecschema_metadata_1.SchemaItemKey(itemName, context.targetSchemaKey);
32
+ const schemaItem = await context.editor.schemaContext.getSchemaItem(schemaItemKey);
33
+ if (schemaItem === undefined) {
34
+ throw new ecschema_metadata_1.ECObjectsError(ecschema_metadata_1.ECObjectsStatus.ClassNotFound, `${schemaType} ${schemaItemKey.fullName} not found in schema context.`);
35
+ }
36
+ return schemaItem;
37
+ }
38
+ exports.locateSchemaItem = locateSchemaItem;
39
+ /**
40
+ * Merges the given set of schema items. As schema items may depend or relate with other
41
+ * schema items, the list gets filtered to ensure the items get merged in a certain order.
42
+ * @param context The current merging context.
43
+ * @param itemChanges Set of schema item that differed.
44
+ * @returns An async iterable with the merge result for each schema item.
45
+ * @internal
46
+ */
47
+ async function* mergeSchemaItems(context, itemChanges) {
48
+ for (const difference of itemChanges.filter(SchemaDifference_1.SchemaDifference.isUnitSystemDifference)) {
49
+ yield await mergeSchemaItem(context, difference, UnitSystemMerger_1.unitSystemMerger);
50
+ }
51
+ for (const difference of itemChanges.filter(SchemaDifference_1.SchemaDifference.isPropertyCategoryDifference)) {
52
+ yield await mergeSchemaItem(context, difference, PropertyCategoryMerger_1.propertyCategoryMerger);
53
+ }
54
+ for (const difference of itemChanges.filter(SchemaDifference_1.SchemaDifference.isEnumerationDifference)) {
55
+ yield await mergeSchemaItem(context, difference, EnumerationMerger_1.enumerationMerger);
56
+ }
57
+ for (const difference of itemChanges.filter(SchemaDifference_1.SchemaDifference.isEnumeratorDifference)) {
58
+ yield await mergeSchemaItem(context, difference, EnumerationMerger_1.enumeratorMerger);
59
+ }
60
+ for (const difference of itemChanges.filter(SchemaDifference_1.SchemaDifference.isPhenomenonDifference)) {
61
+ yield await mergeSchemaItem(context, difference, PhenomenonMerger_1.phenomenonMerger);
62
+ }
63
+ // TODO:
64
+ // The following schema items are not supported yet. Mentioned in the processing order:
65
+ // - Unit
66
+ // - Inverted Unit
67
+ // - Format
68
+ for (const difference of itemChanges.filter(SchemaDifference_1.SchemaDifference.isKindOfQuantityDifference)) {
69
+ yield await mergeSchemaItem(context, difference, KindOfQuantityMerger_1.kindOfQuantityMerger);
45
70
  }
46
- async lookup(schemaItem) {
47
- const itemKey = new ecschema_metadata_1.SchemaItemKey(schemaItem.name, this.context.sourceSchema.schemaKey.matches(schemaItem.schema.schemaKey)
48
- ? this.context.targetSchema.schemaKey
49
- : schemaItem.schema.schemaKey);
50
- return this.context.targetSchema.lookupItem(itemKey);
71
+ for (const difference of itemChanges.filter(SchemaDifference_1.SchemaDifference.isConstantDifference)) {
72
+ yield await mergeSchemaItem(context, difference, ConstantMerger_1.constantMerger);
51
73
  }
52
- /**
53
- * Merges the given schema item changes in the current context.
54
- * @param context The merging context
55
- * @param schemaItemChanges An iterable of item changes.
56
- */
57
- static async mergeChanges(context, schemaItemChanges) {
58
- const merger = new this(context);
59
- for (const change of schemaItemChanges) {
60
- // Gets the source and the target item. The target item could be undefined at that point.
61
- const sourceItem = (await context.sourceSchema.getItem(change.ecTypeName));
62
- let targetItemKey = new ecschema_metadata_1.SchemaItemKey(change.ecTypeName, context.targetSchema.schemaKey);
63
- // In case the schema item does not exists in the target schema, an instance for
64
- // this schema item is created. It's properties get set by the merger then.
65
- if (change.schemaItemMissing?.changeType === SchemaChanges_1.ChangeType.Missing) {
66
- // Check for name to make sure there is no collision for items with the same name
67
- // but different type.
68
- if (await context.targetSchema.lookupItem(targetItemKey) !== undefined) {
69
- throw new Error(`Schema ${context.targetSchema.name} already contains a Schema Item ${change.ecTypeName}.`);
70
- }
71
- // TODO: Think about renaming the Schema Item. This could be controlled though a flag.
72
- targetItemKey = await SchemaItemFactory_1.SchemaItemFactory.create(context, sourceItem);
73
- }
74
- await merger.mergeItemPropertyValues(targetItemKey, change.propertyValueChanges);
75
- await merger.merge(targetItemKey, sourceItem, change);
76
- }
74
+ // Classes are slightly differently merged, since they can refer each other the process
75
+ // uses several stages to merge.
76
+ for await (const classMergeResult of (0, ClassMerger_1.mergeClassItems)(context, itemChanges)) {
77
+ yield classMergeResult;
77
78
  }
78
- /**
79
- * Merges the property values.
80
- * @param targetItem The current schema item
81
- * @param changes The property changes.
82
- */
83
- async mergeItemPropertyValues(targetItemKey, changes) {
84
- // No need to process anything if no properties differ.
85
- if (changes.length === 0) {
86
- return;
87
- }
88
- const targetItem = (await this.context.targetSchema.lookupItem(targetItemKey));
89
- const jsonProps = (targetItem?.toJSON() ?? {});
90
- const propertyResolver = await this.createPropertyValueResolver();
91
- for (const change of changes) {
92
- const [propertyName, propertyNewValue, propertyOldValue] = change.diagnostic.messageArgs;
93
- const resolver = propertyResolver[propertyName];
94
- jsonProps[propertyName] = resolver !== undefined
95
- ? resolver(propertyNewValue, targetItemKey, propertyOldValue)
96
- : propertyNewValue;
97
- }
98
- await this.context.editor.schemaItems.applyProps(targetItemKey, jsonProps);
79
+ }
80
+ exports.mergeSchemaItems = mergeSchemaItems;
81
+ /**
82
+ * Convenience-method around updateSchemaItemKey that returns the full name instead of a SchemaItemKey.
83
+ * @internal
84
+ */
85
+ async function updateSchemaItemFullName(context, reference) {
86
+ const schemaItemKey = await updateSchemaItemKey(context, reference);
87
+ return schemaItemKey.fullName;
88
+ }
89
+ exports.updateSchemaItemFullName = updateSchemaItemFullName;
90
+ /**
91
+ * Updates the given reference if it refers to a SchemaItem in the source Schema and
92
+ * returns a SchemaItemKey. If any other schema is referred the reference is not change.
93
+ * @internal
94
+ */
95
+ async function updateSchemaItemKey(context, reference) {
96
+ const [schemaName, itemName] = ecschema_metadata_1.SchemaItem.parseFullName(reference);
97
+ if (context.sourceSchemaKey.compareByName(schemaName)) {
98
+ return resolveSchemaItemKey(context.editor.schemaContext, new ecschema_metadata_1.SchemaItemKey(itemName, context.targetSchemaKey));
99
+ }
100
+ const referencedSchema = await context.targetSchema.getReference(schemaName);
101
+ if (referencedSchema !== undefined) {
102
+ return resolveSchemaItemKey(context.editor.schemaContext, new ecschema_metadata_1.SchemaItemKey(itemName, referencedSchema.schemaKey));
103
+ }
104
+ throw new Error(`Cannot locate referenced schema item ${reference}`);
105
+ }
106
+ exports.updateSchemaItemKey = updateSchemaItemKey;
107
+ /**
108
+ * To support case insensitivity for schema items, the given key is checked if there
109
+ * exists an item for it.
110
+ * @internal
111
+ */
112
+ async function resolveSchemaItemKey(schemaContext, itemKey) {
113
+ const item = await schemaContext.getSchemaItem(itemKey);
114
+ if (item === undefined) {
115
+ // If the schema item hasn't been created yet, we have to trust the given key is correctly spelled.
116
+ return itemKey;
99
117
  }
118
+ return item.key;
100
119
  }
101
- exports.SchemaItemMerger = SchemaItemMerger;
102
120
  //# sourceMappingURL=SchemaItemMerger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaItemMerger.js","sourceRoot":"","sources":["../../../src/Merging/SchemaItemMerger.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { SchemaItem, SchemaItemKey } from \"@itwin/ecschema-metadata\";\r\nimport { ChangeType, PropertyValueChange, SchemaItemChanges } from \"../Validation/SchemaChanges\";\r\nimport { SchemaItemFactory } from \"./SchemaItemFactory\";\r\nimport { SchemaMergeContext } from \"./SchemaMerger\";\r\n\r\n/**\r\n * Defines a type-safe interface of Property Value resolver.\r\n * @internal\r\n */\r\nexport type PropertyValueResolver<T extends SchemaItem, TProps=MutableSchemaItemProps<T>> = {\r\n [P in keyof TProps]?: (newValue: any, item: SchemaItemKey, oldValue?: any) => any;\r\n};\r\n\r\n/**\r\n * Defines a Mutable Schema Props interface.\r\n */\r\ntype MutableSchemaItemProps<T extends SchemaItem> = {\r\n -readonly [key in keyof ReturnType<T[\"toJSON\"]>]: ReturnType<T[\"toJSON\"]>[key];\r\n};\r\n\r\n/**\r\n * The SchemaItemMerger is an base class for several other mergers with the actual logic\r\n * to perform merging for a certain schema item type. The class provides the shared logics\r\n * that is shared for all schema item mergers and custom logic can be applied by overriding\r\n * the protected class members.\r\n * @internal\r\n */\r\nexport class SchemaItemMerger<TItem extends SchemaItem> {\r\n\r\n protected readonly context: SchemaMergeContext;\r\n\r\n /**\r\n * Constructor of the SchemaItemMerger class. This should not be overriden or extended\r\n * by sub-implementations.\r\n * @param context The current merging context.\r\n */\r\n constructor(context: SchemaMergeContext) {\r\n this.context = context;\r\n }\r\n\r\n /**\r\n * This overridable method allows to create a property value resolver that gets defines\r\n * a handler function for every possible property change. This allows adding complex handing\r\n * if a property value requires complicated merging.\r\n * @returns A resolver map with resolvers for the property.\r\n */\r\n protected async createPropertyValueResolver(): Promise<PropertyValueResolver<TItem>> {\r\n // Can be overriden for complex property value merging\r\n return {};\r\n }\r\n\r\n /**\r\n * This overridable method gets called for more complex merging.\r\n * @param _itemKey The key of the current schema item.\r\n * @param _source The source item that shall gets merged into.\r\n * @param _change The schema item change to be applied.\r\n */\r\n protected async merge(_itemKey: SchemaItemKey, _source: TItem, _change: SchemaItemChanges) {\r\n // Can be overriden for complex merging\r\n }\r\n\r\n protected async lookup<T extends SchemaItem>(schemaItem: T): Promise<T | undefined>{\r\n const itemKey = new SchemaItemKey(schemaItem.name, this.context.sourceSchema.schemaKey.matches(schemaItem.schema.schemaKey)\r\n ? this.context.targetSchema.schemaKey\r\n : schemaItem.schema.schemaKey,\r\n );\r\n return this.context.targetSchema.lookupItem<T>(itemKey);\r\n }\r\n\r\n /**\r\n * Merges the given schema item changes in the current context.\r\n * @param context The merging context\r\n * @param schemaItemChanges An iterable of item changes.\r\n */\r\n public static async mergeChanges<TChange extends SchemaItemChanges>(context: SchemaMergeContext, schemaItemChanges: Iterable<TChange>) {\r\n const merger = new this(context);\r\n for(const change of schemaItemChanges) {\r\n\r\n // Gets the source and the target item. The target item could be undefined at that point.\r\n const sourceItem = (await context.sourceSchema.getItem<SchemaItem>(change.ecTypeName))!;\r\n let targetItemKey = new SchemaItemKey(change.ecTypeName, context.targetSchema.schemaKey);\r\n\r\n // In case the schema item does not exists in the target schema, an instance for\r\n // this schema item is created. It's properties get set by the merger then.\r\n if(change.schemaItemMissing?.changeType === ChangeType.Missing) {\r\n // Check for name to make sure there is no collision for items with the same name\r\n // but different type.\r\n if(await context.targetSchema.lookupItem(targetItemKey) !== undefined) {\r\n throw new Error(`Schema ${context.targetSchema.name} already contains a Schema Item ${change.ecTypeName}.`);\r\n }\r\n\r\n // TODO: Think about renaming the Schema Item. This could be controlled though a flag.\r\n targetItemKey = await SchemaItemFactory.create(context, sourceItem);\r\n }\r\n\r\n await merger.mergeItemPropertyValues(targetItemKey, change.propertyValueChanges);\r\n await merger.merge(targetItemKey, sourceItem, change);\r\n }\r\n }\r\n /**\r\n * Merges the property values.\r\n * @param targetItem The current schema item\r\n * @param changes The property changes.\r\n */\r\n private async mergeItemPropertyValues(targetItemKey: SchemaItemKey, changes: PropertyValueChange[]) {\r\n // No need to process anything if no properties differ.\r\n if(changes.length === 0) {\r\n return;\r\n }\r\n\r\n const targetItem = (await this.context.targetSchema.lookupItem<SchemaItem>(targetItemKey));\r\n const jsonProps = (targetItem?.toJSON() ?? {}) as MutableSchemaItemProps<TItem>;\r\n const propertyResolver = await this.createPropertyValueResolver();\r\n\r\n for(const change of changes) {\r\n const [propertyName, propertyNewValue, propertyOldValue] = change.diagnostic.messageArgs! as [keyof typeof jsonProps, any, any];\r\n const resolver = propertyResolver[propertyName];\r\n jsonProps[propertyName] = resolver !== undefined\r\n ? resolver(propertyNewValue, targetItemKey, propertyOldValue)\r\n : propertyNewValue;\r\n }\r\n\r\n await this.context.editor.schemaItems.applyProps(targetItemKey, jsonProps);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"SchemaItemMerger.js","sourceRoot":"","sources":["../../../src/Merging/SchemaItemMerger.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport type { SchemaMergeContext } from \"./SchemaMerger\";\nimport type { SchemaEditResults, SchemaItemEditResults } from \"../Editing/Editor\";\nimport { AnySchemaDifference, AnySchemaItemDifference, AnySchemaItemPathDifference, SchemaDifference } from \"../Differencing/SchemaDifference\";\nimport { ECObjectsError, ECObjectsStatus, SchemaContext, SchemaItem, SchemaItemKey } from \"@itwin/ecschema-metadata\";\nimport { enumerationMerger, enumeratorMerger } from \"./EnumerationMerger\";\nimport { phenomenonMerger } from \"./PhenomenonMerger\";\nimport { propertyCategoryMerger } from \"./PropertyCategoryMerger\";\nimport { unitSystemMerger } from \"./UnitSystemMerger\";\nimport { kindOfQuantityMerger } from \"./KindOfQuantityMerger\";\nimport { constantMerger } from \"./ConstantMerger\";\nimport { mergeClassItems } from \"./ClassMerger\";\n\n/**\n * @internal\n */\nexport interface SchemaItemMergerHandler<T extends AnySchemaItemDifference | AnySchemaItemPathDifference> {\n add: (context: SchemaMergeContext, change: T) => Promise<SchemaItemEditResults>;\n modify: (context: SchemaMergeContext, change: T, itemKey: SchemaItemKey, item: any) => Promise<SchemaItemEditResults>;\n}\n\n/**\n * Handles the merging logic for everything that is same for all schema items such as labels or descriptions\n * @internal\n */\nasync function mergeSchemaItem<T extends AnySchemaItemDifference|AnySchemaItemPathDifference>(context: SchemaMergeContext, change: T, merger: SchemaItemMergerHandler<T>): Promise<SchemaEditResults> {\n if(change.changeType === \"add\") {\n return merger.add(context, change);\n }\n\n if(change.changeType === \"modify\") {\n const schemaItem = await locateSchemaItem(context, change.itemName, change.schemaType);\n return merger.modify(context, change, schemaItem.key, schemaItem);\n }\n\n return { errorMessage: `The merger does not support ${change.changeType} of ${change.schemaType}.` };\n}\n\n/**\n * @internal\n */\nexport async function locateSchemaItem(context: SchemaMergeContext, itemName: string, schemaType: string) {\n const schemaItemKey = new SchemaItemKey(itemName, context.targetSchemaKey);\n const schemaItem = await context.editor.schemaContext.getSchemaItem(schemaItemKey);\n if (schemaItem === undefined) {\n throw new ECObjectsError(ECObjectsStatus.ClassNotFound, `${schemaType} ${schemaItemKey.fullName} not found in schema context.`);\n }\n\n return schemaItem;\n}\n\n/**\n * Merges the given set of schema items. As schema items may depend or relate with other\n * schema items, the list gets filtered to ensure the items get merged in a certain order.\n * @param context The current merging context.\n * @param itemChanges Set of schema item that differed.\n * @returns An async iterable with the merge result for each schema item.\n * @internal\n */\nexport async function* mergeSchemaItems(context: SchemaMergeContext, itemChanges: AnySchemaDifference[]) {\n for (const difference of itemChanges.filter(SchemaDifference.isUnitSystemDifference)) {\n yield await mergeSchemaItem(context, difference, unitSystemMerger);\n }\n\n for (const difference of itemChanges.filter(SchemaDifference.isPropertyCategoryDifference)) {\n yield await mergeSchemaItem(context, difference, propertyCategoryMerger);\n }\n\n for (const difference of itemChanges.filter(SchemaDifference.isEnumerationDifference)) {\n yield await mergeSchemaItem(context, difference, enumerationMerger);\n }\n\n for (const difference of itemChanges.filter(SchemaDifference.isEnumeratorDifference)) {\n yield await mergeSchemaItem(context, difference, enumeratorMerger);\n }\n\n for (const difference of itemChanges.filter(SchemaDifference.isPhenomenonDifference)) {\n yield await mergeSchemaItem(context, difference, phenomenonMerger);\n }\n\n // TODO:\n // The following schema items are not supported yet. Mentioned in the processing order:\n // - Unit\n // - Inverted Unit\n // - Format\n\n for (const difference of itemChanges.filter(SchemaDifference.isKindOfQuantityDifference)) {\n yield await mergeSchemaItem(context, difference, kindOfQuantityMerger);\n }\n\n for (const difference of itemChanges.filter(SchemaDifference.isConstantDifference)) {\n yield await mergeSchemaItem(context, difference, constantMerger);\n }\n\n // Classes are slightly differently merged, since they can refer each other the process\n // uses several stages to merge.\n for await (const classMergeResult of mergeClassItems(context, itemChanges)) {\n yield classMergeResult;\n }\n}\n\n/**\n * Convenience-method around updateSchemaItemKey that returns the full name instead of a SchemaItemKey.\n * @internal\n */\nexport async function updateSchemaItemFullName(context: SchemaMergeContext, reference: string) {\n const schemaItemKey = await updateSchemaItemKey(context, reference);\n return schemaItemKey.fullName;\n}\n\n/**\n * Updates the given reference if it refers to a SchemaItem in the source Schema and\n * returns a SchemaItemKey. If any other schema is referred the reference is not change.\n * @internal\n */\nexport async function updateSchemaItemKey(context: SchemaMergeContext, reference: string) {\n const [schemaName, itemName] = SchemaItem.parseFullName(reference);\n if (context.sourceSchemaKey.compareByName(schemaName)) {\n return resolveSchemaItemKey(context.editor.schemaContext, new SchemaItemKey(itemName, context.targetSchemaKey));\n }\n\n const referencedSchema = await context.targetSchema.getReference(schemaName);\n if (referencedSchema !== undefined) {\n return resolveSchemaItemKey(context.editor.schemaContext, new SchemaItemKey(itemName, referencedSchema.schemaKey));\n }\n\n throw new Error(`Cannot locate referenced schema item ${reference}`);\n}\n\n/**\n * To support case insensitivity for schema items, the given key is checked if there\n * exists an item for it.\n * @internal\n */\nasync function resolveSchemaItemKey(schemaContext: SchemaContext, itemKey: SchemaItemKey): Promise<SchemaItemKey> {\n const item = await schemaContext.getSchemaItem(itemKey);\n if (item === undefined) {\n // If the schema item hasn't been created yet, we have to trust the given key is correctly spelled.\n return itemKey;\n }\n return item.key;\n}\n"]}
@@ -1,15 +1,17 @@
1
1
  /** @packageDocumentation
2
2
  * @module Merging
3
3
  */
4
- import { Schema } from "@itwin/ecschema-metadata";
4
+ import { Schema, type SchemaContext, SchemaKey } from "@itwin/ecschema-metadata";
5
5
  import { SchemaContextEditor } from "../Editing/Editor";
6
+ import { SchemaDifferences } from "../Differencing/SchemaDifference";
6
7
  /**
7
8
  * Defines the context of a Schema merging run.
8
9
  * @beta
9
10
  */
10
11
  export interface SchemaMergeContext {
11
12
  readonly targetSchema: Schema;
12
- readonly sourceSchema: Schema;
13
+ readonly targetSchemaKey: SchemaKey;
14
+ readonly sourceSchemaKey: SchemaKey;
13
15
  readonly editor: SchemaContextEditor;
14
16
  }
15
17
  /**
@@ -18,15 +20,12 @@ export interface SchemaMergeContext {
18
20
  * @beta
19
21
  */
20
22
  export declare class SchemaMerger {
23
+ private readonly _editor;
21
24
  /**
22
- * Gets the @see SchemaChanges between the two given Schemas from perspective of the source
23
- * to the target schema. For example if source contains a class which does not exists in the
24
- * target one, it would be listed as missing.
25
- * @param targetSchema The schema the differences gets merged into.
26
- * @param sourceSchema The schema to compare.
27
- * @returns An instance of @see SchemaChanges between the two schemas.
25
+ * Constructs a new instance of the SchemaMerger object.
26
+ * @param editingContext The schema contexts that holds the schema to be edited.
28
27
  */
29
- private getSchemaChanges;
28
+ constructor(editingContext: SchemaContext);
30
29
  /**
31
30
  * Copy the SchemaItems of the source schemas to the target schema.
32
31
  * @param targetSchema The schema the SchemaItems gets merged to.
@@ -34,5 +33,18 @@ export declare class SchemaMerger {
34
33
  * @returns The merged target schema.
35
34
  */
36
35
  merge(targetSchema: Schema, sourceSchema: Schema): Promise<Schema>;
36
+ /**
37
+ * Merges the schema differences into the target schema context.
38
+ * @param differences The changes that shall be applied to the target schema.
39
+ * @alpha
40
+ */
41
+ merge(differences: SchemaDifferences): Promise<Schema>;
42
+ /**
43
+ * Merges the schema differences in the target schema. The target schema is defined
44
+ * in the given differences object.
45
+ * @param differences The differences between a source schema and the target schema.
46
+ * @returns The modified Schema.
47
+ */
48
+ private mergeSchemas;
37
49
  }
38
50
  //# sourceMappingURL=SchemaMerger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaMerger.d.ts","sourceRoot":"","sources":["../../../src/Merging/SchemaMerger.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAkB,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAcxD;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;CACtC;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACvB;;;;;;;OAOG;YACW,gBAAgB;IAW9B;;;;;OAKG;IACU,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA0ChF"}
1
+ {"version":3,"file":"SchemaMerger.d.ts","sourceRoot":"","sources":["../../../src/Merging/SchemaMerger.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAoB,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAKvF;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;CACtC;AAED;;;;GAIG;AACH,qBAAa,YAAY;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAE9C;;;OAGG;gBACS,cAAc,EAAE,aAAa;IAIzC;;;;;OAKG;IACI,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAEzE;;;;OAIG;IACI,KAAK,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IA0B7D;;;;;OAKG;YACW,YAAY;CA6C3B"}
@@ -9,19 +9,11 @@
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.SchemaMerger = void 0;
11
11
  const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
12
- const SchemaComparer_1 = require("../Validation/SchemaComparer");
13
12
  const Editor_1 = require("../Editing/Editor");
13
+ const SchemaDifference_1 = require("../Differencing/SchemaDifference");
14
+ const CustomAttributeMerger_1 = require("./CustomAttributeMerger");
14
15
  const SchemaItemMerger_1 = require("./SchemaItemMerger");
15
16
  const SchemaReferenceMerger_1 = require("./SchemaReferenceMerger");
16
- const CAClassMerger_1 = require("./CAClassMerger");
17
- const EnumerationMerger_1 = require("./EnumerationMerger");
18
- const ConstantMerger_1 = require("./ConstantMerger");
19
- const EntityClassMerger_1 = require("./EntityClassMerger");
20
- const StructClassMerger_1 = require("./StructClassMerger");
21
- const MixinMerger_1 = require("./MixinMerger");
22
- const CustomAttributeMerger_1 = require("./CustomAttributeMerger");
23
- const KindOfQuantityMerger_1 = require("./KindOfQuantityMerger");
24
- const RelationshipClassMerger_1 = require("./RelationshipClassMerger");
25
17
  /**
26
18
  * Class to merge two schemas together.
27
19
  * @see [[merge]] to merge the schemas.
@@ -29,94 +21,88 @@ const RelationshipClassMerger_1 = require("./RelationshipClassMerger");
29
21
  */
30
22
  class SchemaMerger {
31
23
  /**
32
- * Gets the @see SchemaChanges between the two given Schemas from perspective of the source
33
- * to the target schema. For example if source contains a class which does not exists in the
34
- * target one, it would be listed as missing.
35
- * @param targetSchema The schema the differences gets merged into.
36
- * @param sourceSchema The schema to compare.
37
- * @returns An instance of @see SchemaChanges between the two schemas.
24
+ * Constructs a new instance of the SchemaMerger object.
25
+ * @param editingContext The schema contexts that holds the schema to be edited.
38
26
  */
39
- async getSchemaChanges(targetSchema, sourceSchema) {
40
- const changesList = [];
41
- const schemaComparer = new SchemaComparer_1.SchemaComparer({ report: changesList.push.bind(changesList) });
42
- // It is important to compare the schema items by name, not full name as otherwise
43
- // we'd often see differences when comparing two different schemas.
44
- await schemaComparer.compareSchemas(sourceSchema, targetSchema);
45
- return changesList[0];
27
+ constructor(editingContext) {
28
+ this._editor = new Editor_1.SchemaContextEditor(editingContext);
46
29
  }
47
30
  /**
48
- * Copy the SchemaItems of the source schemas to the target schema.
49
- * @param targetSchema The schema the SchemaItems gets merged to.
50
- * @param sourceSchema The schema the SchemaItems gets copied from.
51
- * @returns The merged target schema.
31
+ * Merges the source and the target. If the target is a SchemaDifference, the
32
+ * source parameter must not be set. If it's a schema, it'll internally call
33
+ * the Differencing api and recall itself with the difference argument overload.
34
+ * @param input The methods input either a schema or a SchemaDifferences
35
+ * @param source A source schema.
36
+ * @returns The merged schema.
37
+ * @alpha
52
38
  */
53
- async merge(targetSchema, sourceSchema) {
54
- const schemaChanges = await this.getSchemaChanges(targetSchema, sourceSchema);
55
- const mergeContext = {
56
- editor: new Editor_1.SchemaContextEditor(targetSchema.context),
57
- targetSchema,
58
- sourceSchema,
39
+ async merge(input, source) {
40
+ if (ecschema_metadata_1.Schema.isSchema(input)) {
41
+ if (source === undefined) {
42
+ throw new Error("When merging two schemas, source must not be undefined.");
43
+ }
44
+ return this.merge(await SchemaDifference_1.SchemaDifference.fromSchemas(input, source));
45
+ }
46
+ if (input.conflicts && input.conflicts.length > 0) {
47
+ throw new Error("Schema's can't be merged if there are unresolved conflicts.");
48
+ }
49
+ return this.mergeSchemas(input);
50
+ }
51
+ /**
52
+ * Merges the schema differences in the target schema. The target schema is defined
53
+ * in the given differences object.
54
+ * @param differences The differences between a source schema and the target schema.
55
+ * @returns The modified Schema.
56
+ */
57
+ async mergeSchemas(differences) {
58
+ const targetSchemaKey = ecschema_metadata_1.SchemaKey.parseString(differences.targetSchemaName);
59
+ const sourceSchemaKey = ecschema_metadata_1.SchemaKey.parseString(differences.sourceSchemaName);
60
+ const schema = await this._editor.getSchema(targetSchemaKey);
61
+ if (schema === undefined) {
62
+ throw new Error();
63
+ }
64
+ const context = {
65
+ editor: this._editor,
66
+ targetSchema: schema,
67
+ targetSchemaKey,
68
+ sourceSchemaKey,
59
69
  };
60
- await (0, SchemaReferenceMerger_1.default)(mergeContext, schemaChanges);
61
- const itemChanges = getSchemaItemChanges(schemaChanges);
62
- await EnumerationMerger_1.default.mergeChanges(mergeContext, itemChanges.enumeratations);
63
- await SchemaItemMerger_1.SchemaItemMerger.mergeChanges(mergeContext, itemChanges.propertyCategories);
64
- await SchemaItemMerger_1.SchemaItemMerger.mergeChanges(mergeContext, itemChanges.unitSystems);
65
- await SchemaItemMerger_1.SchemaItemMerger.mergeChanges(mergeContext, itemChanges.phenomenons);
66
- await ConstantMerger_1.default.mergeChanges(mergeContext, itemChanges.constants);
67
- await KindOfQuantityMerger_1.default.mergeChanges(mergeContext, itemChanges.kindOfQuantities);
68
- // TODO: For now we just do simple copy and merging of properties and classes. For more complex types
69
- // with bases classes or relationships, this might need to get extended.
70
- await CAClassMerger_1.default.mergeItemStubChanges(mergeContext, itemChanges.customAttributeClasses);
71
- await StructClassMerger_1.default.mergeItemStubChanges(mergeContext, itemChanges.structClasses);
72
- await EntityClassMerger_1.default.mergeItemStubChanges(mergeContext, itemChanges.entityClasses);
73
- await MixinMerger_1.default.mergeItemStubChanges(mergeContext, itemChanges.mixins);
74
- await RelationshipClassMerger_1.default.mergeItemStubChanges(mergeContext, itemChanges.relationships);
75
- // 2nd pass to complete merge changes such as properties, baseClasses and mixins.
76
- await CAClassMerger_1.default.mergeItemContentChanges(mergeContext, itemChanges.customAttributeClasses);
77
- await StructClassMerger_1.default.mergeItemContentChanges(mergeContext, itemChanges.structClasses);
78
- await EntityClassMerger_1.default.mergeItemContentChanges(mergeContext, itemChanges.entityClasses);
79
- await MixinMerger_1.default.mergeItemContentChanges(mergeContext, itemChanges.mixins);
80
- await RelationshipClassMerger_1.default.mergeItemContentChanges(mergeContext, itemChanges.relationships);
81
- await (0, CustomAttributeMerger_1.mergeCustomAttributes)(mergeContext, schemaChanges.customAttributeChanges.values(), async (ca) => {
82
- return mergeContext.editor.addCustomAttribute(mergeContext.targetSchema.schemaKey, ca);
83
- });
84
- // TODO: For now we directly manipulate the target schema. For error handing purposes, we should first
85
- // merge into a temporary schema and eventually swap that with the given instance.
86
- return targetSchema;
70
+ if (differences.changes === undefined) {
71
+ return schema;
72
+ }
73
+ for (const referenceChange of differences.changes.filter(SchemaDifference_1.SchemaDifference.isSchemaReferenceDifference)) {
74
+ await (0, SchemaReferenceMerger_1.mergeSchemaReferences)(context, referenceChange);
75
+ }
76
+ const schemaDifference = differences.changes.find(SchemaDifference_1.SchemaDifference.isSchemaDifference);
77
+ if (schemaDifference !== undefined) {
78
+ await mergeSchemaProperties(schema, schemaDifference);
79
+ }
80
+ // Filter a list of possible schema item changes. This list gets filtered and order in the
81
+ // mergeSchemaItems method.
82
+ for await (const mergeResult of (0, SchemaItemMerger_1.mergeSchemaItems)(context, differences.changes)) {
83
+ if (mergeResult.errorMessage) {
84
+ throw new Error(mergeResult.errorMessage);
85
+ }
86
+ }
87
+ // At last the custom attributes gets merged because it could be that the CustomAttributes
88
+ // depend on classes that has to get merged in as items before.
89
+ for (const customAttributeChange of differences.changes.filter(SchemaDifference_1.SchemaDifference.isCustomAttributeDifference)) {
90
+ await (0, CustomAttributeMerger_1.mergeCustomAttribute)(context, customAttributeChange);
91
+ }
92
+ return schema;
87
93
  }
88
94
  }
89
95
  exports.SchemaMerger = SchemaMerger;
90
96
  /**
91
- * This helper method composes the different schema change objects to a single easier
92
- * to use object that should improve readability when the methods get called.
97
+ * Sets the editable properties of a Schema.
98
+ * @internal
93
99
  */
94
- function getSchemaItemChanges(schemaChanges) {
95
- return {
96
- get constants() { return filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.Constant); },
97
- get customAttributeClasses() { return filterChangesByItemType(schemaChanges.classChanges, ecschema_metadata_1.SchemaItemType.CustomAttributeClass); },
98
- get entityClasses() { return filterChangesByItemType(schemaChanges.classChanges, ecschema_metadata_1.SchemaItemType.EntityClass); },
99
- get enumeratations() { return schemaChanges.enumerationChanges.values(); },
100
- get kindOfQuantities() { return schemaChanges.kindOfQuantityChanges.values(); },
101
- get mixins() { return filterChangesByItemType(schemaChanges.classChanges, ecschema_metadata_1.SchemaItemType.Mixin); },
102
- get phenomenons() { return filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.Phenomenon); },
103
- get propertyCategories() { return filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.PropertyCategory); },
104
- get relationships() { return filterChangesByItemType(schemaChanges.classChanges, ecschema_metadata_1.SchemaItemType.RelationshipClass); },
105
- get structClasses() { return filterChangesByItemType(schemaChanges.classChanges, ecschema_metadata_1.SchemaItemType.StructClass); },
106
- get unitSystems() { return filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.UnitSystem); },
107
- };
108
- }
109
- /**
110
- * Filters and returns the changed items by its schema item type.
111
- * @param changes A map of changed schema items.
112
- * @param types A list of schema item types to filter.
113
- * @returns An Iterable with the filtered schema items.
114
- */
115
- function* filterChangesByItemType(changes, ...types) {
116
- for (const change of changes.values()) {
117
- if (types.includes(change.schemaItemType)) {
118
- yield change;
119
- }
100
+ async function mergeSchemaProperties(schema, changes) {
101
+ if (changes.difference.label !== undefined) {
102
+ schema.setDisplayLabel(changes.difference.label);
103
+ }
104
+ if (changes.difference.description !== undefined) {
105
+ schema.setDescription(changes.difference.description);
120
106
  }
121
107
  }
122
108
  //# sourceMappingURL=SchemaMerger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaMerger.js","sourceRoot":"","sources":["../../../src/Merging/SchemaMerger.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Merging\r\n */\r\n\r\nimport { Schema, SchemaItemType } from \"@itwin/ecschema-metadata\";\r\nimport { SchemaChanges, SchemaItemChanges } from \"../Validation/SchemaChanges\";\r\nimport { SchemaComparer } from \"../Validation/SchemaComparer\";\r\nimport { SchemaContextEditor } from \"../Editing/Editor\";\r\nimport { SchemaItemMerger } from \"./SchemaItemMerger\";\r\n\r\nimport mergeSchemaReferences from \"./SchemaReferenceMerger\";\r\nimport CAClassMerger from \"./CAClassMerger\";\r\nimport EnumerationMerger from \"./EnumerationMerger\";\r\nimport ConstantsMerger from \"./ConstantMerger\";\r\nimport EntityClassMerger from \"./EntityClassMerger\";\r\nimport StructClassMerger from \"./StructClassMerger\";\r\nimport MixinMerger from \"./MixinMerger\";\r\nimport { mergeCustomAttributes } from \"./CustomAttributeMerger\";\r\nimport KindOfQuantityMerger from \"./KindOfQuantityMerger\";\r\nimport RelationshipClassMerger from \"./RelationshipClassMerger\";\r\n\r\n/**\r\n * Defines the context of a Schema merging run.\r\n * @beta\r\n */\r\nexport interface SchemaMergeContext {\r\n readonly targetSchema: Schema;\r\n readonly sourceSchema: Schema;\r\n readonly editor: SchemaContextEditor;\r\n}\r\n\r\n/**\r\n * Class to merge two schemas together.\r\n * @see [[merge]] to merge the schemas.\r\n * @beta\r\n */\r\nexport class SchemaMerger {\r\n /**\r\n * Gets the @see SchemaChanges between the two given Schemas from perspective of the source\r\n * to the target schema. For example if source contains a class which does not exists in the\r\n * target one, it would be listed as missing.\r\n * @param targetSchema The schema the differences gets merged into.\r\n * @param sourceSchema The schema to compare.\r\n * @returns An instance of @see SchemaChanges between the two schemas.\r\n */\r\n private async getSchemaChanges(targetSchema: Schema, sourceSchema: Schema): Promise<SchemaChanges> {\r\n const changesList: SchemaChanges[] = [];\r\n const schemaComparer = new SchemaComparer({ report: changesList.push.bind(changesList) });\r\n\r\n // It is important to compare the schema items by name, not full name as otherwise\r\n // we'd often see differences when comparing two different schemas.\r\n await schemaComparer.compareSchemas(sourceSchema, targetSchema);\r\n\r\n return changesList[0];\r\n }\r\n\r\n /**\r\n * Copy the SchemaItems of the source schemas to the target schema.\r\n * @param targetSchema The schema the SchemaItems gets merged to.\r\n * @param sourceSchema The schema the SchemaItems gets copied from.\r\n * @returns The merged target schema.\r\n */\r\n public async merge(targetSchema: Schema, sourceSchema: Schema): Promise<Schema> {\r\n const schemaChanges = await this.getSchemaChanges(targetSchema, sourceSchema);\r\n const mergeContext: SchemaMergeContext = {\r\n editor: new SchemaContextEditor(targetSchema.context),\r\n targetSchema,\r\n sourceSchema,\r\n };\r\n\r\n await mergeSchemaReferences(mergeContext, schemaChanges);\r\n\r\n const itemChanges = getSchemaItemChanges(schemaChanges);\r\n await EnumerationMerger.mergeChanges(mergeContext, itemChanges.enumeratations);\r\n await SchemaItemMerger.mergeChanges(mergeContext, itemChanges.propertyCategories);\r\n\r\n await SchemaItemMerger.mergeChanges(mergeContext, itemChanges.unitSystems);\r\n await SchemaItemMerger.mergeChanges(mergeContext, itemChanges.phenomenons);\r\n await ConstantsMerger.mergeChanges(mergeContext, itemChanges.constants);\r\n await KindOfQuantityMerger.mergeChanges(mergeContext, itemChanges.kindOfQuantities);\r\n\r\n // TODO: For now we just do simple copy and merging of properties and classes. For more complex types\r\n // with bases classes or relationships, this might need to get extended.\r\n await CAClassMerger.mergeItemStubChanges(mergeContext, itemChanges.customAttributeClasses);\r\n await StructClassMerger.mergeItemStubChanges(mergeContext, itemChanges.structClasses);\r\n await EntityClassMerger.mergeItemStubChanges(mergeContext, itemChanges.entityClasses);\r\n await MixinMerger.mergeItemStubChanges(mergeContext, itemChanges.mixins);\r\n await RelationshipClassMerger.mergeItemStubChanges(mergeContext, itemChanges.relationships);\r\n\r\n // 2nd pass to complete merge changes such as properties, baseClasses and mixins.\r\n await CAClassMerger.mergeItemContentChanges(mergeContext, itemChanges.customAttributeClasses);\r\n await StructClassMerger.mergeItemContentChanges(mergeContext, itemChanges.structClasses);\r\n await EntityClassMerger.mergeItemContentChanges(mergeContext, itemChanges.entityClasses);\r\n await MixinMerger.mergeItemContentChanges(mergeContext, itemChanges.mixins);\r\n await RelationshipClassMerger.mergeItemContentChanges(mergeContext, itemChanges.relationships);\r\n\r\n await mergeCustomAttributes(mergeContext, schemaChanges.customAttributeChanges.values(), async (ca) => {\r\n return mergeContext.editor.addCustomAttribute(mergeContext.targetSchema.schemaKey, ca);\r\n });\r\n\r\n // TODO: For now we directly manipulate the target schema. For error handing purposes, we should first\r\n // merge into a temporary schema and eventually swap that with the given instance.\r\n return targetSchema;\r\n }\r\n}\r\n\r\n/**\r\n * This helper method composes the different schema change objects to a single easier\r\n * to use object that should improve readability when the methods get called.\r\n */\r\nfunction getSchemaItemChanges(schemaChanges: SchemaChanges) {\r\n return {\r\n get constants() { return filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.Constant); },\r\n get customAttributeClasses() { return filterChangesByItemType(schemaChanges.classChanges, SchemaItemType.CustomAttributeClass); },\r\n get entityClasses() { return filterChangesByItemType(schemaChanges.classChanges, SchemaItemType.EntityClass); },\r\n get enumeratations() { return schemaChanges.enumerationChanges.values(); },\r\n get kindOfQuantities() { return schemaChanges.kindOfQuantityChanges.values(); },\r\n get mixins() { return filterChangesByItemType(schemaChanges.classChanges, SchemaItemType.Mixin); },\r\n get phenomenons() { return filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.Phenomenon); },\r\n get propertyCategories() { return filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.PropertyCategory); },\r\n get relationships() { return filterChangesByItemType(schemaChanges.classChanges, SchemaItemType.RelationshipClass); },\r\n get structClasses() { return filterChangesByItemType(schemaChanges.classChanges, SchemaItemType.StructClass); },\r\n get unitSystems() { return filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.UnitSystem); },\r\n };\r\n}\r\n\r\n/**\r\n * Filters and returns the changed items by its schema item type.\r\n * @param changes A map of changed schema items.\r\n * @param types A list of schema item types to filter.\r\n * @returns An Iterable with the filtered schema items.\r\n */\r\nfunction * filterChangesByItemType<TChange extends SchemaItemChanges>(changes: Map<string, TChange>, ...types: SchemaItemType[]): Iterable<TChange> {\r\n for(const change of changes.values()) {\r\n if (types.includes(change.schemaItemType)) {\r\n yield change;\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"SchemaMerger.js","sourceRoot":"","sources":["../../../src/Merging/SchemaMerger.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Merging\n */\n\nimport { Schema, type SchemaContext, SchemaKey } from \"@itwin/ecschema-metadata\";\nimport { SchemaContextEditor } from \"../Editing/Editor\";\nimport { MutableSchema } from \"../Editing/Mutable/MutableSchema\";\nimport { SchemaDifference, SchemaDifferences } from \"../Differencing/SchemaDifference\";\nimport { mergeCustomAttribute } from \"./CustomAttributeMerger\";\nimport { mergeSchemaItems } from \"./SchemaItemMerger\";\nimport { mergeSchemaReferences } from \"./SchemaReferenceMerger\";\n\n/**\n * Defines the context of a Schema merging run.\n * @beta\n */\nexport interface SchemaMergeContext {\n readonly targetSchema: Schema;\n readonly targetSchemaKey: SchemaKey;\n readonly sourceSchemaKey: SchemaKey;\n readonly editor: SchemaContextEditor;\n}\n\n/**\n * Class to merge two schemas together.\n * @see [[merge]] to merge the schemas.\n * @beta\n */\nexport class SchemaMerger {\n\n private readonly _editor: SchemaContextEditor;\n\n /**\n * Constructs a new instance of the SchemaMerger object.\n * @param editingContext The schema contexts that holds the schema to be edited.\n */\n constructor(editingContext: SchemaContext) {\n this._editor = new SchemaContextEditor(editingContext);\n }\n\n /**\n * Copy the SchemaItems of the source schemas to the target schema.\n * @param targetSchema The schema the SchemaItems gets merged to.\n * @param sourceSchema The schema the SchemaItems gets copied from.\n * @returns The merged target schema.\n */\n public merge(targetSchema: Schema, sourceSchema: Schema): Promise<Schema>;\n\n /**\n * Merges the schema differences into the target schema context.\n * @param differences The changes that shall be applied to the target schema.\n * @alpha\n */\n public merge(differences: SchemaDifferences): Promise<Schema>;\n\n /**\n * Merges the source and the target. If the target is a SchemaDifference, the\n * source parameter must not be set. If it's a schema, it'll internally call\n * the Differencing api and recall itself with the difference argument overload.\n * @param input The methods input either a schema or a SchemaDifferences\n * @param source A source schema.\n * @returns The merged schema.\n * @alpha\n */\n public async merge(input: SchemaDifferences | Schema, source?: Schema): Promise<Schema> {\n if(Schema.isSchema(input)) {\n if(source === undefined) {\n throw new Error(\"When merging two schemas, source must not be undefined.\");\n }\n return this.merge(await SchemaDifference.fromSchemas(input, source));\n }\n\n if(input.conflicts && input.conflicts.length > 0) {\n throw new Error(\"Schema's can't be merged if there are unresolved conflicts.\");\n }\n\n return this.mergeSchemas(input);\n }\n\n /**\n * Merges the schema differences in the target schema. The target schema is defined\n * in the given differences object.\n * @param differences The differences between a source schema and the target schema.\n * @returns The modified Schema.\n */\n private async mergeSchemas(differences: SchemaDifferences): Promise<Schema> {\n const targetSchemaKey = SchemaKey.parseString(differences.targetSchemaName);\n const sourceSchemaKey = SchemaKey.parseString(differences.sourceSchemaName);\n\n const schema = await this._editor.getSchema(targetSchemaKey);\n if (schema === undefined) {\n throw new Error();\n }\n\n const context: SchemaMergeContext = {\n editor: this._editor,\n targetSchema: schema,\n targetSchemaKey,\n sourceSchemaKey,\n };\n\n if(differences.changes === undefined) {\n return schema;\n }\n\n for (const referenceChange of differences.changes.filter(SchemaDifference.isSchemaReferenceDifference)) {\n await mergeSchemaReferences(context, referenceChange);\n }\n\n const schemaDifference = differences.changes.find(SchemaDifference.isSchemaDifference);\n if(schemaDifference !== undefined) {\n await mergeSchemaProperties(schema, schemaDifference);\n }\n\n // Filter a list of possible schema item changes. This list gets filtered and order in the\n // mergeSchemaItems method.\n for await (const mergeResult of mergeSchemaItems(context, differences.changes)) {\n if(mergeResult.errorMessage) {\n throw new Error(mergeResult.errorMessage);\n }\n }\n\n // At last the custom attributes gets merged because it could be that the CustomAttributes\n // depend on classes that has to get merged in as items before.\n for (const customAttributeChange of differences.changes.filter(SchemaDifference.isCustomAttributeDifference)) {\n await mergeCustomAttribute(context, customAttributeChange);\n }\n\n return schema;\n }\n}\n\n/**\n * Sets the editable properties of a Schema.\n * @internal\n */\nasync function mergeSchemaProperties(schema: MutableSchema, changes: SchemaDifference) {\n if(changes.difference.label !== undefined) {\n schema.setDisplayLabel(changes.difference.label);\n }\n if(changes.difference.description !== undefined) {\n schema.setDescription(changes.difference.description);\n }\n}\n"]}
@@ -1,10 +1,10 @@
1
- import { SchemaChanges } from "../Validation/SchemaChanges";
2
- import { SchemaMergeContext } from "./SchemaMerger";
1
+ import { type SchemaMergeContext } from "./SchemaMerger";
2
+ import { type SchemaReferenceDifference } from "../Differencing/SchemaDifference";
3
3
  /**
4
4
  * Merges the schema references of two schemas.
5
- * @param mergeContext current merge context
6
- * @param changes schema changes.
5
+ * @param context current merge context
6
+ * @param change schema changes.
7
7
  * @internal
8
8
  */
9
- export default function mergeSchemaReferences(mergeContext: SchemaMergeContext, changes: SchemaChanges): Promise<void>;
9
+ export declare function mergeSchemaReferences(context: SchemaMergeContext, change: SchemaReferenceDifference): Promise<void>;
10
10
  //# sourceMappingURL=SchemaReferenceMerger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaReferenceMerger.d.ts","sourceRoot":"","sources":["../../../src/Merging/SchemaReferenceMerger.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;;;;GAKG;AACH,wBAA8B,qBAAqB,CAAC,YAAY,EAAE,kBAAkB,EAAE,OAAO,EAAE,aAAa,iBA+B3G"}
1
+ {"version":3,"file":"SchemaReferenceMerger.d.ts","sourceRoot":"","sources":["../../../src/Merging/SchemaReferenceMerger.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAGlF;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,yBAAyB,iBA8BzG"}