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';