From 2d20d1adbc4592aeff7f09ef9e5f9f0d2443b854 Mon Sep 17 00:00:00 2001 From: Bek Masharipov Date: Tue, 3 Mar 2026 01:27:37 +0100 Subject: [PATCH 1/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Update=20userConfigPat?= =?UTF-8?q?h=20resolution=20to=20use=20CONFIGURU=5FCONFIG=20and=20deprecat?= =?UTF-8?q?e=20CFG=5FJSON=5FPATH?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/loader.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/lib/loader.ts b/src/lib/loader.ts index 9451c4f..890638a 100644 --- a/src/lib/loader.ts +++ b/src/lib/loader.ts @@ -9,9 +9,22 @@ export interface ConfigLoaderOptions { envMode?: 'all' | 'default' | 'merged' | 'none' } +const resolveUserConfigPath = () => { + if (process.env.CONFIGURU_CONFIG) { + return process.env.CONFIGURU_CONFIG + } + if (process.env.CFG_JSON_PATH) { + console.warn( + 'Configuru: CFG_JSON_PATH is deprecated, use CONFIGURU_CONFIG instead. It will be removed in the next major version.' + ) + return process.env.CFG_JSON_PATH + } + return undefined +} + const defaultOpts: ConfigLoaderOptions = { defaultConfigPath: '.env', - userConfigPath: process.env.CFG_JSON_PATH, + userConfigPath: resolveUserConfigPath(), envMode: 'default', } From aa4fd79f0f72e0531e3140ded08f92bb4d2b527a Mon Sep 17 00:00:00 2001 From: Bek Masharipov Date: Tue, 3 Mar 2026 01:28:27 +0100 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=85=20Add=20tests=20for=20user=20conf?= =?UTF-8?q?ig=20variable=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/loader.test.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/test/loader.test.ts b/src/test/loader.test.ts index e30ab03..1198f49 100644 --- a/src/test/loader.test.ts +++ b/src/test/loader.test.ts @@ -157,3 +157,31 @@ describe('simple loads', () => { }) }) }) + +describe('User config variable', () => { + const defaultConfig = resolve(__dirname, './sandbox/default.json') + + afterEach(() => { + delete process.env.CONFIGURU_CONFIG + delete process.env.CFG_JSON_PATH + }) + + test('CONFIGURU_CONFIG inline JSON', () => { + process.env.CONFIGURU_CONFIG = JSON.stringify({ foo: 'from_configuru' }) + jest.resetModules() // loader reads env at import time, so we must re-import + const { createLoader } = require('../lib/loader') + const loader = createLoader({ defaultConfigPath: defaultConfig }) + const config = loader({ foo: schema.string('foo') }).values() + expect(config.foo).toBe('from_configuru') + }) + + test('CONFIGURU_CONFIG over CFG_JSON_PATH', () => { + process.env.CONFIGURU_CONFIG = JSON.stringify({ foo: 'new' }) + process.env.CFG_JSON_PATH = JSON.stringify({ foo: 'old' }) + jest.resetModules() // loader reads env at import time, so we must re-import + const { createLoader } = require('../lib/loader') + const loader = createLoader({ defaultConfigPath: defaultConfig }) + const config = loader({ foo: schema.string('foo') }).values() + expect(config.foo).toBe('new') + }) +}) From 8abb84d8f3dc57bf49e29683505e7c0dd28ac143 Mon Sep 17 00:00:00 2001 From: Bek Masharipov Date: Tue, 3 Mar 2026 01:28:43 +0100 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=93=9D=20Update=20README=20and=20adva?= =?UTF-8?q?nced=20usage=20documentation=20to=20reflect=20the=20deprecation?= =?UTF-8?q?=20of=20CFG=5FJSON=5FPATH=20in=20favor=20of=20CONFIGURU=5FCONFI?= =?UTF-8?q?G?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++++-- wiki/advanced-usage.md | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bdb003d..c0962b2 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,11 @@ npm install configuru } ``` -3. _(optional)_ As a developer (or environment), create a custom override file (e.g. `~/.env/my-project.jsonc`) and save the path in your `CFG_JSON_PATH`. +3. _(optional)_ As a developer (or environment), create a custom override file (e.g. `~/.env/my-project.jsonc`) and save the path in your `CONFIGURU_CONFIG`. - Tip: Use inline secrets like `CFG_JSON_PATH='{"mysecret":"Sssshhh..."}'` or load from GCP Secret Manager: `CFG_JSON_PATH=$(gcloud secrets versions access latest --project=myproject --secret=mysecret)` + Tip: Use inline secrets like `CONFIGURU_CONFIG='{"mysecret":"Sssshhh..."}'` or load from GCP Secret Manager: `CONFIGURU_CONFIG=$(gcloud secrets versions access latest --project=myproject --secret=mysecret)` + + **Note:** The legacy `CFG_JSON_PATH` variable is still supported but deprecated and will be removed in the next major version. 4. Create a configuration module (e.g. `config.ts`) diff --git a/wiki/advanced-usage.md b/wiki/advanced-usage.md index fedecfa..8e67fcc 100644 --- a/wiki/advanced-usage.md +++ b/wiki/advanced-usage.md @@ -100,13 +100,13 @@ maskedConfig.apiKey // [redacted] import { createLoader } from 'configuru' const loader = createLoader({ defaultConfigPath: 'default-config', // defaults to ".env" - userConfigPath: process.env.USER_CONFIG, // defaults to process.env.CFG_JSON_PATH + userConfigPath: process.env.USER_CONFIG, // defaults to process.env.CONFIGURU_CONFIG envMode: 'all', // defaults to "default" }) ``` 1. `defaultConfigPath`: Where to look for your default config JSON file (provide null to skip) -2. `userConfigPath`: Where to look for your user config JSON file (provide null to skip) +2. `userConfigPath`: Where to look for your user config JSON file. Defaults to `process.env.CONFIGURU_CONFIG`, falling back to `process.env.CFG_JSON_PATH` (deprecated). Provide null to skip 3. `envMode`: How to handle process.env variables 1. `all` - Load (override) all vars available in process.env to the store 2. `default` - Load (override) only vars with keys from default config