Skip to content

Commit f776790

Browse files
Add populateProcessEnv option to getPlatformProxy to populate process.env with text and JSON bindings
1 parent c7d0d18 commit f776790

File tree

7 files changed

+443
-0
lines changed

7 files changed

+443
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
"wrangler": minor
3+
---
4+
5+
Add `populateProcessEnv` option to `getPlatformProxy` to populate `process.env` with text and JSON bindings
6+
7+
The `getPlatformProxy` utility now supports an optional `populateProcessEnv` option that mirrors the workerd behavior of the `nodejs_compat_populate_process_env` compatibility flag.
8+
9+
When enabled, `process.env` is side-effectfully updated with environment variables and secrets from your wrangler configuration and `.env` files. JSON values are stringified. The original `process.env` values are restored when `dispose()` is called.
10+
11+
Behavior:
12+
13+
- `populateProcessEnv: true` - Always populate `process.env`
14+
- `populateProcessEnv: false` - Never populate `process.env`
15+
- `populateProcessEnv: undefined` (default) - Follows the same rules as workerd:
16+
- Enabled when `nodejs_compat` compatibility flag is set AND either:
17+
- `compatibility_date` is `"2025-04-01"` or later, OR
18+
- `nodejs_compat_populate_process_env` flag is explicitly set
19+
- Disabled when `nodejs_compat_do_not_populate_process_env` flag is set
20+
21+
Example:
22+
23+
```typescript
24+
import { getPlatformProxy } from "wrangler";
25+
26+
// Uses default behavior based on your wrangler.json compat settings
27+
const { env, dispose } = await getPlatformProxy();
28+
29+
// process.env now contains your vars and secrets (if enabled)
30+
console.log(process.env.MY_VAR);
31+
32+
// Cleanup restores original process.env
33+
await dispose();
34+
```
35+
36+
```typescript
37+
// Explicitly enable regardless of compat settings
38+
const { env, dispose } = await getPlatformProxy({
39+
populateProcessEnv: true,
40+
});
41+
```
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
import path from "node:path";
2+
import { beforeEach, describe, it, vi } from "vitest";
3+
import { getPlatformProxy } from "wrangler";
4+
5+
const modernConfigPath = path.join(
6+
__dirname,
7+
"..",
8+
"wrangler_process_env_modern.jsonc"
9+
);
10+
const oldConfigPath = path.join(
11+
__dirname,
12+
"..",
13+
"wrangler_process_env_old.jsonc"
14+
);
15+
const oldWithFlagConfigPath = path.join(
16+
__dirname,
17+
"..",
18+
"wrangler_process_env_old_with_flag.jsonc"
19+
);
20+
const modernDisabledConfigPath = path.join(
21+
__dirname,
22+
"..",
23+
"wrangler_process_env_modern_disabled.jsonc"
24+
);
25+
26+
describe("getPlatformProxy - process.env population", () => {
27+
beforeEach(() => {
28+
// Hide stdout messages from the test logs
29+
vi.spyOn(console, "log").mockImplementation(() => {});
30+
vi.spyOn(console, "error").mockImplementation(() => {});
31+
vi.spyOn(console, "warn").mockImplementation(() => {});
32+
});
33+
34+
describe("explicit populateProcessEnv option", () => {
35+
it("populates process.env when populateProcessEnv is true", async ({
36+
expect,
37+
}) => {
38+
const originalMyVar = process.env.MY_VAR;
39+
const originalMyJsonVar = process.env.MY_JSON_VAR;
40+
41+
// Use old config (which wouldn't auto-enable) but explicitly enable
42+
const { dispose } = await getPlatformProxy({
43+
configPath: oldConfigPath,
44+
populateProcessEnv: true,
45+
persist: false,
46+
});
47+
48+
try {
49+
expect(process.env.MY_VAR).toBe("my-var-value");
50+
expect(process.env.MY_JSON_VAR).toBe(
51+
JSON.stringify({ test: true, nested: { value: 123 } })
52+
);
53+
} finally {
54+
await dispose();
55+
}
56+
57+
expect(process.env.MY_VAR).toEqual(originalMyVar);
58+
expect(process.env.MY_JSON_VAR).toEqual(originalMyJsonVar);
59+
});
60+
61+
it("does NOT populate process.env when populateProcessEnv is false", async ({
62+
expect,
63+
}) => {
64+
// Use modern config (which would auto-enable) but explicitly disable
65+
const originalMyVar = process.env.MY_VAR;
66+
const originalMyJsonVar = process.env.MY_JSON_VAR;
67+
68+
const { dispose } = await getPlatformProxy({
69+
configPath: modernConfigPath,
70+
populateProcessEnv: false,
71+
persist: false,
72+
});
73+
74+
try {
75+
expect(process.env.MY_VAR).toEqual(originalMyVar);
76+
expect(process.env.MY_JSON_VAR).toEqual(originalMyJsonVar);
77+
} finally {
78+
await dispose();
79+
}
80+
});
81+
});
82+
83+
describe("default behavior based on compat date/flags", () => {
84+
it("auto-enables for modern compat date (>= 2025-04-01) with nodejs_compat", async ({
85+
expect,
86+
}) => {
87+
const originalMyVar = process.env.MY_VAR;
88+
const originalMyJsonVar = process.env.MY_JSON_VAR;
89+
90+
const { dispose } = await getPlatformProxy({
91+
configPath: modernConfigPath,
92+
persist: false,
93+
});
94+
95+
try {
96+
expect(process.env.MY_VAR).toBe("my-var-value");
97+
expect(process.env.MY_JSON_VAR).toBe(
98+
JSON.stringify({ test: true, nested: { value: 123 } })
99+
);
100+
} finally {
101+
await dispose();
102+
}
103+
104+
expect(process.env.MY_VAR).toEqual(originalMyVar);
105+
expect(process.env.MY_JSON_VAR).toEqual(originalMyJsonVar);
106+
});
107+
108+
it("does NOT auto-enable for old compat date (< 2025-04-01)", async ({
109+
expect,
110+
}) => {
111+
const originalMyVar = process.env.MY_VAR;
112+
const originalMyJsonVar = process.env.MY_JSON_VAR;
113+
114+
const { dispose } = await getPlatformProxy({
115+
configPath: oldConfigPath,
116+
persist: false,
117+
});
118+
119+
try {
120+
expect(process.env.MY_VAR).toEqual(originalMyVar);
121+
expect(process.env.MY_JSON_VAR).toEqual(originalMyJsonVar);
122+
} finally {
123+
await dispose();
124+
}
125+
});
126+
127+
it("auto-enables for old compat date with explicit nodejs_compat_populate_process_env flag", async ({
128+
expect,
129+
}) => {
130+
const originalMyVar = process.env.MY_VAR;
131+
const originalMyJsonVar = process.env.MY_JSON_VAR;
132+
133+
const { dispose } = await getPlatformProxy({
134+
configPath: oldWithFlagConfigPath,
135+
persist: false,
136+
});
137+
138+
try {
139+
expect(process.env.MY_VAR).toBe("my-var-value");
140+
expect(process.env.MY_JSON_VAR).toBe(
141+
JSON.stringify({ test: true, nested: { value: 123 } })
142+
);
143+
} finally {
144+
await dispose();
145+
}
146+
147+
expect(process.env.MY_VAR).toEqual(originalMyVar);
148+
expect(process.env.MY_JSON_VAR).toEqual(originalMyJsonVar);
149+
});
150+
151+
it("does NOT auto-enable for modern compat date with nodejs_compat_do_not_populate_process_env flag", async ({
152+
expect,
153+
}) => {
154+
const originalMyVar = process.env.MY_VAR;
155+
const originalMyJsonVar = process.env.MY_JSON_VAR;
156+
157+
const { dispose } = await getPlatformProxy({
158+
configPath: modernDisabledConfigPath,
159+
persist: false,
160+
});
161+
162+
try {
163+
expect(process.env.MY_VAR).toEqual(originalMyVar);
164+
expect(process.env.MY_JSON_VAR).toEqual(originalMyJsonVar);
165+
} finally {
166+
await dispose();
167+
}
168+
});
169+
});
170+
171+
describe("dispose() behavior", () => {
172+
it("restores original process.env values on dispose", async ({
173+
expect,
174+
}) => {
175+
process.env.MY_VAR = "original-value";
176+
process.env.MY_JSON_VAR = "original-json";
177+
178+
const { dispose } = await getPlatformProxy({
179+
configPath: modernConfigPath,
180+
persist: false,
181+
});
182+
183+
expect(process.env.MY_VAR).toBe("my-var-value");
184+
expect(process.env.MY_JSON_VAR).toBe(
185+
JSON.stringify({ test: true, nested: { value: 123 } })
186+
);
187+
188+
await dispose();
189+
190+
expect(process.env.MY_VAR).toEqual("original-value");
191+
expect(process.env.MY_JSON_VAR).toEqual("original-json");
192+
193+
delete process.env.MY_VAR;
194+
delete process.env.MY_JSON_VAR;
195+
});
196+
197+
it("deletes keys that did not exist before getPlatformProxy was called", async ({
198+
expect,
199+
}) => {
200+
delete process.env.MY_VAR;
201+
delete process.env.MY_JSON_VAR;
202+
203+
const { dispose } = await getPlatformProxy({
204+
configPath: modernConfigPath,
205+
persist: false,
206+
});
207+
208+
expect(process.env.MY_VAR).toBe("my-var-value");
209+
expect(process.env.MY_JSON_VAR).toBeDefined();
210+
211+
await dispose();
212+
213+
expect("MY_VAR" in process.env).toBe(false);
214+
expect("MY_JSON_VAR" in process.env).toBe(false);
215+
});
216+
});
217+
218+
describe("JSON value handling", () => {
219+
it("stringifies JSON values when adding to process.env", async ({
220+
expect,
221+
}) => {
222+
const { dispose } = await getPlatformProxy({
223+
configPath: modernConfigPath,
224+
persist: false,
225+
});
226+
227+
try {
228+
const jsonValue = process.env.MY_JSON_VAR;
229+
expect(typeof jsonValue).toBe("string");
230+
expect(JSON.parse(jsonValue!)).toEqual({
231+
test: true,
232+
nested: { value: 123 },
233+
});
234+
} finally {
235+
await dispose();
236+
}
237+
});
238+
});
239+
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
// Modern compat date (>= 2025-04-01) with nodejs_compat
3+
// This should auto-enable process.env population
4+
"name": "get-platform-proxy-process-env-modern",
5+
"main": "src/index.ts",
6+
"compatibility_date": "2025-04-01",
7+
"compatibility_flags": ["nodejs_compat"],
8+
"vars": {
9+
"MY_VAR": "my-var-value",
10+
"MY_JSON_VAR": {
11+
"test": true,
12+
"nested": { "value": 123 },
13+
},
14+
},
15+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
// Modern compat date but with explicit disable flag
3+
// This should NOT auto-enable process.env population
4+
"name": "get-platform-proxy-process-env-modern-disabled",
5+
"main": "src/index.ts",
6+
"compatibility_date": "2025-04-01",
7+
"compatibility_flags": [
8+
"nodejs_compat",
9+
"nodejs_compat_do_not_populate_process_env",
10+
],
11+
"vars": {
12+
"MY_VAR": "my-var-value",
13+
"MY_JSON_VAR": {
14+
"test": true,
15+
"nested": { "value": 123 },
16+
},
17+
},
18+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
// Old compat date (< 2025-04-01) with nodejs_compat
3+
// This should NOT auto-enable process.env population
4+
"name": "get-platform-proxy-process-env-old",
5+
"main": "src/index.ts",
6+
"compatibility_date": "2024-01-01",
7+
"compatibility_flags": ["nodejs_compat"],
8+
"vars": {
9+
"MY_VAR": "my-var-value",
10+
"MY_JSON_VAR": {
11+
"test": true,
12+
"nested": { "value": 123 },
13+
},
14+
},
15+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
// Old compat date but with explicit nodejs_compat_populate_process_env flag
3+
// This should auto-enable process.env population
4+
"name": "get-platform-proxy-process-env-old-with-flag",
5+
"main": "src/index.ts",
6+
"compatibility_date": "2024-01-01",
7+
"compatibility_flags": [
8+
"nodejs_compat",
9+
"nodejs_compat_populate_process_env",
10+
],
11+
"vars": {
12+
"MY_VAR": "my-var-value",
13+
"MY_JSON_VAR": {
14+
"test": true,
15+
"nested": { "value": 123 },
16+
},
17+
},
18+
}

0 commit comments

Comments
 (0)