From 4c62e78ca5c45d956405b821054bfa0cae116c91 Mon Sep 17 00:00:00 2001 From: Advait Paliwal Date: Thu, 26 Mar 2026 17:49:11 -0700 Subject: [PATCH] fix: enforce bundled node version floor --- scripts/build-native-bundle.mjs | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/scripts/build-native-bundle.mjs b/scripts/build-native-bundle.mjs index 2b94ed5..29e126c 100644 --- a/scripts/build-native-bundle.mjs +++ b/scripts/build-native-bundle.mjs @@ -6,13 +6,45 @@ import { spawnSync } from "node:child_process"; const appRoot = resolve(import.meta.dirname, ".."); const packageJson = JSON.parse(readFileSync(resolve(appRoot, "package.json"), "utf8")); const packageLockPath = resolve(appRoot, "package-lock.json"); -const bundledNodeVersion = process.env.FEYNMAN_BUNDLED_NODE_VERSION ?? process.version.slice(1); +const minBundledNodeVersion = packageJson.engines?.node?.replace(/^>=/, "").trim() || process.version.slice(1); + +function parseSemver(version) { + const [major = "0", minor = "0", patch = "0"] = version.split("."); + return [Number.parseInt(major, 10) || 0, Number.parseInt(minor, 10) || 0, Number.parseInt(patch, 10) || 0]; +} + +function compareSemver(left, right) { + for (let index = 0; index < 3; index += 1) { + const diff = left[index] - right[index]; + if (diff !== 0) return diff; + } + return 0; +} function fail(message) { console.error(`[feynman] ${message}`); process.exit(1); } +function resolveBundledNodeVersion() { + const requestedNodeVersion = process.env.FEYNMAN_BUNDLED_NODE_VERSION?.trim(); + if (requestedNodeVersion) { + if (compareSemver(parseSemver(requestedNodeVersion), parseSemver(minBundledNodeVersion)) < 0) { + fail( + `FEYNMAN_BUNDLED_NODE_VERSION=${requestedNodeVersion} is below the supported floor ${minBundledNodeVersion}`, + ); + } + return requestedNodeVersion; + } + + const currentNodeVersion = process.version.slice(1); + return compareSemver(parseSemver(currentNodeVersion), parseSemver(minBundledNodeVersion)) < 0 + ? minBundledNodeVersion + : currentNodeVersion; +} + +const bundledNodeVersion = resolveBundledNodeVersion(); + function resolveCommand(command) { if (process.platform === "win32" && command === "npm") { return "npm.cmd";