Skip to content

Commit 33aaf31

Browse files
authored
Merge pull request #4 from GalvinPython/feat/associate-variable-to-cli-flag
#3: Associate variable to CLI flag
2 parents c59ae04 + 4ee9b5d commit 33aaf31

File tree

8 files changed

+181
-36
lines changed

8 files changed

+181
-36
lines changed

.github/workflows/main.yml

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
name: "CI: Test, Build, and Publish Package to npmjs"
22

33
on:
4-
release:
5-
types: [published]
4+
release:
5+
types: [published]
66

77
jobs:
8-
build-and-publish:
9-
runs-on: ubuntu-latest
10-
permissions:
11-
contents: read
12-
id-token: write
8+
build-and-publish:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: read
12+
id-token: write
1313

14-
steps:
15-
- uses: actions/checkout@v4
14+
steps:
15+
- uses: actions/checkout@v4
1616

17-
- uses: actions/setup-node@v4
18-
with:
19-
node-version: "20.x"
20-
registry-url: "https://registry.npmjs.org"
17+
- uses: actions/setup-node@v4
18+
with:
19+
node-version: "20.x"
20+
registry-url: "https://registry.npmjs.org"
2121

22-
- name: Install dependencies
23-
run: npm ci
22+
- name: Install dependencies
23+
run: npm ci
2424

25-
- name: Run tests
26-
run: npm test
25+
- name: Run tests
26+
run: npm test
2727

28-
- name: Build package
29-
run: npm run build
28+
- name: Build package
29+
run: npm run build
3030

31-
- name: Publish to npm
32-
run: npm publish --provenance --access public
33-
env:
34-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
31+
- name: Publish to npm
32+
run: npm publish --provenance --access public
33+
env:
34+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.github/workflows/test-node.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Test package across all maintained/active/current versions of Node.js
2+
3+
name: "CI: Test (Node.js)"
4+
5+
on:
6+
push:
7+
branches:
8+
- "main"
9+
pull_request:
10+
11+
concurrency:
12+
group: node-build-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
build:
17+
runs-on: ubuntu-latest
18+
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
node-version: [20, 22, 24, 25]
23+
24+
steps:
25+
- name: Checkout repository
26+
uses: actions/checkout@v4
27+
28+
- name: Setup Node.js
29+
uses: actions/setup-node@v4
30+
with:
31+
node-version: ${{ matrix.node-version }}
32+
cache: npm
33+
34+
- name: Install dependencies
35+
run: npm ci
36+
37+
- name: Test
38+
run: npm test

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# ManagedEnv
22

3+
[![CI: Test (Node.js)](https://github.com/GalvinPython/managedenv/actions/workflows/test-node.yml/badge.svg)](https://github.com/GalvinPython/managedenv/actions/workflows/test-node.yml)
34
[![Publish Package to npmjs](https://github.com/GalvinPython/managedenv/actions/workflows/main.yml/badge.svg)](https://github.com/GalvinPython/managedenv/actions/workflows/main.yml)
45
[![NPM Version](https://img.shields.io/npm/v/managedenv)](https://www.npmjs.com/package/managedenv)
6+
[![Supported NodeJS Versions](https://img.shields.io/badge/NodeJS%20Versions-20,22,24,25-blue)](https://www.npmjs.com/package/managedenv)
57

68
Notice: ManagedEnv is currently in beta
79

@@ -60,6 +62,11 @@ API_KEY: test
6062

6163
## Preview
6264

65+
### 0.2.0
66+
67+
- Removed `flag` property in favour of `useFlagInstead`
68+
- Added new `useWithFlag` property to load an environment variable when an associated flag is passed into the arguments
69+
6370
### 0.1.0
6471

6572
- Added documentation

SECURITY.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ Only the latest major version is actively maintained and receives security updat
88
| ------- | --------- |
99
| 0.x ||
1010

11-
<!-- For future reference -->
12-
<!-- | 0.x | ❌ | -->
13-
1411
## Reporting a Vulnerability
1512

1613
If you discover a security vulnerability in this project, please report it responsibly using one of the two listed methods. Do **not** create an issue about any vulnerabilities.
@@ -27,4 +24,4 @@ I prefer it if you [opened a GitHub security advisory](https://github.com/galvin
2724

2825
### Alternative Contact
2926

30-
If you do not wish to use GitHub, you may send an email to `imgalvin@pm.me` with the details of the issue
27+
If you do not wish to use GitHub, you may send an email to `contact@socialstats.app` with the details of the issue

package-lock.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "managedenv",
3-
"version": "0.1.1",
3+
"version": "0.2.0",
44
"description": "Manage your environment variables with ease",
55
"repository": {
66
"type": "git",
@@ -60,4 +60,4 @@
6060
"ts-jest": "^29.4.0",
6161
"typescript": "^5.8.3"
6262
}
63-
}
63+
}

src/index.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@ export interface VariableDefinition<T = unknown> {
2828
/**
2929
* Optional CLI flag (e.g., --token) that can be used instead of ENV.
3030
*/
31-
flag?: string;
31+
useFlagInstead?: string;
32+
33+
/**
34+
* Only load the variable if this CLI flag is present.
35+
*/
36+
useWithFlag?: string;
3237

3338
/**
3439
* Whether to quit the process if a required variable is missing.
@@ -88,20 +93,25 @@ export class EnvManager<T extends ProjectVars = {}> {
8893
required = false,
8994
default: defVal,
9095
type = (v => v) as (val: string) => any,
91-
flag,
96+
useFlagInstead,
97+
useWithFlag,
9298
quitOnMissing,
9399
} = def;
94100

95101
if (!result[project]) result[project] = {};
96102

103+
if (useWithFlag && !process.argv.includes(useWithFlag)) {
104+
continue;
105+
}
106+
97107
// First try CLI flag, then fallback to env var
98-
const raw = (flag && this.getFlagValue(flag)) || process.env[name];
108+
const raw = (useFlagInstead && this.getFlagValue(useFlagInstead)) || process.env[name];
99109

100110
if (raw === undefined || raw === "") {
101111
if (defVal !== undefined) {
102112
result[project][name] = defVal;
103113
} else if (required) {
104-
const msg = `Missing required variable/flag: ${name}${flag ? ` (flag: ${flag})` : ""}`;
114+
const msg = `Missing required variable/flag: ${name}${useFlagInstead ? ` (flag: ${useFlagInstead})` : ""}`;
105115
if (quitOnMissing !== false) throw new Error(msg);
106116
else console.warn(msg);
107117
}

tests/index.test.ts

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe("EnvManager", () => {
1313
const manager = new EnvManager()
1414
.add({
1515
name: "DISCORD_TOKEN",
16-
flag: "--discord-token",
16+
useFlagInstead: "--discord-token",
1717
type: String,
1818
project: "discordBot",
1919
required: true,
@@ -28,7 +28,7 @@ describe("EnvManager", () => {
2828
const manager = new EnvManager()
2929
.add({
3030
name: "PORT",
31-
flag: "--port",
31+
useFlagInstead: "--port",
3232
type: Number,
3333
project: "apiServer",
3434
default: 3000,
@@ -47,7 +47,7 @@ describe("EnvManager", () => {
4747
const manager = new EnvManager()
4848
.add({
4949
name: "PORT",
50-
flag: "--port",
50+
useFlagInstead: "--port",
5151
type: Number,
5252
project: "apiServer",
5353
required: false
@@ -58,6 +58,95 @@ describe("EnvManager", () => {
5858
expect(env.apiServer.PORT).toBe(8080);
5959
});
6060

61+
it("should load variable only when useWithFlag is present", () => {
62+
process.env.POSTGRES_DEV_URL = "postgres://user:pass@localhost:5432/devdb";
63+
process.argv.push("--dev");
64+
65+
const manager = new EnvManager().add({
66+
name: "POSTGRES_DEV_URL",
67+
type: String,
68+
required: true,
69+
useWithFlag: "--dev",
70+
});
71+
72+
const env = manager.load();
73+
74+
expect(env.env.POSTGRES_DEV_URL).toBe("postgres://user:pass@localhost:5432/devdb");
75+
});
76+
77+
it("should ignore variable when useWithFlag flag is not present", () => {
78+
process.env.POSTGRES_DEV_URL = "postgres://user:pass@localhost:5432/devdb";
79+
80+
const manager = new EnvManager().add({
81+
name: "POSTGRES_DEV_URL",
82+
type: String,
83+
required: true,
84+
useWithFlag: "--dev",
85+
});
86+
87+
const env = manager.load();
88+
89+
expect(env.env.POSTGRES_DEV_URL).toBeUndefined();
90+
});
91+
92+
it("should not throw required error when useWithFlag is missing", () => {
93+
const manager = new EnvManager().add({
94+
name: "POSTGRES_DEV_URL",
95+
required: true,
96+
useWithFlag: "--dev",
97+
});
98+
99+
expect(() => manager.load()).not.toThrow();
100+
});
101+
102+
it("should throw when useWithFlag is present but variable is missing", () => {
103+
process.argv.push("--dev");
104+
105+
const manager = new EnvManager().add({
106+
name: "POSTGRES_DEV_URL",
107+
required: true,
108+
useWithFlag: "--dev",
109+
});
110+
111+
expect(() => manager.load()).toThrow(
112+
"Missing required variable/flag: POSTGRES_DEV_URL"
113+
);
114+
});
115+
116+
it("should only apply default when useWithFlag is present", () => {
117+
const manager = new EnvManager().add({
118+
name: "OPTIONAL_DEV_ONLY",
119+
default: "dev-default",
120+
useWithFlag: "--dev",
121+
required: false,
122+
});
123+
124+
// flag not present
125+
let env = manager.load();
126+
expect(env.env.OPTIONAL_DEV_ONLY).toBeUndefined();
127+
128+
// flag present
129+
process.argv.push("--dev");
130+
env = manager.load();
131+
expect(env.env.OPTIONAL_DEV_ONLY).toBe("dev-default");
132+
});
133+
134+
it("should combine useWithFlag and useFlagInstead correctly", () => {
135+
process.argv.push("--dev", "--db-url", "postgres://flag");
136+
137+
const manager = new EnvManager().add({
138+
name: "POSTGRES_DEV_URL",
139+
useWithFlag: "--dev",
140+
useFlagInstead: "--db-url",
141+
type: String,
142+
required: true,
143+
});
144+
145+
const env = manager.load();
146+
147+
expect(env.env.POSTGRES_DEV_URL).toBe("postgres://flag");
148+
});
149+
61150
it("should throw for missing required variable", () => {
62151
const manager = new EnvManager()
63152
.add({

0 commit comments

Comments
 (0)