From 13a0555eee09791154d1bbfc694a6df19000e02e Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Sat, 17 Feb 2024 10:26:40 -0800 Subject: [PATCH 1/4] demonstrate expansion from prior process.env --- tests/.env.test | 3 +++ tests/main.js | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/tests/.env.test b/tests/.env.test index c3cd3e7..84427be 100644 --- a/tests/.env.test +++ b/tests/.env.test @@ -72,3 +72,6 @@ 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 +BASE_URL=https://${APP_DOMAIN}/api/ diff --git a/tests/main.js b/tests/main.js index a2b8aa9..cc9e6b3 100644 --- a/tests/main.js +++ b/tests/main.js @@ -510,6 +510,17 @@ t.test('does not attempt to expand password if already existed in processEnv', c ct.end() }) +t.test('expands using processEnv already set on docker machine', ct => { + process.env.APP_DOMAIN = 'example.com' // simulate env set on docker already + + const dotenv = require('dotenv').config({ path: 'tests/.env.test' }) + dotenvExpand.expand(dotenv) + + ct.equal(process.env.BASE_URL, 'https://example.com/api/') + + ct.end() +}) + t.test('does not expand dollar sign that are not variables', ct => { const dotenv = { parsed: { From 8fdcb937f5c1ee30e5453ea5a2ac63e4d081035f Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Sat, 17 Feb 2024 14:07:50 -0800 Subject: [PATCH 2/4] add failing spec for recursive expansion beginning from pre-existing process.env --- tests/.env.test | 2 ++ tests/main.js | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/tests/.env.test b/tests/.env.test index 84427be..389dc57 100644 --- a/tests/.env.test +++ b/tests/.env.test @@ -75,3 +75,5 @@ DOMAIN="https://${HOST}" https://github.com/motdotla/dotenv-expand/issues/120 BASE_URL=https://${APP_DOMAIN}/api/ +PUBLIC_DOMAIN="${DEVCONTAINER_CADDY_PUBLIC_DOMAIN}" +PUBLIC_BASE_URL="https://${PUBLIC_DOMAIN}" diff --git a/tests/main.js b/tests/main.js index cc9e6b3..2864199 100644 --- a/tests/main.js +++ b/tests/main.js @@ -521,6 +521,18 @@ t.test('expands using processEnv already set on docker machine', ct => { ct.end() }) +t.test('recursively expands using processEnv already set on docker machine', ct => { + process.env.DEVCONTAINER_CADDY_PUBLIC_DOMAIN = 'mydom.test' // simulate env set on docker already + + const dotenv = require('dotenv').config({ path: 'tests/.env.test' }) + dotenvExpand.expand(dotenv) + + ct.equal(process.env.PUBLIC_DOMAIN, 'mydom.test') + ct.equal(process.env.PUBLIC_BASE_URL, 'https://mydom.test') + + ct.end() +}) + t.test('does not expand dollar sign that are not variables', ct => { const dotenv = { parsed: { From 678f0083241d52863febd27cb1d46701be93f0a9 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Sat, 17 Feb 2024 16:35:53 -0800 Subject: [PATCH 3/4] fix recursive expansion --- lib/main.js | 8 ++++-- package-lock.json | 16 +++++------ package.json | 2 +- tests/.env.test | 10 ++++--- tests/main.js | 69 +++++++++++++++++++---------------------------- 5 files changed, 49 insertions(+), 56 deletions(-) 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 389dc57..b5a602f 100644 --- a/tests/.env.test +++ b/tests/.env.test @@ -73,7 +73,9 @@ EXPAND_SELF=$EXPAND_SELF HOST="something" DOMAIN="https://${HOST}" -https://github.com/motdotla/dotenv-expand/issues/120 -BASE_URL=https://${APP_DOMAIN}/api/ -PUBLIC_DOMAIN="${DEVCONTAINER_CADDY_PUBLIC_DOMAIN}" -PUBLIC_BASE_URL="https://${PUBLIC_DOMAIN}" +# 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 2864199..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: { @@ -510,29 +492,6 @@ t.test('does not attempt to expand password if already existed in processEnv', c ct.end() }) -t.test('expands using processEnv already set on docker machine', ct => { - process.env.APP_DOMAIN = 'example.com' // simulate env set on docker already - - const dotenv = require('dotenv').config({ path: 'tests/.env.test' }) - dotenvExpand.expand(dotenv) - - ct.equal(process.env.BASE_URL, 'https://example.com/api/') - - ct.end() -}) - -t.test('recursively expands using processEnv already set on docker machine', ct => { - process.env.DEVCONTAINER_CADDY_PUBLIC_DOMAIN = 'mydom.test' // simulate env set on docker already - - const dotenv = require('dotenv').config({ path: 'tests/.env.test' }) - dotenvExpand.expand(dotenv) - - ct.equal(process.env.PUBLIC_DOMAIN, 'mydom.test') - ct.equal(process.env.PUBLIC_BASE_URL, 'https://mydom.test') - - ct.end() -}) - t.test('does not expand dollar sign that are not variables', ct => { const dotenv = { parsed: { @@ -579,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() +}) From e9803316f278730df92d5d49ac14161a13c7c4ff Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Sat, 17 Feb 2024 16:37:48 -0800 Subject: [PATCH 4/4] =?UTF-8?q?changelog=20=F0=9F=AA=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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)