-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathi18n.ts
48 lines (39 loc) · 1.6 KB
/
i18n.ts
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
import langs from './langs'
export const defaultLang = 'en'
export function ensureSupportedLang(lang: string) {
return lang in langs ? lang : defaultLang
}
export function translate(lang: string, key: string, options?: { values: object }): string {
const keys = key.split('\.')
let result = langs[lang] || langs[defaultLang]
for (let k of keys) {
result = result[k]
if (!result) return lang === defaultLang ? key : translate(defaultLang, key, options)
}
if (result && options?.values) result = replaceValues(lang, result, options.values)
return result ?? key
}
function replaceValues(lang: string, text: string, values: object) {
let lastPos = 0, bracePos = 0, result = ''
while ((bracePos = text.indexOf('{', lastPos)) >= 0) {
result += text.substring(lastPos, bracePos)
let closingPos = text.indexOf('}', bracePos)
const textToReplace = text.substring(bracePos + 1, closingPos)
result += replacePlaceholder(textToReplace, values, lang)
lastPos = closingPos + 1
}
result += text.substring(lastPos)
return result
}
function replacePlaceholder(text: string, values: object, lang: string) {
const pluralTokens = text.split('|')
const field = pluralTokens.first()
if (pluralTokens.length == 1) return values[field] ?? field
const pluralRules = new Intl.PluralRules(lang)
const key = values[field] === 0 ? 'zero' : pluralRules.select(values[field])
for (let i = 1; i < pluralTokens.length; i++) {
const [candidateKey, candidateText] = pluralTokens[i].split(':', 2)
if (candidateKey === key) return candidateText.replace('#', values[field])
}
return field
}