mirror of
https://github.com/strapi/strapi.git
synced 2025-10-29 17:04:13 +00:00
Add codemod for useRBAC import statement (#21023)
* feat: add codemode for useRBAC import statement * fix: add admin and server as allowed root paths * fix: preserve aliases and add import statetment after other import statements * feat: change useAPIErrorHandler import to `@strapi/strapi/admin` codemod (#21025) * enhancement: abstract changeImportSpecifier as a utility method * fix: account for multiple aliases
This commit is contained in:
parent
1467b8f3ff
commit
a2eac9d891
21
packages/utils/upgrade/resources/codemods/5.0.0/change-useAPIErrorHandler-import.code.ts
vendored
Normal file
21
packages/utils/upgrade/resources/codemods/5.0.0/change-useAPIErrorHandler-import.code.ts
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import type { Transform } from 'jscodeshift';
|
||||
import { changeImportSpecifier } from '../../utils/change-import';
|
||||
|
||||
/**
|
||||
* change useAPIErrorHandler import from '@strapi/helper-plugin' to '@strapi/strapi/admin'
|
||||
*/
|
||||
const transform: Transform = (file, api) => {
|
||||
const { j } = api;
|
||||
|
||||
const root = j.withParser('tsx')(file.source);
|
||||
|
||||
changeImportSpecifier(root, j, {
|
||||
methodName: 'useAPIErrorHandler',
|
||||
oldDependency: '@strapi/helper-plugin',
|
||||
newDependency: '@strapi/strapi/admin',
|
||||
});
|
||||
|
||||
return root.toSource();
|
||||
};
|
||||
|
||||
export default transform;
|
||||
21
packages/utils/upgrade/resources/codemods/5.0.0/useRBAC-hook-import-change.code.ts
vendored
Normal file
21
packages/utils/upgrade/resources/codemods/5.0.0/useRBAC-hook-import-change.code.ts
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import type { Transform } from 'jscodeshift';
|
||||
import { changeImportSpecifier } from '../../utils/change-import';
|
||||
|
||||
/**
|
||||
* change useRBAC import from '@strapi/helper-plugin' to '@strapi/strapi/admin'
|
||||
*/
|
||||
const transform: Transform = (file, api) => {
|
||||
const { j } = api;
|
||||
|
||||
const root = j.withParser('tsx')(file.source);
|
||||
|
||||
changeImportSpecifier(root, j, {
|
||||
methodName: 'useRBAC',
|
||||
oldDependency: '@strapi/helper-plugin',
|
||||
newDependency: '@strapi/strapi/admin',
|
||||
});
|
||||
|
||||
return root.toSource();
|
||||
};
|
||||
|
||||
export default transform;
|
||||
96
packages/utils/upgrade/resources/utils/change-import.ts
Normal file
96
packages/utils/upgrade/resources/utils/change-import.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import type { ImportDeclaration, JSCodeshift, Collection } from 'jscodeshift';
|
||||
|
||||
export const changeImportSpecifier = (
|
||||
root: Collection,
|
||||
j: JSCodeshift,
|
||||
options: { methodName: string; oldDependency: string; newDependency: string }
|
||||
): void => {
|
||||
const { methodName, oldDependency, newDependency } = options;
|
||||
|
||||
// Flag to check if the method was imported from the old dependency
|
||||
let methodImportedFromOldDependency = false;
|
||||
const methodAliases: string[] = [];
|
||||
|
||||
// Remove the method from the old dependency and check if it was imported
|
||||
root
|
||||
.find(j.ImportDeclaration)
|
||||
.filter((path) => path.node.source.value === oldDependency)
|
||||
.forEach((path) => {
|
||||
const importDeclaration: ImportDeclaration = path.node;
|
||||
|
||||
// Check if the method is imported from the old dependency
|
||||
const methodSpecifiers = importDeclaration.specifiers?.filter(
|
||||
(specifier) =>
|
||||
specifier.type === 'ImportSpecifier' && specifier.imported.name === methodName
|
||||
);
|
||||
|
||||
if (methodSpecifiers && methodSpecifiers.length > 0) {
|
||||
methodImportedFromOldDependency = true;
|
||||
|
||||
// Collect all aliases for the method
|
||||
methodSpecifiers.forEach((specifier) => {
|
||||
if (specifier.local && specifier.local.name !== methodName) {
|
||||
methodAliases.push(specifier.local.name);
|
||||
} else {
|
||||
methodAliases.push(methodName);
|
||||
}
|
||||
});
|
||||
|
||||
// Remove the method specifiers from the old import
|
||||
const updatedSpecifiers = importDeclaration.specifiers?.filter(
|
||||
(specifier) =>
|
||||
specifier.type !== 'ImportSpecifier' || specifier.imported.name !== methodName
|
||||
);
|
||||
|
||||
if (updatedSpecifiers && updatedSpecifiers.length > 0) {
|
||||
// Replace the import with the updated specifiers if there are other imports left
|
||||
j(path).replaceWith(j.importDeclaration(updatedSpecifiers, j.literal(oldDependency)));
|
||||
} else {
|
||||
// Remove the entire import statement if the specified method was the only import
|
||||
j(path).remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add new import dependency if the method was imported from the old dependency
|
||||
if (methodImportedFromOldDependency) {
|
||||
const dependencies = root
|
||||
.find(j.ImportDeclaration)
|
||||
.filter((path) => path.node.source.value === newDependency);
|
||||
|
||||
if (dependencies.length > 0) {
|
||||
dependencies.forEach((path) => {
|
||||
const importDeclaration: ImportDeclaration = path.node;
|
||||
|
||||
methodAliases.forEach((alias) => {
|
||||
const newSpecifier = j.importSpecifier(j.identifier(methodName), j.identifier(alias));
|
||||
const specifiersArray = importDeclaration.specifiers || [];
|
||||
j(path).replaceWith(
|
||||
j.importDeclaration([...specifiersArray, newSpecifier], j.literal(newDependency))
|
||||
);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const newSpecifiers = methodAliases.map((alias) =>
|
||||
j.importSpecifier(j.identifier(methodName), j.identifier(alias))
|
||||
);
|
||||
|
||||
const newImportDeclaration = j.importDeclaration(newSpecifiers, j.literal(newDependency));
|
||||
|
||||
// Find the index of the first non-import declaration
|
||||
const body = root.get().node.program.body;
|
||||
const lastImportIndex = body.findIndex((node) => node.type !== 'ImportDeclaration');
|
||||
|
||||
if (lastImportIndex > -1) {
|
||||
// Insert the new import declaration just before the first non-import node
|
||||
body.splice(lastImportIndex, 0, newImportDeclaration);
|
||||
} else {
|
||||
// Check if 'use strict' exists at the beginning
|
||||
const hasUseStrict =
|
||||
body[0]?.type === 'ExpressionStatement' && body[0]?.expression?.value === 'use strict';
|
||||
// Add the new import after 'use strict' if it exists, otherwise at the beginning
|
||||
body.splice(hasUseStrict ? 1 : 0, 0, newImportDeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
export const PROJECT_PACKAGE_JSON = 'package.json';
|
||||
|
||||
export const PROJECT_DEFAULT_ALLOWED_ROOT_PATHS = ['src', 'config', 'public'];
|
||||
export const PROJECT_DEFAULT_ALLOWED_ROOT_PATHS = ['src', 'config', 'public', 'admin', 'server'];
|
||||
|
||||
export const PROJECT_DEFAULT_CODE_EXTENSIONS = [
|
||||
// Source files
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user