index.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*!
  2. // Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
  3. // Released under the MIT license
  4. // https://opensource.org/licenses/mit-license.php
  5. */
  6. /*!
  7. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  8. Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
  9. Released under the MIT license
  10. https://opensource.org/licenses/mit-license.php
  11. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  12. */
  13. import * as lcid from "lcid";
  14. import { execFile, execFileSync, } from "child_process";
  15. const defaultLocale = "en_US";
  16. const getStdOut = async (command, args) => await new Promise((resolve) => {
  17. execFile(command, args, (err, stdout) => {
  18. resolve(err || stdout);
  19. });
  20. });
  21. const getStdOutSync = (command, args) => {
  22. try {
  23. return execFileSync(command, args);
  24. }
  25. catch (e) {
  26. return e;
  27. }
  28. };
  29. const normalise = (input) => input.replace(/_/, "-");
  30. function validate(result, processor) {
  31. if (typeof result === "string" && result.length) {
  32. return processor ? processor(result) : result.trim();
  33. }
  34. return defaultLocale;
  35. }
  36. const getEnvLocale = (env = process.env) => env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE || "";
  37. function parseLocale(str) {
  38. const env = str.split("\n").reduce((env, definition) => {
  39. const [key, value] = definition.split("=");
  40. if (key && value) {
  41. env[key] = value.replace(/^"|"$/g, "");
  42. }
  43. return env;
  44. }, {});
  45. return getEnvLocale(env);
  46. }
  47. const purgeExtraToken = (str) => (str && str.replace(/[.:].*/, "")) || defaultLocale;
  48. const getSupportedLocale = (locale, locales) => locales.includes(locale) ? locale : defaultLocale;
  49. const [getAppleLocale, getAppleLocaleSync] = ((cmd0, args0, cmd1, args1) => {
  50. return [
  51. async () => {
  52. const results = await Promise.all([
  53. getStdOut(cmd0, args0).then(ret => validate(ret)),
  54. getStdOut(cmd1, args1).then(ret => validate(ret))
  55. ]);
  56. return getSupportedLocale(results[0], results[1]);
  57. },
  58. () => getSupportedLocale(validate(getStdOutSync(cmd0, args0)), validate(getStdOutSync(cmd1, args1)))
  59. ];
  60. })("defaults", ["read", "-globalDomain", "AppleLocale"], "locale", ["-a"]);
  61. const getUnixLocale = async () => purgeExtraToken(parseLocale(await getStdOut("locale").then(ret => validate(ret))));
  62. const getUnixLocaleSync = () => purgeExtraToken(parseLocale(validate(getStdOutSync("locale"))));
  63. const parseLCID = (result) => {
  64. const lcidCode = parseInt(result.replace("Locale", ""), 16);
  65. return lcid.from(lcidCode);
  66. };
  67. const [getWinLocale, getWinLocaleSync] = ((cmd0, args0) => {
  68. return [
  69. async () => validate(await getStdOut(cmd0, args0), parseLCID),
  70. () => validate(getStdOutSync(cmd0, args0), parseLCID)
  71. ];
  72. })("wmic", ["os", "get", "locale"]);
  73. let detector;
  74. {
  75. const gettersSlot = [
  76. {
  77. win32: getWinLocaleSync,
  78. darwin: getAppleLocaleSync,
  79. linux: getUnixLocaleSync,
  80. }, {
  81. win32: getWinLocale,
  82. darwin: getAppleLocale,
  83. linux: getUnixLocale,
  84. }
  85. ];
  86. const typeString = {}.toString;
  87. const isPromise = (o) => typeString.call(o) === "[object Promise]";
  88. let cacheLocal;
  89. const base = (async) => (options = {}) => {
  90. options = { spawn: true, cache: true, ...options };
  91. const cache = options.cache;
  92. if (cache && (cacheLocal === null || cacheLocal === void 0 ? void 0 : cacheLocal.length)) {
  93. return (async ? Promise.resolve(cacheLocal) : cacheLocal);
  94. }
  95. const functions = gettersSlot[+(!!async)];
  96. let locale;
  97. const withCache = (l, mustPromise) => {
  98. l = normalise(l);
  99. cacheLocal = cache ? l : void 0;
  100. return (mustPromise ? Promise.resolve(l) : l);
  101. };
  102. const envLocale = getEnvLocale();
  103. if (envLocale || !options.spawn) {
  104. locale = purgeExtraToken(envLocale);
  105. }
  106. else {
  107. let { platform } = process;
  108. if (platform !== "win32" && platform !== "darwin") {
  109. platform = "linux";
  110. }
  111. locale = functions[platform]();
  112. }
  113. if (isPromise(locale)) {
  114. return locale.then(result => withCache(result));
  115. }
  116. else {
  117. return withCache(locale, async === true || void 0);
  118. }
  119. };
  120. detector = (base(true));
  121. detector.sync = base();
  122. Object.defineProperties(detector, {
  123. purge: {
  124. value: () => cacheLocal = void 0,
  125. enumerable: false,
  126. },
  127. version: {
  128. value: "v1.0.8",
  129. enumerable: true,
  130. },
  131. });
  132. }
  133. export const osLocale = Object.freeze(detector);