@itwin/presentation-backend 4.0.0-dev.8 → 4.0.0-dev.80

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 (59) hide show
  1. package/CHANGELOG.md +47 -1
  2. package/lib/cjs/assets/supplemental-presentation-rules/BisCore.PresentationRuleSet.json +5 -3
  3. package/lib/cjs/presentation-backend/BackendLoggerCategory.d.ts +41 -41
  4. package/lib/cjs/presentation-backend/BackendLoggerCategory.js +50 -50
  5. package/lib/cjs/presentation-backend/Constants.d.ts +8 -8
  6. package/lib/cjs/presentation-backend/Constants.js +40 -36
  7. package/lib/cjs/presentation-backend/Constants.js.map +1 -1
  8. package/lib/cjs/presentation-backend/ElementPropertiesHelper.d.ts +11 -11
  9. package/lib/cjs/presentation-backend/ElementPropertiesHelper.js +260 -262
  10. package/lib/cjs/presentation-backend/ElementPropertiesHelper.js.map +1 -1
  11. package/lib/cjs/presentation-backend/NativePlatform.d.ts +87 -87
  12. package/lib/cjs/presentation-backend/NativePlatform.d.ts.map +1 -1
  13. package/lib/cjs/presentation-backend/NativePlatform.js +140 -140
  14. package/lib/cjs/presentation-backend/NativePlatform.js.map +1 -1
  15. package/lib/cjs/presentation-backend/Presentation.d.ts +106 -106
  16. package/lib/cjs/presentation-backend/Presentation.d.ts.map +1 -1
  17. package/lib/cjs/presentation-backend/Presentation.js +148 -150
  18. package/lib/cjs/presentation-backend/Presentation.js.map +1 -1
  19. package/lib/cjs/presentation-backend/PresentationIpcHandler.d.ts +12 -12
  20. package/lib/cjs/presentation-backend/PresentationIpcHandler.js +41 -41
  21. package/lib/cjs/presentation-backend/PresentationManager.d.ts +456 -445
  22. package/lib/cjs/presentation-backend/PresentationManager.d.ts.map +1 -1
  23. package/lib/cjs/presentation-backend/PresentationManager.js +309 -311
  24. package/lib/cjs/presentation-backend/PresentationManager.js.map +1 -1
  25. package/lib/cjs/presentation-backend/PresentationManagerDetail.d.ts +61 -61
  26. package/lib/cjs/presentation-backend/PresentationManagerDetail.js +430 -430
  27. package/lib/cjs/presentation-backend/PresentationManagerDetail.js.map +1 -1
  28. package/lib/cjs/presentation-backend/PresentationRpcImpl.d.ts +62 -62
  29. package/lib/cjs/presentation-backend/PresentationRpcImpl.d.ts.map +1 -1
  30. package/lib/cjs/presentation-backend/PresentationRpcImpl.js +388 -388
  31. package/lib/cjs/presentation-backend/PresentationRpcImpl.js.map +1 -1
  32. package/lib/cjs/presentation-backend/RulesetEmbedder.d.ts +102 -102
  33. package/lib/cjs/presentation-backend/RulesetEmbedder.d.ts.map +1 -1
  34. package/lib/cjs/presentation-backend/RulesetEmbedder.js +284 -279
  35. package/lib/cjs/presentation-backend/RulesetEmbedder.js.map +1 -1
  36. package/lib/cjs/presentation-backend/RulesetManager.d.ts +53 -53
  37. package/lib/cjs/presentation-backend/RulesetManager.js +73 -73
  38. package/lib/cjs/presentation-backend/RulesetVariablesManager.d.ts +140 -140
  39. package/lib/cjs/presentation-backend/RulesetVariablesManager.js +129 -129
  40. package/lib/cjs/presentation-backend/SelectionScopesHelper.d.ts +28 -28
  41. package/lib/cjs/presentation-backend/SelectionScopesHelper.js +210 -213
  42. package/lib/cjs/presentation-backend/SelectionScopesHelper.js.map +1 -1
  43. package/lib/cjs/presentation-backend/TemporaryStorage.d.ts +123 -123
  44. package/lib/cjs/presentation-backend/TemporaryStorage.js +151 -151
  45. package/lib/cjs/presentation-backend/UpdatesTracker.d.ts +27 -27
  46. package/lib/cjs/presentation-backend/UpdatesTracker.js +54 -54
  47. package/lib/cjs/presentation-backend/Utils.d.ts +49 -49
  48. package/lib/cjs/presentation-backend/Utils.d.ts.map +1 -1
  49. package/lib/cjs/presentation-backend/Utils.js +107 -106
  50. package/lib/cjs/presentation-backend/Utils.js.map +1 -1
  51. package/lib/cjs/presentation-backend/domain/PresentationRulesDomain.d.ts +16 -16
  52. package/lib/cjs/presentation-backend/domain/PresentationRulesDomain.js +55 -51
  53. package/lib/cjs/presentation-backend/domain/PresentationRulesDomain.js.map +1 -1
  54. package/lib/cjs/presentation-backend/domain/RulesetElements.d.ts +21 -21
  55. package/lib/cjs/presentation-backend/domain/RulesetElements.js +38 -38
  56. package/lib/cjs/presentation-backend.d.ts +19 -19
  57. package/lib/cjs/presentation-backend.js +39 -35
  58. package/lib/cjs/presentation-backend.js.map +1 -1
  59. package/package.json +18 -18
@@ -1,283 +1,288 @@
1
- "use strict";
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
- * See LICENSE.md in the project root for license terms and full copyright notice.
5
- *--------------------------------------------------------------------------------------------*/
6
- /** @packageDocumentation
7
- * @module Core
8
- */
9
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
12
- }) : (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- o[k2] = m[k];
15
- }));
16
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
- Object.defineProperty(o, "default", { enumerable: true, value: v });
18
- }) : function(o, v) {
19
- o["default"] = v;
20
- });
21
- var __importStar = (this && this.__importStar) || function (mod) {
22
- if (mod && mod.__esModule) return mod;
23
- var result = {};
24
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
25
- __setModuleDefault(result, mod);
26
- return result;
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.RulesetEmbedder = void 0;
30
- const path = __importStar(require("path"));
31
- const semver_1 = require("semver");
32
- const core_backend_1 = require("@itwin/core-backend");
33
- const core_bentley_1 = require("@itwin/core-bentley");
34
- const core_common_1 = require("@itwin/core-common");
35
- const PresentationRulesDomain_1 = require("./domain/PresentationRulesDomain");
36
- const RulesetElements = __importStar(require("./domain/RulesetElements"));
37
- const Utils_1 = require("./Utils");
38
- /**
39
- * An API for embedding presentation rulesets into iModels.
40
- * @public
41
- */
42
- class RulesetEmbedder {
43
- /**
44
- * Constructs RulesetEmbedder
45
- */
46
- constructor(props) {
47
- this._schemaPath = path.join(core_backend_1.KnownLocations.nativeAssetsDir, "ECSchemas/Domain/PresentationRules.ecschema.xml");
48
- this._rulesetModelName = "PresentationRules";
49
- this._rulesetSubjectName = "PresentationRules";
50
- PresentationRulesDomain_1.PresentationRules.registerSchema();
51
- this._imodel = props.imodel;
52
- }
53
- /**
54
- * Inserts a ruleset into iModel.
55
- * @param ruleset Ruleset to insert.
56
- * @param options Options for inserting a ruleset.
57
- * @returns ID of inserted ruleset element or, if insertion was skipped, ID of existing ruleset with the same ID and highest version.
58
- */
59
- async insertRuleset(ruleset, options) {
60
- const normalizedOptions = normalizeRulesetInsertOptions(options);
61
- const rulesetVersion = (0, Utils_1.normalizeVersion)(ruleset.version);
62
- // ensure imodel has PresentationRules schema and required CodeSpecs
63
- await this.handleElementOperationPrerequisites();
64
- // find all rulesets with the same ID
65
- const rulesetsWithSameId = [];
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module Core
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || function (mod) {
26
+ if (mod && mod.__esModule) return mod;
27
+ var result = {};
28
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29
+ __setModuleDefault(result, mod);
30
+ return result;
31
+ };
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.RulesetEmbedder = void 0;
34
+ const path = __importStar(require("path"));
35
+ const semver_1 = require("semver");
36
+ const core_backend_1 = require("@itwin/core-backend");
37
+ const core_bentley_1 = require("@itwin/core-bentley");
38
+ const core_common_1 = require("@itwin/core-common");
39
+ const PresentationRulesDomain_1 = require("./domain/PresentationRulesDomain");
40
+ const RulesetElements = __importStar(require("./domain/RulesetElements"));
41
+ const Utils_1 = require("./Utils");
42
+ /**
43
+ * An API for embedding presentation rulesets into iModels.
44
+ * @public
45
+ */
46
+ class RulesetEmbedder {
47
+ /**
48
+ * Constructs RulesetEmbedder
49
+ */
50
+ constructor(props) {
51
+ this._schemaPath = path.join(core_backend_1.KnownLocations.nativeAssetsDir, "ECSchemas/Domain/PresentationRules.ecschema.xml");
52
+ this._rulesetModelName = "PresentationRules";
53
+ this._rulesetSubjectName = "PresentationRules";
54
+ PresentationRulesDomain_1.PresentationRules.registerSchema();
55
+ this._imodel = props.imodel;
56
+ }
57
+ /**
58
+ * Inserts a ruleset into iModel.
59
+ * @param ruleset Ruleset to insert.
60
+ * @param options Options for inserting a ruleset.
61
+ * @returns ID of inserted ruleset element or, if insertion was skipped, ID of existing ruleset with the same ID and highest version.
62
+ */
63
+ async insertRuleset(ruleset, options) {
64
+ const normalizedOptions = normalizeRulesetInsertOptions(options);
65
+ const rulesetVersion = (0, Utils_1.normalizeVersion)(ruleset.version);
66
+ // ensure imodel has PresentationRules schema and required CodeSpecs
67
+ await this.handleElementOperationPrerequisites();
68
+ // find all rulesets with the same ID
69
+ const rulesetsWithSameId = [];
66
70
  const query = `
67
71
  SELECT ECInstanceId, JsonProperties
68
72
  FROM ${RulesetElements.Ruleset.schema.name}.${RulesetElements.Ruleset.className}
69
- WHERE json_extract(JsonProperties, '$.jsonProperties.id') = :rulesetId`;
70
- for await (const row of this._imodel.query(query, core_common_1.QueryBinder.from({ rulesetId: ruleset.id }), { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames })) {
71
- const existingRulesetElementId = row.id;
72
- const existingRuleset = JSON.parse(row.jsonProperties).jsonProperties;
73
- rulesetsWithSameId.push({
74
- id: existingRulesetElementId,
75
- ruleset: existingRuleset,
76
- normalizedVersion: (0, Utils_1.normalizeVersion)(existingRuleset.version),
77
- });
78
- }
79
- // check if we need to do anything at all
80
- const shouldSkip = normalizedOptions.skip === "same-id" && rulesetsWithSameId.length > 0
81
- || normalizedOptions.skip === "same-id-and-version-eq" && rulesetsWithSameId.some((entry) => entry.normalizedVersion === rulesetVersion)
82
- || normalizedOptions.skip === "same-id-and-version-gte" && rulesetsWithSameId.some((entry) => (0, semver_1.gte)(entry.normalizedVersion, rulesetVersion));
83
- if (shouldSkip) {
84
- // we're not inserting anything - return ID of the ruleset element with the highest version
85
- const rulesetEntryWithHighestVersion = rulesetsWithSameId.reduce((highest, curr) => {
86
- if (!highest.ruleset.version || curr.ruleset.version && (0, semver_1.gt)(curr.ruleset.version, highest.ruleset.version))
87
- return curr;
88
- return highest;
89
- }, rulesetsWithSameId[0]);
90
- return rulesetEntryWithHighestVersion.id;
91
- }
92
- // if requested, delete existing rulesets
93
- const rulesetsToRemove = [];
94
- const shouldRemove = (_, normalizedVersion) => {
95
- switch (normalizedOptions.replaceVersions) {
96
- case "all":
97
- return normalizedVersion !== rulesetVersion;
98
- case "all-lower":
99
- return normalizedVersion !== rulesetVersion && (0, semver_1.lt)(normalizedVersion, rulesetVersion);
100
- }
101
- return false;
102
- };
103
- rulesetsWithSameId.forEach((entry) => {
104
- if (shouldRemove(entry.ruleset, entry.normalizedVersion))
105
- rulesetsToRemove.push(entry.id);
106
- });
107
- this._imodel.elements.deleteElement(rulesetsToRemove);
108
- // attempt to update ruleset with same ID and version
109
- const exactMatch = rulesetsWithSameId.find((curr) => curr.normalizedVersion === rulesetVersion);
110
- if (exactMatch !== undefined) {
111
- return this.updateRuleset(exactMatch.id, ruleset, normalizedOptions.onEntityUpdate);
112
- }
113
- // no exact match found - insert a new ruleset element
114
- const model = await this.getOrCreateRulesetModel(normalizedOptions.onEntityInsert);
115
- const rulesetCode = RulesetElements.Ruleset.createRulesetCode(this._imodel, model.id, ruleset);
116
- return this.insertNewRuleset(ruleset, model, rulesetCode, normalizedOptions.onEntityInsert);
117
- }
118
- async updateRuleset(elementId, ruleset, callbacks) {
119
- const existingRulesetElement = this._imodel.elements.tryGetElement(elementId);
120
- (0, core_bentley_1.assert)(existingRulesetElement !== undefined);
121
- existingRulesetElement.jsonProperties.jsonProperties = ruleset;
122
- await this.updateElement(existingRulesetElement, callbacks);
123
- this._imodel.saveChanges();
124
- return existingRulesetElement.id;
125
- }
126
- async insertNewRuleset(ruleset, model, rulesetCode, callbacks) {
127
- const props = {
128
- model: model.id,
129
- code: rulesetCode,
130
- classFullName: RulesetElements.Ruleset.classFullName,
131
- jsonProperties: { jsonProperties: ruleset },
132
- };
133
- const element = await this.insertElement(props, callbacks);
134
- this._imodel.saveChanges();
135
- return element.id;
136
- }
137
- /**
138
- * Get all rulesets embedded in the iModel.
139
- */
140
- async getRulesets() {
141
- if (!this._imodel.containsClass(RulesetElements.Ruleset.classFullName))
142
- return [];
143
- const rulesetList = [];
144
- this._imodel.withPreparedStatement(`SELECT ECInstanceId AS id FROM ${RulesetElements.Ruleset.classFullName}`, (statement) => {
145
- while (core_bentley_1.DbResult.BE_SQLITE_ROW === statement.step()) {
146
- const row = statement.getRow();
147
- const rulesetElement = this._imodel.elements.getElement({ id: row.id });
148
- const ruleset = rulesetElement.jsonProperties.jsonProperties;
149
- rulesetList.push(ruleset);
150
- }
151
- });
152
- return rulesetList;
153
- }
154
- async getOrCreateRulesetModel(callbacks) {
155
- const rulesetModel = this.queryRulesetModel();
156
- if (undefined !== rulesetModel)
157
- return rulesetModel;
158
- const rulesetSubject = await this.insertSubject(callbacks);
159
- const definitionPartition = await this.insertDefinitionPartition(rulesetSubject, callbacks);
160
- return this.insertDefinitionModel(definitionPartition, callbacks);
161
- }
162
- queryRulesetModel() {
163
- const definitionPartition = this.queryDefinitionPartition();
164
- if (undefined === definitionPartition)
165
- return undefined;
166
- return this._imodel.models.getSubModel(definitionPartition.id);
167
- }
168
- queryDefinitionPartition() {
169
- const subject = this.querySubject();
170
- if (undefined === subject)
171
- return undefined;
172
- return this._imodel.elements.tryGetElement(core_backend_1.DefinitionPartition.createCode(this._imodel, subject.id, this._rulesetModelName));
173
- }
174
- querySubject() {
175
- const root = this._imodel.elements.getRootSubject();
176
- const codeSpec = this._imodel.codeSpecs.getByName(core_common_1.BisCodeSpec.subject);
177
- const code = new core_common_1.Code({
178
- spec: codeSpec.id,
179
- scope: root.id,
180
- value: this._rulesetSubjectName,
181
- });
182
- return this._imodel.elements.tryGetElement(code);
183
- }
184
- async insertDefinitionModel(definitionPartition, callbacks) {
185
- const modelProps = {
186
- modeledElement: definitionPartition,
187
- name: this._rulesetModelName,
188
- classFullName: core_backend_1.DefinitionModel.classFullName,
189
- isPrivate: true,
190
- };
191
- return this.insertModel(modelProps, callbacks);
192
- }
193
- async insertDefinitionPartition(rulesetSubject, callbacks) {
194
- const partitionCode = core_backend_1.DefinitionPartition.createCode(this._imodel, rulesetSubject.id, this._rulesetModelName);
195
- const definitionPartitionProps = {
196
- parent: {
197
- id: rulesetSubject.id,
198
- relClassName: "BisCore:SubjectOwnsPartitionElements",
199
- },
200
- model: rulesetSubject.model,
201
- code: partitionCode,
202
- classFullName: core_backend_1.DefinitionPartition.classFullName,
203
- };
204
- return this.insertElement(definitionPartitionProps, callbacks);
205
- }
206
- async insertSubject(callbacks) {
207
- const root = this._imodel.elements.getRootSubject();
208
- const codeSpec = this._imodel.codeSpecs.getByName(core_common_1.BisCodeSpec.subject);
209
- const subjectCode = new core_common_1.Code({
210
- spec: codeSpec.id,
211
- scope: root.id,
212
- value: this._rulesetSubjectName,
213
- });
214
- const subjectProps = {
215
- classFullName: core_backend_1.Subject.classFullName,
216
- model: root.model,
217
- parent: {
218
- id: root.id,
219
- relClassName: "BisCore:SubjectOwnsSubjects",
220
- },
221
- code: subjectCode,
222
- };
223
- return this.insertElement(subjectProps, callbacks);
224
- }
225
- async handleElementOperationPrerequisites() {
226
- if (this._imodel.containsClass(RulesetElements.Ruleset.classFullName))
227
- return;
228
- // import PresentationRules ECSchema
229
- await this._imodel.importSchemas([this._schemaPath]);
230
- // insert CodeSpec for ruleset elements
231
- this._imodel.codeSpecs.insert(core_common_1.CodeSpec.create(this._imodel, PresentationRulesDomain_1.PresentationRules.CodeSpec.Ruleset, core_common_1.CodeScopeSpec.Type.Model));
232
- this._imodel.saveChanges();
233
- }
234
- async insertElement(props, callbacks) {
235
- const element = this._imodel.elements.createElement(props);
236
- // istanbul ignore next
237
- await (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onBeforeInsert(element));
238
- try {
239
- return this._imodel.elements.getElement(element.insert());
240
- }
241
- finally {
242
- // istanbul ignore next
243
- await (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onAfterInsert(element));
244
- }
245
- }
246
- async insertModel(props, callbacks) {
247
- const model = this._imodel.models.createModel(props);
248
- // istanbul ignore next
249
- await (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onBeforeInsert(model));
250
- try {
251
- model.id = model.insert();
252
- return model;
253
- }
254
- finally {
255
- // istanbul ignore next
256
- await (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onAfterInsert(model));
257
- }
258
- }
259
- async updateElement(element, callbacks) {
260
- // istanbul ignore next
261
- await (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onBeforeUpdate(element));
262
- try {
263
- element.update();
264
- }
265
- finally {
266
- // istanbul ignore next
267
- await (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onAfterUpdate(element));
268
- }
269
- }
270
- }
271
- exports.RulesetEmbedder = RulesetEmbedder;
272
- function normalizeRulesetInsertOptions(options) {
273
- var _a, _b;
274
- if (options === undefined)
275
- return { skip: "same-id-and-version-eq", replaceVersions: "exact" };
276
- return {
277
- skip: (_a = options.skip) !== null && _a !== void 0 ? _a : "same-id-and-version-eq",
278
- replaceVersions: (_b = options.replaceVersions) !== null && _b !== void 0 ? _b : "exact",
279
- onEntityUpdate: options.onEntityUpdate,
280
- onEntityInsert: options.onEntityInsert,
281
- };
282
- }
73
+ WHERE json_extract(JsonProperties, '$.jsonProperties.id') = :rulesetId`;
74
+ const reader = this._imodel.createQueryReader(query, core_common_1.QueryBinder.from({ rulesetId: ruleset.id }), { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames });
75
+ while (await reader.step()) {
76
+ const row = reader.current.toRow();
77
+ const existingRulesetElementId = row.id;
78
+ const existingRuleset = JSON.parse(row.jsonProperties).jsonProperties;
79
+ rulesetsWithSameId.push({
80
+ id: existingRulesetElementId,
81
+ ruleset: existingRuleset,
82
+ normalizedVersion: (0, Utils_1.normalizeVersion)(existingRuleset.version),
83
+ });
84
+ }
85
+ // check if we need to do anything at all
86
+ const shouldSkip = normalizedOptions.skip === "same-id" && rulesetsWithSameId.length > 0
87
+ || normalizedOptions.skip === "same-id-and-version-eq" && rulesetsWithSameId.some((entry) => entry.normalizedVersion === rulesetVersion)
88
+ || normalizedOptions.skip === "same-id-and-version-gte" && rulesetsWithSameId.some((entry) => (0, semver_1.gte)(entry.normalizedVersion, rulesetVersion));
89
+ if (shouldSkip) {
90
+ // we're not inserting anything - return ID of the ruleset element with the highest version
91
+ const rulesetEntryWithHighestVersion = rulesetsWithSameId.reduce((highest, curr) => {
92
+ if (!highest.ruleset.version || curr.ruleset.version && (0, semver_1.gt)(curr.ruleset.version, highest.ruleset.version))
93
+ return curr;
94
+ return highest;
95
+ }, rulesetsWithSameId[0]);
96
+ return rulesetEntryWithHighestVersion.id;
97
+ }
98
+ // if requested, delete existing rulesets
99
+ const rulesetsToRemove = [];
100
+ const shouldRemove = (_, normalizedVersion) => {
101
+ switch (normalizedOptions.replaceVersions) {
102
+ case "all":
103
+ return normalizedVersion !== rulesetVersion;
104
+ case "all-lower":
105
+ return normalizedVersion !== rulesetVersion && (0, semver_1.lt)(normalizedVersion, rulesetVersion);
106
+ }
107
+ return false;
108
+ };
109
+ rulesetsWithSameId.forEach((entry) => {
110
+ if (shouldRemove(entry.ruleset, entry.normalizedVersion))
111
+ rulesetsToRemove.push(entry.id);
112
+ });
113
+ this._imodel.elements.deleteElement(rulesetsToRemove);
114
+ // attempt to update ruleset with same ID and version
115
+ const exactMatch = rulesetsWithSameId.find((curr) => curr.normalizedVersion === rulesetVersion);
116
+ if (exactMatch !== undefined) {
117
+ return this.updateRuleset(exactMatch.id, ruleset, normalizedOptions.onEntityUpdate);
118
+ }
119
+ // no exact match found - insert a new ruleset element
120
+ const model = await this.getOrCreateRulesetModel(normalizedOptions.onEntityInsert);
121
+ const rulesetCode = RulesetElements.Ruleset.createRulesetCode(this._imodel, model.id, ruleset);
122
+ return this.insertNewRuleset(ruleset, model, rulesetCode, normalizedOptions.onEntityInsert);
123
+ }
124
+ async updateRuleset(elementId, ruleset, callbacks) {
125
+ const existingRulesetElement = this._imodel.elements.tryGetElement(elementId);
126
+ (0, core_bentley_1.assert)(existingRulesetElement !== undefined);
127
+ existingRulesetElement.jsonProperties.jsonProperties = ruleset;
128
+ await this.updateElement(existingRulesetElement, callbacks);
129
+ this._imodel.saveChanges();
130
+ return existingRulesetElement.id;
131
+ }
132
+ async insertNewRuleset(ruleset, model, rulesetCode, callbacks) {
133
+ const props = {
134
+ model: model.id,
135
+ code: rulesetCode,
136
+ classFullName: RulesetElements.Ruleset.classFullName,
137
+ jsonProperties: { jsonProperties: ruleset },
138
+ };
139
+ const element = await this.insertElement(props, callbacks);
140
+ this._imodel.saveChanges();
141
+ return element.id;
142
+ }
143
+ /**
144
+ * Get all rulesets embedded in the iModel.
145
+ */
146
+ async getRulesets() {
147
+ if (!this._imodel.containsClass(RulesetElements.Ruleset.classFullName))
148
+ return [];
149
+ const rulesetList = [];
150
+ this._imodel.withPreparedStatement(`SELECT ECInstanceId AS id FROM ${RulesetElements.Ruleset.classFullName}`, (statement) => {
151
+ while (core_bentley_1.DbResult.BE_SQLITE_ROW === statement.step()) {
152
+ const row = statement.getRow();
153
+ const rulesetElement = this._imodel.elements.getElement({ id: row.id });
154
+ const ruleset = rulesetElement.jsonProperties.jsonProperties;
155
+ rulesetList.push(ruleset);
156
+ }
157
+ });
158
+ return rulesetList;
159
+ }
160
+ async getOrCreateRulesetModel(callbacks) {
161
+ const rulesetModel = this.queryRulesetModel();
162
+ if (undefined !== rulesetModel)
163
+ return rulesetModel;
164
+ const rulesetSubject = await this.insertSubject(callbacks);
165
+ const definitionPartition = await this.insertDefinitionPartition(rulesetSubject, callbacks);
166
+ return this.insertDefinitionModel(definitionPartition, callbacks);
167
+ }
168
+ queryRulesetModel() {
169
+ const definitionPartition = this.queryDefinitionPartition();
170
+ if (undefined === definitionPartition)
171
+ return undefined;
172
+ return this._imodel.models.getSubModel(definitionPartition.id);
173
+ }
174
+ queryDefinitionPartition() {
175
+ const subject = this.querySubject();
176
+ if (undefined === subject)
177
+ return undefined;
178
+ return this._imodel.elements.tryGetElement(core_backend_1.DefinitionPartition.createCode(this._imodel, subject.id, this._rulesetModelName));
179
+ }
180
+ querySubject() {
181
+ const root = this._imodel.elements.getRootSubject();
182
+ const codeSpec = this._imodel.codeSpecs.getByName(core_common_1.BisCodeSpec.subject);
183
+ const code = new core_common_1.Code({
184
+ spec: codeSpec.id,
185
+ scope: root.id,
186
+ value: this._rulesetSubjectName,
187
+ });
188
+ return this._imodel.elements.tryGetElement(code);
189
+ }
190
+ async insertDefinitionModel(definitionPartition, callbacks) {
191
+ const modelProps = {
192
+ modeledElement: definitionPartition,
193
+ name: this._rulesetModelName,
194
+ classFullName: core_backend_1.DefinitionModel.classFullName,
195
+ isPrivate: true,
196
+ };
197
+ return this.insertModel(modelProps, callbacks);
198
+ }
199
+ async insertDefinitionPartition(rulesetSubject, callbacks) {
200
+ const partitionCode = core_backend_1.DefinitionPartition.createCode(this._imodel, rulesetSubject.id, this._rulesetModelName);
201
+ const definitionPartitionProps = {
202
+ parent: {
203
+ id: rulesetSubject.id,
204
+ relClassName: "BisCore:SubjectOwnsPartitionElements",
205
+ },
206
+ model: rulesetSubject.model,
207
+ code: partitionCode,
208
+ classFullName: core_backend_1.DefinitionPartition.classFullName,
209
+ };
210
+ return this.insertElement(definitionPartitionProps, callbacks);
211
+ }
212
+ async insertSubject(callbacks) {
213
+ const root = this._imodel.elements.getRootSubject();
214
+ const codeSpec = this._imodel.codeSpecs.getByName(core_common_1.BisCodeSpec.subject);
215
+ const subjectCode = new core_common_1.Code({
216
+ spec: codeSpec.id,
217
+ scope: root.id,
218
+ value: this._rulesetSubjectName,
219
+ });
220
+ const subjectProps = {
221
+ classFullName: core_backend_1.Subject.classFullName,
222
+ model: root.model,
223
+ parent: {
224
+ id: root.id,
225
+ relClassName: "BisCore:SubjectOwnsSubjects",
226
+ },
227
+ code: subjectCode,
228
+ };
229
+ return this.insertElement(subjectProps, callbacks);
230
+ }
231
+ async handleElementOperationPrerequisites() {
232
+ if (this._imodel.containsClass(RulesetElements.Ruleset.classFullName))
233
+ return;
234
+ // import PresentationRules ECSchema
235
+ await this._imodel.importSchemas([this._schemaPath]);
236
+ // insert CodeSpec for ruleset elements
237
+ this._imodel.codeSpecs.insert(core_common_1.CodeSpec.create(this._imodel, PresentationRulesDomain_1.PresentationRules.CodeSpec.Ruleset, core_common_1.CodeScopeSpec.Type.Model));
238
+ this._imodel.saveChanges();
239
+ }
240
+ async insertElement(props, callbacks) {
241
+ const element = this._imodel.elements.createElement(props);
242
+ // istanbul ignore next
243
+ await callbacks?.onBeforeInsert(element);
244
+ try {
245
+ return this._imodel.elements.getElement(element.insert());
246
+ }
247
+ finally {
248
+ // istanbul ignore next
249
+ await callbacks?.onAfterInsert(element);
250
+ }
251
+ }
252
+ async insertModel(props, callbacks) {
253
+ const model = this._imodel.models.createModel(props);
254
+ // istanbul ignore next
255
+ await callbacks?.onBeforeInsert(model);
256
+ try {
257
+ model.id = model.insert();
258
+ return model;
259
+ }
260
+ finally {
261
+ // istanbul ignore next
262
+ await callbacks?.onAfterInsert(model);
263
+ }
264
+ }
265
+ async updateElement(element, callbacks) {
266
+ // istanbul ignore next
267
+ await callbacks?.onBeforeUpdate(element);
268
+ try {
269
+ element.update();
270
+ }
271
+ finally {
272
+ // istanbul ignore next
273
+ await callbacks?.onAfterUpdate(element);
274
+ }
275
+ }
276
+ }
277
+ exports.RulesetEmbedder = RulesetEmbedder;
278
+ function normalizeRulesetInsertOptions(options) {
279
+ if (options === undefined)
280
+ return { skip: "same-id-and-version-eq", replaceVersions: "exact" };
281
+ return {
282
+ skip: options.skip ?? "same-id-and-version-eq",
283
+ replaceVersions: options.replaceVersions ?? "exact",
284
+ onEntityUpdate: options.onEntityUpdate,
285
+ onEntityInsert: options.onEntityInsert,
286
+ };
287
+ }
283
288
  //# sourceMappingURL=RulesetEmbedder.js.map