mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-03-27 03:31:53 +00:00
chore: add translation cleanup tooling and remove unused keys
- Add check-unused-translations.js script for detecting unused i18n keys - Remove unused player keys: refresh_tracks, audio_tracks, playback_state, index - Remove unused aspect_ratio section (7 keys) - Update copilot-instructions.md with i18n guidelines (only edit en.json, Crowdin handles other languages)
This commit is contained in:
121
scripts/check-unused-translations.js
Normal file
121
scripts/check-unused-translations.js
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Check for unused translation keys in en.json
|
||||
* Usage: bun run scripts/check-unused-translations.js [--remove]
|
||||
*/
|
||||
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const { execSync } = require("node:child_process");
|
||||
|
||||
const TRANSLATION_FILE = path.join(__dirname, "../translations/en.json");
|
||||
const REMOVE_UNUSED = process.argv.includes("--remove");
|
||||
|
||||
// Read translation file
|
||||
const translations = JSON.parse(fs.readFileSync(TRANSLATION_FILE, "utf8"));
|
||||
|
||||
// Flatten nested keys
|
||||
function flattenKeys(obj, prefix = "") {
|
||||
let keys = [];
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
const fullKey = prefix ? `${prefix}.${key}` : key;
|
||||
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
||||
keys = keys.concat(flattenKeys(value, fullKey));
|
||||
} else {
|
||||
keys.push(fullKey);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
// Search for key usage in codebase
|
||||
function isKeyUsed(key) {
|
||||
try {
|
||||
// Escape special regex characters in the key
|
||||
const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
|
||||
// Search in TypeScript/TSX files
|
||||
const result = execSync(
|
||||
`git grep -l "${escapedKey}" -- "*.ts" "*.tsx" 2>nul || echo ""`,
|
||||
{
|
||||
encoding: "utf8",
|
||||
cwd: path.join(__dirname, ".."),
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
},
|
||||
).trim();
|
||||
|
||||
return result.length > 0;
|
||||
} catch (_error) {
|
||||
// If grep fails, assume key is used to be safe
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove nested key from object
|
||||
function removeNestedKey(obj, keyPath) {
|
||||
const keys = keyPath.split(".");
|
||||
const lastKey = keys.pop();
|
||||
let current = obj;
|
||||
|
||||
for (const key of keys) {
|
||||
if (!current[key]) return false;
|
||||
current = current[key];
|
||||
}
|
||||
|
||||
if (current[lastKey] !== undefined) {
|
||||
delete current[lastKey];
|
||||
|
||||
// Clean up empty parent objects
|
||||
if (Object.keys(current).length === 0 && keys.length > 0) {
|
||||
removeNestedKey(obj, keys.join("."));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log("🔍 Checking for unused translation keys...\n");
|
||||
|
||||
const allKeys = flattenKeys(translations);
|
||||
const unusedKeys = [];
|
||||
|
||||
for (const key of allKeys) {
|
||||
if (!isKeyUsed(key)) {
|
||||
unusedKeys.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (unusedKeys.length === 0) {
|
||||
console.log("✅ All translation keys are being used!");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
console.log(`Found ${unusedKeys.length} unused translation keys:\n`);
|
||||
for (const key of unusedKeys) {
|
||||
console.log(` ❌ ${key}`);
|
||||
}
|
||||
|
||||
if (REMOVE_UNUSED) {
|
||||
console.log("\n🗑️ Removing unused keys...");
|
||||
|
||||
let removed = 0;
|
||||
for (const key of unusedKeys) {
|
||||
if (removeNestedKey(translations, key)) {
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Write back to file
|
||||
fs.writeFileSync(
|
||||
TRANSLATION_FILE,
|
||||
`${JSON.stringify(translations, null, 2)}\n`,
|
||||
"utf8",
|
||||
);
|
||||
|
||||
console.log(`✅ Removed ${removed} unused translation keys from en.json`);
|
||||
} else {
|
||||
console.log("\n💡 Run with --remove flag to remove these keys from en.json");
|
||||
console.log(
|
||||
" Example: bun run scripts/check-unused-translations.js --remove",
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user