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
|
export const docsLocale = [
"ar",
"bs",
"da",
"de",
"es",
"fr",
"it",
"ja",
"ko",
"nb",
"pl",
"pt-br",
"ru",
"th",
"tr",
"zh-cn",
"zh-tw",
] as const
export type DocsLocale = (typeof docsLocale)[number]
export const locale = ["root", ...docsLocale] as const
export type Locale = (typeof locale)[number]
export const localeAlias = {
ar: "ar",
br: "pt-br",
bs: "bs",
da: "da",
de: "de",
en: "root",
es: "es",
fr: "fr",
it: "it",
ja: "ja",
ko: "ko",
nb: "nb",
nn: "nb",
no: "nb",
pl: "pl",
pt: "pt-br",
"pt-br": "pt-br",
root: "root",
ru: "ru",
th: "th",
tr: "tr",
zh: "zh-cn",
"zh-cn": "zh-cn",
zht: "zh-tw",
"zh-tw": "zh-tw",
} as const satisfies Record<string, Locale>
const starts = [
["ko", "ko"],
["bs", "bs"],
["de", "de"],
["es", "es"],
["fr", "fr"],
["it", "it"],
["da", "da"],
["ja", "ja"],
["pl", "pl"],
["ru", "ru"],
["ar", "ar"],
["th", "th"],
["tr", "tr"],
["en", "root"],
] as const
function parse(input: string) {
let decoded = ""
try {
decoded = decodeURIComponent(input)
} catch {
return null
}
const value = decoded.trim().toLowerCase()
if (!value) return null
return value
}
export function exactLocale(input: string) {
const value = parse(input)
if (!value) return null
if (value in localeAlias) {
return localeAlias[value as keyof typeof localeAlias]
}
return null
}
export function matchLocale(input: string) {
const value = parse(input)
if (!value) return null
if (value.startsWith("zh")) {
if (value.includes("hant") || value.includes("-tw") || value.includes("-hk") || value.includes("-mo")) {
return "zh-tw"
}
return "zh-cn"
}
if (value in localeAlias) {
return localeAlias[value as keyof typeof localeAlias]
}
if (value.startsWith("pt")) return "pt-br"
if (value.startsWith("no") || value.startsWith("nb") || value.startsWith("nn")) return "nb"
return starts.find((item) => value.startsWith(item[0]))?.[1] ?? null
}
|