2 const execa = require('execa');
3 const lcid = require('lcid');
4 const mem = require('mem');
6 const defaultOptions = {spawn: true};
7 const defaultLocale = 'en_US';
9 function getEnvLocale(env = process.env) {
10 return env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE;
13 function parseLocale(string) {
14 const env = string.split('\n').reduce((env, def) => {
15 const [key, value] = def.split('=');
16 env[key] = value.replace(/^"|"$/g, '');
20 return getEnvLocale(env);
23 function getLocale(string) {
24 return (string && string.replace(/[.:].*/, ''));
27 function getLocales() {
28 return execa.stdout('locale', ['-a']);
31 function getLocalesSync() {
32 return execa.sync('locale', ['-a']).stdout;
35 function getSupportedLocale(locale, locales = '') {
36 return locales.includes(locale) ? locale : defaultLocale;
39 function getAppleLocale() {
41 execa.stdout('defaults', ['read', '-globalDomain', 'AppleLocale']),
43 ]).then(results => getSupportedLocale(results[0], results[1]));
46 function getAppleLocaleSync() {
47 return getSupportedLocale(
48 execa.sync('defaults', ['read', '-globalDomain', 'AppleLocale']).stdout,
53 function getUnixLocale() {
54 if (process.platform === 'darwin') {
55 return getAppleLocale();
58 return execa.stdout('locale')
59 .then(stdout => getLocale(parseLocale(stdout)));
62 function getUnixLocaleSync() {
63 if (process.platform === 'darwin') {
64 return getAppleLocaleSync();
67 return getLocale(parseLocale(execa.sync('locale').stdout));
70 function getWinLocale() {
71 return execa.stdout('wmic', ['os', 'get', 'locale'])
73 const lcidCode = parseInt(stdout.replace('Locale', ''), 16);
74 return lcid.from(lcidCode);
78 function getWinLocaleSync() {
79 const {stdout} = execa.sync('wmic', ['os', 'get', 'locale']);
80 const lcidCode = parseInt(stdout.replace('Locale', ''), 16);
81 return lcid.from(lcidCode);
84 module.exports = mem((options = defaultOptions) => {
85 const envLocale = getEnvLocale();
88 if (envLocale || options.spawn === false) {
89 thenable = Promise.resolve(getLocale(envLocale));
90 } else if (process.platform === 'win32') {
91 thenable = getWinLocale();
93 thenable = getUnixLocale();
97 .then(locale => locale || defaultLocale)
98 .catch(() => defaultLocale);
101 module.exports.sync = mem((options = defaultOptions) => {
102 const envLocale = getEnvLocale();
105 if (envLocale || options.spawn === false) {
106 res = getLocale(envLocale);
109 res = process.platform === 'win32' ? getWinLocaleSync() : getUnixLocaleSync();
113 return res || defaultLocale;