motdotla / dotenv-expand

Variable expansion for dotenv. Expand variables already on your machine for use in your .env file.
https://dotenvx.com
BSD 2-Clause "Simplified" License
953 stars 95 forks source link

Bug in safari #94

Closed SpUm09 closed 8 months ago

SpUm09 commented 1 year ago

https://github.com/motdotla/dotenv-expand/blob/4ac51eac991d6ed87d1d56f35f4b85c77bb4ed5f/lib/main.js#L12 https://github.com/motdotla/dotenv-expand/blob/4ac51eac991d6ed87d1d56f35f4b85c77bb4ed5f/lib/main.js#L32

Safari does not support https://caniuse.com/js-regexp-lookbehind

SpUm09 commented 1 year ago

First line: I'm not very strong with regular expressions. So far I've only found this option: (?:[^\\])(\$) but in this case it is necessary to work with the second group Or enough: (\b[$]) but I'm not sure.

Second line: (\${?([\w]+)(?::-([^}\\]*))?}?) The result seems to be similar

kadiiski commented 1 year ago

It doesn't work beacuse Safari doesn't support lookbehind: https://caniuse.com/js-regexp-lookbehind

kadiiski commented 1 year ago

Here is a fix for safari. I don't have access to create a PR for this, but this works for me. You can use the package "patch-package" and patch it on your side as well.

Put this in the lib/main.js and remove the old one.

// Works in safari as well.
function _interpolate (envValue, environment, config) {
  let dollarIndex = envValue.lastIndexOf('$')
  while (dollarIndex !== -1) {
    // Check if the dollar sign is escaped.
    if (dollarIndex > 0 && envValue[dollarIndex - 1] === '\\') {
      // Escape character found, skip this dollar sign.
      dollarIndex = envValue.lastIndexOf('$', dollarIndex - 1)
      continue
    }

    // Find the closing bracket of the variable.
    const bracketIndex = envValue.indexOf('}', dollarIndex)
    if (bracketIndex === -1) {
      // No closing bracket found, skip this dollar sign.
      dollarIndex = envValue.lastIndexOf('$', dollarIndex - 1)
      continue
    }

    // Extract the variable name and default value (if any).
    const variable = envValue.substring(dollarIndex + 1, bracketIndex)
    const [variableName, defaultValue] = variable.split(':-')

    // Replace the variable with its value or default value (if any).
    const value = environment[variableName] || defaultValue || config.parsed[variableName] || ''
    envValue = envValue.substring(0, dollarIndex) + value + envValue.substring(bracketIndex + 1)

    // Look for the next dollar sign.
    dollarIndex = envValue.lastIndexOf('$', dollarIndex - 1)
  }

  return envValue
}
kadiiski commented 1 year ago

PR created: https://github.com/motdotla/dotenv-expand/pull/97

budakhasan commented 1 year ago

This problem is still causing errors even in Safari version 16.3

motdotla commented 9 months ago

can you explain how you are using this in safari? dotenv-expand is a back-end lib like dotenv. it should typically be part of your build and not called from runtime front-end.

but maybe there is an interesting use case i am not privy to?