@itwin/imodel-transformer 2.0.0-dev.2 → 2.0.0-dev.20

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 (55) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/lib/cjs/BranchProvenanceInitializer.js +18 -15
  3. package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
  4. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +1 -1
  5. package/lib/cjs/DetachedExportElementAspectsStrategy.js +8 -6
  6. package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +1 -1
  7. package/lib/cjs/ECReferenceTypesCache.d.ts +3 -0
  8. package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
  9. package/lib/cjs/ECReferenceTypesCache.js +103 -40
  10. package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
  11. package/lib/cjs/ElementCascadingDeleter.d.ts.map +1 -1
  12. package/lib/cjs/ElementCascadingDeleter.js +10 -9
  13. package/lib/cjs/ElementCascadingDeleter.js.map +1 -1
  14. package/lib/cjs/EntityUnifier.d.ts +1 -1
  15. package/lib/cjs/EntityUnifier.d.ts.map +1 -1
  16. package/lib/cjs/EntityUnifier.js +11 -12
  17. package/lib/cjs/EntityUnifier.js.map +1 -1
  18. package/lib/cjs/ExportElementAspectsStrategy.d.ts +4 -4
  19. package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +1 -1
  20. package/lib/cjs/ExportElementAspectsStrategy.js +1 -1
  21. package/lib/cjs/ExportElementAspectsStrategy.js.map +1 -1
  22. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +1 -1
  23. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +17 -16
  24. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +1 -1
  25. package/lib/cjs/IModelCloneContext.d.ts +3 -3
  26. package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
  27. package/lib/cjs/IModelCloneContext.js +60 -52
  28. package/lib/cjs/IModelCloneContext.js.map +1 -1
  29. package/lib/cjs/IModelExporter.d.ts +28 -19
  30. package/lib/cjs/IModelExporter.d.ts.map +1 -1
  31. package/lib/cjs/IModelExporter.js +145 -119
  32. package/lib/cjs/IModelExporter.js.map +1 -1
  33. package/lib/cjs/IModelImporter.d.ts +21 -21
  34. package/lib/cjs/IModelImporter.d.ts.map +1 -1
  35. package/lib/cjs/IModelImporter.js +94 -74
  36. package/lib/cjs/IModelImporter.js.map +1 -1
  37. package/lib/cjs/IModelTransformer.d.ts +84 -178
  38. package/lib/cjs/IModelTransformer.d.ts.map +1 -1
  39. package/lib/cjs/IModelTransformer.js +371 -997
  40. package/lib/cjs/IModelTransformer.js.map +1 -1
  41. package/lib/cjs/ProvenanceManager.d.ts +159 -0
  42. package/lib/cjs/ProvenanceManager.d.ts.map +1 -0
  43. package/lib/cjs/ProvenanceManager.js +677 -0
  44. package/lib/cjs/ProvenanceManager.js.map +1 -0
  45. package/lib/cjs/SyncTypeResolver.d.ts +34 -0
  46. package/lib/cjs/SyncTypeResolver.d.ts.map +1 -0
  47. package/lib/cjs/SyncTypeResolver.js +84 -0
  48. package/lib/cjs/SyncTypeResolver.js.map +1 -0
  49. package/lib/cjs/TransformerLoggerCategory.d.ts +6 -5
  50. package/lib/cjs/TransformerLoggerCategory.d.ts.map +1 -1
  51. package/lib/cjs/TransformerLoggerCategory.js +6 -5
  52. package/lib/cjs/TransformerLoggerCategory.js.map +1 -1
  53. package/lib/cjs/imodel-transformer.js +2 -2
  54. package/lib/cjs/imodel-transformer.js.map +1 -1
  55. package/package.json +38 -33
@@ -15,6 +15,7 @@ const TransformerLoggerCategory_1 = require("./TransformerLoggerCategory");
15
15
  const core_backend_1 = require("@itwin/core-backend");
16
16
  const assert = require("assert");
17
17
  const ElementCascadingDeleter_1 = require("./ElementCascadingDeleter");
18
+ const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
18
19
  const loggerCategory = TransformerLoggerCategory_1.TransformerLoggerCategory.IModelImporter;
19
20
  /** Base class for importing data into an iModel.
20
21
  * @see [iModel Transformation and Data Exchange]($docs/learning/transformer/index.md)
@@ -105,7 +106,7 @@ class IModelImporter {
105
106
  this._elementsToUpdateDuringPreserveIds.add(elementId);
106
107
  }
107
108
  /** Import the specified ModelProps (either as an insert or an update) into the target iModel. */
108
- importModel(modelProps) {
109
+ async importModel(modelProps) {
109
110
  if (undefined === modelProps.id || !core_bentley_1.Id64.isValidId64(modelProps.id))
110
111
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.InvalidId, "Model Id not provided, should be the same as the ModeledElementId");
111
112
  if (this.doNotUpdateElement(modelProps.id)) {
@@ -115,14 +116,14 @@ class IModelImporter {
115
116
  try {
116
117
  const model = this.targetDb.models.getModel(modelProps.id); // throws IModelError.NotFound if model does not exist
117
118
  if (hasEntityChanged(model, modelProps, this._modelPropertiesToIgnore)) {
118
- this.onUpdateModel(modelProps);
119
+ await this.onUpdateModel(modelProps);
119
120
  }
120
121
  }
121
122
  catch (error) {
122
123
  // catch NotFound error and insertModel
123
124
  if (error instanceof core_common_1.IModelError &&
124
125
  error.errorNumber === core_bentley_1.IModelStatus.NotFound) {
125
- this.onInsertModel(modelProps);
126
+ await this.onInsertModel(modelProps);
126
127
  return;
127
128
  }
128
129
  throw error;
@@ -131,11 +132,12 @@ class IModelImporter {
131
132
  /** Create a new Model from the specified ModelProps and insert it into the target iModel.
132
133
  * @note A subclass may override this method to customize insert behavior but should call `super.onInsertModel`.
133
134
  */
134
- onInsertModel(modelProps) {
135
+ async onInsertModel(modelProps) {
135
136
  try {
137
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
136
138
  const modelId = this.targetDb.models.insertModel(modelProps);
137
139
  core_bentley_1.Logger.logInfo(loggerCategory, `Inserted ${this.formatModelForLogger(modelProps)}`);
138
- this.trackProgress();
140
+ await this.trackProgress();
139
141
  return modelId;
140
142
  }
141
143
  catch (error) {
@@ -150,30 +152,33 @@ class IModelImporter {
150
152
  /** Update an existing Model in the target iModel from the specified ModelProps.
151
153
  * @note A subclass may override this method to customize update behavior but should call `super.onUpdateModel`.
152
154
  */
153
- onUpdateModel(modelProps) {
155
+ async onUpdateModel(modelProps) {
156
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
154
157
  this.targetDb.models.updateModel(modelProps);
155
158
  core_bentley_1.Logger.logInfo(loggerCategory, `Updated ${this.formatModelForLogger(modelProps)}`);
156
- this.trackProgress();
159
+ await this.trackProgress();
157
160
  }
158
161
  /** Format a Model for the Logger. */
159
162
  formatModelForLogger(modelProps) {
163
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
160
164
  return `${modelProps.classFullName} [${modelProps.id}]`;
161
165
  }
162
166
  /**
163
167
  * Tries to update an element with the specified element properties.
164
168
  * If a duplicate code error occurs, it assigns a new unique code value and retries the update
165
169
  */
166
- tryUpdateElement(elemProps) {
170
+ async tryUpdateElement(elemProps) {
167
171
  try {
168
- this.onUpdateElement(elemProps);
172
+ await this.onUpdateElement(elemProps);
169
173
  }
170
174
  catch (err) {
171
175
  if (err.errorNumber === core_bentley_1.IModelStatus.DuplicateCode) {
172
176
  assert(elemProps.code.value !== undefined, "NULL code values are always considered unique and cannot clash");
177
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
173
178
  this._duplicateCodeValueMap.set(elemProps.id, elemProps.code.value);
174
179
  // Using NULL code values as an alternative is not valid because definition elements cannot have NULL code values.
175
180
  elemProps.code.value = core_bentley_1.Guid.createValue();
176
- this.onUpdateElement(elemProps);
181
+ await this.onUpdateElement(elemProps);
177
182
  }
178
183
  else {
179
184
  throw err;
@@ -181,7 +186,7 @@ class IModelImporter {
181
186
  }
182
187
  }
183
188
  /** Import the specified ElementProps (either as an insert or an update) into the target iModel. */
184
- importElement(elementProps) {
189
+ async importElement(elementProps) {
185
190
  if (undefined !== elementProps.id &&
186
191
  this.doNotUpdateElement(elementProps.id)) {
187
192
  core_bentley_1.Logger.logInfo(loggerCategory, `Do not update target element ${elementProps.id}`);
@@ -197,24 +202,24 @@ class IModelImporter {
197
202
  // Always present elements (0xe, 0x1, 0x10) also will be updated to prevent duplicate inserts.
198
203
  if ((isSubCategory(elementProps) && isDefaultSubCategory(elementProps)) ||
199
204
  this._rootElementIds.has(elementProps.id)) {
200
- this.onUpdateElement(elementProps);
205
+ await this.onUpdateElement(elementProps);
201
206
  }
202
207
  else {
203
208
  if (this._elementsToUpdateDuringPreserveIds.has(elementProps.id)) {
204
- this.tryUpdateElement(elementProps);
209
+ await this.tryUpdateElement(elementProps);
205
210
  this._elementsToUpdateDuringPreserveIds.delete(elementProps.id);
206
211
  }
207
212
  else {
208
- this.onInsertElement(elementProps);
213
+ await this.onInsertElement(elementProps);
209
214
  }
210
215
  }
211
216
  }
212
217
  else {
213
218
  if (undefined !== elementProps.id) {
214
- this.tryUpdateElement(elementProps);
219
+ await this.tryUpdateElement(elementProps);
215
220
  }
216
221
  else {
217
- this.onInsertElement(elementProps); // targetElementProps.id assigned by insertElement
222
+ elementProps.id = await this.onInsertElement(elementProps); // targetElementProps.id assigned by insertElement
218
223
  }
219
224
  }
220
225
  return elementProps.id;
@@ -223,16 +228,16 @@ class IModelImporter {
223
228
  * @returns The Id of the newly inserted Element.
224
229
  * @note A subclass may override this method to customize insert behavior but should call `super.onInsertElement`.
225
230
  */
226
- onInsertElement(elementProps) {
227
- /* eslint-disable deprecation/deprecation */
231
+ async onInsertElement(elementProps) {
228
232
  try {
233
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
229
234
  const elementId = this.targetDb.elements.insertElement(elementProps, {
230
235
  forceUseId: this.options.preserveElementIdsForFiltering,
231
236
  });
232
237
  // set the id like [IModelDb.insertElement]($backend), does, the raw nativeDb method does not
233
238
  elementProps.id = elementId;
234
239
  core_bentley_1.Logger.logInfo(loggerCategory, `Inserted ${this.formatElementForLogger(elementProps)}`);
235
- this.trackProgress();
240
+ await this.trackProgress();
236
241
  if (this.options.simplifyElementGeometry) {
237
242
  this.targetDb.simplifyElementGeometry({
238
243
  id: elementId,
@@ -250,20 +255,19 @@ class IModelImporter {
250
255
  }
251
256
  throw error; // throw original error
252
257
  }
253
- /* eslint-enable deprecation/deprecation */
254
258
  }
255
259
  /** Update an existing Element in the target iModel from the specified ElementProps.
256
260
  * @note A subclass may override this method to customize update behavior but should call `super.onUpdateElement`.
257
261
  */
258
- onUpdateElement(elementProps) {
262
+ async onUpdateElement(elementProps) {
259
263
  if (!elementProps.id) {
260
264
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.InvalidId, "ElementId not provided");
261
265
  }
266
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
262
267
  this.targetDb.elements.updateElement(elementProps);
263
268
  core_bentley_1.Logger.logInfo(loggerCategory, `Updated ${this.formatElementForLogger(elementProps)}`);
264
- this.trackProgress();
269
+ await this.trackProgress();
265
270
  if (this.options.simplifyElementGeometry) {
266
- /* eslint-disable-next-line deprecation/deprecation */
267
271
  this.targetDb.simplifyElementGeometry({
268
272
  id: elementProps.id,
269
273
  convertBReps: true,
@@ -275,30 +279,31 @@ class IModelImporter {
275
279
  * Will delete special elements like definition elements and subjects.
276
280
  * @note A subclass may override this method to customize delete behavior but should call `super.onDeleteElement`.
277
281
  */
278
- onDeleteElement(elementId) {
282
+ async onDeleteElement(elementId) {
279
283
  (0, ElementCascadingDeleter_1.deleteElementTreeCascade)(this.targetDb, elementId);
280
284
  core_bentley_1.Logger.logInfo(loggerCategory, `Deleted element ${elementId} and its descendants`);
281
- this.trackProgress();
285
+ await this.trackProgress();
282
286
  }
283
287
  /** Delete the specified Element from the target iModel. */
284
- deleteElement(elementId) {
288
+ async deleteElement(elementId) {
285
289
  if (this.doNotUpdateElement(elementId)) {
286
290
  core_bentley_1.Logger.logInfo(loggerCategory, `Do not delete target element ${elementId}`);
287
291
  return;
288
292
  }
289
- this.onDeleteElement(elementId);
293
+ await this.onDeleteElement(elementId);
290
294
  }
291
295
  /** Delete the specified Model from the target iModel.
292
296
  * @note A subclass may override this method to customize delete behavior but should call `super.onDeleteModel`.
293
297
  */
294
- onDeleteModel(modelId) {
298
+ async onDeleteModel(modelId) {
299
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
295
300
  this.targetDb.models.deleteModel(modelId);
296
301
  core_bentley_1.Logger.logInfo(loggerCategory, `Deleted model ${modelId}`);
297
- this.trackProgress();
302
+ await this.trackProgress();
298
303
  }
299
304
  /** Delete the specified Model from the target iModel. */
300
- deleteModel(modelId) {
301
- this.onDeleteModel(modelId);
305
+ async deleteModel(modelId) {
306
+ await this.onDeleteModel(modelId);
302
307
  }
303
308
  /** Format an Element for the Logger. */
304
309
  formatElementForLogger(elementProps) {
@@ -310,14 +315,14 @@ class IModelImporter {
310
315
  return `${elementProps.classFullName} ${namePiece}[${elementProps.id}]`;
311
316
  }
312
317
  /** Import an ElementUniqueAspect into the target iModel. */
313
- importElementUniqueAspect(aspectProps) {
318
+ async importElementUniqueAspect(aspectProps) {
314
319
  const aspects = this.targetDb.elements.getAspects(aspectProps.element.id, aspectProps.classFullName);
315
320
  if (aspects.length === 0) {
316
321
  return this.onInsertElementAspect(aspectProps);
317
322
  }
318
323
  else if (hasEntityChanged(aspects[0], aspectProps)) {
319
324
  aspectProps.id = aspects[0].id;
320
- this.onUpdateElementAspect(aspectProps);
325
+ await this.onUpdateElementAspect(aspectProps);
321
326
  }
322
327
  return aspects[0].id;
323
328
  }
@@ -327,7 +332,7 @@ class IModelImporter {
327
332
  * @note For insert vs. update reasons, it is important to process all ElementMultiAspects owned by an Element at once since we don't have aspect-specific provenance.
328
333
  * @returns the array of ids of the resulting ElementMultiAspects, in the same order of the aspectPropsArray parameter
329
334
  */
330
- importElementMultiAspects(aspectPropsArray,
335
+ async importElementMultiAspects(aspectPropsArray,
331
336
  /** caller must use this to enforce any aspects added by IModelTransformer are not considered for update */
332
337
  filterFunc = () => true) {
333
338
  const result = new Array(aspectPropsArray.length).fill(undefined);
@@ -341,7 +346,7 @@ class IModelImporter {
341
346
  aspectClassFullNames.add(aspectsProps.classFullName);
342
347
  });
343
348
  // Handle ElementMultiAspects in groups by class
344
- aspectClassFullNames.forEach((aspectClassFullName) => {
349
+ for (const aspectClassFullName of aspectClassFullNames) {
345
350
  const proposedAspects = aspectPropsArray
346
351
  .map((props, index) => ({ props, index }))
347
352
  .filter(({ props }) => aspectClassFullName === props.classFullName);
@@ -350,50 +355,53 @@ class IModelImporter {
350
355
  .map((props, index) => ({ props, index }))
351
356
  .filter(({ props }) => filterFunc(props));
352
357
  if (proposedAspects.length >= currentAspects.length) {
353
- proposedAspects.forEach(({ props, index: resultIndex }, index) => {
358
+ for (let index = 0; index < proposedAspects.length; index++) {
359
+ const { props, index: resultIndex } = proposedAspects[index];
354
360
  let id;
355
361
  if (index < currentAspects.length) {
356
362
  id = currentAspects[index].props.id;
357
363
  props.id = id;
358
364
  if (hasEntityChanged(currentAspects[index].props, props)) {
359
- this.onUpdateElementAspect(props);
365
+ await this.onUpdateElementAspect(props);
360
366
  }
361
367
  id = props.id;
362
368
  }
363
369
  else {
364
- id = this.onInsertElementAspect(props);
370
+ id = await this.onInsertElementAspect(props);
365
371
  }
366
372
  result[resultIndex] = id;
367
- });
373
+ }
368
374
  }
369
375
  else {
370
- currentAspects.forEach(({ props, index: resultIndex }, index) => {
376
+ for (let index = 0; index < currentAspects.length; index++) {
377
+ const { props, index: resultIndex } = currentAspects[index];
371
378
  let id;
372
379
  if (index < proposedAspects.length) {
373
380
  id = props.id;
374
381
  proposedAspects[index].props.id = id;
375
382
  if (hasEntityChanged(props, proposedAspects[index].props)) {
376
- this.onUpdateElementAspect(proposedAspects[index].props);
383
+ await this.onUpdateElementAspect(proposedAspects[index].props);
377
384
  }
378
385
  result[resultIndex] = id;
379
386
  }
380
387
  else {
381
- this.onDeleteElementAspect(props);
388
+ await this.onDeleteElementAspect(props);
382
389
  }
383
- });
390
+ }
384
391
  }
385
- });
392
+ }
386
393
  assert(result.every((r) => typeof r !== undefined));
387
394
  return result;
388
395
  }
389
396
  /** Insert the ElementAspect into the target iModel.
390
397
  * @note A subclass may override this method to customize insert behavior but should call `super.onInsertElementAspect`.
391
398
  */
392
- onInsertElementAspect(aspectProps) {
399
+ async onInsertElementAspect(aspectProps) {
393
400
  try {
401
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
394
402
  const id = this.targetDb.elements.insertAspect(aspectProps);
395
403
  core_bentley_1.Logger.logInfo(loggerCategory, `Inserted ${this.formatElementAspectForLogger(aspectProps)}`);
396
- this.trackProgress();
404
+ await this.trackProgress();
397
405
  return id;
398
406
  }
399
407
  catch (error) {
@@ -408,18 +416,20 @@ class IModelImporter {
408
416
  /** Update the ElementAspect within the target iModel.
409
417
  * @note A subclass may override this method to customize update behavior but should call `super.onUpdateElementAspect`.
410
418
  */
411
- onUpdateElementAspect(aspectProps) {
419
+ async onUpdateElementAspect(aspectProps) {
420
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
412
421
  this.targetDb.elements.updateAspect(aspectProps);
413
422
  core_bentley_1.Logger.logInfo(loggerCategory, `Updated ${this.formatElementAspectForLogger(aspectProps)}`);
414
- this.trackProgress();
423
+ await this.trackProgress();
415
424
  }
416
425
  /** Delete the specified ElementAspect from the target iModel.
417
426
  * @note A subclass may override this method to customize delete behavior but should call `super.onDeleteElementAspect`.
418
427
  */
419
- onDeleteElementAspect(targetElementAspect) {
428
+ async onDeleteElementAspect(targetElementAspect) {
429
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
420
430
  this.targetDb.elements.deleteAspect(targetElementAspect.id);
421
431
  core_bentley_1.Logger.logInfo(loggerCategory, `Deleted ${this.formatElementAspectForLogger(targetElementAspect)}`);
422
- this.trackProgress();
432
+ await this.trackProgress();
423
433
  }
424
434
  /** Format an ElementAspect for the Logger. */
425
435
  formatElementAspectForLogger(elementAspectProps) {
@@ -428,7 +438,7 @@ class IModelImporter {
428
438
  /** Import the specified RelationshipProps (either as an insert or an update) into the target iModel.
429
439
  * @returns The instance Id of the inserted or updated Relationship.
430
440
  */
431
- importRelationship(relationshipProps) {
441
+ async importRelationship(relationshipProps) {
432
442
  if (undefined === relationshipProps.sourceId ||
433
443
  !core_bentley_1.Id64.isValidId64(relationshipProps.sourceId)) {
434
444
  core_bentley_1.Logger.logInfo(loggerCategory, `Ignoring ${relationshipProps.classFullName} instance because of invalid RelationshipProps.sourceId`);
@@ -449,7 +459,7 @@ class IModelImporter {
449
459
  // if relationship found, update it
450
460
  relationshipProps.id = relationship.id;
451
461
  if (hasEntityChanged(relationship, relationshipProps)) {
452
- this.onUpdateRelationship(relationshipProps);
462
+ await this.onUpdateRelationship(relationshipProps);
453
463
  }
454
464
  return relationshipProps.id;
455
465
  }
@@ -461,11 +471,13 @@ class IModelImporter {
461
471
  * @returns The instance Id of the newly inserted relationship.
462
472
  * @note A subclass may override this method to customize insert behavior but should call `super.onInsertRelationship`.
463
473
  */
464
- onInsertRelationship(relationshipProps) {
474
+ async onInsertRelationship(relationshipProps) {
465
475
  try {
466
- const targetRelInstanceId = this.targetDb.relationships.insertInstance(relationshipProps);
476
+ const targetRelInstanceId =
477
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
478
+ this.targetDb.relationships.insertInstance(relationshipProps);
467
479
  core_bentley_1.Logger.logInfo(loggerCategory, `Inserted ${this.formatRelationshipForLogger(relationshipProps)}`);
468
- this.trackProgress();
480
+ await this.trackProgress();
469
481
  return targetRelInstanceId;
470
482
  }
471
483
  catch (error) {
@@ -480,43 +492,45 @@ class IModelImporter {
480
492
  /** Update an existing Relationship in the target iModel from the specified RelationshipProps.
481
493
  * @note A subclass may override this method to customize update behavior but should call `super.onUpdateRelationship`.
482
494
  */
483
- onUpdateRelationship(relationshipProps) {
495
+ async onUpdateRelationship(relationshipProps) {
484
496
  if (!relationshipProps.id) {
485
497
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.InvalidId, "Relationship instance Id not provided");
486
498
  }
499
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
487
500
  this.targetDb.relationships.updateInstance(relationshipProps);
488
501
  core_bentley_1.Logger.logInfo(loggerCategory, `Updated ${this.formatRelationshipForLogger(relationshipProps)}`);
489
- this.trackProgress();
502
+ await this.trackProgress();
490
503
  }
491
504
  /** Delete the specified Relationship from the target iModel. */
492
- onDeleteRelationship(relationshipProps) {
505
+ async onDeleteRelationship(relationshipProps) {
493
506
  // Only passing in what deleteInstance actually uses, full relationshipProps is not necessary.
507
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
494
508
  this.targetDb.relationships.deleteInstance({
495
509
  id: relationshipProps.id,
496
510
  classFullName: relationshipProps.classFullName,
497
511
  });
498
512
  core_bentley_1.Logger.logInfo(loggerCategory, `Deleted relationship ${relationshipProps.classFullName} id=${relationshipProps.id}`);
499
- this.trackProgress();
513
+ await this.trackProgress();
500
514
  }
501
515
  /** Delete the specified Relationship from the target iModel. */
502
- deleteRelationship(relationshipProps) {
503
- this.onDeleteRelationship(relationshipProps);
516
+ async deleteRelationship(relationshipProps) {
517
+ await this.onDeleteRelationship(relationshipProps);
504
518
  }
505
519
  /** Format a Relationship for the Logger. */
506
520
  formatRelationshipForLogger(relProps) {
507
521
  return `${relProps.classFullName} sourceId=[${relProps.sourceId}] targetId=[${relProps.targetId}]`;
508
522
  }
509
523
  /** Tracks incremental progress */
510
- trackProgress() {
524
+ async trackProgress() {
511
525
  this._progressCounter++;
512
526
  if (0 === this._progressCounter % this.progressInterval) {
513
- this.onProgress();
527
+ await this.onProgress();
514
528
  }
515
529
  }
516
530
  /** This method is called when IModelImporter has made incremental progress based on the [[progressInterval]] setting.
517
531
  * @note A subclass may override this method to report custom progress but should call `super.onProgress`.
518
532
  */
519
- onProgress() { }
533
+ async onProgress() { }
520
534
  /** Optionally compute the projectExtents for the target iModel depending on the options for this IModelImporter.
521
535
  * @note This method is automatically called from [IModelTransformer.process]($transformer).
522
536
  * @see [IModelDb.computeProjectExtents]($backend), [[autoExtendProjectExtents]]
@@ -533,10 +547,15 @@ class IModelImporter {
533
547
  const excludeOutliers = typeof this.options.autoExtendProjectExtents === "object"
534
548
  ? this.options.autoExtendProjectExtents.excludeOutliers
535
549
  : false;
536
- const newProjectExtents = excludeOutliers
537
- ? computedProjectExtents.extents
538
- : computedProjectExtents.extentsWithOutliers;
550
+ // If excludeOutliers is true, use the extents without outliers.
551
+ // Otherwise prefer extentsWithOutliers, but fall back to extents if it's undefined or a null range.
552
+ const extentsWithOutliers = computedProjectExtents.extentsWithOutliers;
553
+ const useExtentsWithOutliers = !excludeOutliers && extentsWithOutliers && !extentsWithOutliers.isNull;
554
+ const newProjectExtents = useExtentsWithOutliers
555
+ ? extentsWithOutliers
556
+ : computedProjectExtents.extents;
539
557
  if (!newProjectExtents.isAlmostEqual(this.targetDb.projectExtents)) {
558
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
540
559
  this.targetDb.updateProjectExtents(newProjectExtents);
541
560
  core_bentley_1.Logger.logInfo(loggerCategory, `Updated projectExtents=${JSON.stringify(this.targetDb.projectExtents)}`);
542
561
  }
@@ -562,7 +581,6 @@ class IModelImporter {
562
581
  */
563
582
  optimizeGeometry(options) {
564
583
  if (options.inlineUniqueGeometryParts) {
565
- /* eslint-disable-next-line deprecation/deprecation */
566
584
  const result = this.targetDb.inlineGeometryParts();
567
585
  core_bentley_1.Logger.logInfo(loggerCategory, `Inlined ${result.numRefsInlined} references to ${result.numCandidateParts} geometry parts and deleted ${result.numPartsDeleted} parts.`);
568
586
  }
@@ -571,6 +589,7 @@ class IModelImporter {
571
589
  for (const [elementId, codeValue] of this._duplicateCodeValueMap) {
572
590
  const element = this.targetDb.elements.getElement(elementId);
573
591
  element.code.value = codeValue;
592
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
574
593
  element.update();
575
594
  }
576
595
  this._duplicateCodeValueMap.clear();
@@ -594,19 +613,20 @@ exports.IModelImporter = IModelImporter;
594
613
  */
595
614
  function hasEntityChanged(entity, entityProps, namesToIgnore) {
596
615
  let changed = false;
597
- entity.forEachProperty((propertyName, propertyMeta) => {
616
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
617
+ entity.forEach((propertyName, property) => {
598
618
  if (!changed) {
599
619
  if (namesToIgnore && namesToIgnore.has(propertyName)) {
600
620
  // skip
601
621
  }
602
- else if (core_common_1.PrimitiveTypeCode.Binary === propertyMeta.primitiveType) {
603
- changed = hasBinaryValueChanged(entity.asAny[propertyName], entityProps[propertyName]);
622
+ else if (ecschema_metadata_1.PropertyType.Binary === property.propertyType) {
623
+ changed = hasBinaryValueChanged(entity.asAny[core_common_1.ECJsNames.toJsName(propertyName)], entityProps[core_common_1.ECJsNames.toJsName(propertyName)]);
604
624
  }
605
- else if (propertyMeta.isNavigation) {
606
- changed = hasNavigationValueChanged(entity.asAny[propertyName], entityProps[propertyName]);
625
+ else if (property.isNavigation()) {
626
+ changed = hasNavigationValueChanged(entity.asAny[core_common_1.ECJsNames.toJsName(propertyName)], entityProps[core_common_1.ECJsNames.toJsName(propertyName)]);
607
627
  }
608
628
  else {
609
- changed = hasValueChanged(entity.asAny[propertyName], entityProps[propertyName]);
629
+ changed = hasValueChanged(entity.asAny[core_common_1.ECJsNames.toJsName(propertyName)], entityProps[core_common_1.ECJsNames.toJsName(propertyName)]);
610
630
  }
611
631
  }
612
632
  });