From b39c629dcc9801abf82df5c770dfd6555cd2719c Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Thu, 26 Feb 2026 18:33:21 -0800 Subject: [PATCH] Validate dev runner port overrides and honor env state dir - Prefer `T3CODE_STATE_DIR` from env when `--state-dir` is unset or blank - Throw on invalid `T3CODE_PORT` overrides and always recompute `VITE_WS_URL` - Add tests for env/state-dir precedence, blank overrides, and invalid ports --- scripts/dev-runner.mjs | 23 ++++++++++++++++++----- scripts/dev-runner.test.ts | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/scripts/dev-runner.mjs b/scripts/dev-runner.mjs index 1c6efcc63d6068221babce6b0509274c7f715a82..723806bbebc23207a6d530b835df6b0d12f70885 100644 --- a/scripts/dev-runner.mjs +++ b/scripts/dev-runner.mjs @@ -151,8 +151,18 @@ export function parseDevRunnerArgs(rawArgs) { }; } -function resolveStateDir(envOverrides) { - return envOverrides.T3CODE_STATE_DIR ?? DEFAULT_DEV_STATE_DIR; +function resolveStateDir(env, envOverrides) { + const overrideValue = envOverrides?.T3CODE_STATE_DIR?.trim(); + if (overrideValue) { + return overrideValue; + } + + const envValue = env?.T3CODE_STATE_DIR?.trim(); + if (envValue) { + return envValue; + } + + return DEFAULT_DEV_STATE_DIR; } export function createDevRunnerEnv({ mode, env, offset, envOverrides }) { @@ -169,12 +179,15 @@ export function createDevRunnerEnv({ mode, env, offset, envOverrides }) { ...envOverrides, }; - output.T3CODE_STATE_DIR = resolveStateDir(envOverrides); + output.T3CODE_STATE_DIR = resolveStateDir(env, envOverrides); const parsedServerPort = Number(output.T3CODE_PORT); - if (Number.isInteger(parsedServerPort) && parsedServerPort > 0 && parsedServerPort <= 65535) { - output.VITE_WS_URL = `ws://localhost:${parsedServerPort}`; + if (!Number.isInteger(parsedServerPort) || parsedServerPort < 1 || parsedServerPort > 65535) { + throw new Error( + `Invalid T3CODE_PORT override: '${String(output.T3CODE_PORT)}'. Expected an integer between 1 and 65535.`, + ); } + output.VITE_WS_URL = `ws://localhost:${parsedServerPort}`; if (mode === "dev" || mode === "dev:server" || mode === "dev:web") { // Running server/web in browser mode should not inherit desktop launcher state. diff --git a/scripts/dev-runner.test.ts b/scripts/dev-runner.test.ts index 4501bf7922705fdcc736004848020c1922fb4801..988f57c137d6b5a21bb4e7b5dd8396c02f42e56f 100644 --- a/scripts/dev-runner.test.ts +++ b/scripts/dev-runner.test.ts @@ -42,7 +42,7 @@ describe("createDevRunnerEnv", () => { it("defaults state dir to ~/.t3/dev when not provided", () => { const env = createDevRunnerEnv({ mode: "dev", - env: { T3CODE_STATE_DIR: "/tmp/prod-state" }, + env: {}, offset: 0, envOverrides: {}, }); @@ -50,6 +50,17 @@ describe("createDevRunnerEnv", () => { expect(env.T3CODE_STATE_DIR).toBe(DEFAULT_DEV_STATE_DIR); }); + it("uses existing env state dir when --state-dir is not provided", () => { + const env = createDevRunnerEnv({ + mode: "dev:server", + env: { T3CODE_STATE_DIR: "/tmp/existing-state" }, + offset: 0, + envOverrides: {}, + }); + + expect(env.T3CODE_STATE_DIR).toBe("/tmp/existing-state"); + }); + it("lets --state-dir override existing env state dir", () => { const env = createDevRunnerEnv({ mode: "dev:server", @@ -61,6 +72,17 @@ describe("createDevRunnerEnv", () => { expect(env.T3CODE_STATE_DIR).toBe("/tmp/override-state"); }); + it("treats whitespace-only --state-dir as missing and falls back to env/default", () => { + const env = createDevRunnerEnv({ + mode: "dev:server", + env: { T3CODE_STATE_DIR: "/tmp/existing-state" }, + offset: 0, + envOverrides: { T3CODE_STATE_DIR: " " }, + }); + + expect(env.T3CODE_STATE_DIR).toBe("/tmp/existing-state"); + }); + it("recomputes websocket url when port is overridden", () => { const env = createDevRunnerEnv({ mode: "dev", @@ -89,4 +111,15 @@ describe("createDevRunnerEnv", () => { expect(env.T3CODE_NO_BROWSER).toBe("1"); expect(env.T3CODE_AUTH_TOKEN).toBe("cli-token"); }); + + it("fails fast for invalid port overrides", () => { + expect(() => + createDevRunnerEnv({ + mode: "dev", + env: {}, + offset: 0, + envOverrides: { T3CODE_PORT: "not-a-port" }, + }), + ).toThrow("Invalid T3CODE_PORT override"); + }); }); -- 2.54.0