chore(upgrade): codemod for replacing nocontent with emptystatelayout (#21122)

This commit is contained in:
Jamie Howard 2024-09-02 15:54:40 +01:00 committed by GitHub
parent 43f30b747f
commit ec11400460
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 97 additions and 9 deletions

View File

@ -0,0 +1,30 @@
import type { Transform } from 'jscodeshift';
import { changeImportSpecifier } from '../../utils/change-import';
import { replaceJSXElement } from '../../utils/replace-jsx';
/**
* change NoContent import from '@strapi/helper-plugin' to EmptyStateLayout from '@strapi/design-system'
* And replace all uses of NoContent with EmptyStateLayout
*/
const transform: Transform = (file, api) => {
const { j } = api;
const root = j.withParser('tsx')(file.source);
replaceJSXElement(root, j, {
oldElementName: 'NoContent',
newElementName: 'EmptyStateLayout',
oldDependency: '@strapi/helper-plugin',
});
changeImportSpecifier(root, j, {
oldMethodName: 'NoContent',
newMethodName: 'EmptyStateLayout',
oldDependency: '@strapi/helper-plugin',
newDependency: '@strapi/design-system',
});
return root.toSource();
};
export default transform;

View File

@ -10,7 +10,7 @@ const transform: Transform = (file, api) => {
const root = j.withParser('tsx')(file.source);
changeImportSpecifier(root, j, {
methodName: 'useRBAC',
oldMethodName: 'useRBAC',
oldDependency: '@strapi/helper-plugin',
newDependency: '@strapi/strapi/admin',
});

View File

@ -3,9 +3,15 @@ import type { ImportDeclaration, JSCodeshift, Collection } from 'jscodeshift';
export const changeImportSpecifier = (
root: Collection,
j: JSCodeshift,
options: { methodName: string; oldDependency: string; newDependency: string }
options: {
oldDependency: string;
newDependency: string;
oldMethodName: string;
newMethodName?: string;
}
): void => {
const { methodName, oldDependency, newDependency } = options;
const { oldMethodName, newMethodName, oldDependency, newDependency } = options;
const methodNameToReplace = newMethodName ?? oldMethodName;
// Flag to check if the method was imported from the old dependency
let methodImportedFromOldDependency = false;
@ -21,7 +27,7 @@ export const changeImportSpecifier = (
// Check if the method is imported from the old dependency
const methodSpecifiers = importDeclaration.specifiers?.filter(
(specifier) =>
specifier.type === 'ImportSpecifier' && specifier.imported.name === methodName
specifier.type === 'ImportSpecifier' && specifier.imported.name === oldMethodName
);
if (methodSpecifiers && methodSpecifiers.length > 0) {
@ -29,17 +35,17 @@ export const changeImportSpecifier = (
// Collect all aliases for the method
methodSpecifiers.forEach((specifier) => {
if (specifier.local && specifier.local.name !== methodName) {
if (specifier.local && specifier.local.name !== oldMethodName) {
methodAliases.push(specifier.local.name);
} else {
methodAliases.push(methodName);
methodAliases.push(methodNameToReplace);
}
});
// Remove the method specifiers from the old import
const updatedSpecifiers = importDeclaration.specifiers?.filter(
(specifier) =>
specifier.type !== 'ImportSpecifier' || specifier.imported.name !== methodName
specifier.type !== 'ImportSpecifier' || specifier.imported.name !== oldMethodName
);
if (updatedSpecifiers && updatedSpecifiers.length > 0) {
@ -63,7 +69,10 @@ export const changeImportSpecifier = (
const importDeclaration: ImportDeclaration = path.node;
methodAliases.forEach((alias) => {
const newSpecifier = j.importSpecifier(j.identifier(methodName), j.identifier(alias));
const newSpecifier = j.importSpecifier(
j.identifier(methodNameToReplace),
j.identifier(alias)
);
const specifiersArray = importDeclaration.specifiers || [];
j(path).replaceWith(
j.importDeclaration([...specifiersArray, newSpecifier], j.literal(newDependency))
@ -72,7 +81,7 @@ export const changeImportSpecifier = (
});
} else {
const newSpecifiers = methodAliases.map((alias) =>
j.importSpecifier(j.identifier(methodName), j.identifier(alias))
j.importSpecifier(j.identifier(methodNameToReplace), j.identifier(alias))
);
const newImportDeclaration = j.importDeclaration(newSpecifiers, j.literal(newDependency));

View File

@ -0,0 +1,49 @@
import type { JSCodeshift, Collection } from 'jscodeshift';
export const replaceJSXElement = (
root: Collection,
j: JSCodeshift,
{
oldElementName,
newElementName,
oldDependency,
}: {
oldElementName: string;
newElementName: string;
oldDependency: string;
}
) => {
// Find the import declaration for the old dependency
const importDeclaration = root.find(j.ImportDeclaration, {
source: { value: oldDependency },
});
if (importDeclaration.size() === 0) {
return;
}
// Get the local name of the imported element
const localName = importDeclaration
.find(j.ImportSpecifier, {
imported: { name: oldElementName },
})
.nodes()[0]?.local?.name;
if (!localName) {
return;
}
// Replace JSX elements
root.findJSXElements(localName).forEach((path) => {
const openingElement = path.node.openingElement;
const closingElement = path.node.closingElement;
if (j.JSXIdentifier.check(openingElement.name)) {
openingElement.name.name = newElementName;
}
if (closingElement && j.JSXIdentifier.check(closingElement.name)) {
closingElement.name.name = newElementName;
}
});
};