Files
2026-09-05 12:31:25 +05:30

80 lines
3.7 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const srcAppDir = path.join(__dirname, 'src', 'app');
// 1. Walk through all files and add "use client" and replace react-router-dom
function walkDir(dir, callback) {
fs.readdirSync(dir).forEach(f => {
const dirPath = path.join(dir, f);
const isDirectory = fs.statSync(dirPath).isDirectory();
if (isDirectory) {
walkDir(dirPath, callback);
} else {
callback(path.join(dir, f));
}
});
}
walkDir(srcAppDir, (filePath) => {
if (filePath.endsWith('.tsx') || filePath.endsWith('.ts')) {
let content = fs.readFileSync(filePath, 'utf8');
// Add "use client" if it's a React component or hook and doesn't have it
if (!content.includes('"use client"') && !content.includes("'use client'")) {
// Just add to all ts/tsx files for now except layout.tsx and page.tsx
if (!filePath.endsWith('layout.tsx') && filePath !== path.join(srcAppDir, 'page.tsx')) {
content = '"use client";\n' + content;
}
}
// Replace react-router-dom imports
if (content.includes('react-router-dom')) {
// Link
content = content.replace(/import\s+{[^}]*Link[^}]*}\s+from\s+['"]react-router-dom['"];?/g, "import Link from 'next/link';");
// useNavigate
content = content.replace(/useNavigate/g, 'useRouter');
content = content.replace(/import\s+{[^}]*useRouter[^}]*}\s+from\s+['"]react-router-dom['"];?/g, "import { useRouter } from 'next/navigation';");
// useLocation -> usePathname, useSearchParams
if (content.includes('useLocation')) {
content = content.replace(/useLocation/g, 'usePathname'); // naive replacement, will need manual fixing if they use location.search
content = content.replace(/import\s+{[^}]*usePathname[^}]*}\s+from\s+['"]react-router-dom['"];?/g, "import { usePathname } from 'next/navigation';");
}
// General fallback if multiple imports were in one line
content = content.replace(/import\s+{(.*)}\s+from\s+['"]react-router-dom['"];?/g, (match, p1) => {
let imports = p1.split(',').map(s => s.trim());
let nextNav = [];
let hasLink = false;
imports.forEach(i => {
if (i === 'Link') hasLink = true;
else if (i === 'useNavigate') nextNav.push('useRouter');
else if (i === 'useLocation') nextNav.push('usePathname', 'useSearchParams');
});
let res = '';
if (hasLink) res += "import Link from 'next/link';\n";
if (nextNav.length > 0) res += `import { ${[...new Set(nextNav)].join(', ')} } from 'next/navigation';\n`;
return res;
});
}
// Replace <Link to="..."> with <Link href="...">
content = content.replace(/<Link([^>]+)to=/g, '<Link$1href=');
// Remove lucide-react if not installed (they are in the old project, let's assume they'll install it)
// Fix asset imports (e.g. import bg from '@/assets/landing/...')
// We moved assets to public/landing/...
// Let's replace '@/assets/landing/...' with '/landing/...'
content = content.replace(/import\s+(\w+)\s+from\s+['"]@\/assets\/landing\/([^'"]+)['"];?/g, 'const $1 = "/landing/$2";');
// Also replace "../../assets/landing"
content = content.replace(/import\s+(\w+)\s+from\s+['"]\.\.\/\.\.\/assets\/landing\/([^'"]+)['"];?/g, 'const $1 = "/landing/$2";');
content = content.replace(/import\s+(\w+)\s+from\s+['"]\.\.\/assets\/landing\/([^'"]+)['"];?/g, 'const $1 = "/landing/$2";');
fs.writeFileSync(filePath, content, 'utf8');
}
});
console.log('Migration script completed.');