Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "major",
"comment": "IModelTransformer now uses a dedicated IModelExportHandler instead of inheriting from IModelExportHandler.",
"packageName": "@itwin/imodel-transformer",
"email": "44824788+DanRod1999@users.noreply.github.com",
"dependentChangeType": "patch"
}
6 changes: 5 additions & 1 deletion common/api/imodel-transformer.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ export class IModelExporter {
exportCodeSpecByName(codeSpecName: string): Promise<void>;
exportCodeSpecs(): Promise<void>;
exportElement(elementId: Id64String): Promise<void>;
// @internal
exportElementAspects(): Promise<void>;
exportFontByFontFamilyDescriptor(fontFamily: FontFamilyDescriptor): Promise<void>;
exportFontByFontProps(fontProps: FontProps): Promise<void>;
exportFontByName(fontName: string): Promise<void>;
Expand Down Expand Up @@ -254,7 +256,7 @@ export interface IModelTransformArgs {
}

// @beta
export class IModelTransformer extends IModelExportHandler {
export class IModelTransformer {
constructor(args: IModelTransformArgs, options?: IModelTransformOptions);
protected addCustomChanges(_sourceDbChanges: ChangedInstanceIds): Promise<void>;
calculateEcefTransform(): Transform | undefined;
Expand Down Expand Up @@ -291,6 +293,8 @@ export class IModelTransformer extends IModelExportHandler {
onExportModel(sourceModel: Model): Promise<void>;
onExportRelationship(sourceRelationship: Relationship): Promise<void>;
onExportSchema(schema: ECSchemaMetaData.Schema): Promise<void | ExportSchemaResult>;
onProgress(): Promise<void>;
onSkipElement(_sourceElementId: Id64String): Promise<void>;
onTransformElement(sourceElement: Element_2): Promise<ElementProps>;
protected onTransformElementAspect(sourceElementAspect: ElementAspect): Promise<ElementAspectProps>;
onTransformModel(sourceModel: Model, targetModeledElementId: Id64String): ModelProps;
Expand Down
23 changes: 23 additions & 0 deletions docs/changehistory/NEXT_VERSION.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Next release notes

## Breaking change: `IModelTransformer` no longer extends `IModelExportHandler`

`IModelTransformer` now registers a dedicated internal `IModelExportHandler` with its exporter instead of acting as the export handler itself. Existing transformer subclass overrides such as `shouldExportElement()`, `onExportElement()`, `onProgress()`, and `onSkipElement()` continue to be invoked with the same behavior.

Code that treated an `IModelTransformer` instance as an `IModelExportHandler` must use a separate handler for direct `IModelExporter` workflows:

```ts
const transformer = new IModelTransformer({
source: sourceDb,
target: targetEditTxn,
});

// The transformer configures its own internal export handler.
await transformer.process();

// Direct exporter workflows require their own handler.
const exporter = new IModelExporter(sourceDb);
exporter.registerHandler(myExportHandler);
await exporter.exportAll();
```

The `IModelTransformer.exporter` property and support for passing a preconfigured exporter as `IModelTransformArgs.source` are unchanged.

## Breaking change: transformer errors now have stable identifiers

Errors detected and owned by `@itwin/imodel-transformer` now use `ITwinError` with scope `@itwin/imodel-transformer` and a key from `IModelTransformerError`. These errors previously used a mix of `IModelError` and plain `Error`.
Expand Down
1 change: 1 addition & 0 deletions docs/learning/transformer/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ iModel entities are highly related to each other. Therefore, *cloning* an entity
The [IModelTransformer]($transformer) base class is used when the **source** and **target** in an ETL workflow are both/different iModels and some sort of data transformation is needed in the middle.
An instance of `IModelTransformer` holds instances of `IModelExporter`, `IModelImporter`, and `IModelElementCloneContext`.
This means that customization is possible at the export stage, the transformation stage, and the import stage of the overall ETL process.
`IModelTransformer` configures a dedicated internal `IModelExportHandler` for its exporter; the transformer itself is not an export handler.

Potential transformations include:

Expand Down
5 changes: 3 additions & 2 deletions packages/transformer/src/IModelExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ export class IModelExporter {
} else {
await this.exportModel(IModel.repositoryModelId);
}
await this.exportAllAspects();
await this.exportElementAspects();
await this.exportRelationships(ElementRefersToElements.classFullName);

// handle deletes
Expand Down Expand Up @@ -974,8 +974,9 @@ export class IModelExporter {
}

/** Exports all aspects present in the iModel.
* @internal
*/
private async exportAllAspects(): Promise<void> {
public async exportElementAspects(): Promise<void> {
return this._exportElementAspectsStrategy.exportAllElementAspects();
}

Expand Down
Loading
Loading