UNPKG

cytoscape

Version:

Graph theory (a.k.a. network) library for analysis and visualisation

131 lines (111 loc) 4.07 kB
#!/usr/bin/env node import fs from 'fs'; import path from 'path'; import process from 'process'; // Adjust the base directory to match your project layout: const SRC_DIR = path.join(process.cwd(), 'test'); /** * Recursively gather all .mjs files in the given directory */ function getAllMjsFiles(dir) { let results = []; const list = fs.readdirSync(dir, { withFileTypes: true }); for (const dirent of list) { const fullPath = path.join(dir, dirent.name); if (dirent.isDirectory()) { // Recurse into subdirectories results = results.concat(getAllMjsFiles(fullPath)); } else if (dirent.isFile() && fullPath.endsWith('.mjs')) { results.push(fullPath); } } return results; } /** * Given an import path like '../../util', figure out if we should rewrite * to '../../util.mjs' or '../../util/index.mjs', based on what is present in the file system. */ function resolveImport(rawImportPath, currentFileDir) { // We only care about relative imports if (!rawImportPath.startsWith('.')) { // If it's not relative, leave it alone (e.g. 'react' or 'lodash') return rawImportPath; } // The path on disk relative to the current file const absoluteImportPath = path.resolve(currentFileDir, rawImportPath); // 1. Check if `absoluteImportPath.mjs` exists const candidateMjsFile = `${absoluteImportPath}.mjs`; if (fs.existsSync(candidateMjsFile)) { // Convert back to a relative path from the current file return pathRelativeWinSafe(currentFileDir, candidateMjsFile); } // 2. Check if `absoluteImportPath/index.mjs` exists const candidateIndexFile = path.join(absoluteImportPath, 'index.mjs'); if (fs.existsSync(candidateIndexFile)) { return pathRelativeWinSafe(currentFileDir, candidateIndexFile); } // If neither .mjs nor index.mjs exist, leave it unchanged (or optionally throw an error) return rawImportPath; } /** * Convert absolute path back to a relative path (with forward slashes on all platforms). * Because Node on Windows returns backslashes, which ESM imports won't like. */ function pathRelativeWinSafe(from, to) { let relPath = path.relative(from, to); // Replace backslashes with forward slashes relPath = relPath.replace(/\\/g, '/'); // Ensure it starts with '.' or '..' if it isn’t already if (!relPath.startsWith('.')) { relPath = `./${relPath}`; } return relPath; } /** * Perform the in-place rewrites for import statements in a single file. */ function rewriteImportsInFile(filePath) { const fileDir = path.dirname(filePath); let src = fs.readFileSync(filePath, 'utf8'); // Simple pattern capturing import statements of the form: // import ... from '...'; // This will NOT catch every possible ESM shape (e.g., multiline). Adapt as needed. const importRegex = /(\bimport\s+(?:[\s\S]+?)\s+from\s+['"])([^'"]+)(['"];)/g; let changed = false; src = src.replace(importRegex, (match, before, importPath, after) => { const newImportPath = resolveImport(importPath, fileDir); if (newImportPath !== importPath) { changed = true; return `${before}${newImportPath}${after}`; } return match; }); // Optionally, handle require() if needed: // const requireRegex = /(\brequire\s*\(\s*['"])([^'"]+)(['"]\s*\))/g; // src = src.replace(requireRegex, (match, before, importPath, after) => { // const newImportPath = resolveImport(importPath, fileDir); // if (newImportPath !== importPath) { // changed = true; // return `${before}${newImportPath}${after}`; // } // return match; // }); if (changed) { fs.writeFileSync(filePath, src, 'utf8'); console.log(`Updated imports in: ${filePath}`); } } /** * Main routine: * 1. Collect all .mjs files in src/ * 2. Rewrite their import statements */ function main() { const allMjsFiles = getAllMjsFiles(SRC_DIR); console.log(`Found ${allMjsFiles.length} .mjs files in ${SRC_DIR}.`); for (const filePath of allMjsFiles) { rewriteImportsInFile(filePath); } console.log('Done.'); } main();