-
-
Notifications
You must be signed in to change notification settings - Fork 368
/
Copy pathcheckLocale.mjs
138 lines (122 loc) · 3.44 KB
/
checkLocale.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import fs from 'fs/promises'
import path from 'path'
// current support --baseLocale and --locales flag
// default baseLocale is "en", default locale is "all"
// e.g --baseLocale=en --locales=en,fr,de or --locales=all
const argArr = process.argv.slice(2)
let args = {
baseLocale: 'en',
locales: 'all',
}
argArr.forEach((arg) => {
if (arg.indexOf('locales') > -1) {
args.locales = arg
.substring(arg.indexOf('=') + 1)
.split(',')
.map(x => x.toLocaleLowerCase())
}
if (arg.indexOf('baseLocale') > -1) {
args.baseLocale = arg.substring(arg.indexOf('=') + 1).toLocaleLowerCase()
}
})
const CONSTANTS = {
BASE_LOCALE: args.baseLocale,
LOCALE_DIR: 'i18n/locales',
LOCALES: args.locales,
}
async function readJson(filePath) {
try {
const content = await fs.readFile(filePath, { encoding: 'utf8' })
return JSON.parse(content)
}
catch (err) {
throw new Error(err.message)
}
}
async function writeJson(filePath, json) {
await fs.writeFile(filePath, JSON.stringify(json, null, 2))
}
async function getLocales() {
const locales = {}
let dirs = []
if (CONSTANTS.LOCALES === 'all') {
// get json file like en.json, fr.json in locale directory
dirs = (await fs.readdir(path.join(CONSTANTS.LOCALE_DIR))).filter(
fileName => /^[a-z]{2}\.json/.test(fileName),
)
}
else if (Array.isArray(CONSTANTS.LOCALES)) {
dirs = CONSTANTS.LOCALES.map(lang => `${lang}.json`)
}
for (let key of dirs) {
locales[key] = await readJson(path.join(CONSTANTS.LOCALE_DIR, key))
}
return locales
}
function sortJson(json) {
let sorted = {}
Object.keys(json)
// compare key case-insensitive
.sort((a, b) => a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase()))
.forEach((key) => {
if (typeof json[key] === 'object') {
sorted[key] = sortJson(json[key])
}
else {
sorted[key] = json[key]
}
})
return sorted
}
function compareLocale(baseLocale, locale, prefix = '') {
let res = []
Object.keys(baseLocale).forEach((key) => {
if (locale[key] === undefined) {
res.push(`${prefix}${key}`)
}
else if (typeof baseLocale[key] === 'object') {
res = res.concat(
compareLocale(baseLocale[key], locale[key], `${prefix}${key}.`),
)
}
})
return res
}
async function resortJson() {
const allLocales = await getLocales()
Object.keys(allLocales).forEach(async (locale) => {
const sortedJson = sortJson(allLocales[locale])
await writeJson(path.join(CONSTANTS.LOCALE_DIR, locale), sortedJson)
})
}
async function checkLocale() {
const res = {}
const baseLocale = await readJson(
path.join(CONSTANTS.LOCALE_DIR, `${CONSTANTS.BASE_LOCALE}.json`),
)
const allLocales = await getLocales()
for (let locale in allLocales) {
const localeJson = await readJson(path.join(CONSTANTS.LOCALE_DIR, locale))
const list = compareLocale(baseLocale, localeJson)
if (list.length > 0) {
res[locale] = list
}
}
return res
}
await resortJson()
const checkResult = await checkLocale()
if (Object.keys(checkResult).length > 0) {
const table = [['Locale File', 'Missing Key(s)']]
Object.keys(checkResult).forEach((key) => {
table.push([key, checkResult[key]])
})
console.table(table)
await writeJson('locale-check.log.json', checkResult)
throw new Error(
'❌ Missing translations, please check locale-check.log.json for detail.',
)
}
else {
console.log('🚀 Translation check passed!')
}