123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. 'use strict';
  2. var childProcess = require('child_process');
  3. var execFileSync = childProcess.execFileSync;
  4. var lcid = require('lcid');
  5. var defaultOpts = {spawn: true};
  6. var cache;
  7. function fallback() {
  8. cache = 'en_US';
  9. return cache;
  10. }
  11. function getEnvLocale(env) {
  12. env = env || process.env;
  13. var ret = env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE;
  14. cache = getLocale(ret);
  15. return ret;
  16. }
  17. function parseLocale(x) {
  18. var env = x.split('\n').reduce(function (env, def) {
  19. def = def.split('=');
  20. env[def[0]] = def[1];
  21. return env;
  22. }, {});
  23. return getEnvLocale(env);
  24. }
  25. function getLocale(str) {
  26. return (str && str.replace(/[.:].*/, '')) || fallback();
  27. }
  28. module.exports = function (opts, cb) {
  29. if (typeof opts === 'function') {
  30. cb = opts;
  31. opts = defaultOpts;
  32. } else {
  33. opts = opts || defaultOpts;
  34. }
  35. if (cache || getEnvLocale() || opts.spawn === false) {
  36. setImmediate(cb, null, cache);
  37. return;
  38. }
  39. var getAppleLocale = function () {
  40. childProcess.execFile('defaults', ['read', '-g', 'AppleLocale'], function (err, stdout) {
  41. if (err) {
  42. fallback();
  43. return;
  44. }
  45. cache = stdout.trim() || fallback();
  46. cb(null, cache);
  47. });
  48. };
  49. if (process.platform === 'win32') {
  50. childProcess.execFile('wmic', ['os', 'get', 'locale'], function (err, stdout) {
  51. if (err) {
  52. fallback();
  53. return;
  54. }
  55. var lcidCode = parseInt(stdout.replace('Locale', ''), 16);
  56. cache = lcid.from(lcidCode) || fallback();
  57. cb(null, cache);
  58. });
  59. } else {
  60. childProcess.execFile('locale', function (err, stdout) {
  61. if (err) {
  62. fallback();
  63. return;
  64. }
  65. var res = parseLocale(stdout);
  66. if (!res && process.platform === 'darwin') {
  67. getAppleLocale();
  68. return;
  69. }
  70. cache = getLocale(res);
  71. cb(null, cache);
  72. });
  73. }
  74. };
  75. module.exports.sync = function (opts) {
  76. opts = opts || defaultOpts;
  77. if (cache || getEnvLocale() || !execFileSync || opts.spawn === false) {
  78. return cache;
  79. }
  80. if (process.platform === 'win32') {
  81. var stdout;
  82. try {
  83. stdout = execFileSync('wmic', ['os', 'get', 'locale'], {encoding: 'utf8'});
  84. } catch (err) {
  85. return fallback();
  86. }
  87. var lcidCode = parseInt(stdout.replace('Locale', ''), 16);
  88. cache = lcid.from(lcidCode) || fallback();
  89. return cache;
  90. }
  91. var res;
  92. try {
  93. res = parseLocale(execFileSync('locale', {encoding: 'utf8'}));
  94. } catch (err) {}
  95. if (!res && process.platform === 'darwin') {
  96. try {
  97. cache = execFileSync('defaults', ['read', '-g', 'AppleLocale'], {encoding: 'utf8'}).trim() || fallback();
  98. return cache;
  99. } catch (err) {
  100. return fallback();
  101. }
  102. }
  103. cache = getLocale(res);
  104. return cache;
  105. };