variable.js 2.5 KB

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