Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
4.6 kB · 143 lines
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144const fs = require("fs");const path = require("path");
const wordSeparators = /[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]+/;const capital_plus_lower = /[A-ZÀ-Ý\u00C0-\u00D6\u00D9-\u00DD][a-zà-ÿ]/g;const capitals = /[A-Z0-9À-Ý\u00C0-\u00D6\u00D9-\u00DD]+/g;
function kebabCase(str) { let res = str; res = str.replace( capital_plus_lower, (match) => ` ${match[0].toLowerCase() || match[0]}${match[1]}`, ); res = res.replace(capitals, (match) => ` ${match.toLowerCase()}`); return res .trim() .split(wordSeparators) .join("-") .replace(/^-/, "") .replace(/-\s*$/, "");}
// Build icon name to file mapping from lucide's export filelet iconToFileMap;function getIconMapping(baseDir) { if (iconToFileMap) return iconToFileMap;
iconToFileMap = {};
try { // Walk up the directory tree to find node_modules let searchDir = baseDir; let lucideExportsPath; while (searchDir !== path.dirname(searchDir)) { const candidatePath = path.join( searchDir, "node_modules/lucide-react-native/dist/esm/lucide-react-native.js", ); if (fs.existsSync(candidatePath)) { lucideExportsPath = candidatePath; break; } searchDir = path.dirname(searchDir); }
if (!lucideExportsPath) { const err = new Error( `Could not find lucide-react-native/dist/esm/lucide-react-native.js in node_modules. Searched from: ${baseDir}`, ); console.error(err.message); throw err; }
const content = fs.readFileSync(lucideExportsPath, "utf8");
// Match lines like: export { default as User2, default as UserRound } from './icons/user-round.js'; // Split by lines and parse each line individually const lines = content.split("\n"); let matchCount = 0;
for (const line of lines) { // Use string indexOf/substring instead of regex if (line.includes("from './icons/") && line.includes("export {")) { const iconsIndex = line.indexOf("from './icons/"); if (iconsIndex === -1) continue;
const filenameStart = iconsIndex + "from './icons/".length; const filenameEnd = line.indexOf(".js'", filenameStart); if (filenameEnd === -1) continue;
const filename = line.substring(filenameStart, filenameEnd);
const exportsStart = line.indexOf("{") + 1; const exportsEnd = line.indexOf("}"); if (exportsStart === -1 || exportsEnd === -1) continue;
const exports = line.substring(exportsStart, exportsEnd); matchCount++;
// Extract all icon names from the export list const names = exports .split(",") .map((name) => name.trim()) .filter((name) => name.startsWith("default as ")) .map((name) => name.replace("default as ", "").trim());
// Map each name to the filename names.forEach((name) => { iconToFileMap[name] = filename; }); } } } catch (err) { console.error( "[lucide-transform] Failed to parse lucide exports, using hardcoded mappings:", err.message, ); // Keep the hardcoded mappings we initialized with }
return iconToFileMap;}
function lucideTransformPlugin({ types: t }) { return { visitor: { ImportDeclaration(path, state) { const source = path.node.source.value; if (source === "lucide-react-native") { const imports = []; const baseDir = state.file.opts.root || process.cwd(); const mapping = getIconMapping(baseDir);
path.node.specifiers.forEach((specifier) => { if (specifier.type === "ImportSpecifier") { const importedName = specifier.imported.name; const localName = specifier.local.name;
// Use the mapping if available, otherwise fall back to kebab-case const filename = mapping[importedName] || kebabCase(importedName);
// Create individual default import for each icon imports.push( t.importDeclaration( [t.importDefaultSpecifier(t.identifier(localName))], t.stringLiteral( `lucide-react-native/dist/esm/icons/${filename}`, ), ), ); } });
// Replace the original import with individual imports path.replaceWithMultiple(imports); } }, }, };}
module.exports = lucideTransformPlugin;