-
Notifications
You must be signed in to change notification settings - Fork 472
/
Copy pathgetLanguage.ts
130 lines (118 loc) · 3.39 KB
/
getLanguage.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
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
import * as fs from 'node:fs'
import * as path from 'node:path'
import { pathToFileURL } from 'node:url'
interface LanguageItem {
hint?: string
message: string
invalidMessage?: string
dirForPrompts?: {
current: string
target: string
}
toggleOptions?: {
active: string
inactive: string
}
selectOptions?: {
[key: string]: { title: string; desc?: string }
}
}
interface Language {
projectName: LanguageItem
shouldOverwrite: LanguageItem
packageName: LanguageItem
featureSelection: LanguageItem
needsTypeScript: LanguageItem
needsJsx: LanguageItem
needsRouter: LanguageItem
needsPinia: LanguageItem
needsVitest: LanguageItem
needsE2eTesting: LanguageItem
needsEslint: LanguageItem
needsPrettier: LanguageItem
e2eSelection: LanguageItem & {
selectOptions?: {
[key: string]: { title: string; desc?: string; hintOnComponentTesting?: string }
}
}
needsOxlint: LanguageItem
errors: {
operationCancelled: string
}
defaultToggleOptions: {
active: string
inactive: string
}
infos: {
scaffolding: string
done: string
optionalGitCommand: string
}
}
/**
*
* This function is used to link obtained locale with correct locale file in order to make locales reusable
*
* @param locale the obtained locale
* @returns locale that linked with correct name
*/
function linkLocale(locale: string) {
// The C locale is the default system locale for POSIX systems.
// https://docs.oracle.com/cd/E36784_01/html/E36823/glmar.html
// https://sourceware.org/glibc/wiki/Proposals/C.UTF-8
// It is common among containerized environments or minimal virtual environments
// though most user-facing systems would have a more specific locale set.
// The problem here is that the C locale is not a valid language tag for the Intl API.
// But it is not desirable to throw an error in this case.
// So we map it to 'en-US'.
if (locale === 'C') {
return 'en-US'
}
let linkedLocale: string
try {
linkedLocale = Intl.getCanonicalLocales(locale)[0]
} catch (error) {
console.log(`${error.toString()}, invalid language tag: "${locale}"\n`)
}
switch (linkedLocale) {
case 'zh-TW':
case 'zh-HK':
case 'zh-MO':
linkedLocale = 'zh-Hant'
break
case 'zh-CN':
case 'zh-SG':
linkedLocale = 'zh-Hans'
break
default:
linkedLocale = locale
}
return linkedLocale
}
function getLocale() {
const shellLocale =
process.env.LC_ALL || // POSIX locale environment variables
process.env.LC_MESSAGES ||
process.env.LANG ||
Intl.DateTimeFormat().resolvedOptions().locale || // Built-in ECMA-402 support
'en-US' // Default fallback
return linkLocale(shellLocale.split('.')[0].replace('_', '-'))
}
async function loadLanguageFile(filePath: string): Promise<Language> {
return await fs.promises.readFile(filePath, 'utf-8').then((data) => {
const parsedData = JSON.parse(data)
if (parsedData) {
return parsedData
}
})
}
export default async function getLanguage(localesRoot: string) {
const locale = getLocale()
const languageFilePath = path.resolve(localesRoot, `${locale}.json`)
const fallbackPath = path.resolve(localesRoot, 'en-US.json')
const doesLanguageExist = fs.existsSync(languageFilePath)
const lang: Language = doesLanguageExist
? await loadLanguageFile(languageFilePath)
: await loadLanguageFile(fallbackPath)
return lang
}