From 5c36976b1e2927a018a2c8c34cdecb1ec8653831 Mon Sep 17 00:00:00 2001 From: flavien Date: Fri, 11 Oct 2024 11:14:18 +0200 Subject: [PATCH] [codemods] Add a new utility to rename imports --- packages/x-codemod/src/util/renameImports.ts | 162 ++++++++++++++++++ .../pickers/view-components-rename/index.ts | 156 ++++++++--------- .../view-components-rename.test.ts | 3 +- .../actual-nested-imports.spec.tsx | 1 + .../expected-nested-imports.spec.tsx | 7 +- .../expected-root-imports.spec.tsx | 12 +- .../index.ts | 66 +++---- ...rename-tree-view-simple-tree-view.test.ts} | 0 .../tree-view/rename-use-tree-item/index.ts | 37 ++-- ...e-item.ts => rename-use-tree-item.test.ts} | 0 10 files changed, 279 insertions(+), 165 deletions(-) create mode 100644 packages/x-codemod/src/util/renameImports.ts rename packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/{rename-tree-view-simple-tree-view.ts => rename-tree-view-simple-tree-view.test.ts} (100%) rename packages/x-codemod/src/v7.0.0/tree-view/rename-use-tree-item/{rename-use-tree-item.ts => rename-use-tree-item.test.ts} (100%) diff --git a/packages/x-codemod/src/util/renameImports.ts b/packages/x-codemod/src/util/renameImports.ts new file mode 100644 index 0000000000000..a54133c39311a --- /dev/null +++ b/packages/x-codemod/src/util/renameImports.ts @@ -0,0 +1,162 @@ +import type { + ASTPath, + Collection, + ImportDeclaration, + ImportSpecifier, + JSCodeshift, +} from 'jscodeshift'; + +interface ImportConfig { + oldEndpoint?: string; + newEndpoint?: string; + skipRoot?: boolean; + importsMapping: Record; +} + +interface RenameImportsParameters { + j: JSCodeshift; + root: Collection; + packageNames: string[]; + imports: ImportConfig[]; +} + +const getPathStrFromPath = (path: ASTPath | ASTPath) => { + let cleanPath: ASTPath; + if (path.get('type').value === 'ImportDeclaration') { + cleanPath = path as ASTPath; + } else { + cleanPath = path.parentPath.parentPath as ASTPath; + } + + return cleanPath.node.source.value?.toString() ?? ''; +}; + +const getRelativeEndpointFromPathStr = (pathStr: string, packageNames: string[]) => { + return pathStr.replace(new RegExp(`^(${packageNames.join('|')})/`), ''); +}; + +const getMatchingNestedImport = ( + path: ASTPath | ASTPath, + parameters: RenameImportsParameters, +) => { + const pathStr = getPathStrFromPath(path); + const relativeEndpoint = getRelativeEndpointFromPathStr(pathStr, parameters.packageNames); + return parameters.imports.find((importConfig) => importConfig.oldEndpoint === relativeEndpoint); +}; + +const getMatchingRootImport = ( + path: ASTPath, + parameters: RenameImportsParameters, +) => { + return parameters.imports.find((importConfig) => { + return ( + !importConfig.skipRoot && importConfig.importsMapping.hasOwnProperty(path.node.imported.name) + ); + }); +}; + +export function renameImports(parameters: RenameImportsParameters) { + const { j, root } = parameters; + + const importDeclarations = root + // Find all the import declarations (import { ... } from '...') + .find(j.ImportDeclaration); + + // Rename the nested imports specifiers + // - import { A } from '@mui/x-date-pickers/A' + // + import { B } from '@mui/x-date-pickers/A' + const nestedImportRegExp = new RegExp(`^(${parameters.packageNames.join('|')})/(.*)$`); + importDeclarations + // Filter out the declarations that are not nested endpoint of the matching packages or that don't have any update to apply + .filter((path) => { + const pathStr = getPathStrFromPath(path); + if (!pathStr.match(nestedImportRegExp)) { + return false; + } + + return !!getMatchingNestedImport(path, parameters); + }) + // Find all the import specifiers (extract A in import { A } from '...') + .find(j.ImportSpecifier) + // Filter out the specifiers that don't need to be updated + .filter((path) => { + return getMatchingNestedImport(path, parameters)!.importsMapping.hasOwnProperty( + path.node.imported.name, + ); + }) + // Rename the import specifiers + .replaceWith((path) => { + const newName = getMatchingNestedImport(path, parameters)!.importsMapping[ + path.node.imported.name + ]; + return j.importSpecifier(j.identifier(newName)); + }); + + // Rename the root imports specifiers + // - import { A } from '@mui/x-date-pickers' + // + import { B } from '@mui/x-date-pickers' + const rootImportRegExp = new RegExp(`^(${parameters.packageNames.join('|')})$`); + importDeclarations + // Filter out the declarations that are not root endpoint of the matching packages + .filter((path) => { + const pathStr = getPathStrFromPath(path); + return !!pathStr.match(rootImportRegExp); + }) + .find(j.ImportSpecifier) + .filter((path) => { + return !!getMatchingRootImport(path, parameters); + }) + // Rename the import specifiers + .replaceWith((path) => { + const newName = getMatchingRootImport(path, parameters)!.importsMapping[ + path.node.imported.name + ]; + return j.importSpecifier(j.identifier(newName)); + }); + + // Rename the nested import declarations + // - import { B } from '@mui/x-date-pickers/A' + // + import { B } from '@mui/x-date-pickers/B' + importDeclarations + // Filter out the declarations that are not nested endpoint of the matching packages or that don't have any update to apply + .filter((path) => { + const pathStr = getPathStrFromPath(path); + if (!pathStr.match(nestedImportRegExp)) { + return false; + } + + return !!getMatchingNestedImport(path, parameters)?.newEndpoint; + }) + .replaceWith((path) => { + const pathStr = getPathStrFromPath(path); + const oldEndpoint = getRelativeEndpointFromPathStr(pathStr, parameters.packageNames); + const newEndpoint = getMatchingNestedImport(path, parameters)!.newEndpoint; + const newPathStr = pathStr.replace(oldEndpoint, newEndpoint!); + + return j.importDeclaration( + // Copy over the existing import specifiers + path.node.specifiers, + // Replace the source with our new source + j.stringLiteral(newPathStr), + ); + }); + + // Rename the import usage + // - + // + + root + .find(j.Identifier) + .filter((path) => { + return parameters.imports.some((importConfig) => + importConfig.importsMapping.hasOwnProperty(path.node.name), + ); + }) + .replaceWith((path) => { + const newName = parameters.imports.find((importConfig) => + importConfig.importsMapping.hasOwnProperty(path.node.name), + )!.importsMapping[path.node.name]; + return j.identifier(newName); + }); + + return root; +} diff --git a/packages/x-codemod/src/v6.0.0/pickers/view-components-rename/index.ts b/packages/x-codemod/src/v6.0.0/pickers/view-components-rename/index.ts index b6c16cfd4ba3f..194996e1a0f46 100644 --- a/packages/x-codemod/src/v6.0.0/pickers/view-components-rename/index.ts +++ b/packages/x-codemod/src/v6.0.0/pickers/view-components-rename/index.ts @@ -1,59 +1,6 @@ -import { ASTPath, ImportDeclaration } from 'jscodeshift'; import type { JsCodeShiftAPI, JsCodeShiftFileInfo } from '../../../types'; +import { renameImports } from '../../../util/renameImports'; -const SUB_PACKAGES = { - CalendarPicker: 'DateCalendar', - CalendarPickerSkeleton: 'DayCalendarSkeleton', - MonthPicker: 'MonthCalendar', - YearPicker: 'YearCalendar', - ClockPicker: 'TimeClock', -}; - -const VARIABLES = { - // Date Calendar - CalendarPicker: 'DateCalendar', - CalendarPickerProps: 'DateCalendarProps', - CalendarPickerSlotsComponent: 'DateCalendarSlotsComponent', - CalendarPickerSlotsComponentsProps: 'DateCalendarSlotsComponentsProps', - CalendarPickerClasses: 'DateCalendarClasses', - CalendarPickerClassKey: 'DateCalendarClassKey', - calendarPickerClasses: 'dateCalendarClasses', - getCalendarPickerUtilityClass: 'getDateCalendarUtilityClass', - - // Month Calendar - MonthPicker: 'MonthCalendar', - MonthPickerProps: 'MonthCalendarProps', - MonthPickerClasses: 'MonthCalendarClasses', - MonthPickerClassKey: 'MonthCalendarClassKey', - monthPickerClasses: 'monthCalendarClasses', - getMonthPickerUtilityClass: 'getMonthCalendarUtilityClass', - - YearPicker: 'YearCalendar', - YearPickerProps: 'YearCalendarProps', - YearPickerClasses: 'YearCalendarClasses', - YearPickerClassKey: 'YearCalendarClassKey', - yearPickerClasses: 'yearCalendarClasses', - getYearPickerUtilityClass: 'getYearCalendarUtilityClass', - - ClockPicker: 'TimeClock', - ClockPickerProps: 'TimeClockProps', - ClockPickerClasses: 'TimeClockClasses', - ClockPickerClassKey: 'TimeClockClassKey', - clockPickerClasses: 'timeClockClasses', - getClockPickerUtilityClass: 'getTimeClockUtilityClass', - - CalendarPickerSkeleton: 'DayCalendarSkeleton', - CalendarPickerSkeletonProps: 'DayCalendarSkeletonProps', - CalendarPickerSkeletonClasses: 'DayCalendarSkeletonClasses', - CalendarPickerSkeletonClassKey: 'DayCalendarSkeletonClassKey', - calendarPickerSkeletonClasses: 'dayCalendarSkeletonClasses', - getCalendarPickerSkeletonUtilityClass: 'getDayCalendarSkeletonUtilityClass', -}; - -const PACKAGE_REGEXP = /@mui\/x-date-pickers(-pro|)(\/(.*)|)/; - -const matchImport = (path: ASTPath) => - (path.node.source.value?.toString() ?? '').match(PACKAGE_REGEXP); export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftAPI, options: any) { const j = api.jscodeshift; const root = j(file.source); @@ -63,38 +10,75 @@ export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftA trailingComma: true, }; - const matchingImports = root.find(j.ImportDeclaration).filter((path) => !!matchImport(path)); - - // Rename the import specifiers - // - import { MonthPicker } from '@mui/x-date-pickers/MonthPicker' - // + import { MonthCalendar } from '@mui/x-date-pickers/MonthPicker' - matchingImports - .find(j.ImportSpecifier) - .filter((path) => VARIABLES.hasOwnProperty(path.node.imported.name)) - .replaceWith((path) => j.importSpecifier(j.identifier(VARIABLES[path.node.imported.name]))); - - // Rename the nested import declarations - // - import {} from '@mui/x-date-pickers/MonthPicker' - // + import {} from '@mui/x-date-pickers/MonthCalendar' - matchingImports - .filter((path) => SUB_PACKAGES.hasOwnProperty(matchImport(path)?.[3] ?? '')) - .replaceWith((path) => { - const subPackage = matchImport(path)![3]; - const importPath = path.node.source.value?.toString() ?? ''; - - return j.importDeclaration( - path.node.specifiers, // copy over the existing import specifiers - j.stringLiteral(importPath.replace(subPackage, SUB_PACKAGES[subPackage])), // Replace the source with our new source - ); - }); - - // Rename the import usage - // - - // + - root - .find(j.Identifier) - .filter((path) => VARIABLES.hasOwnProperty(path.node.name)) - .replaceWith((path) => j.identifier(VARIABLES[path.node.name])); + renameImports({ + j, + root, + packageNames: ['@mui/x-date-pickers', '@mui/x-date-pickers-pro'], + imports: [ + { + oldEndpoint: 'CalendarPicker', + newEndpoint: 'DateCalendar', + importsMapping: { + CalendarPicker: 'DateCalendar', + CalendarPickerProps: 'DateCalendarProps', + CalendarPickerSlotsComponent: 'DateCalendarSlotsComponent', + CalendarPickerSlotsComponentsProps: 'DateCalendarSlotsComponentsProps', + CalendarPickerClasses: 'DateCalendarClasses', + CalendarPickerClassKey: 'DateCalendarClassKey', + calendarPickerClasses: 'dateCalendarClasses', + getCalendarPickerUtilityClass: 'getDateCalendarUtilityClass', + }, + }, + { + oldEndpoint: 'MonthPicker', + newEndpoint: 'MonthCalendar', + importsMapping: { + MonthPicker: 'MonthCalendar', + MonthPickerProps: 'MonthCalendarProps', + MonthPickerClasses: 'MonthCalendarClasses', + MonthPickerClassKey: 'MonthCalendarClassKey', + monthPickerClasses: 'monthCalendarClasses', + getMonthPickerUtilityClass: 'getMonthCalendarUtilityClass', + }, + }, + { + oldEndpoint: 'YearPicker', + newEndpoint: 'YearCalendar', + importsMapping: { + YearPicker: 'YearCalendar', + YearPickerProps: 'YearCalendarProps', + YearPickerClasses: 'YearCalendarClasses', + YearPickerClassKey: 'YearCalendarClassKey', + yearPickerClasses: 'yearCalendarClasses', + getYearPickerUtilityClass: 'getYearCalendarUtilityClass', + }, + }, + { + oldEndpoint: 'ClockPicker', + newEndpoint: 'TimeClock', + importsMapping: { + ClockPicker: 'TimeClock', + ClockPickerProps: 'TimeClockProps', + ClockPickerClasses: 'TimeClockClasses', + ClockPickerClassKey: 'TimeClockClassKey', + clockPickerClasses: 'timeClockClasses', + getClockPickerUtilityClass: 'getTimeClockUtilityClass', + }, + }, + { + oldEndpoint: 'CalendarPickerSkeleton', + newEndpoint: 'DayCalendarSkeleton', + importsMapping: { + CalendarPickerSkeleton: 'DayCalendarSkeleton', + CalendarPickerSkeletonProps: 'DayCalendarSkeletonProps', + CalendarPickerSkeletonClasses: 'DayCalendarSkeletonClasses', + CalendarPickerSkeletonClassKey: 'DayCalendarSkeletonClassKey', + calendarPickerSkeletonClasses: 'dayCalendarSkeletonClasses', + getCalendarPickerSkeletonUtilityClass: 'getDayCalendarSkeletonUtilityClass', + }, + }, + ], + }); return root.toSource(printOptions); } diff --git a/packages/x-codemod/src/v6.0.0/pickers/view-components-rename/view-components-rename.test.ts b/packages/x-codemod/src/v6.0.0/pickers/view-components-rename/view-components-rename.test.ts index c45d637ea35ab..a9e4b766e1ef0 100644 --- a/packages/x-codemod/src/v6.0.0/pickers/view-components-rename/view-components-rename.test.ts +++ b/packages/x-codemod/src/v6.0.0/pickers/view-components-rename/view-components-rename.test.ts @@ -9,6 +9,7 @@ function read(fileName) { } const TEST_FILES = ['community-nested-imports', 'community-root-imports', 'pro-root-imports']; +// const TEST_FILES = ['community-nested-imports']; describe('v6.0.0/pickers', () => { describe('view-components-rename', () => { @@ -16,7 +17,7 @@ describe('v6.0.0/pickers', () => { const actualPath = `./actual-${testFile}.spec.tsx`; const expectedPath = `./expected-${testFile}.spec.tsx`; - describe(`Community package (${testFile.replace(/-/g, ' ')})`, () => { + describe(`Package (${testFile.replace(/-/g, ' ')})`, () => { it('transforms imports as needed', () => { const actual = transform( { source: read(actualPath) }, diff --git a/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/actual-nested-imports.spec.tsx b/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/actual-nested-imports.spec.tsx index 45035f6c615bb..b36d2c603cc2e 100644 --- a/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/actual-nested-imports.spec.tsx +++ b/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/actual-nested-imports.spec.tsx @@ -13,6 +13,7 @@ import { TreeItem } from '@mui/x-tree-view/TreeItem'; function App() { getTreeViewUtilityClass('root'); + // prettier-ignore return ( diff --git a/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/expected-nested-imports.spec.tsx b/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/expected-nested-imports.spec.tsx index b2d2c5e39c905..5f709c3eba0af 100644 --- a/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/expected-nested-imports.spec.tsx +++ b/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/expected-nested-imports.spec.tsx @@ -7,15 +7,16 @@ import { SimpleTreeViewClassKey, simpleTreeViewClasses, getSimpleTreeViewUtilityClass, -} from '@mui/x-tree-view/TreeView'; +} from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; function App() { getSimpleTreeViewUtilityClass('root'); + // prettier-ignore return ( - + ( - + ) ); } diff --git a/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/expected-root-imports.spec.tsx b/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/expected-root-imports.spec.tsx index 4a6b80863b69c..29aca88cef92d 100644 --- a/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/expected-root-imports.spec.tsx +++ b/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/expected-root-imports.spec.tsx @@ -1,10 +1,10 @@ /* eslint-disable no-restricted-imports */ // @ts-nocheck import { - TreeView, - TreeViewProps, - TreeViewClasses, - TreeViewClassKey, - treeViewClasses, - getTreeViewUtilityClass, + SimpleTreeView, + SimpleTreeViewProps, + SimpleTreeViewClasses, + SimpleTreeViewClassKey, + simpleTreeViewClasses, + getSimpleTreeViewUtilityClass, } from '@mui/x-tree-view'; diff --git a/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/index.ts b/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/index.ts index d3fe7ea1347cb..21f2db6adaf21 100644 --- a/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/index.ts +++ b/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/index.ts @@ -1,19 +1,5 @@ -import { ASTPath, ImportDeclaration } from 'jscodeshift'; import type { JsCodeShiftAPI, JsCodeShiftFileInfo } from '../../../types'; - -const VARIABLES = { - TreeView: 'SimpleTreeView', - TreeViewProps: 'SimpleTreeViewProps', - TreeViewClasses: 'SimpleTreeViewClasses', - TreeViewClassKey: 'SimpleTreeViewClassKey', - treeViewClasses: 'simpleTreeViewClasses', - getTreeViewUtilityClass: 'getSimpleTreeViewUtilityClass', -}; - -const PACKAGE_REGEXP = /@mui\/x-tree-view(\/(.*)|)/; - -const matchImport = (path: ASTPath) => - (path.node.source.value?.toString() ?? '').match(PACKAGE_REGEXP); +import { renameImports } from '../../../util/renameImports'; export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftAPI, options: any) { const j = api.jscodeshift; @@ -24,37 +10,25 @@ export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftA trailingComma: true, }; - const matchingImports = root.find(j.ImportDeclaration).filter((path) => !!matchImport(path)); - - // Rename the import specifiers - // - import { TreeView } from '@mui/x-tree-view/TreeView' - // + import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView' - matchingImports - .find(j.ImportSpecifier) - .filter((path) => VARIABLES.hasOwnProperty(path.node.imported.name)) - .replaceWith((path) => j.importSpecifier(j.identifier(VARIABLES[path.node.imported.name]))); - - // Rename the nested import declarations - // - import {} from '@mui/x-tree-view/TreeView' - // + import {} from '@mui/x-tree-view/SimpleTreeView' - matchingImports - .filter((path) => matchImport(path)?.[2] === 'TreeView') - .replaceWith((path) => { - const importPath = path.node.source.value?.toString() ?? ''; - - return j.importDeclaration( - path.node.specifiers, // copy over the existing import specifiers - j.stringLiteral(importPath.replace('TreeView', 'SimpleTreeView')), // Replace the source with our new source - ); - }); - - // Rename the import usage - // - - // + - root - .find(j.Identifier) - .filter((path) => VARIABLES.hasOwnProperty(path.node.name)) - .replaceWith((path) => j.identifier(VARIABLES[path.node.name])); + renameImports({ + j, + root, + packageNames: ['@mui/x-tree-view'], + imports: [ + { + oldEndpoint: 'TreeView', + newEndpoint: 'SimpleTreeView', + importsMapping: { + TreeView: 'SimpleTreeView', + TreeViewProps: 'SimpleTreeViewProps', + TreeViewClasses: 'SimpleTreeViewClasses', + TreeViewClassKey: 'SimpleTreeViewClassKey', + treeViewClasses: 'simpleTreeViewClasses', + getTreeViewUtilityClass: 'getSimpleTreeViewUtilityClass', + }, + }, + ], + }); return root.toSource(printOptions); } diff --git a/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/rename-tree-view-simple-tree-view.ts b/packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/rename-tree-view-simple-tree-view.test.ts similarity index 100% rename from packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/rename-tree-view-simple-tree-view.ts rename to packages/x-codemod/src/v7.0.0/tree-view/rename-tree-view-simple-tree-view/rename-tree-view-simple-tree-view.test.ts diff --git a/packages/x-codemod/src/v7.0.0/tree-view/rename-use-tree-item/index.ts b/packages/x-codemod/src/v7.0.0/tree-view/rename-use-tree-item/index.ts index 8dac34f0a5233..d3bee203ed83b 100644 --- a/packages/x-codemod/src/v7.0.0/tree-view/rename-use-tree-item/index.ts +++ b/packages/x-codemod/src/v7.0.0/tree-view/rename-use-tree-item/index.ts @@ -1,10 +1,5 @@ -import { ASTPath, ImportDeclaration } from 'jscodeshift'; import type { JsCodeShiftAPI, JsCodeShiftFileInfo } from '../../../types'; - -const PACKAGE_REGEXP = /@mui\/x-tree-view(\/TreeItem|)/; - -const matchImport = (path: ASTPath) => - (path.node.source.value?.toString() ?? '').match(PACKAGE_REGEXP); +import { renameImports } from '../../../util/renameImports'; export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftAPI, options: any) { const j = api.jscodeshift; @@ -15,23 +10,19 @@ export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftA trailingComma: true, }; - const matchingImports = root.find(j.ImportDeclaration).filter((path) => !!matchImport(path)); - - // Rename the import specifiers - // - import { useTreeItem } from '@mui/x-tree-view/TreeItem' - // + import { useTreeItemState } from '@mui/x-tree-view/TreeItem' - matchingImports - .find(j.ImportSpecifier) - .filter((path) => path.node.imported.name === 'useTreeItem') - .replaceWith(j.importSpecifier(j.identifier('useTreeItemState'))); - - // Rename the import usage - // - useTreeItem(nodeId); - // + useTreeItemState(nodeId) - root - .find(j.Identifier) - .filter((path) => path.node.name === 'useTreeItem') - .replaceWith(j.identifier('useTreeItemState')); + renameImports({ + j, + root, + packageNames: ['@mui/x-tree-view'], + imports: [ + { + oldEndpoint: 'TreeItem', + importsMapping: { + useTreeItem: 'useTreeItemState', + }, + }, + ], + }); return root.toSource(printOptions); } diff --git a/packages/x-codemod/src/v7.0.0/tree-view/rename-use-tree-item/rename-use-tree-item.ts b/packages/x-codemod/src/v7.0.0/tree-view/rename-use-tree-item/rename-use-tree-item.test.ts similarity index 100% rename from packages/x-codemod/src/v7.0.0/tree-view/rename-use-tree-item/rename-use-tree-item.ts rename to packages/x-codemod/src/v7.0.0/tree-view/rename-use-tree-item/rename-use-tree-item.test.ts