import { API, Collection, FileInfo, Identifier, JSXElement, MemberExpression } from 'jscodeshift'; import { getComponent, geComponentKey, getFlexVariable, getCallExpressions, getDOMWarnings } from '../../utils/parse'; import { Operation } from '../../types/transformer'; import { generateUID } from '../../utils/helper'; import { MigrateReport, TransformError, UIConfig, GenericWarning } from '../../types/runner'; import { saveTempData } from '../../utils/file'; import { modifyAST } from '../../utils/transform'; export default async (file: FileInfo, api: API, options: { reportDir: string }): Promise => { const errors: TransformError[] = []; const uiConfig: UIConfig = { components: {}, }; const modifiedFiles = []; const warnings: GenericWarning[] = []; let warningMessages: string[] = []; let root!: Collection; try { const j = api.jscodeshift; root = j(file.source); warningMessages = getDOMWarnings(root, j); if (warningMessages.length > 0) { warnings.push({ file: file.path, messages: warningMessages, }); } const flexVariable = getFlexVariable(root, j); if (flexVariable) { const callExpressions = getCallExpressions(flexVariable, root, j); callExpressions.forEach((expr) => { const originalArgs = expr.node.arguments || []; const calleeNode = expr.node.callee as MemberExpression; const operation = (calleeNode.property as Identifier)?.name as Operation; const customComponentHint = getComponent(calleeNode) as string; const customComponentJSX = originalArgs.find((ex) => ex.type === 'JSXElement') as JSXElement; const componentKey = geComponentKey(customComponentJSX) || generateUID(); if (!Object.values(Operation).includes(operation)) { return; } if (!customComponentHint) { throw new Error('Unable to find the Dynamic Component usage'); } modifyAST(operation, uiConfig, componentKey, customComponentHint, originalArgs, flexVariable, expr, j); }); } } catch (e: any) { errors.push({ file: file.path, message: e.message, }); } const updatedSource = root.toSource(); if (updatedSource !== file.source) { modifiedFiles.push(file.path); } await saveTempData( { modifiedFiles, uiConfig, domManipulation: warnings, errors, }, options.reportDir, ); return updatedSource; };