@itwin/ecschema-editing 4.3.0-dev.2 → 4.3.0-dev.5

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 (53) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/lib/cjs/Editing/Editor.d.ts +3 -0
  3. package/lib/cjs/Editing/Editor.d.ts.map +1 -1
  4. package/lib/cjs/Editing/Editor.js +3 -0
  5. package/lib/cjs/Editing/Editor.js.map +1 -1
  6. package/lib/cjs/Editing/Enumerations.d.ts +2 -0
  7. package/lib/cjs/Editing/Enumerations.d.ts.map +1 -1
  8. package/lib/cjs/Editing/Enumerations.js +22 -0
  9. package/lib/cjs/Editing/Enumerations.js.map +1 -1
  10. package/lib/cjs/Editing/SchemaItems.d.ts +15 -0
  11. package/lib/cjs/Editing/SchemaItems.d.ts.map +1 -0
  12. package/lib/cjs/Editing/SchemaItems.js +28 -0
  13. package/lib/cjs/Editing/SchemaItems.js.map +1 -0
  14. package/lib/cjs/Merging/CAClassMerger.d.ts +8 -2
  15. package/lib/cjs/Merging/CAClassMerger.d.ts.map +1 -1
  16. package/lib/cjs/Merging/CAClassMerger.js +12 -20
  17. package/lib/cjs/Merging/CAClassMerger.js.map +1 -1
  18. package/lib/cjs/Merging/ClassMerger.d.ts +7 -2
  19. package/lib/cjs/Merging/ClassMerger.d.ts.map +1 -1
  20. package/lib/cjs/Merging/ClassMerger.js +41 -45
  21. package/lib/cjs/Merging/ClassMerger.js.map +1 -1
  22. package/lib/cjs/Merging/ConstantMerger.d.ts +7 -7
  23. package/lib/cjs/Merging/ConstantMerger.d.ts.map +1 -1
  24. package/lib/cjs/Merging/ConstantMerger.js +37 -46
  25. package/lib/cjs/Merging/ConstantMerger.js.map +1 -1
  26. package/lib/cjs/Merging/EnumerationMerger.d.ts +8 -7
  27. package/lib/cjs/Merging/EnumerationMerger.d.ts.map +1 -1
  28. package/lib/cjs/Merging/EnumerationMerger.js +38 -67
  29. package/lib/cjs/Merging/EnumerationMerger.js.map +1 -1
  30. package/lib/cjs/Merging/SchemaItemFactory.d.ts +9 -2
  31. package/lib/cjs/Merging/SchemaItemFactory.d.ts.map +1 -1
  32. package/lib/cjs/Merging/SchemaItemFactory.js +45 -11
  33. package/lib/cjs/Merging/SchemaItemFactory.js.map +1 -1
  34. package/lib/cjs/Merging/SchemaItemMerger.d.ts +49 -20
  35. package/lib/cjs/Merging/SchemaItemMerger.d.ts.map +1 -1
  36. package/lib/cjs/Merging/SchemaItemMerger.js +76 -71
  37. package/lib/cjs/Merging/SchemaItemMerger.js.map +1 -1
  38. package/lib/cjs/Merging/SchemaMerger.d.ts +2 -0
  39. package/lib/cjs/Merging/SchemaMerger.d.ts.map +1 -1
  40. package/lib/cjs/Merging/SchemaMerger.js +29 -21
  41. package/lib/cjs/Merging/SchemaMerger.js.map +1 -1
  42. package/lib/cjs/Merging/SchemaReferenceMerger.d.ts.map +1 -1
  43. package/lib/cjs/Merging/SchemaReferenceMerger.js +8 -10
  44. package/lib/cjs/Merging/SchemaReferenceMerger.js.map +1 -1
  45. package/package.json +9 -9
  46. package/lib/cjs/Merging/PhenomenonMerger.d.ts +0 -7
  47. package/lib/cjs/Merging/PhenomenonMerger.d.ts.map +0 -1
  48. package/lib/cjs/Merging/PhenomenonMerger.js +0 -16
  49. package/lib/cjs/Merging/PhenomenonMerger.js.map +0 -1
  50. package/lib/cjs/Merging/PropertyCategoryMerger.d.ts +0 -7
  51. package/lib/cjs/Merging/PropertyCategoryMerger.d.ts.map +0 -1
  52. package/lib/cjs/Merging/PropertyCategoryMerger.js +0 -16
  53. package/lib/cjs/Merging/PropertyCategoryMerger.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getItemNameAndSchemaRef = exports.mergeSchemaItemProperties = void 0;
3
+ exports.SchemaItemMerger = void 0;
4
4
  /*---------------------------------------------------------------------------------------------
5
5
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
6
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -8,83 +8,88 @@ exports.getItemNameAndSchemaRef = exports.mergeSchemaItemProperties = void 0;
8
8
  const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
9
9
  const SchemaChanges_1 = require("../Validation/SchemaChanges");
10
10
  const SchemaItemFactory_1 = require("./SchemaItemFactory");
11
- class MutableSchemaItem extends ecschema_metadata_1.SchemaItem {
12
- }
13
11
  /**
14
- * Merges schema items from the source in the target schema. This method applies for all schema items
15
- * and handles the basic processing such as create-if-not-exists or name collisions or base property setting.
16
- * @param context The current merge context
17
- * @param schemaItemChanges The schema items to be merged
18
- * @param mergeFn Merge function for complex merging.
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.
19
16
  * @internal
20
17
  */
21
- async function mergeSchemaItems(context, schemaItemChanges, mergeFn) {
22
- for (const change of schemaItemChanges) {
23
- // Gets the source and the target item. The target item could be undefined at that point.
24
- const sourceItem = (await context.sourceSchema.getItem(change.ecTypeName));
25
- let targetItem = await context.targetSchema.getItem(change.ecTypeName);
26
- // In case the schema item does not exists in the target schema, an instance for
27
- // this schema item is created. It's properties get set by the merger then.
28
- if (change.schemaItemMissing?.changeType === SchemaChanges_1.ChangeType.Missing) {
29
- // Check for name to make sure there is no collision for items with the same name
30
- // but different type.
31
- if (targetItem !== undefined) {
32
- throw new Error(`Schema ${context.targetSchema.name} already contains a Schema Item ${change.ecTypeName}.`);
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;
26
+ }
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 {};
36
+ }
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
45
+ }
46
+ /**
47
+ * Merges the given schema item changes in the current context.
48
+ * @param context The merging context
49
+ * @param schemaItemChanges An iterable of item changes.
50
+ */
51
+ static async mergeChanges(context, schemaItemChanges) {
52
+ const merger = new this(context);
53
+ for (const change of schemaItemChanges) {
54
+ // Gets the source and the target item. The target item could be undefined at that point.
55
+ const sourceItem = (await context.sourceSchema.getItem(change.ecTypeName));
56
+ let targetItemKey = new ecschema_metadata_1.SchemaItemKey(change.ecTypeName, context.targetSchema.schemaKey);
57
+ // In case the schema item does not exists in the target schema, an instance for
58
+ // this schema item is created. It's properties get set by the merger then.
59
+ if (change.schemaItemMissing?.changeType === SchemaChanges_1.ChangeType.Missing) {
60
+ // Check for name to make sure there is no collision for items with the same name
61
+ // but different type.
62
+ if (await context.targetSchema.lookupItem(targetItemKey) !== undefined) {
63
+ throw new Error(`Schema ${context.targetSchema.name} already contains a Schema Item ${change.ecTypeName}.`);
64
+ }
65
+ // TODO: Think about renaming the Schema Item. This could be controlled though a flag.
66
+ targetItemKey = await SchemaItemFactory_1.SchemaItemFactory.create(context, sourceItem);
33
67
  }
34
- // TODO: Think about renaming the Schema Item. This could be controlled though a flag.
35
- const createdItem = await SchemaItemFactory_1.SchemaItemFactory.create(context.targetSchema, sourceItem);
36
- context.targetSchema.addItem(targetItem = createdItem);
37
- }
38
- if (targetItem === undefined) {
39
- throw new Error("Invalid state, targetItem must not be undefined at that point.");
68
+ await merger.mergeItemPropertyValues(targetItemKey, change.propertyValueChanges);
69
+ await merger.merge(targetItemKey, sourceItem, change);
40
70
  }
41
- // Sets the Schema items base properties...
42
- await mergeSchemaItemProperties(targetItem, change.propertyValueChanges, (item, propertyName, propertyValue) => {
43
- const mutableSchemaItem = item;
44
- switch (propertyName) {
45
- case "label":
46
- mutableSchemaItem.setDisplayLabel(propertyValue);
47
- return true;
48
- case "description":
49
- mutableSchemaItem.setDescription(propertyValue);
50
- return true;
51
- case "schemaItemType":
52
- return true;
53
- }
54
- return;
55
- });
56
- if (mergeFn)
57
- await mergeFn(targetItem, sourceItem, change, context);
58
71
  }
59
- }
60
- exports.default = mergeSchemaItems;
61
- /**
62
- * Performs the specified action for each property in the given PropertyValueChange array.
63
- * @param targetItem The target item
64
- * @param changes The array with PropertyValueChanges
65
- * @param handler The callback that gets invoked vor every change.
66
- * @internal
67
- */
68
- async function mergeSchemaItemProperties(targetItem, changes, handler) {
69
- for (let index = 0, increment = true; index < changes.length; increment && index++, increment = true) {
70
- const [propertyName, propertyValue] = changes[index].diagnostic.messageArgs;
71
- if (handler(targetItem, propertyName, propertyValue) === true) {
72
- changes.splice(index, 1);
73
- increment = false;
72
+ /**
73
+ * Merges the property values.
74
+ * @param targetItem The current schema item
75
+ * @param changes The property changes.
76
+ */
77
+ async mergeItemPropertyValues(targetItemKey, changes) {
78
+ // No need to process anything if no properties differ.
79
+ if (changes.length === 0) {
80
+ return;
81
+ }
82
+ const jsonProps = {};
83
+ const propertyResolver = await this.createPropertyValueResolver();
84
+ for (const change of changes) {
85
+ const [propertyName, propertyValue] = change.diagnostic.messageArgs;
86
+ const resolver = propertyResolver[propertyName];
87
+ jsonProps[propertyName] = resolver !== undefined
88
+ ? resolver(propertyValue, targetItemKey)
89
+ : propertyValue;
74
90
  }
91
+ await this.context.editor.schemaItems.applyProps(targetItemKey, jsonProps);
75
92
  }
76
93
  }
77
- exports.mergeSchemaItemProperties = mergeSchemaItemProperties;
78
- /**
79
- * @param source The schema item the reference gets copied from
80
- * @param itemFullName Parsing through item full name give us the schema reference name and the item name, these values are needed to create a new schema item key.
81
- * @returns Item referenced schema and item name.
82
- * @internal
83
- */
84
- async function getItemNameAndSchemaRef(source, itemFullName) {
85
- const [schemaName, itemName] = ecschema_metadata_1.SchemaItem.parseFullName(itemFullName);
86
- const refSchema = await source.schema.getReference(schemaName);
87
- return [refSchema, itemName];
88
- }
89
- exports.getItemNameAndSchemaRef = getItemNameAndSchemaRef;
94
+ exports.SchemaItemMerger = SchemaItemMerger;
90
95
  //# 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 { Schema, SchemaItem } from \"@itwin/ecschema-metadata\";\r\nimport { ChangeType, PropertyValueChange, SchemaItemChanges } from \"../Validation/SchemaChanges\";\r\nimport { MutableSchema } from \"../Editing/Mutable/MutableSchema\";\r\nimport { SchemaItemFactory } from \"./SchemaItemFactory\";\r\nimport { SchemaMergeContext } from \"./SchemaMerger\";\r\n\r\ntype SchemaItemMergeFn<TChange extends SchemaItemChanges, TItem extends SchemaItem> = (target: TItem, source: TItem, change: TChange, context: SchemaMergeContext) => Promise<void>;\r\ntype PropertyChangedFn<TItem extends SchemaItem> = (item: TItem, propertyName: string, propertyValue: any) => void | boolean;\r\n\r\nabstract class MutableSchemaItem extends SchemaItem{\r\n public abstract override setDisplayLabel(displayLabel: string): void;\r\n public abstract override setDescription(description: string): void;\r\n}\r\n\r\n/**\r\n * Merges schema items from the source in the target schema. This method applies for all schema items\r\n * and handles the basic processing such as create-if-not-exists or name collisions or base property setting.\r\n * @param context The current merge context\r\n * @param schemaItemChanges The schema items to be merged\r\n * @param mergeFn Merge function for complex merging.\r\n * @internal\r\n */\r\nexport default async function mergeSchemaItems<TChange extends SchemaItemChanges, TItem extends SchemaItem>(context: SchemaMergeContext, schemaItemChanges: Iterable<TChange>, mergeFn?: SchemaItemMergeFn<TChange, TItem>) {\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<TItem>(change.ecTypeName))!;\r\n let targetItem = await context.targetSchema.getItem<TItem>(change.ecTypeName);\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(targetItem !== 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\r\n const createdItem = await SchemaItemFactory.create(context.targetSchema, sourceItem) as TItem;\r\n (context.targetSchema as MutableSchema).addItem(targetItem = createdItem);\r\n }\r\n\r\n if(targetItem === undefined) {\r\n throw new Error(\"Invalid state, targetItem must not be undefined at that point.\");\r\n }\r\n\r\n // Sets the Schema items base properties...\r\n await mergeSchemaItemProperties(targetItem, change.propertyValueChanges, (item, propertyName, propertyValue) => {\r\n const mutableSchemaItem = item as unknown as MutableSchemaItem;\r\n switch(propertyName) {\r\n case \"label\":\r\n mutableSchemaItem.setDisplayLabel(propertyValue);\r\n return true;\r\n case \"description\":\r\n mutableSchemaItem.setDescription(propertyValue);\r\n return true;\r\n case \"schemaItemType\":\r\n return true;\r\n }\r\n return;\r\n });\r\n\r\n if (mergeFn)\r\n await mergeFn(targetItem, sourceItem, change, context);\r\n }\r\n}\r\n\r\n/**\r\n * Performs the specified action for each property in the given PropertyValueChange array.\r\n * @param targetItem The target item\r\n * @param changes The array with PropertyValueChanges\r\n * @param handler The callback that gets invoked vor every change.\r\n * @internal\r\n */\r\nexport async function mergeSchemaItemProperties<T extends SchemaItem>(targetItem: T, changes: PropertyValueChange[], handler: PropertyChangedFn<T>) {\r\n for(let index = 0, increment = true; index < changes.length; increment && index++, increment = true) {\r\n const [propertyName, propertyValue] = changes[index].diagnostic.messageArgs!;\r\n if(handler(targetItem, propertyName, propertyValue) === true) {\r\n changes.splice(index, 1);\r\n increment = false;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * @param source The schema item the reference gets copied from\r\n * @param itemFullName Parsing through item full name give us the schema reference name and the item name, these values are needed to create a new schema item key.\r\n * @returns Item referenced schema and item name.\r\n * @internal\r\n */\r\nexport async function getItemNameAndSchemaRef(source: SchemaItem, itemFullName: string): Promise<[Schema | undefined, string]> {\r\n const [schemaName, itemName] = SchemaItem.parseFullName(itemFullName);\r\n const refSchema = await source.schema.getReference(schemaName);\r\n return [refSchema, itemName];\r\n}\r\n"]}
1
+ {"version":3,"file":"SchemaItemMerger.js","sourceRoot":"","sources":["../../../src/Merging/SchemaItemMerger.ts"],"names":[],"mappings":";;;AAAA;;;+FAG+F;AAC/F,gEAAqE;AACrE,+DAAiG;AACjG,2DAAwD;AAkBxD;;;;;;GAMG;AACH,MAAa,gBAAgB;IAI3B;;;;OAIG;IACH,YAAY,OAA2B;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACO,KAAK,CAAC,2BAA2B;QACzC,sDAAsD;QACtD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;OAKG;IACO,KAAK,CAAC,KAAK,CAAC,QAAuB,EAAE,OAAc,EAAE,OAA0B;QACvF,uCAAuC;IACzC,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,KAAK,CAAC,YAAY,CAAoC,OAA2B,EAAE,iBAAoC;QACnI,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,KAAI,MAAM,MAAM,IAAI,iBAAiB,EAAE;YAErC,yFAAyF;YACzF,MAAM,UAAU,GAAG,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,OAAO,CAAa,MAAM,CAAC,UAAU,CAAC,CAAE,CAAC;YACxF,IAAI,aAAa,GAAG,IAAI,iCAAa,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAEzF,gFAAgF;YAChF,2EAA2E;YAC3E,IAAG,MAAM,CAAC,iBAAiB,EAAE,UAAU,KAAK,0BAAU,CAAC,OAAO,EAAE;gBAC9D,iFAAiF;gBACjF,sBAAsB;gBACtB,IAAG,MAAM,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,SAAS,EAAE;oBACrE,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,CAAC,YAAY,CAAC,IAAI,mCAAmC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC;iBAC7G;gBAED,sFAAsF;gBACtF,aAAa,GAAG,MAAM,qCAAiB,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;aACrE;YAED,MAAM,MAAM,CAAC,uBAAuB,CAAC,aAAa,EAAE,MAAM,CAAC,oBAAoB,CAAC,CAAC;YACjF,MAAM,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;SACvD;IACH,CAAC;IACD;;;;OAIG;IACK,KAAK,CAAC,uBAAuB,CAAC,aAA4B,EAAE,OAA8B;QAChG,uDAAuD;QACvD,IAAG,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;YACvB,OAAO;SACR;QAED,MAAM,SAAS,GAAG,EAAmC,CAAC;QACtD,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,2BAA2B,EAAE,CAAC;QAElE,KAAI,MAAM,MAAM,IAAI,OAAO,EAAE;YAC3B,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,WAA6C,CAAC;YACtG,MAAM,QAAQ,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;YAChD,SAAS,CAAC,YAAY,CAAC,GAAG,QAAQ,KAAK,SAAS;gBAC9C,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;gBACxC,CAAC,CAAC,aAAa,CAAC;SACnB;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IAC7E,CAAC;CACF;AAxFD,4CAwFC","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]?: (value: any, item: SchemaItemKey) => 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 /**\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 jsonProps = {} as MutableSchemaItemProps<TItem>;\r\n const propertyResolver = await this.createPropertyValueResolver();\r\n\r\n for(const change of changes) {\r\n const [propertyName, propertyValue] = change.diagnostic.messageArgs! as [keyof typeof jsonProps, any];\r\n const resolver = propertyResolver[propertyName];\r\n jsonProps[propertyName] = resolver !== undefined\r\n ? resolver(propertyValue, targetItemKey)\r\n : propertyValue;\r\n }\r\n\r\n await this.context.editor.schemaItems.applyProps(targetItemKey, jsonProps);\r\n }\r\n}\r\n"]}
@@ -2,6 +2,7 @@
2
2
  * @module Merging
3
3
  */
4
4
  import { Schema } from "@itwin/ecschema-metadata";
5
+ import { SchemaContextEditor } from "../Editing/Editor";
5
6
  /**
6
7
  * Defines the context of a Schema merging run.
7
8
  * @beta
@@ -9,6 +10,7 @@ import { Schema } from "@itwin/ecschema-metadata";
9
10
  export interface SchemaMergeContext {
10
11
  readonly targetSchema: Schema;
11
12
  readonly sourceSchema: Schema;
13
+ readonly editor: SchemaContextEditor;
12
14
  }
13
15
  /**
14
16
  * Class to merge two schemas together.
@@ -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;AAalE;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACvB;;;;;;;OAOG;YACW,gBAAgB;IAa9B;;;;;OAKG;IACU,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAmChF"}
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;AASxD;;;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;IAa9B;;;;;OAKG;IACU,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA2BhF"}
@@ -10,13 +10,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.SchemaMerger = void 0;
11
11
  const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
12
12
  const SchemaComparer_1 = require("../Validation/SchemaComparer");
13
- const ClassMerger_1 = require("./ClassMerger");
14
- const EnumerationMerger_1 = require("./EnumerationMerger");
15
- const PropertyCategoryMerger_1 = require("./PropertyCategoryMerger");
13
+ const Editor_1 = require("../Editing/Editor");
16
14
  const SchemaItemMerger_1 = require("./SchemaItemMerger");
17
15
  const SchemaReferenceMerger_1 = require("./SchemaReferenceMerger");
16
+ const ClassMerger_1 = require("./ClassMerger");
18
17
  const CAClassMerger_1 = require("./CAClassMerger");
19
- const PhenomenonMerger_1 = require("./PhenomenonMerger");
18
+ const EnumerationMerger_1 = require("./EnumerationMerger");
20
19
  const ConstantMerger_1 = require("./ConstantMerger");
21
20
  /**
22
21
  * Class to merge two schemas together.
@@ -51,44 +50,53 @@ class SchemaMerger {
51
50
  async merge(targetSchema, sourceSchema) {
52
51
  const schemaChanges = await this.getSchemaChanges(targetSchema, sourceSchema);
53
52
  const mergeContext = {
53
+ editor: new Editor_1.SchemaContextEditor(targetSchema.context),
54
54
  targetSchema,
55
55
  sourceSchema,
56
56
  };
57
57
  await (0, SchemaReferenceMerger_1.default)(mergeContext, schemaChanges);
58
- await (0, SchemaItemMerger_1.default)(mergeContext, schemaChanges.enumerationChanges.values(), EnumerationMerger_1.default);
59
- const propertyCategoryChanges = filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.PropertyCategory);
60
- await (0, SchemaItemMerger_1.default)(mergeContext, propertyCategoryChanges, PropertyCategoryMerger_1.default);
61
- const unitSystemChanges = filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.UnitSystem);
62
- await (0, SchemaItemMerger_1.default)(mergeContext, unitSystemChanges);
63
- const phenomenonChanges = filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.Phenomenon);
64
- await (0, SchemaItemMerger_1.default)(mergeContext, phenomenonChanges, PhenomenonMerger_1.default);
65
- const constantChanges = filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.Constant);
66
- await (0, SchemaItemMerger_1.default)(mergeContext, constantChanges, ConstantMerger_1.default);
58
+ const itemChanges = getSchemaItemChanges(schemaChanges);
59
+ await EnumerationMerger_1.default.mergeChanges(mergeContext, itemChanges.enumeratations);
60
+ await SchemaItemMerger_1.SchemaItemMerger.mergeChanges(mergeContext, itemChanges.propertyCategories);
61
+ await SchemaItemMerger_1.SchemaItemMerger.mergeChanges(mergeContext, itemChanges.unitSystems);
62
+ await SchemaItemMerger_1.SchemaItemMerger.mergeChanges(mergeContext, itemChanges.phenomenons);
63
+ await ConstantMerger_1.default.mergeChanges(mergeContext, itemChanges.constants);
67
64
  // TODO: For now we just do simple copy and merging of properties and classes. For more complex types
68
65
  // with bases classes or relationships, this might need to get extended.
69
- const caClassChanges = filterChangesByItemType(schemaChanges.classChanges, ecschema_metadata_1.SchemaItemType.CustomAttributeClass);
70
- await (0, SchemaItemMerger_1.default)(mergeContext, caClassChanges, CAClassMerger_1.default);
71
- const classChanges = filterChangesByItemType(schemaChanges.classChanges, ecschema_metadata_1.SchemaItemType.EntityClass, ecschema_metadata_1.SchemaItemType.StructClass);
72
- await (0, SchemaItemMerger_1.default)(mergeContext, classChanges, ClassMerger_1.default);
66
+ await CAClassMerger_1.default.mergeChanges(mergeContext, itemChanges.customAttributeClasses);
67
+ await ClassMerger_1.default.mergeChanges(mergeContext, itemChanges.classes);
73
68
  // TODO: For now we directly manipulate the target schema. For error handing purposes, we should first
74
69
  // merge into a temporary schema and eventually swap that with the given instance.
75
70
  return targetSchema;
76
71
  }
77
72
  }
78
73
  exports.SchemaMerger = SchemaMerger;
74
+ /**
75
+ * This helper method composes the different schema change objects to a single easier
76
+ * to use object that should improve readability when the methods get called.
77
+ */
78
+ function getSchemaItemChanges(schemaChanges) {
79
+ return {
80
+ get classes() { return filterChangesByItemType(schemaChanges.classChanges, ecschema_metadata_1.SchemaItemType.EntityClass, ecschema_metadata_1.SchemaItemType.StructClass); },
81
+ get constants() { return filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.Constant); },
82
+ get customAttributeClasses() { return filterChangesByItemType(schemaChanges.classChanges, ecschema_metadata_1.SchemaItemType.CustomAttributeClass); },
83
+ get enumeratations() { return schemaChanges.enumerationChanges.values(); },
84
+ get phenomenons() { return filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.Phenomenon); },
85
+ get propertyCategories() { return filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.PropertyCategory); },
86
+ get unitSystems() { return filterChangesByItemType(schemaChanges.schemaItemChanges, ecschema_metadata_1.SchemaItemType.UnitSystem); },
87
+ };
88
+ }
79
89
  /**
80
90
  * Filters and returns the changed items by its schema item type.
81
91
  * @param changes A map of changed schema items.
82
92
  * @param types A list of schema item types to filter.
83
93
  * @returns An Iterable with the filtered schema items.
84
94
  */
85
- function filterChangesByItemType(changes, ...types) {
86
- const result = [];
95
+ function* filterChangesByItemType(changes, ...types) {
87
96
  for (const change of changes.values()) {
88
97
  if (types.includes(change.schemaItemType)) {
89
- result.push(change);
98
+ yield change;
90
99
  }
91
100
  }
92
- return result;
93
101
  }
94
102
  //# 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\n\r\nimport mergeClasses from \"./ClassMerger\";\r\nimport mergeEnumeration from \"./EnumerationMerger\";\r\nimport mergePropertyCategory from \"./PropertyCategoryMerger\";\r\nimport mergeSchemaItems from \"./SchemaItemMerger\";\r\nimport mergeSchemaReferences from \"./SchemaReferenceMerger\";\r\nimport mergeCAClasses from \"./CAClassMerger\";\r\nimport mergePhenomenon from \"./PhenomenonMerger\";\r\nimport mergeConstant from \"./ConstantMerger\";\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}\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 compareItemFullName: false,\r\n });\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 targetSchema,\r\n sourceSchema,\r\n };\r\n\r\n await mergeSchemaReferences(mergeContext, schemaChanges);\r\n\r\n await mergeSchemaItems(mergeContext, schemaChanges.enumerationChanges.values(), mergeEnumeration);\r\n\r\n const propertyCategoryChanges = filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.PropertyCategory);\r\n await mergeSchemaItems(mergeContext, propertyCategoryChanges, mergePropertyCategory);\r\n\r\n const unitSystemChanges = filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.UnitSystem);\r\n await mergeSchemaItems(mergeContext, unitSystemChanges);\r\n\r\n const phenomenonChanges = filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.Phenomenon);\r\n await mergeSchemaItems(mergeContext, phenomenonChanges, mergePhenomenon);\r\n\r\n const constantChanges = filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.Constant);\r\n await mergeSchemaItems(mergeContext, constantChanges, mergeConstant);\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 const caClassChanges = filterChangesByItemType(schemaChanges.classChanges, SchemaItemType.CustomAttributeClass);\r\n await mergeSchemaItems(mergeContext, caClassChanges, mergeCAClasses);\r\n\r\n const classChanges = filterChangesByItemType(schemaChanges.classChanges, SchemaItemType.EntityClass, SchemaItemType.StructClass);\r\n await mergeSchemaItems(mergeContext, classChanges, mergeClasses);\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 * 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 const result: TChange[] = [];\r\n for(const change of changes.values()) {\r\n if (types.includes(change.schemaItemType)) {\r\n result.push(change);\r\n }\r\n }\r\n return result;\r\n}\r\n"]}
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 ClassMerger from \"./ClassMerger\";\r\nimport CAClassMerger from \"./CAClassMerger\";\r\nimport EnumerationMerger from \"./EnumerationMerger\";\r\nimport ConstantsMerger from \"./ConstantMerger\";\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 compareItemFullName: false,\r\n });\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\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.mergeChanges(mergeContext, itemChanges.customAttributeClasses);\r\n await ClassMerger.mergeChanges(mergeContext, itemChanges.classes);\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 classes() { return filterChangesByItemType(schemaChanges.classChanges, SchemaItemType.EntityClass, SchemaItemType.StructClass); },\r\n get constants() { return filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.Constant); },\r\n get customAttributeClasses() { return filterChangesByItemType(schemaChanges.classChanges, SchemaItemType.CustomAttributeClass); },\r\n get enumeratations() { return schemaChanges.enumerationChanges.values(); },\r\n get phenomenons() { return filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.Phenomenon); },\r\n get propertyCategories() { return filterChangesByItemType(schemaChanges.schemaItemChanges, SchemaItemType.PropertyCategory); },\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 +1 @@
1
- {"version":3,"file":"SchemaReferenceMerger.d.ts","sourceRoot":"","sources":["../../../src/Merging/SchemaReferenceMerger.ts"],"names":[],"mappings":"AAMA,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,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"}
@@ -17,7 +17,7 @@ async function mergeSchemaReferences(mergeContext, changes) {
17
17
  // but should be checked if it's schema references have collisions with existing references.
18
18
  for (const missingSchemaReference of changes.missingSchemaReferences) {
19
19
  const [referencedSchema] = missingSchemaReference.diagnostic.messageArgs;
20
- await addSchemaReference(targetSchema, referencedSchema);
20
+ await mergeContext.editor.addSchemaReference(targetSchema.schemaKey, referencedSchema);
21
21
  }
22
22
  // If the source schema referenced a schema that is also referenced by the target
23
23
  // schema but in a different version, it is marked as delta. Here we need to check if
@@ -35,18 +35,16 @@ async function mergeSchemaReferences(mergeContext, changes) {
35
35
  }
36
36
  const index = targetSchema.references.findIndex((reference) => reference === existingSchema);
37
37
  targetSchema.references.splice(index, 1);
38
- await addSchemaReference(targetSchema, referencedSchema);
38
+ await mergeContext.editor.addSchemaReference(targetSchema.schemaKey, referencedSchema);
39
39
  }
40
40
  }
41
41
  exports.default = mergeSchemaReferences;
42
- async function addSchemaReference(targetSchema, referencedSchema) {
43
- const mutableSchema = targetSchema;
44
- // TODO: Collision Check
45
- await mutableSchema.addReference(referencedSchema);
46
- if (!await targetSchema.context.getSchema(referencedSchema.schemaKey)) {
47
- await targetSchema.context.addSchema(referencedSchema);
48
- }
49
- }
42
+ /**
43
+ * Compares the schemas and return them in order of their versions [older, latest].
44
+ * @param left The first schema to be added.
45
+ * @param right The second schema to be added.
46
+ * @returns The schemas in order.
47
+ */
50
48
  function compareSchemas(left, right) {
51
49
  return left.schemaKey.compareByVersion(right.schemaKey) < 0
52
50
  ? [left, right]
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaReferenceMerger.js","sourceRoot":"","sources":["../../../src/Merging/SchemaReferenceMerger.ts"],"names":[],"mappings":";;AAAA;;;+FAG+F;AAC/F,gEAAmE;AAKnE;;;;;GAKG;AACY,KAAK,UAAU,qBAAqB,CAAC,YAAgC,EAAE,OAAsB;IAC1G,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,CAAC;IAE/C,kFAAkF;IAClF,4FAA4F;IAC5F,KAAI,MAAM,sBAAsB,IAAI,OAAO,CAAC,uBAAuB,EAAE;QACnE,MAAM,CAAC,gBAAgB,CAAC,GAAG,sBAAsB,CAAC,UAAU,CAAC,WAAwB,CAAC;QACtF,MAAM,kBAAkB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;KAC1D;IAED,iFAAiF;IACjF,qFAAqF;IACrF,qFAAqF;IACrF,8BAA8B;IAC9B,KAAI,MAAM,wBAAwB,IAAI,OAAO,CAAC,qBAAqB,EAAE;QACnE,MAAM,CAAC,gBAAgB,CAAC,GAAG,wBAAwB,CAAC,UAAU,CAAC,WAAwB,CAAC;QACxF,MAAM,cAAc,GAAG,CAAC,MAAM,YAAY,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAE,CAAC;QAEjF,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,cAAc,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;QACzE,IAAG,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,mCAAe,CAAC,qBAAqB,CAAC,EAAE;YACpF,MAAM,IAAI,KAAK,CAAC,yBAAyB,gBAAgB,CAAC,IAAI,gCAAgC,KAAK,CAAC,SAAS,CAAC,OAAO,QAAQ,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;SAC1J;QACD,IAAG,MAAM,KAAK,cAAc,EAAE;YAC5B,SAAS;SACV;QAED,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,cAAc,CAAC,CAAC;QAC7F,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAEzC,MAAM,kBAAkB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;KAC1D;AACH,CAAC;AA/BD,wCA+BC;AAED,KAAK,UAAU,kBAAkB,CAAC,YAAoB,EAAE,gBAAwB;IAC9E,MAAM,aAAa,GAAG,YAA6B,CAAC;IAEpD,wBAAwB;IAExB,MAAM,aAAa,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;IACnD,IAAG,CAAE,MAAM,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE;QACrE,MAAM,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;KACxD;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,KAAa;IACjD,OAAO,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC;QACzD,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC;QACf,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACpB,CAAC","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 { Schema, SchemaMatchType } from \"@itwin/ecschema-metadata\";\r\nimport { MutableSchema } from \"../Editing/Mutable/MutableSchema\";\r\nimport { SchemaChanges } from \"../Validation/SchemaChanges\";\r\nimport { SchemaMergeContext } from \"./SchemaMerger\";\r\n\r\n/**\r\n * Merges the schema references of two schemas.\r\n * @param mergeContext current merge context\r\n * @param changes schema changes.\r\n * @internal\r\n */\r\nexport default async function mergeSchemaReferences(mergeContext: SchemaMergeContext, changes: SchemaChanges) {\r\n const targetSchema = mergeContext.targetSchema;\r\n\r\n // If the target schema does not have a reference to a schema yet, it can be added\r\n // but should be checked if it's schema references have collisions with existing references.\r\n for(const missingSchemaReference of changes.missingSchemaReferences) {\r\n const [referencedSchema] = missingSchemaReference.diagnostic.messageArgs! as [Schema];\r\n await addSchemaReference(targetSchema, referencedSchema);\r\n }\r\n\r\n // If the source schema referenced a schema that is also referenced by the target\r\n // schema but in a different version, it is marked as delta. Here we need to check if\r\n // the source schema is compatible to the existing one. This is not be checked by the\r\n // schema instance when added.\r\n for(const differentSchemaReference of changes.schemaReferenceDeltas) {\r\n const [referencedSchema] = differentSchemaReference.diagnostic.messageArgs! as [Schema];\r\n const existingSchema = (await targetSchema.getReference(referencedSchema.name))!;\r\n\r\n const [older, latest] = compareSchemas(existingSchema, referencedSchema);\r\n if(!latest.schemaKey.matches(older.schemaKey, SchemaMatchType.LatestWriteCompatible)) {\r\n throw new Error(`Schemas references of ${referencedSchema.name} have incompatible versions: ${older.schemaKey.version} and ${latest.schemaKey.version}`);\r\n }\r\n if(latest === existingSchema) {\r\n continue;\r\n }\r\n\r\n const index = targetSchema.references.findIndex((reference) => reference === existingSchema);\r\n targetSchema.references.splice(index, 1);\r\n\r\n await addSchemaReference(targetSchema, referencedSchema);\r\n }\r\n}\r\n\r\nasync function addSchemaReference(targetSchema: Schema, referencedSchema: Schema) {\r\n const mutableSchema = targetSchema as MutableSchema;\r\n\r\n // TODO: Collision Check\r\n\r\n await mutableSchema.addReference(referencedSchema);\r\n if(! await targetSchema.context.getSchema(referencedSchema.schemaKey)) {\r\n await targetSchema.context.addSchema(referencedSchema);\r\n }\r\n}\r\n\r\nfunction compareSchemas(left: Schema, right: Schema): [Schema, Schema] {\r\n return left.schemaKey.compareByVersion(right.schemaKey) < 0\r\n ? [left, right]\r\n : [right, left];\r\n}\r\n"]}
1
+ {"version":3,"file":"SchemaReferenceMerger.js","sourceRoot":"","sources":["../../../src/Merging/SchemaReferenceMerger.ts"],"names":[],"mappings":";;AAAA;;;+FAG+F;AAC/F,gEAAmE;AAInE;;;;;GAKG;AACY,KAAK,UAAU,qBAAqB,CAAC,YAAgC,EAAE,OAAsB;IAC1G,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,CAAC;IAE/C,kFAAkF;IAClF,4FAA4F;IAC5F,KAAI,MAAM,sBAAsB,IAAI,OAAO,CAAC,uBAAuB,EAAE;QACnE,MAAM,CAAC,gBAAgB,CAAC,GAAG,sBAAsB,CAAC,UAAU,CAAC,WAAwB,CAAC;QACtF,MAAM,YAAY,CAAC,MAAM,CAAC,kBAAkB,CAAC,YAAY,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;KACxF;IAED,iFAAiF;IACjF,qFAAqF;IACrF,qFAAqF;IACrF,8BAA8B;IAC9B,KAAI,MAAM,wBAAwB,IAAI,OAAO,CAAC,qBAAqB,EAAE;QACnE,MAAM,CAAC,gBAAgB,CAAC,GAAG,wBAAwB,CAAC,UAAU,CAAC,WAAwB,CAAC;QACxF,MAAM,cAAc,GAAG,CAAC,MAAM,YAAY,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAE,CAAC;QAEjF,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,cAAc,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;QACzE,IAAG,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,mCAAe,CAAC,qBAAqB,CAAC,EAAE;YACpF,MAAM,IAAI,KAAK,CAAC,yBAAyB,gBAAgB,CAAC,IAAI,gCAAgC,KAAK,CAAC,SAAS,CAAC,OAAO,QAAQ,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;SAC1J;QACD,IAAG,MAAM,KAAK,cAAc,EAAE;YAC5B,SAAS;SACV;QAED,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,cAAc,CAAC,CAAC;QAC7F,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAEzC,MAAM,YAAY,CAAC,MAAM,CAAC,kBAAkB,CAAC,YAAY,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;KACxF;AACH,CAAC;AA/BD,wCA+BC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,IAAY,EAAE,KAAa;IACjD,OAAO,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC;QACzD,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC;QACf,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACpB,CAAC","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 { Schema, SchemaMatchType } from \"@itwin/ecschema-metadata\";\r\nimport { SchemaChanges } from \"../Validation/SchemaChanges\";\r\nimport { SchemaMergeContext } from \"./SchemaMerger\";\r\n\r\n/**\r\n * Merges the schema references of two schemas.\r\n * @param mergeContext current merge context\r\n * @param changes schema changes.\r\n * @internal\r\n */\r\nexport default async function mergeSchemaReferences(mergeContext: SchemaMergeContext, changes: SchemaChanges) {\r\n const targetSchema = mergeContext.targetSchema;\r\n\r\n // If the target schema does not have a reference to a schema yet, it can be added\r\n // but should be checked if it's schema references have collisions with existing references.\r\n for(const missingSchemaReference of changes.missingSchemaReferences) {\r\n const [referencedSchema] = missingSchemaReference.diagnostic.messageArgs! as [Schema];\r\n await mergeContext.editor.addSchemaReference(targetSchema.schemaKey, referencedSchema);\r\n }\r\n\r\n // If the source schema referenced a schema that is also referenced by the target\r\n // schema but in a different version, it is marked as delta. Here we need to check if\r\n // the source schema is compatible to the existing one. This is not be checked by the\r\n // schema instance when added.\r\n for(const differentSchemaReference of changes.schemaReferenceDeltas) {\r\n const [referencedSchema] = differentSchemaReference.diagnostic.messageArgs! as [Schema];\r\n const existingSchema = (await targetSchema.getReference(referencedSchema.name))!;\r\n\r\n const [older, latest] = compareSchemas(existingSchema, referencedSchema);\r\n if(!latest.schemaKey.matches(older.schemaKey, SchemaMatchType.LatestWriteCompatible)) {\r\n throw new Error(`Schemas references of ${referencedSchema.name} have incompatible versions: ${older.schemaKey.version} and ${latest.schemaKey.version}`);\r\n }\r\n if(latest === existingSchema) {\r\n continue;\r\n }\r\n\r\n const index = targetSchema.references.findIndex((reference) => reference === existingSchema);\r\n targetSchema.references.splice(index, 1);\r\n\r\n await mergeContext.editor.addSchemaReference(targetSchema.schemaKey, referencedSchema);\r\n }\r\n}\r\n\r\n/**\r\n * Compares the schemas and return them in order of their versions [older, latest].\r\n * @param left The first schema to be added.\r\n * @param right The second schema to be added.\r\n * @returns The schemas in order.\r\n */\r\nfunction compareSchemas(left: Schema, right: Schema): [Schema, Schema] {\r\n return left.schemaKey.compareByVersion(right.schemaKey) < 0\r\n ? [left, right]\r\n : [right, left];\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/ecschema-editing",
3
- "version": "4.3.0-dev.2",
3
+ "version": "4.3.0-dev.5",
4
4
  "description": "ECSchema editing and validation API",
5
5
  "license": "MIT",
6
6
  "main": "lib/cjs/ecschema-editing.js",
@@ -42,16 +42,16 @@
42
42
  "rimraf": "^3.0.2",
43
43
  "sinon": "^15.0.4",
44
44
  "typescript": "~5.0.2",
45
- "@itwin/build-tools": "4.3.0-dev.2",
46
- "@itwin/core-bentley": "4.3.0-dev.2",
47
- "@itwin/ecschema-metadata": "4.3.0-dev.2",
48
- "@itwin/core-quantity": "4.3.0-dev.2",
49
- "@itwin/core-common": "4.3.0-dev.2"
45
+ "@itwin/build-tools": "4.3.0-dev.5",
46
+ "@itwin/core-bentley": "4.3.0-dev.5",
47
+ "@itwin/core-common": "4.3.0-dev.5",
48
+ "@itwin/core-quantity": "4.3.0-dev.5",
49
+ "@itwin/ecschema-metadata": "4.3.0-dev.5"
50
50
  },
51
51
  "peerDependencies": {
52
- "@itwin/core-bentley": "^4.3.0-dev.2",
53
- "@itwin/core-quantity": "^4.3.0-dev.2",
54
- "@itwin/ecschema-metadata": "^4.3.0-dev.2"
52
+ "@itwin/core-bentley": "^4.3.0-dev.5",
53
+ "@itwin/core-quantity": "^4.3.0-dev.5",
54
+ "@itwin/ecschema-metadata": "^4.3.0-dev.5"
55
55
  },
56
56
  "nyc": {
57
57
  "extends": "./node_modules/@itwin/build-tools/.nycrc"
@@ -1,7 +0,0 @@
1
- import { Phenomenon } from "@itwin/ecschema-metadata";
2
- import { SchemaItemChanges } from "../Validation/SchemaChanges";
3
- /**
4
- * @internal
5
- */
6
- export default function mergePhenomenon(target: Phenomenon, source: Phenomenon, _changes?: SchemaItemChanges): Promise<void>;
7
- //# sourceMappingURL=PhenomenonMerger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PhenomenonMerger.d.ts","sourceRoot":"","sources":["../../../src/Merging/PhenomenonMerger.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGhE;;GAEG;AACH,wBAA8B,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,iBAAiB,iBAQjH"}
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- /**
4
- * @internal
5
- */
6
- async function mergePhenomenon(target, source, _changes) {
7
- const mutablePhenomenon = target;
8
- if (mutablePhenomenon.definition === "") {
9
- await mutablePhenomenon.setDefinition(source.definition);
10
- }
11
- else {
12
- throw Error(`Failed to merge schemas, definition attribute conflict: ${source.definition} -> ${target.definition}`);
13
- }
14
- }
15
- exports.default = mergePhenomenon;
16
- //# sourceMappingURL=PhenomenonMerger.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PhenomenonMerger.js","sourceRoot":"","sources":["../../../src/Merging/PhenomenonMerger.ts"],"names":[],"mappings":";;AAQA;;GAEG;AACY,KAAK,UAAU,eAAe,CAAC,MAAkB,EAAE,MAAkB,EAAE,QAA4B;IAChH,MAAM,iBAAiB,GAAG,MAA2B,CAAC;IAEtD,IAAG,iBAAiB,CAAC,UAAU,KAAK,EAAE,EAAC;QACrC,MAAM,iBAAiB,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;KAC1D;SAAI;QACH,MAAM,KAAK,CAAC,2DAA2D,MAAM,CAAC,UAAU,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;KACrH;AACH,CAAC;AARD,kCAQC","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 { Phenomenon } from \"@itwin/ecschema-metadata\";\r\nimport { SchemaItemChanges } from \"../Validation/SchemaChanges\";\r\nimport { MutablePhenomenon } from \"../Editing/Mutable/MutablePhenomenon\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport default async function mergePhenomenon(target: Phenomenon, source: Phenomenon, _changes?: SchemaItemChanges) {\r\n const mutablePhenomenon = target as MutablePhenomenon;\r\n\r\n if(mutablePhenomenon.definition === \"\"){\r\n await mutablePhenomenon.setDefinition(source.definition);\r\n }else{\r\n throw Error(`Failed to merge schemas, definition attribute conflict: ${source.definition} -> ${target.definition}`);\r\n }\r\n}\r\n"]}
@@ -1,7 +0,0 @@
1
- import { PropertyCategory } from "@itwin/ecschema-metadata";
2
- import { SchemaItemChanges } from "../Validation/SchemaChanges";
3
- /**
4
- * @internal
5
- */
6
- export default function mergePropertyCategory(target: PropertyCategory, _source: PropertyCategory, changes: SchemaItemChanges): Promise<void>;
7
- //# sourceMappingURL=PropertyCategoryMerger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PropertyCategoryMerger.d.ts","sourceRoot":"","sources":["../../../src/Merging/PropertyCategoryMerger.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGhE;;GAEG;AACH,wBAA8B,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,iBAAiB,iBAOlI"}
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const SchemaItemMerger_1 = require("./SchemaItemMerger");
4
- /**
5
- * @internal
6
- */
7
- async function mergePropertyCategory(target, _source, changes) {
8
- const mutablePropertyCategory = target;
9
- await (0, SchemaItemMerger_1.mergeSchemaItemProperties)(mutablePropertyCategory, changes.propertyValueChanges, (item, propertyName, propertyValue) => {
10
- switch (propertyName) {
11
- case "priority": return item.setPriority(propertyValue);
12
- }
13
- });
14
- }
15
- exports.default = mergePropertyCategory;
16
- //# sourceMappingURL=PropertyCategoryMerger.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PropertyCategoryMerger.js","sourceRoot":"","sources":["../../../src/Merging/PropertyCategoryMerger.ts"],"names":[],"mappings":";;AAOA,yDAA+D;AAE/D;;GAEG;AACY,KAAK,UAAU,qBAAqB,CAAC,MAAwB,EAAE,OAAyB,EAAE,OAA0B;IACjI,MAAM,uBAAuB,GAAG,MAAiC,CAAC;IAClE,MAAM,IAAA,4CAAyB,EAAC,uBAAuB,EAAE,OAAO,CAAC,oBAAoB,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,EAAE;QAC3H,QAAO,YAAY,EAAE;YACnB,KAAK,UAAU,CAAC,CAAC,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;SACzD;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAPD,wCAOC","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 { PropertyCategory } from \"@itwin/ecschema-metadata\";\r\nimport { MutablePropertyCategory } from \"../Editing/Mutable/MutablePropertyCategory\";\r\nimport { SchemaItemChanges } from \"../Validation/SchemaChanges\";\r\nimport { mergeSchemaItemProperties } from \"./SchemaItemMerger\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport default async function mergePropertyCategory(target: PropertyCategory, _source: PropertyCategory, changes: SchemaItemChanges) {\r\n const mutablePropertyCategory = target as MutablePropertyCategory;\r\n await mergeSchemaItemProperties(mutablePropertyCategory, changes.propertyValueChanges, (item, propertyName, propertyValue) => {\r\n switch(propertyName) {\r\n case \"priority\": return item.setPriority(propertyValue);\r\n }\r\n });\r\n}\r\n"]}