index.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. 'use strict';
  2. const execa = require('execa');
  3. const lcid = require('lcid');
  4. const mem = require('mem');
  5. const defaultOptions = {spawn: true};
  6. const defaultLocale = 'en_US';
  7. function getEnvLocale(env = process.env) {
  8. return env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE;
  9. }
  10. function parseLocale(string) {
  11. const env = string.split('\n').reduce((env, def) => {
  12. const [key, value] = def.split('=');
  13. env[key] = value.replace(/^"|"$/g, '');
  14. return env;
  15. }, {});
  16. return getEnvLocale(env);
  17. }
  18. function getLocale(string) {
  19. return (string && string.replace(/[.:].*/, ''));
  20. }
  21. function getLocales() {
  22. return execa.stdout('locale', ['-a']);
  23. }
  24. function getLocalesSync() {
  25. return execa.sync('locale', ['-a']).stdout;
  26. }
  27. function getSupportedLocale(locale, locales = '') {
  28. return locales.includes(locale) ? locale : defaultLocale;
  29. }
  30. function getAppleLocale() {
  31. return Promise.all([
  32. execa.stdout('defaults', ['read', '-globalDomain', 'AppleLocale']),
  33. getLocales()
  34. ]).then(results => getSupportedLocale(results[0], results[1]));
  35. }
  36. function getAppleLocaleSync() {
  37. return getSupportedLocale(
  38. execa.sync('defaults', ['read', '-globalDomain', 'AppleLocale']).stdout,
  39. getLocalesSync()
  40. );
  41. }
  42. function getUnixLocale() {
  43. if (process.platform === 'darwin') {
  44. return getAppleLocale();
  45. }
  46. return execa.stdout('locale')
  47. .then(stdout => getLocale(parseLocale(stdout)));
  48. }
  49. function getUnixLocaleSync() {
  50. if (process.platform === 'darwin') {
  51. return getAppleLocaleSync();
  52. }
  53. return getLocale(parseLocale(execa.sync('locale').stdout));
  54. }
  55. function getWinLocale() {
  56. return execa.stdout('wmic', ['os', 'get', 'locale'])
  57. .then(stdout => {
  58. const lcidCode = parseInt(stdout.replace('Locale', ''), 16);
  59. return lcid.from(lcidCode);
  60. });
  61. }
  62. function getWinLocaleSync() {
  63. const {stdout} = execa.sync('wmic', ['os', 'get', 'locale']);
  64. const lcidCode = parseInt(stdout.replace('Locale', ''), 16);
  65. return lcid.from(lcidCode);
  66. }
  67. module.exports = mem((options = defaultOptions) => {
  68. const envLocale = getEnvLocale();
  69. let thenable;
  70. if (envLocale || options.spawn === false) {
  71. thenable = Promise.resolve(getLocale(envLocale));
  72. } else if (process.platform === 'win32') {
  73. thenable = getWinLocale();
  74. } else {
  75. thenable = getUnixLocale();
  76. }
  77. return thenable
  78. .then(locale => locale || defaultLocale)
  79. .catch(() => defaultLocale);
  80. });
  81. module.exports.sync = mem((options = defaultOptions) => {
  82. const envLocale = getEnvLocale();
  83. let res;
  84. if (envLocale || options.spawn === false) {
  85. res = getLocale(envLocale);
  86. } else {
  87. try {
  88. res = process.platform === 'win32' ? getWinLocaleSync() : getUnixLocaleSync();
  89. } catch (_) {}
  90. }
  91. return res || defaultLocale;
  92. });