diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d22467..bfc031f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -## [Unreleased](https://github.com/motdotla/dotenv-expand/compare/v11.0.4...master) +## [Unreleased](https://github.com/motdotla/dotenv-expand/compare/v11.0.5...master) + +## [11.0.5](https://github.com/motdotla/dotenv-expand/compare/v11.0.4...v11.0.5) (2024-02-17) + +### Changed + +- 🐞 fix recursive expansion when expansion key is sourced from `process.env` ([#121](https://github.com/motdotla/dotenv-expand/pull/121)) ## [11.0.4](https://github.com/motdotla/dotenv-expand/compare/v11.0.3...v11.0.4) (2024-02-15) diff --git a/lib/main.js b/lib/main.js index 40bf18b..33e38db 100644 --- a/lib/main.js +++ b/lib/main.js @@ -22,7 +22,12 @@ function interpolate (value, processEnv, parsed) { return match.slice(1) } else { if (processEnv[key]) { - return processEnv[key] + if (processEnv[key] === parsed[key]) { + return processEnv[key] + } else { + // scenario: PASSWORD_EXPAND_NESTED=${PASSWORD_EXPAND} + return interpolate(processEnv[key], processEnv, parsed) + } } if (parsed[key]) { @@ -57,7 +62,6 @@ function expand (options) { let value = options.parsed[key] const inProcessEnv = Object.prototype.hasOwnProperty.call(processEnv, key) - if (inProcessEnv) { if (processEnv[key] === options.parsed[key]) { // assume was set to processEnv from the .env file if the values match and therefore interpolate diff --git a/package-lock.json b/package-lock.json index da68650..45272b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "11.0.4", "license": "BSD-2-Clause", "dependencies": { - "dotenv": "^16.4.1" + "dotenv": "^16.4.4" }, "devDependencies": { "@types/node": "^18.11.3", @@ -1615,14 +1615,14 @@ } }, "node_modules/dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "version": "16.4.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz", + "integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/dotgitignore": { @@ -9841,9 +9841,9 @@ } }, "dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==" + "version": "16.4.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz", + "integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==" }, "dotgitignore": { "version": "2.1.0", diff --git a/package.json b/package.json index 6ea8fe4..76cd467 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,6 @@ "node": ">=12" }, "dependencies": { - "dotenv": "^16.4.1" + "dotenv": "^16.4.4" } } diff --git a/tests/.env.test b/tests/.env.test index c3cd3e7..b5a602f 100644 --- a/tests/.env.test +++ b/tests/.env.test @@ -72,3 +72,10 @@ EXPAND_SELF=$EXPAND_SELF # https://github.com/motdotla/dotenv-expand/issues/112#issuecomment-1937330651 HOST="something" DOMAIN="https://${HOST}" + +# https://github.com/motdotla/dotenv-expand/issues/120 +PASSWORD=password +PASSWORD_EXPAND=${PASSWORD} +PASSWORD_EXPAND_SIMPLE=$PASSWORD +PASSWORD_EXPAND_NESTED=${PASSWORD_EXPAND} +PASSWORD_EXPAND_NESTED_NESTED=${PASSWORD_EXPAND_NESTED} diff --git a/tests/main.js b/tests/main.js index a2b8aa9..3db8947 100644 --- a/tests/main.js +++ b/tests/main.js @@ -63,24 +63,6 @@ t.test('uses environment variables existing already on the machine for expansion ct.end() }) -t.test('does not expand environment variables existing already on the machine that look like they could expand', ct => { - process.env.PASSWORD = 'pas$word' - const dotenv = { - parsed: { - PASSWORD: 'dude', - PASSWORD_EXPAND: '${PASSWORD}', - PASSWORD_EXPAND_SIMPLE: '$PASSWORD' - } - } - const parsed = dotenvExpand.expand(dotenv).parsed - - ct.equal(parsed.PASSWORD_EXPAND, 'pas$word') - ct.equal(parsed.PASSWORD_EXPAND_SIMPLE, 'pas$word') - ct.equal(parsed.PASSWORD, 'pas$word') - - ct.end() -}) - t.test('expands missing environment variables to an empty string', ct => { const dotenv = { parsed: { @@ -556,3 +538,31 @@ t.test('expands recursively reverse order', ct => { ct.end() }) + +t.test('expands recursively', ct => { + const dotenv = require('dotenv').config({ path: 'tests/.env.test' }) + dotenvExpand.expand(dotenv) + + ct.equal(process.env.PASSWORD_EXPAND, 'password') + ct.equal(process.env.PASSWORD_EXPAND_SIMPLE, 'password') + ct.equal(process.env.PASSWORD, 'password') + ct.equal(process.env.PASSWORD_EXPAND_NESTED, 'password') + ct.equal(process.env.PASSWORD_EXPAND_NESTED, 'password') + + ct.end() +}) + +t.test('expands recursively but is smart enough to not attempt expansion of a pre-set env in process.env', ct => { + process.env.PASSWORD = 'pas$word' + + const dotenv = require('dotenv').config({ path: 'tests/.env.test' }) + dotenvExpand.expand(dotenv) + + ct.equal(process.env.PASSWORD_EXPAND, 'pas$word') + ct.equal(process.env.PASSWORD_EXPAND_SIMPLE, 'pas$word') + ct.equal(process.env.PASSWORD, 'pas$word') + ct.equal(process.env.PASSWORD_EXPAND_NESTED, 'pas$word') + ct.equal(process.env.PASSWORD_EXPAND_NESTED, 'pas$word') + + ct.end() +})