diff --git a/.changeset/silver-eyes-sing.md b/.changeset/silver-eyes-sing.md new file mode 100644 index 000000000000..89d5cfca47f7 --- /dev/null +++ b/.changeset/silver-eyes-sing.md @@ -0,0 +1,6 @@ +--- +"@cloudflare/unenv-preset": patch +"wrangler": patch +--- + +Use the native `node:tty`, `node:repl`, `node:readline`, `node:inspector`, `node:v8`, and `node:dgram` modules when available diff --git a/packages/unenv-preset/src/preset.ts b/packages/unenv-preset/src/preset.ts index cecfa5c62752..e37427ae3238 100644 --- a/packages/unenv-preset/src/preset.ts +++ b/packages/unenv-preset/src/preset.ts @@ -74,6 +74,12 @@ export function getCloudflarePreset({ const fsOverrides = getFsOverrides(compat); const punycodeOverrides = getPunycodeOverrides(compat); const clusterOverrides = getClusterOverrides(compat); + const ttyOverrides = getTtyOverrides(compat); + const replOverrides = getReplOverrides(compat); + const readlineOverrides = getReadlineOverrides(compat); + const inspectorOverrides = getInspectorOverrides(compat); + const v8Overrides = getV8Overrides(compat); + const dgramOverrides = getDgramOverrides(compat); // "dynamic" as they depend on the compatibility date and flags const dynamicNativeModules = [ @@ -84,6 +90,12 @@ export function getCloudflarePreset({ ...fsOverrides.nativeModules, ...punycodeOverrides.nativeModules, ...clusterOverrides.nativeModules, + ...ttyOverrides.nativeModules, + ...replOverrides.nativeModules, + ...readlineOverrides.nativeModules, + ...inspectorOverrides.nativeModules, + ...v8Overrides.nativeModules, + ...dgramOverrides.nativeModules, ]; // "dynamic" as they depend on the compatibility date and flags @@ -95,6 +107,12 @@ export function getCloudflarePreset({ ...fsOverrides.hybridModules, ...punycodeOverrides.hybridModules, ...clusterOverrides.hybridModules, + ...ttyOverrides.hybridModules, + ...replOverrides.hybridModules, + ...readlineOverrides.hybridModules, + ...inspectorOverrides.hybridModules, + ...v8Overrides.hybridModules, + ...dgramOverrides.hybridModules, ]; return { @@ -387,3 +405,231 @@ function getClusterOverrides({ hybridModules: [], }; } + +/** + * Returns the overrides for `node:tty` (unenv or workerd) + * + * The native tty implementation: + * - is experimental + * - can be enabled with the "enable_nodejs_tty_module" flag + * - can be disabled with the "disable_nodejs_tty_module" flag + */ +function getTtyOverrides({ + // eslint-disable-next-line unused-imports/no-unused-vars + compatibilityDate, + compatibilityFlags, +}: { + compatibilityDate: string; + compatibilityFlags: string[]; +}): { nativeModules: string[]; hybridModules: string[] } { + const disabledByFlag = compatibilityFlags.includes( + "disable_nodejs_tty_module" + ); + + // TODO: add `enabledByDate` when a date is defined in workerd + const enabledByFlag = + compatibilityFlags.includes("enable_nodejs_tty_module") && + compatibilityFlags.includes("experimental"); + + const enabled = enabledByFlag && !disabledByFlag; + + return enabled + ? { + nativeModules: ["tty"], + hybridModules: [], + } + : { + nativeModules: [], + hybridModules: [], + }; +} + +/** + * Returns the overrides for `node:repl` (unenv or workerd) + * + * The native repl implementation: + * - is experimental + * - can be enabled with the "enable_nodejs_repl_module" flag + * - can be disabled with the "disable_nodejs_repl_module" flag + */ +function getReplOverrides({ + // eslint-disable-next-line unused-imports/no-unused-vars + compatibilityDate, + compatibilityFlags, +}: { + compatibilityDate: string; + compatibilityFlags: string[]; +}): { nativeModules: string[]; hybridModules: string[] } { + const disabledByFlag = compatibilityFlags.includes( + "disable_nodejs_repl_module" + ); + + // TODO: add `enabledByDate` when a date is defined in workerd + const enabledByFlag = + compatibilityFlags.includes("enable_nodejs_repl_module") && + compatibilityFlags.includes("experimental"); + + const enabled = enabledByFlag && !disabledByFlag; + + return enabled + ? { + nativeModules: ["repl"], + hybridModules: [], + } + : { + nativeModules: [], + hybridModules: [], + }; +} + +/** + * Returns the overrides for `node:readline` (unenv or workerd) + * + * The native readline implementation: + * - is experimental + * - can be enabled with the "enable_nodejs_readline_module" flag + * - can be disabled with the "disable_nodejs_readline_module" flag + */ +function getReadlineOverrides({ + // eslint-disable-next-line unused-imports/no-unused-vars + compatibilityDate, + compatibilityFlags, +}: { + compatibilityDate: string; + compatibilityFlags: string[]; +}): { nativeModules: string[]; hybridModules: string[] } { + const disabledByFlag = compatibilityFlags.includes( + "disable_nodejs_readline_module" + ); + + // TODO: add `enabledByDate` when a date is defined in workerd + const enabledByFlag = + compatibilityFlags.includes("enable_nodejs_readline_module") && + compatibilityFlags.includes("experimental"); + + const enabled = enabledByFlag && !disabledByFlag; + + return enabled + ? { + nativeModules: ["readline"], + hybridModules: [], + } + : { + nativeModules: [], + hybridModules: [], + }; +} + +/** + * Returns the overrides for `node:inspector` (unenv or workerd) + * + * The native inspector implementation: + * - is experimental + * - can be enabled with the "enable_nodejs_inspector_module" flag + * - can be disabled with the "disable_nodejs_inspector_module" flag + */ +function getInspectorOverrides({ + // eslint-disable-next-line unused-imports/no-unused-vars + compatibilityDate, + compatibilityFlags, +}: { + compatibilityDate: string; + compatibilityFlags: string[]; +}): { nativeModules: string[]; hybridModules: string[] } { + const disabledByFlag = compatibilityFlags.includes( + "disable_nodejs_inspector_module" + ); + + // TODO: add `enabledByDate` when a date is defined in workerd + const enabledByFlag = + compatibilityFlags.includes("enable_nodejs_inspector_module") && + compatibilityFlags.includes("experimental"); + + const enabled = enabledByFlag && !disabledByFlag; + + return enabled + ? { + nativeModules: ["inspector"], + hybridModules: [], + } + : { + nativeModules: [], + hybridModules: [], + }; +} + +/** + * Returns the overrides for `node:v8` (unenv or workerd) + * + * The native v8 implementation: + * - is experimental + * - can be enabled with the "enable_nodejs_v8_module" flag + * - can be disabled with the "disable_nodejs_v8_module" flag + */ +function getV8Overrides({ + // eslint-disable-next-line unused-imports/no-unused-vars + compatibilityDate, + compatibilityFlags, +}: { + compatibilityDate: string; + compatibilityFlags: string[]; +}): { nativeModules: string[]; hybridModules: string[] } { + const disabledByFlag = compatibilityFlags.includes( + "disable_nodejs_v8_module" + ); + + // TODO: add `enabledByDate` when a date is defined in workerd + const enabledByFlag = + compatibilityFlags.includes("enable_nodejs_v8_module") && + compatibilityFlags.includes("experimental"); + + const enabled = enabledByFlag && !disabledByFlag; + + return enabled + ? { + nativeModules: ["v8"], + hybridModules: [], + } + : { + nativeModules: [], + hybridModules: [], + }; +} + +/** + * Returns the overrides for `node:dgram` (unenv or workerd) + * + * The native dgram implementation: + * - is experimental + * - can be enabled with the "enable_nodejs_dgram_module" flag + * - can be disabled with the "disable_nodejs_dgram_module" flag + */ +function getDgramOverrides({ + // eslint-disable-next-line unused-imports/no-unused-vars + compatibilityDate, + compatibilityFlags, +}: { + compatibilityDate: string; + compatibilityFlags: string[]; +}): { nativeModules: string[]; hybridModules: string[] } { + const disabledByFlag = compatibilityFlags.includes( + "disable_nodejs_dgram_module" + ); + + // TODO: add `enabledByDate` when a date is defined in workerd + const enabledByFlag = + compatibilityFlags.includes("enable_nodejs_dgram_module") && + compatibilityFlags.includes("experimental"); + + const enabled = enabledByFlag && !disabledByFlag; + + return enabled + ? { + nativeModules: ["dgram"], + hybridModules: [], + } + : { + nativeModules: [], + hybridModules: [], + }; +} diff --git a/packages/wrangler/e2e/unenv-preset/preset.test.ts b/packages/wrangler/e2e/unenv-preset/preset.test.ts index 4a96cea0d372..d031da9793da 100644 --- a/packages/wrangler/e2e/unenv-preset/preset.test.ts +++ b/packages/wrangler/e2e/unenv-preset/preset.test.ts @@ -278,6 +278,114 @@ const localTestConfigs: TestConfig[] = [ }, }, ], + [ + { + name: "tty enabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["enable_nodejs_tty_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_tty_module: true, + }, + }, + { + name: "tty disabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["disable_nodejs_tty_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_tty_module: false, + }, + }, + ], + [ + { + name: "repl enabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["enable_nodejs_repl_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_repl_module: true, + }, + }, + { + name: "repl disabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["disable_nodejs_repl_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_repl_module: false, + }, + }, + ], + [ + { + name: "readline enabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["enable_nodejs_readline_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_readline_module: true, + }, + }, + { + name: "readline disabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["disable_nodejs_readline_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_readline_module: false, + }, + }, + ], + [ + { + name: "inspector enabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["enable_nodejs_inspector_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_inspector_module: true, + }, + }, + { + name: "inspector disabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["disable_nodejs_inspector_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_inspector_module: false, + }, + }, + ], + [ + { + name: "v8 enabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["enable_nodejs_v8_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_v8_module: true, + }, + }, + { + name: "v8 disabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["disable_nodejs_v8_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_v8_module: false, + }, + }, + ], + [ + { + name: "dgram enabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["enable_nodejs_dgram_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_dgram_module: true, + }, + }, + { + name: "dgram disabled by flag", + compatibilityDate: "2024-09-23", + compatibilityFlags: ["disable_nodejs_dgram_module", "experimental"], + expectRuntimeFlags: { + enable_nodejs_dgram_module: false, + }, + }, + ], ].flat() as TestConfig[]; describe.each(localTestConfigs)(