localize-ai
Advanced tools
| export {}; | ||
| //# sourceMappingURL=deleteSync.d.ts.map |
| {"version":3,"file":"deleteSync.d.ts","sourceRoot":"","sources":["../../src/scripts/deleteSync.ts"],"names":[],"mappings":""} |
| import fs from "fs"; | ||
| import path from "path"; | ||
| import * as parser from "@babel/parser"; | ||
| import traverseModule from "@babel/traverse"; | ||
| import * as t from "@babel/types"; | ||
| const traverse = traverseModule.default; | ||
| const ROOT = process.cwd(); | ||
| const SRC_DIR = path.join(ROOT, "src"); | ||
| const EXTRACTED_FILE = path.join(ROOT, "extractedText.json"); | ||
| const CLEANED_FILE = path.join(ROOT, "cleaned_strings.json"); | ||
| // 👇 translations folder (you can adjust if needed) | ||
| const PUBLIC_DIR = path.join(ROOT, "public"); | ||
| // 🔥 normalize (same as runtime) | ||
| function normalize(text) { | ||
| return text.trim(); | ||
| } | ||
| // 🔥 collect current keys from AST | ||
| function extractKeys() { | ||
| const usedKeys = new Set(); | ||
| function scanDir(dir) { | ||
| const files = fs.readdirSync(dir); | ||
| for (const file of files) { | ||
| const fullPath = path.join(dir, file); | ||
| if (fs.statSync(fullPath).isDirectory()) { | ||
| scanDir(fullPath); | ||
| } | ||
| else if (/\.(tsx|jsx|ts|js)$/.test(file)) { | ||
| const content = fs.readFileSync(fullPath, "utf-8"); | ||
| try { | ||
| const ast = parser.parse(content, { | ||
| sourceType: "module", | ||
| plugins: ["jsx", "typescript"], | ||
| }); | ||
| traverse(ast, { | ||
| CallExpression(path) { | ||
| const { callee, arguments: args } = path.node; | ||
| if (!t.isIdentifier(callee) || callee.name !== "t") | ||
| return; | ||
| const firstArg = args[0]; | ||
| if (!firstArg) | ||
| return; | ||
| let value = null; | ||
| if (t.isStringLiteral(firstArg)) { | ||
| value = firstArg.value; | ||
| } | ||
| else if (t.isTemplateLiteral(firstArg)) { | ||
| if (firstArg.expressions.length > 0) | ||
| return; | ||
| value = firstArg.quasis | ||
| .map((q) => q.value.cooked || "") | ||
| .join(""); | ||
| } | ||
| if (!value) | ||
| return; | ||
| usedKeys.add(normalize(value)); | ||
| }, | ||
| }); | ||
| } | ||
| catch { | ||
| console.warn(`⚠️ Failed parsing ${fullPath}`); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| scanDir(SRC_DIR); | ||
| return usedKeys; | ||
| } | ||
| // 🔥 remove unused keys from JSON file | ||
| function cleanJsonFile(filePath, usedKeys) { | ||
| if (!fs.existsSync(filePath)) | ||
| return 0; | ||
| const data = JSON.parse(fs.readFileSync(filePath, "utf-8")); | ||
| let updated; | ||
| let removedCount = 0; | ||
| if (Array.isArray(data)) { | ||
| const before = data.length; | ||
| updated = data.filter((key) => usedKeys.has(normalize(key))); | ||
| removedCount = before - updated.length; | ||
| } | ||
| else { | ||
| const before = Object.keys(data).length; | ||
| updated = Object.fromEntries(Object.entries(data).filter(([key]) => usedKeys.has(normalize(key)))); | ||
| const after = Object.keys(updated).length; | ||
| removedCount = before - after; | ||
| } | ||
| fs.writeFileSync(filePath, JSON.stringify(updated, null, 2)); | ||
| return removedCount; | ||
| } | ||
| // 🔥 main runner | ||
| function run() { | ||
| console.log("🔍 Scanning codebase..."); | ||
| const usedKeys = extractKeys(); | ||
| console.log(`✅ Found ${usedKeys.size} active keys\n`); | ||
| let totalRemoved = 0; | ||
| function logResult(filePath, removed) { | ||
| const name = path.basename(filePath); | ||
| if (removed > 0) { | ||
| console.log(`🧹 ${name} → removed ${removed} keys`); | ||
| totalRemoved += removed; | ||
| } | ||
| else { | ||
| console.log(`✅ ${name} → no changes`); | ||
| } | ||
| } | ||
| // extracted files | ||
| logResult(EXTRACTED_FILE, cleanJsonFile(EXTRACTED_FILE, usedKeys)); | ||
| logResult(CLEANED_FILE, cleanJsonFile(CLEANED_FILE, usedKeys)); | ||
| // translations | ||
| if (fs.existsSync(PUBLIC_DIR)) { | ||
| const files = fs.readdirSync(PUBLIC_DIR); | ||
| files.forEach((file) => { | ||
| if (/^translations_.*\.json$/.test(file)) { | ||
| const fullPath = path.join(PUBLIC_DIR, file); | ||
| logResult(fullPath, cleanJsonFile(fullPath, usedKeys)); | ||
| } | ||
| }); | ||
| } | ||
| console.log("\n🚀 Delete sync completed!"); | ||
| if (totalRemoved > 0) { | ||
| console.log(`🔥 Total removed keys: ${totalRemoved}`); | ||
| } | ||
| else { | ||
| console.log("✨ No unused keys found"); | ||
| } | ||
| } | ||
| run(); | ||
| //# sourceMappingURL=deleteSync.js.map |
| {"version":3,"file":"deleteSync.js","sourceRoot":"","sources":["../../src/scripts/deleteSync.ts"],"names":[],"mappings":"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"} |
+5
-0
@@ -12,2 +12,7 @@ #!/usr/bin/env node | ||
| } | ||
| else if (command === "delete-sync") { | ||
| const deletePath = path.join(__dirname, "scripts", "deleteSync.js"); | ||
| execSync(`node "${deletePath}"`, { stdio: "inherit" }); | ||
| console.log("✅ Done"); | ||
| } | ||
| else if (command === "translate") { | ||
@@ -14,0 +19,0 @@ console.log("🚀 Running localization pipeline..."); |
+1
-1
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;IACvB,qBAAqB,EAAE,CAAC;AAC1B,CAAC;KACI,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IAEnD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,sBAAsB,CAAC,CAAC;IAC1E,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAEtE,QAAQ,CAAC,SAAS,WAAW,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACxD,QAAQ,CAAC,SAAS,SAAS,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACtD,QAAQ,CAAC,SAAS,aAAa,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAE1D,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACxB,CAAC;KACI,CAAC;IACJ,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AACnC,CAAC"} | ||
| {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;IACvB,qBAAqB,EAAE,CAAC;AAC1B,CAAC;KACI,IAAI,OAAO,KAAK,aAAa,EAAC,CAAC;IAClC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;IACpE,QAAQ,CAAC,SAAS,UAAU,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAEvD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAExB,CAAC;KACI,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IAEnD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,sBAAsB,CAAC,CAAC;IAC1E,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAEtE,QAAQ,CAAC,SAAS,WAAW,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACxD,QAAQ,CAAC,SAAS,SAAS,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACtD,QAAQ,CAAC,SAAS,aAAa,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAE1D,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACxB,CAAC;KACI,CAAC;IACJ,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AACnC,CAAC"} |
| export declare function useTranslation(): { | ||
| t: (key: string) => string; | ||
| t: (key: string, vars?: Record<string, any>) => string; | ||
| setLang: (lang: string) => void; | ||
@@ -4,0 +4,0 @@ lang: string; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"useTranslations.d.ts","sourceRoot":"","sources":["../../src/hooks/useTranslations.ts"],"names":[],"mappings":"AAGA,wBAAgB,cAAc;aASZ,MAAM,KAAG,MAAM;;;;EAShC"} | ||
| {"version":3,"file":"useTranslations.d.ts","sourceRoot":"","sources":["../../src/hooks/useTranslations.ts"],"names":[],"mappings":"AASA,wBAAgB,cAAc;aA6BZ,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,MAAM;;;;EAY5D"} |
| import { useContext } from "react"; | ||
| import LanguageContext from "../context/LanguageContext.js"; | ||
| // 🔥 SAME NORMALIZER (IMPORTANT — MUST MATCH EXTRACTOR) | ||
| function normalize(text) { | ||
| return text | ||
| .trim(); | ||
| } | ||
| export function useTranslation() { | ||
@@ -9,10 +14,23 @@ const context = useContext(LanguageContext); | ||
| const { lang, translations, setLang, supportedLangs } = context; | ||
| function t(key) { | ||
| const entry = translations[key]; | ||
| if (!entry) | ||
| return key; | ||
| return entry; | ||
| function interpolate(text, vars) { | ||
| if (!vars) | ||
| return text; | ||
| return text.replace(/{{(.*?)}}/g, (_, key) => { | ||
| const value = vars[key.trim()]; | ||
| if (value === undefined) { | ||
| console.warn(`⚠️ Missing variable: ${key}`); | ||
| return `{{${key}}}`; | ||
| } | ||
| return String(value); | ||
| }); | ||
| } | ||
| function t(key, vars) { | ||
| const normalizedKey = normalize(key); | ||
| const baseText = translations[normalizedKey] || | ||
| translations[key] || | ||
| key; | ||
| return interpolate(baseText, vars); | ||
| } | ||
| return { t, setLang, lang, supportedLangs }; | ||
| } | ||
| //# sourceMappingURL=useTranslations.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"useTranslations.js","sourceRoot":"","sources":["../../src/hooks/useTranslations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,eAAe,MAAM,+BAA+B,CAAC;AAE5D,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAE5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAEhE,SAAS,CAAC,CAAC,GAAW;QACpB,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAEhC,IAAI,CAAC,KAAK;YAAE,OAAO,GAAG,CAAC;QAEvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;AAC9C,CAAC"} | ||
| {"version":3,"file":"useTranslations.js","sourceRoot":"","sources":["../../src/hooks/useTranslations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,eAAe,MAAM,+BAA+B,CAAC;AAE5D,wDAAwD;AACxD,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI;SACR,IAAI,EAAE,CAAA;AACX,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAE5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAEhE,SAAS,WAAW,CAClB,IAAY,EACZ,IAA0B;QAE1B,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QAEvB,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YAE/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;gBAC5C,OAAO,KAAK,GAAG,IAAI,CAAC;YACtB,CAAC;YAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,CAAC,GAAW,EAAE,IAA0B;QAChD,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAErC,MAAM,QAAQ,GACZ,YAAY,CAAC,aAAa,CAAC;YAC3B,YAAY,CAAC,GAAG,CAAC;YACjB,GAAG,CAAC;QAEN,OAAO,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;AAC9C,CAAC"} |
@@ -7,12 +7,8 @@ import fs from "fs"; | ||
| function isValid(text) { | ||
| if (!text || text.length < 3) | ||
| if (!text || text.length < 2) | ||
| return false; | ||
| if (/^\d+$/.test(text)) | ||
| return false; | ||
| if (text.includes("@")) | ||
| if (/^[A-Z0-9-_]+$/.test(text)) | ||
| return false; | ||
| if (/^[^a-zA-Z]+$/.test(text)) | ||
| return false; | ||
| if (text.includes("\\\\")) | ||
| return false; | ||
| return true; | ||
@@ -19,0 +15,0 @@ } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"cleanTranslations.js","sourceRoot":"","sources":["../../src/scripts/cleanTranslations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;AACpD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;AAEvD,SAAS,OAAO,CAAC,IAAY;IAC3B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,GAAG,GAAa,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAElE,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAEpC,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE3D,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC"} | ||
| {"version":3,"file":"cleanTranslations.js","sourceRoot":"","sources":["../../src/scripts/cleanTranslations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;AACpD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;AAEvD,SAAS,OAAO,CAAC,IAAY;IAC3B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,GAAG,GAAa,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAElE,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAEpC,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE3D,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC"} |
| import fs from "fs"; | ||
| import path from "path"; | ||
| const ROOT = process.cwd(); // ✅ user project | ||
| import * as parser from "@babel/parser"; | ||
| import traverseModule from "@babel/traverse"; | ||
| import * as t from "@babel/types"; | ||
| const traverse = traverseModule.default; | ||
| const ROOT = process.cwd(); | ||
| const SRC_DIR = path.join(ROOT, "src"); | ||
@@ -11,2 +15,8 @@ const OUTPUT_FILE = path.join(ROOT, "extractedText.json"); | ||
| const newStrings = new Set(); | ||
| // 🔥 Normalize string (CRITICAL FIX) | ||
| function normalize(text) { | ||
| return text | ||
| .trim(); | ||
| } | ||
| // 🔥 Relaxed validation (FIXED) | ||
| function isValidText(text) { | ||
@@ -17,10 +27,56 @@ if (!text || text.length < 2) | ||
| return false; | ||
| if (text.includes("@")) | ||
| if (/^[A-Z0-9-_]+$/.test(text)) | ||
| return false; | ||
| if (/^[A-Z0-9-]+$/.test(text)) | ||
| return false; | ||
| if (/₹|\$|€/.test(text)) | ||
| return false; | ||
| return true; | ||
| } | ||
| function extractFromAST(content, filePath) { | ||
| try { | ||
| const ast = parser.parse(content, { | ||
| sourceType: "module", | ||
| plugins: ["jsx", "typescript"], | ||
| }); | ||
| traverse(ast, { | ||
| CallExpression(path) { | ||
| const { callee, arguments: args } = path.node; | ||
| if (!t.isIdentifier(callee) || callee.name !== "t") | ||
| return; | ||
| const firstArg = args[0]; | ||
| if (!firstArg) | ||
| return; | ||
| let extractedValue = null; | ||
| // ✅ STRING LITERAL | ||
| if (t.isStringLiteral(firstArg)) { | ||
| extractedValue = firstArg.value; | ||
| } | ||
| // ✅ TEMPLATE LITERAL | ||
| else if (t.isTemplateLiteral(firstArg)) { | ||
| // ❌ BLOCK dynamic template usage (IMPORTANT) | ||
| if (firstArg.expressions.length > 0) { | ||
| console.error(` | ||
| ❌ Invalid template literal detected | ||
| 📄 File: ${filePath} | ||
| 📍 Line: ${path.node.loc?.start.line} | ||
| 💡 Code: t(\`...\${}\`) | ||
| 👉 Fix: t("Text {{var}}", { var }) | ||
| `); | ||
| return; | ||
| } | ||
| extractedValue = firstArg.quasis | ||
| .map((q) => q.value.cooked || "") | ||
| .join(""); | ||
| } | ||
| if (!extractedValue) | ||
| return; | ||
| const normalizedText = normalize(extractedValue); | ||
| if (isValidText(normalizedText) && | ||
| !existingStrings.has(normalizedText)) { | ||
| newStrings.add(normalizedText); | ||
| } | ||
| }, | ||
| }); | ||
| } | ||
| catch { | ||
| console.warn(`⚠️ Failed to parse: ${filePath}`); | ||
| } | ||
| } | ||
| function scanDir(dir) { | ||
@@ -35,10 +91,3 @@ const files = fs.readdirSync(dir); | ||
| const content = fs.readFileSync(fullPath, "utf-8"); | ||
| const regex = /t\(\s*["'`]([^"'`]+)["'`]\s*(?:,\s*[a-zA-Z0-9_.]+)?\s*\)/g; | ||
| let match; | ||
| while ((match = regex.exec(content)) !== null) { | ||
| const text = match[1].trim(); | ||
| if (isValidText(text) && !existingStrings.has(text)) { | ||
| newStrings.add(text); | ||
| } | ||
| } | ||
| extractFromAST(content, fullPath); | ||
| } | ||
@@ -45,0 +94,0 @@ } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"extractText.js","sourceRoot":"","sources":["../../src/scripts/extractText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,iBAAiB;AAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAC,oBAAoB,CAAC,CAAC;AAEzD,IAAI,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;AAExC,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;IAC/B,eAAe,GAAG,IAAI,GAAG,CACvB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;AAErC,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAEtC,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACxC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpB,CAAC;aAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEnD,MAAM,KAAK,GACT,2DAA2D,CAAC;YAE9D,IAAI,KAA6B,CAAC;YAExC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;gBAE9B,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACpD,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;QACG,CAAC;IACH,CAAC;AACH,CAAC;AAED,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjB,MAAM,OAAO,GAAG,CAAC,GAAG,eAAe,EAAE,GAAG,UAAU,CAAC,CAAC;AAEpD,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAEhE,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,CAAC,IAAI,cAAc,CAAC,CAAC"} | ||
| {"version":3,"file":"extractText.js","sourceRoot":"","sources":["../../src/scripts/extractText.ts"],"names":[],"mappings":"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"} |
+5
-1
| { | ||
| "name": "localize-ai", | ||
| "version": "1.2.3", | ||
| "version": "1.3.0", | ||
| "description": "AI-powered React localization with context-aware translations, multi-provider support, lazy loading, and per-locale splitting", | ||
@@ -44,2 +44,5 @@ "main": "dist/index.js", | ||
| "dependencies": { | ||
| "@babel/parser": "^7.29.2", | ||
| "@babel/traverse": "^7.29.0", | ||
| "@babel/types": "^7.29.0", | ||
| "@google/generative-ai": "^0.24.1", | ||
@@ -53,2 +56,3 @@ "dotenv": "^17.3.1", | ||
| "devDependencies": { | ||
| "@types/babel__traverse": "^7.28.0", | ||
| "@types/node": "^25.5.0", | ||
@@ -55,0 +59,0 @@ "@types/react": "^19.2.14", |
+46
-9
@@ -18,3 +18,5 @@ # localize-ai | ||
| ### 🔧 Core | ||
| * 🔍 Auto-extract static text (`t("...")`) | ||
| * 🔍 AST-based extraction (no regex) | ||
| * 🧩 Supports template literals with variables | ||
| * 🧹 Removes unused (dead) translations automatically | ||
| * 🌍 AI-powered translations (OpenAI, Gemini) | ||
@@ -51,2 +53,22 @@ * ⚡ Incremental translation (only new strings/languages) | ||
| ### 🧠 Smart Extraction (AST-based) | ||
| Localize-ai uses AST parsing instead of regex, ensuring accurate extraction: | ||
| * Handles complex code patterns | ||
| * Supports template literals with variables | ||
| * Avoids false positives | ||
| Example: | ||
| ``` | ||
| t(`hello {{userName}}, your order {{id}} is ready`, { | ||
| userName, | ||
| id: orderId | ||
| }); | ||
| ``` | ||
| 👉 Variables are preserved and translated correctly. | ||
| --- | ||
| ## 📦 Installation | ||
@@ -142,4 +164,7 @@ | ||
| return <h1>{t("Hello world")}</h1>; | ||
| } | ||
| return ( | ||
| <p> | ||
| {t("Welcome back, {{name}}!", { name: userName })} | ||
| </p> | ||
| )} | ||
| ``` | ||
@@ -159,2 +184,18 @@ | ||
| ## 🧹 Dead Translation Cleanup | ||
| ``` | ||
| npx localize-ai delete-sync | ||
| ``` | ||
| Localize-ai automatically removes unused translations: | ||
| * Detects strings no longer present in code | ||
| * Cleans up translation files | ||
| Keeps JSON lean and optimized | ||
| 👉 Prevents bloated translation files over time. | ||
| --- | ||
| ## 🧠 How it works | ||
@@ -194,7 +235,3 @@ | ||
| { | ||
| "Get started": { | ||
| "en": "Get started", | ||
| "hi": "शुरू करें", | ||
| "fr": "Commencer" | ||
| } | ||
| "Get started": "शुरू करें" | ||
| } | ||
@@ -236,3 +273,3 @@ ``` | ||
| ### Core Improvements | ||
| * [ ] AST-based extraction (no regex) | ||
| * [x] AST-based extraction (no regex) | ||
| * [ ] Better error handling & retry logic for failed translations | ||
@@ -239,0 +276,0 @@ * [ ] CLI UX improvements (spinners, better logs) |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
64979
29.59%50
8.7%746
35.39%323
12.94%7
75%5
25%7
16.67%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added