UNPKG

3.23 kBJavaScriptView Raw
1import lcid from 'lcid';
2import {exec, execSync} from './exec.js';
3
4const defaultOptions = {spawn: true};
5const defaultLocale = 'en-US';
6
7async function getStdOut(command, args) {
8 return (await exec(command, args)).stdout;
9}
10
11function getStdOutSync(command, args) {
12 return execSync(command, args);
13}
14
15function getEnvLocale(env = process.env) {
16 return env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE;
17}
18
19function parseLocale(string) {
20 const env = {};
21 for (const definition of string.split('\n')) {
22 const [key, value] = definition.split('=');
23 env[key] = value.replace(/^"|"$/g, '');
24 }
25
26 return getEnvLocale(env);
27}
28
29function getLocale(string) {
30 return (string && string.replace(/[.:].*/, ''));
31}
32
33async function getLocales() {
34 return getStdOut('locale', ['-a']);
35}
36
37function getLocalesSync() {
38 return getStdOutSync('locale', ['-a']);
39}
40
41function getSupportedLocale(locale, locales = '') {
42 return locales.includes(locale) ? locale : defaultLocale;
43}
44
45async function getAppleLocale() {
46 const results = await Promise.all([
47 getStdOut('defaults', ['read', '-globalDomain', 'AppleLocale']),
48 getLocales(),
49 ]);
50
51 return getSupportedLocale(results[0], results[1]);
52}
53
54function getAppleLocaleSync() {
55 return getSupportedLocale(
56 getStdOutSync('defaults', ['read', '-globalDomain', 'AppleLocale']),
57 getLocalesSync(),
58 );
59}
60
61async function getUnixLocale() {
62 return getLocale(parseLocale(await getStdOut('locale')));
63}
64
65function getUnixLocaleSync() {
66 return getLocale(parseLocale(getStdOutSync('locale')));
67}
68
69async function getWinLocale() {
70 const stdout = await getStdOut('wmic', ['os', 'get', 'locale']);
71 const lcidCode = Number.parseInt(stdout.replace('Locale', ''), 16);
72
73 return lcid.from(lcidCode);
74}
75
76function getWinLocaleSync() {
77 const stdout = getStdOutSync('wmic', ['os', 'get', 'locale']);
78 const lcidCode = Number.parseInt(stdout.replace('Locale', ''), 16);
79
80 return lcid.from(lcidCode);
81}
82
83function normalise(input) {
84 return input.replace(/_/, '-');
85}
86
87const cache = new Map();
88
89export async function osLocale(options = defaultOptions) {
90 if (cache.has(options.spawn)) {
91 return cache.get(options.spawn);
92 }
93
94 let locale;
95
96 try {
97 const envLocale = getEnvLocale();
98
99 if (envLocale || options.spawn === false) {
100 locale = getLocale(envLocale);
101 } else if (process.platform === 'win32') {
102 locale = await getWinLocale();
103 } else if (process.platform === 'darwin') {
104 locale = await getAppleLocale();
105 } else {
106 locale = await getUnixLocale();
107 }
108 } catch {}
109
110 const normalised = normalise(locale || defaultLocale);
111 cache.set(options.spawn, normalised);
112 return normalised;
113}
114
115export function osLocaleSync(options = defaultOptions) {
116 if (cache.has(options.spawn)) {
117 return cache.get(options.spawn);
118 }
119
120 let locale;
121 try {
122 const envLocale = getEnvLocale();
123
124 if (envLocale || options.spawn === false) {
125 locale = getLocale(envLocale);
126 } else if (process.platform === 'win32') {
127 locale = getWinLocaleSync();
128 } else if (process.platform === 'darwin') {
129 locale = getAppleLocaleSync();
130 } else {
131 locale = getUnixLocaleSync();
132 }
133 } catch {}
134
135 const normalised = normalise(locale || defaultLocale);
136 cache.set(options.spawn, normalised);
137 return normalised;
138}