Skip to content

Commit 6b9cd5b

Browse files
vicbanonrig
andauthored
add support for native node:os (#10208)
Co-authored-by: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 626b226 commit 6b9cd5b

File tree

6 files changed

+106
-74
lines changed

6 files changed

+106
-74
lines changed

.changeset/cold-hands-reply.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudflare/unenv-preset": minor
3+
---
4+
5+
add support for native `node:os`

packages/unenv-preset/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
},
5252
"peerDependencies": {
5353
"unenv": "2.0.0-rc.19",
54-
"workerd": "^1.20250730.0"
54+
"workerd": "^1.20250802.0"
5555
},
5656
"peerDependenciesMeta": {
5757
"workerd": {

packages/unenv-preset/src/preset.ts

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,23 @@ export function getCloudflarePreset({
7171
compatibilityFlags,
7272
});
7373

74+
const osOverrides = getOsOverrides({
75+
compatibilityDate,
76+
compatibilityFlags,
77+
});
78+
7479
// "dynamic" as they depend on the compatibility date and flags
7580
const dynamicNativeModules = [
7681
...nativeModules,
7782
...httpOverrides.nativeModules,
83+
...osOverrides.nativeModules,
7884
];
7985

8086
// "dynamic" as they depend on the compatibility date and flags
8187
const dynamicHybridModules = [
8288
...hybridModules,
8389
...httpOverrides.hybridModules,
90+
...osOverrides.hybridModules,
8491
];
8592

8693
return {
@@ -138,6 +145,7 @@ export function getCloudflarePreset({
138145
*
139146
* The native http server APIS implementation:
140147
* - can be enabled with the "enable_nodejs_http_server_modules" flag
148+
* - can be disabled with the "disable_nodejs_http_server_modules" flag
141149
*/
142150
function getHttpOverrides({
143151
compatibilityDate,
@@ -149,31 +157,31 @@ function getHttpOverrides({
149157
const httpDisabledByFlag = compatibilityFlags.includes(
150158
"disable_nodejs_http_modules"
151159
);
152-
const httpEnabledByFlags = compatibilityFlags.includes(
160+
const httpEnabledByFlag = compatibilityFlags.includes(
153161
"enable_nodejs_http_modules"
154162
);
155163
const httpEnabledByDate = compatibilityDate >= "2025-08-15";
156164

157165
const httpEnabled =
158-
(httpEnabledByFlags || httpEnabledByDate) && !httpDisabledByFlag;
166+
(httpEnabledByFlag || httpEnabledByDate) && !httpDisabledByFlag;
159167

160168
if (!httpEnabled) {
161169
// use the unenv polyfill
162170
return { nativeModules: [], hybridModules: [] };
163171
}
164172

165-
const httpServerEnabledByFlags = compatibilityFlags.includes(
166-
"enable_nodejs_http_server_modules"
167-
);
173+
const httpServerEnabledByFlag =
174+
compatibilityFlags.includes("enable_nodejs_http_server_modules") &&
175+
compatibilityFlags.includes("experimental");
168176

169-
const httpServerDisabledByFlags = compatibilityFlags.includes(
177+
const httpServerDisabledByFlag = compatibilityFlags.includes(
170178
"disable_nodejs_http_server_modules"
171179
);
172180

173181
// Note that `httpServerEnabled` requires `httpEnabled`
174182
// TODO: add `httpServerEnabledByDate` when a default date is set
175183
const httpServerEnabled =
176-
httpServerEnabledByFlags && !httpServerDisabledByFlags;
184+
httpServerEnabledByFlag && !httpServerDisabledByFlag;
177185

178186
// Override unenv base aliases with native and hybrid modules
179187
// `node:https` is fully implemented by workerd if both flags are enabled
@@ -189,3 +197,42 @@ function getHttpOverrides({
189197
hybridModules: httpServerEnabled ? ["http"] : ["http", "https"],
190198
};
191199
}
200+
201+
/**
202+
* Returns the overrides for `node:os` (unenv or workerd)
203+
*
204+
* The native http implementation:
205+
* - can be enabled with the "enable_nodejs_os_module" flag
206+
* - can be disabled with the "disable_nodejs_os_module" flag
207+
*/
208+
function getOsOverrides({
209+
// eslint-disable-next-line unused-imports/no-unused-vars
210+
compatibilityDate,
211+
compatibilityFlags,
212+
}: {
213+
compatibilityDate: string;
214+
compatibilityFlags: string[];
215+
}): { nativeModules: string[]; hybridModules: string[] } {
216+
const disabledByFlag = compatibilityFlags.includes(
217+
"disable_nodejs_os_module"
218+
);
219+
220+
const enabledByFlag =
221+
compatibilityFlags.includes("enable_nodejs_os_module") &&
222+
compatibilityFlags.includes("experimental");
223+
224+
// TODO: add `enabledByDate` when a default date is set
225+
const enabled = enabledByFlag && !disabledByFlag;
226+
227+
// The native os module implements all the APIs.
228+
// It can then be used as a native module.
229+
return enabled
230+
? {
231+
nativeModules: ["os"],
232+
hybridModules: [],
233+
}
234+
: {
235+
nativeModules: [],
236+
hybridModules: [],
237+
};
238+
}

packages/wrangler/e2e/unenv-preset/preset.test.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ type TestConfig = {
1515
compatibilityFlags?: string[];
1616
// Assert runtime compatibility flag values
1717
expectRuntimeFlags?: {
18-
// Whether the http modules are enabled
19-
enable_nodejs_http_modules: boolean;
18+
enable_nodejs_http_modules?: boolean;
19+
enable_nodejs_http_server_modules?: boolean;
20+
enable_nodejs_os_module?: boolean;
2021
};
2122
};
2223

@@ -95,6 +96,35 @@ const testConfigs: TestConfig[] = [
9596
},
9697
},
9798
],
99+
// node:os
100+
[
101+
{
102+
name: "os disabled by date",
103+
compatibilityDate: "2025-07-26",
104+
compatibilityFlags: ["experimental"],
105+
expectRuntimeFlags: {
106+
enable_nodejs_os_module: false,
107+
},
108+
},
109+
// TODO: add a config when os is enabled by default (date no set yet)
110+
{
111+
name: "os enabled by flag",
112+
compatibilityDate: "2025-07-26",
113+
compatibilityFlags: ["enable_nodejs_os_module", "experimental"],
114+
expectRuntimeFlags: {
115+
enable_nodejs_os_module: true,
116+
},
117+
},
118+
// TODO: change the date pass the default enabled date (date not set yet)
119+
{
120+
name: "os disabled by flag",
121+
compatibilityDate: "2025-07-26",
122+
compatibilityFlags: ["disable_nodejs_os_module", "experimental"],
123+
expectRuntimeFlags: {
124+
enable_nodejs_os_module: false,
125+
},
126+
},
127+
],
98128
].flat();
99129

100130
describe.each(testConfigs)(

packages/wrangler/e2e/unenv-preset/worker/index.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ export const WorkerdTests: Record<string, () => void> = {
243243
},
244244

245245
async testHttp() {
246-
const http = await import("http");
246+
const http = await import("node:http");
247247

248248
const useNativeHttp = getRuntimeFlagValue("enable_nodejs_http_modules");
249249

@@ -270,7 +270,7 @@ export const WorkerdTests: Record<string, () => void> = {
270270
},
271271

272272
async testHttps() {
273-
const https = await import("https");
273+
const https = await import("node:https");
274274

275275
assert.strictEqual(typeof https.Agent, "function");
276276
assert.strictEqual(typeof https.get, "function");
@@ -279,7 +279,7 @@ export const WorkerdTests: Record<string, () => void> = {
279279
},
280280

281281
async testHttpServer() {
282-
const http = await import("http");
282+
const http = await import("node:http");
283283

284284
const useNativeHttp = getRuntimeFlagValue(
285285
"enable_nodejs_http_server_modules"
@@ -303,7 +303,7 @@ export const WorkerdTests: Record<string, () => void> = {
303303
},
304304

305305
async testHttpsServer() {
306-
const https = await import("https");
306+
const https = await import("node:https");
307307

308308
const useNativeHttp = getRuntimeFlagValue(
309309
"enable_nodejs_http_server_modules"
@@ -325,4 +325,12 @@ export const WorkerdTests: Record<string, () => void> = {
325325
assert.throws(() => new https.Server(), /not implemented/);
326326
}
327327
},
328+
329+
async testOs() {
330+
const os = await import("node:os");
331+
332+
assert.strictEqual(typeof os.arch(), "string");
333+
assert.strictEqual(typeof os.freemem(), "number");
334+
assert.strictEqual(typeof os.availableParallelism(), "number");
335+
},
328336
};

pnpm-lock.yaml

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

0 commit comments

Comments
 (0)