1+ const glob = require ( 'fast-glob' ) ;
2+ const fs = require ( 'fs' ) ;
3+ const path = require ( 'path' ) ;
4+
5+ const KEY_REGEX = / ( [ ' ` ] ) \$ \. ( \w + (?: \. \w + ) + ) (? = ; ; | \1| $ ) / g;
6+ const LOCALE_FILE = path . resolve ( 'locales/en_us.json' ) ;
7+ const SRC_FILES = glob . sync ( [ 'src/**/*.ts' ] , { dot : false } ) ;
8+
9+ const localeData = JSON . parse ( fs . readFileSync ( LOCALE_FILE , 'utf-8' ) ) ;
10+ const flatLocaleKeys = flattenKeys ( localeData ) ;
11+ const usedKeysMap = new Map ( ) ;
12+
13+ for ( const file of SRC_FILES ) {
14+ const content = fs . readFileSync ( file , 'utf-8' ) ;
15+ let match ;
16+ while ( ( match = KEY_REGEX . exec ( content ) ) !== null ) {
17+ const key = match [ 2 ] ;
18+ if ( ! usedKeysMap . has ( key ) ) usedKeysMap . set ( key , new Set ( ) ) ;
19+ usedKeysMap . get ( key ) . add ( file ) ;
20+ }
21+ }
22+
23+ const usedKeys = [ ...usedKeysMap . keys ( ) ] ;
24+ const missingKeys = usedKeys . filter ( ( key ) => ! flatLocaleKeys . has ( key ) ) ;
25+ const unusedKeys = [ ...flatLocaleKeys ] . filter ( ( key ) => ! usedKeysMap . has ( key ) ) ;
26+
27+ console . log ( '\n🔍 Localization Check Results:\n' ) ;
28+
29+ if ( missingKeys . length ) {
30+ console . log ( '❌ Missing keys in en_us.json:' ) ;
31+ missingKeys . forEach ( ( key ) => {
32+ const files = [ ...usedKeysMap . get ( key ) ] ;
33+ files . forEach ( ( file ) => {
34+ console . log ( ` - ${ key } (${ file } )` ) ;
35+ } ) ;
36+ } ) ;
37+ } else {
38+ console . log ( '✅ No missing keys.' ) ;
39+ }
40+
41+ if ( unusedKeys . length ) {
42+ console . log ( '\n⚠️ Unused keys in en_us.json:' ) ;
43+ unusedKeys . forEach ( ( key ) => console . log ( ` - ${ key } ` ) ) ;
44+ console . log ( flatLocaleKeys . size , unusedKeys . length )
45+ } else {
46+ console . log ( '✅ No unused keys.' ) ;
47+ }
48+
49+ if ( missingKeys . length || unusedKeys . length ) {
50+ process . exit ( 1 ) ; // Fail the action
51+ }
52+
53+ function flattenKeys ( obj , prefix = '' ) {
54+ const keys = new Set ( ) ;
55+ for ( const key in obj ) {
56+ const fullKey = prefix ? `${ prefix } .${ key } ` : key ;
57+ if ( typeof obj [ key ] === 'object' && obj [ key ] !== null ) {
58+ for ( const subKey of flattenKeys ( obj [ key ] , fullKey ) ) {
59+ keys . add ( subKey ) ;
60+ }
61+ } else {
62+ keys . add ( fullKey ) ;
63+ }
64+ }
65+ return keys ;
66+ }
0 commit comments