MCPcopy Create free account
hub / github.com/callumalpass/tasknotes / findUnused

Function findUnused

scripts/i18n-manager.mjs:534–602  ·  view source on GitHub ↗

`find-unused`: Finds translation keys in en.ts that are not used in the source code

()

Source from the content-addressed store, hash-verified

532
533/** `find-unused`: Finds translation keys in en.ts that are not used in the source code */
534async function findUnused() {
535 console.log('Finding unused translation keys...\n');
536
537 const manifest = loadJson(MANIFEST_PATH);
538
539 if (Object.keys(manifest).length === 0) {
540 console.error('❌ Error: No manifest found. Run "npm run i18n:sync" first.');
541 process.exit(1);
542 }
543
544 // Get all keys from manifest
545 const allKeys = Object.keys(manifest);
546
547 // Find all translation function calls in the codebase
548 const patterns = [
549 `rg --no-filename --no-heading --no-line-number '\\bt\\(["\\x27]([^"\\x27]+)["\\x27]\\)' -o -r '\$1' src/`,
550 `rg --no-filename --no-heading --no-line-number 'i18n\\.translate\\(["\\x27]([^"\\x27]+)["\\x27]' -o -r '\$1' src/`,
551 `rg --no-filename --no-heading --no-line-number 'this\\.t\\(["\\x27]([^"\\x27]+)["\\x27]' -o -r '\$1' src/`,
552 `rg --no-filename --no-heading --no-line-number 'this\\.translate\\(["\\x27]([^"\\x27]+)["\\x27]' -o -r '\$1' src/`,
553 `rg --no-filename --no-heading --no-line-number '\\btranslate\\(["\\x27]([^"\\x27]+)["\\x27]' -o -r '\$1' src/`
554 ];
555
556 const usedKeys = new Set();
557
558 for (const pattern of patterns) {
559 try {
560 const output = execSync(pattern, { encoding: 'utf8', shell: '/bin/bash' });
561 output.trim().split('\n').filter(Boolean).forEach(key => usedKeys.add(key));
562 } catch (error) {
563 // No matches is fine
564 }
565 }
566
567 // Find keys in manifest but not used in source
568 const unusedKeys = allKeys.filter(key => !usedKeys.has(key));
569
570 console.log(`📊 Statistics:`);
571 console.log(` Total keys in en.ts: ${allKeys.length}`);
572 console.log(` Keys found in source code: ${usedKeys.size}`);
573 console.log(` Potentially unused keys: ${unusedKeys.length}`);
574 console.log(` Coverage: ${Math.round((usedKeys.size / allKeys.length) * 100)}%\n`);
575
576 if (unusedKeys.length > 0) {
577 console.log('⚠️ Potentially unused keys (not found in source code):\n');
578
579 // Group by prefix for easier reading
580 const grouped = {};
581 unusedKeys.forEach(key => {
582 const prefix = key.split('.')[0];
583 if (!grouped[prefix]) grouped[prefix] = [];
584 grouped[prefix].push(key);
585 });
586
587 for (const [prefix, keys] of Object.entries(grouped).sort()) {
588 console.log(`[${prefix}] ${keys.length} keys:`);
589 keys.forEach(key => console.log(` - ${key}`));
590 console.log('');
591 }

Callers 1

i18n-manager.mjsFile · 0.85

Calls 3

loadJsonFunction · 0.85
errorMethod · 0.80
hasMethod · 0.80

Tested by

no test coverage detected