115 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			115 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | const execa = require('execa'); | ||
|  | const lcid = require('lcid'); | ||
|  | const mem = require('mem'); | ||
|  | 
 | ||
|  | const defaultOptions = {spawn: true}; | ||
|  | const defaultLocale = 'en_US'; | ||
|  | 
 | ||
|  | function getEnvLocale(env = process.env) { | ||
|  | 	return env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE; | ||
|  | } | ||
|  | 
 | ||
|  | function parseLocale(string) { | ||
|  | 	const env = string.split('\n').reduce((env, def) => { | ||
|  | 		const [key, value] = def.split('='); | ||
|  | 		env[key] = value.replace(/^"|"$/g, ''); | ||
|  | 		return env; | ||
|  | 	}, {}); | ||
|  | 
 | ||
|  | 	return getEnvLocale(env); | ||
|  | } | ||
|  | 
 | ||
|  | function getLocale(string) { | ||
|  | 	return (string && string.replace(/[.:].*/, '')); | ||
|  | } | ||
|  | 
 | ||
|  | function getLocales() { | ||
|  | 	return execa.stdout('locale', ['-a']); | ||
|  | } | ||
|  | 
 | ||
|  | function getLocalesSync() { | ||
|  | 	return execa.sync('locale', ['-a']).stdout; | ||
|  | } | ||
|  | 
 | ||
|  | function getSupportedLocale(locale, locales = '') { | ||
|  | 	return locales.includes(locale) ? locale : defaultLocale; | ||
|  | } | ||
|  | 
 | ||
|  | function getAppleLocale() { | ||
|  | 	return Promise.all([ | ||
|  | 		execa.stdout('defaults', ['read', '-globalDomain', 'AppleLocale']), | ||
|  | 		getLocales() | ||
|  | 	]).then(results => getSupportedLocale(results[0], results[1])); | ||
|  | } | ||
|  | 
 | ||
|  | function getAppleLocaleSync() { | ||
|  | 	return getSupportedLocale( | ||
|  | 		execa.sync('defaults', ['read', '-globalDomain', 'AppleLocale']).stdout, | ||
|  | 		getLocalesSync() | ||
|  | 	); | ||
|  | } | ||
|  | 
 | ||
|  | function getUnixLocale() { | ||
|  | 	if (process.platform === 'darwin') { | ||
|  | 		return getAppleLocale(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return execa.stdout('locale') | ||
|  | 		.then(stdout => getLocale(parseLocale(stdout))); | ||
|  | } | ||
|  | 
 | ||
|  | function getUnixLocaleSync() { | ||
|  | 	if (process.platform === 'darwin') { | ||
|  | 		return getAppleLocaleSync(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return getLocale(parseLocale(execa.sync('locale').stdout)); | ||
|  | } | ||
|  | 
 | ||
|  | function getWinLocale() { | ||
|  | 	return execa.stdout('wmic', ['os', 'get', 'locale']) | ||
|  | 		.then(stdout => { | ||
|  | 			const lcidCode = parseInt(stdout.replace('Locale', ''), 16); | ||
|  | 			return lcid.from(lcidCode); | ||
|  | 		}); | ||
|  | } | ||
|  | 
 | ||
|  | function getWinLocaleSync() { | ||
|  | 	const {stdout} = execa.sync('wmic', ['os', 'get', 'locale']); | ||
|  | 	const lcidCode = parseInt(stdout.replace('Locale', ''), 16); | ||
|  | 	return lcid.from(lcidCode); | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = mem((options = defaultOptions) => { | ||
|  | 	const envLocale = getEnvLocale(); | ||
|  | 
 | ||
|  | 	let thenable; | ||
|  | 	if (envLocale || options.spawn === false) { | ||
|  | 		thenable = Promise.resolve(getLocale(envLocale)); | ||
|  | 	} else if (process.platform === 'win32') { | ||
|  | 		thenable = getWinLocale(); | ||
|  | 	} else { | ||
|  | 		thenable = getUnixLocale(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return thenable | ||
|  | 		.then(locale => locale || defaultLocale) | ||
|  | 		.catch(() => defaultLocale); | ||
|  | }); | ||
|  | 
 | ||
|  | module.exports.sync = mem((options = defaultOptions) => { | ||
|  | 	const envLocale = getEnvLocale(); | ||
|  | 
 | ||
|  | 	let res; | ||
|  | 	if (envLocale || options.spawn === false) { | ||
|  | 		res = getLocale(envLocale); | ||
|  | 	} else { | ||
|  | 		try { | ||
|  | 			res = process.platform === 'win32' ? getWinLocaleSync() : getUnixLocaleSync(); | ||
|  | 		} catch (_) {} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return res || defaultLocale; | ||
|  | }); |