diff --git a/projects/cdk/schematics/ng-update/v4/index.ts b/projects/cdk/schematics/ng-update/v4/index.ts
index 6992bc6a32f1..7b5f4c5b6741 100644
--- a/projects/cdk/schematics/ng-update/v4/index.ts
+++ b/projects/cdk/schematics/ng-update/v4/index.ts
@@ -43,6 +43,7 @@ import {
} from './steps/constants';
import {MODULES_TO_REPLACE_WITH_PROVIDERS} from './steps/constants/modules-to-replace';
import {TYPES_TO_RENAME} from './steps/constants/types';
+import {migrateEditor} from './steps/migrate-editor';
import {migrateRoot} from './steps/migrate-root';
import {replaceModulesWithProviders} from './steps/utils/replace-modules-with-providers';
@@ -50,6 +51,7 @@ function main(options: TuiSchema): Rule {
return (tree: Tree, context: SchematicContext) => {
const fileSystem = getFileSystem(tree);
+ migrateEditor(fileSystem, options);
replaceEnums(options, ENUMS_TO_REPLACE);
migrateRoot(fileSystem, options);
replaceServices(options, SERVICES_TO_REPLACE);
diff --git a/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts b/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts
index 5c15561c9598..8660fa5dc321 100644
--- a/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts
+++ b/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts
@@ -586,47 +586,6 @@ export const IDENTIFIERS_TO_REPLACE: ReplacementIdentifierMulti[] = [
moduleSpecifier: '@taiga-ui/kit',
},
},
- {
- from: {name: 'TuiEditorModule', moduleSpecifier: '@tinkoff/tui-editor'},
- to: [
- {name: 'TuiEditor', moduleSpecifier: '@taiga-ui/editor'},
- {name: 'TuiEditorSocket', moduleSpecifier: '@taiga-ui/editor'},
- ],
- },
- {
- from: {name: 'TuiEditorSocketModule', moduleSpecifier: '@tinkoff/tui-editor'},
- to: {name: 'TuiEditorSocket', moduleSpecifier: '@taiga-ui/editor'},
- },
- {
- from: {name: 'TuiToolbarModule', moduleSpecifier: '@tinkoff/tui-editor'},
- to: {name: 'TuiToolbar', moduleSpecifier: '@taiga-ui/editor'},
- },
- {
- from: {name: 'defaultEditorExtensions', moduleSpecifier: '@tinkoff/tui-editor'},
- to: {name: 'TUI_EDITOR_DEFAULT_EXTENSIONS', moduleSpecifier: '@taiga-ui/editor'},
- },
- {
- from: {
- name: 'TUI_EDITOR_DEFAULT_EXTENSIONS',
- moduleSpecifier: '@tinkoff/tui-editor',
- },
- to: {name: 'TUI_EDITOR_DEFAULT_EXTENSIONS', moduleSpecifier: '@taiga-ui/editor'},
- },
- {
- from: [
- {name: 'defaultEditorTools', moduleSpecifier: '@tinkoff/tui-editor'},
- {name: 'TUI_EDITOR_DEFAULT_TOOLS', moduleSpecifier: '@tinkoff/tui-editor'},
- ],
- to: {name: 'TUI_EDITOR_DEFAULT_TOOLS', moduleSpecifier: '@taiga-ui/editor'},
- },
- {
- from: {name: 'TuiColorPickerModule', moduleSpecifier: '@tinkoff/tui-editor'},
- to: {name: 'TuiColorPickerModule', moduleSpecifier: '@taiga-ui/legacy'},
- },
- {
- from: {name: 'TuiInputColorModule', moduleSpecifier: '@tinkoff/tui-editor'},
- to: {name: 'TuiInputColorModule', moduleSpecifier: '@taiga-ui/legacy'},
- },
{
from: {name: 'TuiFadeModule', moduleSpecifier: '@taiga-ui/experimental'},
to: {
diff --git a/projects/cdk/schematics/ng-update/v4/steps/migrate-editor.ts b/projects/cdk/schematics/ng-update/v4/steps/migrate-editor.ts
new file mode 100644
index 000000000000..8c82cecde5d0
--- /dev/null
+++ b/projects/cdk/schematics/ng-update/v4/steps/migrate-editor.ts
@@ -0,0 +1,106 @@
+///
+import {type DevkitFileSystem, getPackageJsonDependency} from 'ng-morph';
+import {getSourceFiles, saveActiveProject} from 'ng-morph';
+
+import {ALL_TS_FILES} from '../../../constants/file-globs';
+import type {TuiSchema} from '../../../ng-add/schema';
+import {
+ FINISH_SYMBOL,
+ infoLog,
+ REPLACE_SYMBOL,
+ SMALL_TAB_SYMBOL,
+ titleLog,
+} from '../../../utils/colored-log';
+import {replaceIdentifiers} from '../../steps/replace-identifier';
+import {replacePackageName} from '../../steps/replace-package-name';
+
+export const TUI_EDITOR_VERSION = '^4.0.0';
+
+export function migrateEditor(fileSystem: DevkitFileSystem, options: TuiSchema): void {
+ const moduleSpecifier = ['@tinkoff/tui-editor', '@taiga-ui/addon-editor'];
+ const hasEditor = moduleSpecifier.every(
+ (pkg) => !getPackageJsonDependency(fileSystem.tree, pkg),
+ );
+
+ if (hasEditor) {
+ return;
+ }
+
+ !options['skip-logs'] &&
+ infoLog(`${SMALL_TAB_SYMBOL}${REPLACE_SYMBOL} migrating editor...`);
+
+ replaceIdentifiers(options, [
+ {
+ from: {name: 'TuiEditorModule', moduleSpecifier},
+ to: [
+ {name: 'TuiEditor', moduleSpecifier: '@taiga-ui/editor'},
+ {name: 'TuiEditorSocket', moduleSpecifier: '@taiga-ui/editor'},
+ ],
+ },
+ {
+ from: {name: 'TuiEditorSocketModule', moduleSpecifier},
+ to: {name: 'TuiEditorSocket', moduleSpecifier: '@taiga-ui/editor'},
+ },
+ {
+ from: {name: 'TuiToolbarModule', moduleSpecifier},
+ to: {name: 'TuiToolbar', moduleSpecifier: '@taiga-ui/editor'},
+ },
+ {
+ from: {name: 'defaultEditorExtensions', moduleSpecifier},
+ to: {
+ name: 'TUI_EDITOR_DEFAULT_EXTENSIONS',
+ moduleSpecifier: '@taiga-ui/editor',
+ },
+ },
+ {
+ from: {name: 'TUI_EDITOR_DEFAULT_EXTENSIONS', moduleSpecifier},
+ to: {
+ name: 'TUI_EDITOR_DEFAULT_EXTENSIONS',
+ moduleSpecifier: '@taiga-ui/editor',
+ },
+ },
+ {
+ from: [
+ {name: 'defaultEditorTools', moduleSpecifier},
+ {
+ name: 'TUI_EDITOR_DEFAULT_TOOLS',
+ moduleSpecifier: '@tinkoff/tui-editor',
+ },
+ ],
+ to: {name: 'TUI_EDITOR_DEFAULT_TOOLS', moduleSpecifier: '@taiga-ui/editor'},
+ },
+ {
+ from: {name: 'TuiColorPickerModule', moduleSpecifier},
+ to: {name: 'TuiColorPickerModule', moduleSpecifier: '@taiga-ui/legacy'},
+ },
+ {
+ from: {name: 'TuiInputColorModule', moduleSpecifier},
+ to: {name: 'TuiInputColorModule', moduleSpecifier: '@taiga-ui/legacy'},
+ },
+ ]);
+
+ getSourceFiles(ALL_TS_FILES).forEach((sourceFile) =>
+ sourceFile.replaceWithText(
+ sourceFile
+ .getFullText()
+ .replaceAll(
+ /import\(['"`](@tinkoff|@taiga-ui)\/(tui-editor|addon-editor)\/(.*)['"`]\)/g,
+ "import('@taiga-ui/editor')",
+ ),
+ ),
+ );
+
+ saveActiveProject();
+
+ moduleSpecifier.forEach((pkg) =>
+ replacePackageName(
+ pkg,
+ {name: '@taiga-ui/editor', version: TUI_EDITOR_VERSION},
+ fileSystem.tree,
+ ),
+ );
+
+ saveActiveProject();
+
+ !options['skip-logs'] && titleLog(`${FINISH_SYMBOL} successfully migrated \n`);
+}
diff --git a/projects/cdk/schematics/ng-update/v4/steps/update-packages.ts b/projects/cdk/schematics/ng-update/v4/steps/update-packages.ts
index f84b566d09d0..45fb1091262b 100644
--- a/projects/cdk/schematics/ng-update/v4/steps/update-packages.ts
+++ b/projects/cdk/schematics/ng-update/v4/steps/update-packages.ts
@@ -15,7 +15,6 @@ import {replacePackageName} from '../../steps';
export const TUI_POLYMORPHEUS_VERSION = '^4.6.4';
export const TUI_DOMPURIFY_VERSION = '^4.1.2';
export const TUI_EVENT_PLUGINS_VERSION = '^4.0.1';
-export const TUI_EDITOR_VERSION = '^2.5.0';
export function updatePackages({tree}: DevkitFileSystem, _: TuiSchema): void {
const packagesToRemove = ['@taiga-ui/addon-tablebars', '@taiga-ui/addon-preview'];
@@ -48,14 +47,6 @@ export function updatePackages({tree}: DevkitFileSystem, _: TuiSchema): void {
},
tree,
);
- replacePackageName(
- '@tinkoff/tui-editor',
- {
- name: '@taiga-ui/editor',
- version: TUI_EDITOR_VERSION,
- },
- tree,
- );
const cdk = getPackageJsonDependency(tree, '@taiga-ui/cdk');
diff --git a/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-addon-editor.spec.ts b/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-addon-editor.spec.ts
new file mode 100644
index 000000000000..2cbb52167efb
--- /dev/null
+++ b/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-addon-editor.spec.ts
@@ -0,0 +1,148 @@
+import {join} from 'node:path';
+
+import {HostTree} from '@angular-devkit/schematics';
+import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing';
+import type {TuiSchema} from '@taiga-ui/cdk/schematics/ng-add/schema';
+import {
+ createProject,
+ createSourceFile,
+ resetActiveProject,
+ saveActiveProject,
+ setActiveProject,
+} from 'ng-morph';
+
+const collectionPath = join(__dirname, '../../../migration.json');
+
+const COMPONENT_BEFORE = `
+import {
+ TUI_SANITIZER,
+ TuiAlertModule,
+ TuiDialogModule,
+ TuiRootModule,
+} from '@taiga-ui/core';
+import {NgDompurifySanitizer} from '@tinkoff/ng-dompurify';
+import {TUI_EDITOR_DEFAULT_EXTENSIONS, TUI_EDITOR_EXTENSIONS} from '@taiga-ui/addon-editor';
+import {TuiEditorModule, TuiEditorTool} from '@tinkoff/tui-editor';
+
+@Component({
+ standalone: true,
+ templateUrl: './test.template.html',
+ imports: [TuiEditorModule],
+ providers: [
+ {
+ provide: TUI_EDITOR_EXTENSIONS,
+ deps: [INJECTOR],
+ useFactory: (injector: Injector) => [
+ ...TUI_EDITOR_DEFAULT_EXTENSIONS,
+ import('@taiga-ui/addon-editor/extensions/image-editor').then(
+ ({tuiCreateImageEditorExtension}) =>
+ tuiCreateImageEditorExtension({injector}),
+ ),
+ ],
+ },
+ {
+ provide: TUI_SANITIZER,
+ useClass: NgDompurifySanitizer,
+ }
+ ],
+})
+export class Test {
+ protected readonly builtInTools = [TuiEditorTool.Undo, TuiEditorTool.Img];
+}`;
+
+const COMPONENT_AFTER = `import { TUI_SANITIZER } from "@taiga-ui/legacy";
+import { TuiEditor, TuiEditorSocket, TUI_EDITOR_DEFAULT_EXTENSIONS } from "@taiga-ui/editor";
+
+import { TuiRoot, TuiAlert, TuiDialog } from '@taiga-ui/core';
+import {NgDompurifySanitizer} from '@taiga-ui/dompurify';
+import {TUI_EDITOR_EXTENSIONS} from '@taiga-ui/editor';
+import {TuiEditorTool} from '@taiga-ui/editor';
+
+@Component({
+ standalone: true,
+ templateUrl: './test.template.html',
+ imports: [TuiEditor, TuiEditorSocket],
+ providers: [
+ {
+ provide: TUI_EDITOR_EXTENSIONS,
+ deps: [INJECTOR],
+ useFactory: (injector: Injector) => [
+ ...TUI_EDITOR_DEFAULT_EXTENSIONS,
+ import('@taiga-ui/editor').then(
+ ({tuiCreateImageEditorExtension}) =>
+ tuiCreateImageEditorExtension({injector}),
+ ),
+ ],
+ },
+ {
+ provide: TUI_SANITIZER,
+ useClass: NgDompurifySanitizer,
+ }
+ ],
+})
+export class Test {
+ protected readonly builtInTools = [TuiEditorTool.Undo, TuiEditorTool.Img];
+}
+`.trim();
+
+const PACKAGE_JSON_BEFORE = `{
+ "dependencies": {
+ "@angular/core": "~13.0.0",
+ "@taiga-ui/core": "~3.35.0",
+ "@taiga-ui/cdk": "~3.35.0",
+ "@taiga-ui/addon-editor": "~3.35.0",
+ "@tinkoff/ng-polymorpheus": "1.2.3",
+ "@tinkoff/ng-event-plugins": "4.5.6"
+ }
+}`;
+
+const PACKAGE_JSON_AFTER = `{
+ "dependencies": {
+ "@angular/core": "~13.0.0",
+ "@taiga-ui/core": "~3.35.0",
+ "@taiga-ui/cdk": "~3.35.0",
+ "@taiga-ui/editor": "^4.0.0",
+ "@taiga-ui/event-plugins": "^4.0.1",
+ "@taiga-ui/legacy": "4.4.1",
+ "@taiga-ui/polymorpheus": "^4.6.4"
+ }
+}`.trim();
+
+describe('ng-update', () => {
+ let host: UnitTestTree;
+ let runner: SchematicTestRunner;
+
+ beforeEach(() => {
+ host = new UnitTestTree(new HostTree());
+ runner = new SchematicTestRunner('schematics', collectionPath);
+
+ setActiveProject(createProject(host));
+
+ createMainFiles();
+
+ saveActiveProject();
+ });
+
+ it('should migrate addon editor references in files', async () => {
+ const tree = await runner.runSchematic(
+ 'updateToV4',
+ {'skip-logs': process.env['TUI_CI'] === 'true'} as Partial,
+ host,
+ );
+
+ expect(tree.readContent('package.json').trim()).toEqual(PACKAGE_JSON_AFTER);
+ expect(tree.readContent('test/app/test.component.ts').trim()).toEqual(
+ COMPONENT_AFTER,
+ );
+ });
+
+ afterEach(() => {
+ resetActiveProject();
+ });
+});
+
+function createMainFiles(): void {
+ createSourceFile('test/app/test.component.ts', COMPONENT_BEFORE);
+ createSourceFile('test/app/test.template.html', '');
+ createSourceFile('package.json', PACKAGE_JSON_BEFORE);
+}
diff --git a/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-package-names.spec.ts b/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-package-names.spec.ts
index 49c3ceb5f172..bb8b7b7b40c9 100644
--- a/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-package-names.spec.ts
+++ b/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-package-names.spec.ts
@@ -13,6 +13,7 @@ import {
} from 'ng-morph';
import cdkPackage from '../../../../package.json';
+import {TUI_EDITOR_VERSION} from '../steps/migrate-editor';
const collectionPath = join(__dirname, '../../../migration.json');
@@ -59,7 +60,7 @@ const PACKAGE_JSON_AFTER = {
'@taiga-ui/legacy': TUI_VERSION,
'@taiga-ui/event-plugins': cdkPackage.peerDependencies['@taiga-ui/event-plugins'],
'@taiga-ui/polymorpheus': cdkPackage.peerDependencies['@taiga-ui/polymorpheus'],
- '@taiga-ui/editor': '^2.5.0',
+ '@taiga-ui/editor': TUI_EDITOR_VERSION,
},
};
@@ -107,7 +108,12 @@ describe('ng-update', () => {
createSourceFile(
'package.json',
- JSON.stringify({dependencies: PACKAGE_JSON_DEPS}),
+ JSON.stringify({
+ dependencies: {
+ ...PACKAGE_JSON_DEPS,
+ '@tinkoff/tui-editor': '1.58.0',
+ },
+ }),
{overwrite: true},
);
saveActiveProject();
@@ -122,6 +128,7 @@ describe('ng-update', () => {
expect(JSON.parse(tree.readContent('package.json'))).toEqual({
dependencies: {
...PACKAGE_JSON_DEPS,
+ '@taiga-ui/editor': TUI_EDITOR_VERSION,
'@taiga-ui/event-plugins':
cdkPackage.peerDependencies['@taiga-ui/event-plugins'],
'@taiga-ui/layout': TUI_VERSION,
diff --git a/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-tinkoff-editor.spec.ts b/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-tinkoff-editor.spec.ts
new file mode 100644
index 000000000000..2873e77c1ce4
--- /dev/null
+++ b/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-tinkoff-editor.spec.ts
@@ -0,0 +1,148 @@
+import {join} from 'node:path';
+
+import {HostTree} from '@angular-devkit/schematics';
+import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing';
+import type {TuiSchema} from '@taiga-ui/cdk/schematics/ng-add/schema';
+import {
+ createProject,
+ createSourceFile,
+ resetActiveProject,
+ saveActiveProject,
+ setActiveProject,
+} from 'ng-morph';
+
+const collectionPath = join(__dirname, '../../../migration.json');
+
+const COMPONENT_BEFORE = `
+import {
+ TUI_SANITIZER,
+ TuiAlertModule,
+ TuiDialogModule,
+ TuiRootModule,
+} from '@taiga-ui/core';
+import {NgDompurifySanitizer} from '@tinkoff/ng-dompurify';
+import {TUI_EDITOR_DEFAULT_EXTENSIONS, TUI_EDITOR_EXTENSIONS} from '@tinkoff/tui-editor';
+import {TuiEditorModule, TuiEditorTool} from '@tinkoff/tui-editor';
+
+@Component({
+ standalone: true,
+ templateUrl: './test.template.html',
+ imports: [TuiEditorModule],
+ providers: [
+ {
+ provide: TUI_EDITOR_EXTENSIONS,
+ deps: [INJECTOR],
+ useFactory: (injector: Injector) => [
+ ...TUI_EDITOR_DEFAULT_EXTENSIONS,
+ import('@tinkoff/tui-editor/extensions/image-editor').then(
+ ({tuiCreateImageEditorExtension}) =>
+ tuiCreateImageEditorExtension({injector}),
+ ),
+ ],
+ },
+ {
+ provide: TUI_SANITIZER,
+ useClass: NgDompurifySanitizer,
+ }
+ ],
+})
+export class Test {
+ protected readonly builtInTools = [TuiEditorTool.Undo, TuiEditorTool.Img];
+}`;
+
+const COMPONENT_AFTER = `import { TUI_SANITIZER } from "@taiga-ui/legacy";
+import { TuiEditor, TuiEditorSocket, TUI_EDITOR_DEFAULT_EXTENSIONS } from "@taiga-ui/editor";
+
+import { TuiRoot, TuiAlert, TuiDialog } from '@taiga-ui/core';
+import {NgDompurifySanitizer} from '@taiga-ui/dompurify';
+import {TUI_EDITOR_EXTENSIONS} from '@taiga-ui/editor';
+import {TuiEditorTool} from '@taiga-ui/editor';
+
+@Component({
+ standalone: true,
+ templateUrl: './test.template.html',
+ imports: [TuiEditor, TuiEditorSocket],
+ providers: [
+ {
+ provide: TUI_EDITOR_EXTENSIONS,
+ deps: [INJECTOR],
+ useFactory: (injector: Injector) => [
+ ...TUI_EDITOR_DEFAULT_EXTENSIONS,
+ import('@taiga-ui/editor').then(
+ ({tuiCreateImageEditorExtension}) =>
+ tuiCreateImageEditorExtension({injector}),
+ ),
+ ],
+ },
+ {
+ provide: TUI_SANITIZER,
+ useClass: NgDompurifySanitizer,
+ }
+ ],
+})
+export class Test {
+ protected readonly builtInTools = [TuiEditorTool.Undo, TuiEditorTool.Img];
+}
+`.trim();
+
+const PACKAGE_JSON_BEFORE = `{
+ "dependencies": {
+ "@angular/core": "~13.0.0",
+ "@taiga-ui/core": "~3.42.0",
+ "@taiga-ui/cdk": "~3.42.0",
+ "@tinkoff/ng-polymorpheus": "1.2.3",
+ "@tinkoff/ng-event-plugins": "4.5.6",
+ "@tinkoff/tui-editor": "1.38.0"
+ }
+}`;
+
+const PACKAGE_JSON_AFTER = `{
+ "dependencies": {
+ "@angular/core": "~13.0.0",
+ "@taiga-ui/core": "~3.42.0",
+ "@taiga-ui/cdk": "~3.42.0",
+ "@taiga-ui/editor": "^4.0.0",
+ "@taiga-ui/event-plugins": "^4.0.1",
+ "@taiga-ui/legacy": "4.4.1",
+ "@taiga-ui/polymorpheus": "^4.6.4"
+ }
+}`.trim();
+
+describe('ng-update', () => {
+ let host: UnitTestTree;
+ let runner: SchematicTestRunner;
+
+ beforeEach(() => {
+ host = new UnitTestTree(new HostTree());
+ runner = new SchematicTestRunner('schematics', collectionPath);
+
+ setActiveProject(createProject(host));
+
+ createMainFiles();
+
+ saveActiveProject();
+ });
+
+ it('should migrate editor references in files', async () => {
+ const tree = await runner.runSchematic(
+ 'updateToV4',
+ {'skip-logs': process.env['TUI_CI'] === 'true'} as Partial,
+ host,
+ );
+
+ expect(tree.readContent('package.json').trim()).toEqual(PACKAGE_JSON_AFTER);
+ expect(tree.readContent('test/app/test.component.ts').trim()).toEqual(
+ COMPONENT_AFTER,
+ );
+ });
+
+ afterEach(() => {
+ resetActiveProject();
+ });
+});
+
+function createMainFiles(): void {
+ createSourceFile('test/app/test.component.ts', COMPONENT_BEFORE);
+ createSourceFile('test/app/test.template.html', '');
+ createSourceFile('package.json', PACKAGE_JSON_BEFORE);
+}
diff --git a/projects/cdk/schematics/ng-update/v4/tests/schematic-resolve-package-type.spec.ts b/projects/cdk/schematics/ng-update/v4/tests/schematic-resolve-package-type.spec.ts
index 1d294970161a..3a2947724ffb 100644
--- a/projects/cdk/schematics/ng-update/v4/tests/schematic-resolve-package-type.spec.ts
+++ b/projects/cdk/schematics/ng-update/v4/tests/schematic-resolve-package-type.spec.ts
@@ -13,9 +13,9 @@ import {
setActiveProject,
} from 'ng-morph';
+import {TUI_EDITOR_VERSION} from '../steps/migrate-editor';
import {
TUI_DOMPURIFY_VERSION,
- TUI_EDITOR_VERSION,
TUI_EVENT_PLUGINS_VERSION,
TUI_POLYMORPHEUS_VERSION,
} from '../steps/update-packages';