variable.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { isWindows } from "./is-windows.js";
  2. const pathLikeEnvVarWhitelist = new Set(['PATH', 'NODE_PATH']);
  3. /**
  4. * This will transform UNIX-style list values to Windows-style.
  5. * For example, the value of the $PATH variable "/usr/bin:/usr/local/bin:."
  6. * will become "/usr/bin;/usr/local/bin;." on Windows.
  7. * @param varValue Original value of the env variable
  8. * @param varName Original name of the env variable
  9. * @returns Converted value
  10. */
  11. function replaceListDelimiters(varValue, varName = '') {
  12. const targetSeparator = isWindows() ? ';' : ':';
  13. if (!pathLikeEnvVarWhitelist.has(varName)) {
  14. return varValue;
  15. }
  16. return varValue.replace(/(\\*):/g, (match, backslashes) => {
  17. if (backslashes.length % 2) {
  18. // Odd number of backslashes preceding it means it's escaped,
  19. // remove 1 backslash and return the rest as-is
  20. return match.substring(1);
  21. }
  22. return backslashes + targetSeparator;
  23. });
  24. }
  25. /**
  26. * This will attempt to resolve the value of any env variables that are inside
  27. * this string. For example, it will transform this:
  28. * cross-env FOO=$NODE_ENV BAR=\\$NODE_ENV echo $FOO $BAR
  29. * Into this:
  30. * FOO=development BAR=$NODE_ENV echo $FOO
  31. * (Or whatever value the variable NODE_ENV has)
  32. * Note that this function is only called with the right-side portion of the
  33. * env var assignment, so in that example, this function would transform
  34. * the string "$NODE_ENV" into "development"
  35. * @param varValue Original value of the env variable
  36. * @returns Converted value
  37. */
  38. function resolveEnvVars(varValue) {
  39. const envUnixRegex = /(\\*)(\$(\w+)|\${(\w+)})/g; // $my_var or ${my_var} or \$my_var
  40. return varValue.replace(envUnixRegex, (_, escapeChars, varNameWithDollarSign, varName, altVarName) => {
  41. // do not replace things preceded by a odd number of \
  42. if (escapeChars.length % 2 === 1) {
  43. return varNameWithDollarSign;
  44. }
  45. return (escapeChars.substring(0, escapeChars.length / 2) +
  46. (process.env[varName || altVarName] || ''));
  47. });
  48. }
  49. /**
  50. * Converts an environment variable value to be appropriate for the current OS.
  51. * @param originalValue Original value of the env variable
  52. * @param originalName Original name of the env variable
  53. * @returns Converted value
  54. */
  55. export function varValueConvert(originalValue, originalName) {
  56. return resolveEnvVars(replaceListDelimiters(originalValue, originalName));
  57. }