authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-26 18:33:21-08:00
committergravatar for jmarminge@gmail.comJulius Marminge <jmarminge@gmail.com> 2026-02-26 18:40:23-08:00
logb39c629dcc9801abf82df5c770dfd6555cd2719c
treeffd139ac6fa95e986a39954508c5780f32330d92
parentb95cc59e79b15528a61774d0750d86e7199b0c0b

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

2 files changed, 52 insertions(+), 6 deletions(-)

scripts/dev-runner.mjs+18-5
......@@ -151,8 +151,18 @@ export function parseDevRunnerArgs(rawArgs) {
151151 };
152152}
153153
154function resolveStateDir(envOverrides) {
155 return envOverrides.T3CODE_STATE_DIR ?? DEFAULT_DEV_STATE_DIR;
154function resolveStateDir(env, envOverrides) {
155 const overrideValue = envOverrides?.T3CODE_STATE_DIR?.trim();
156 if (overrideValue) {
157 return overrideValue;
158 }
159
160 const envValue = env?.T3CODE_STATE_DIR?.trim();
161 if (envValue) {
162 return envValue;
163 }
164
165 return DEFAULT_DEV_STATE_DIR;
156166}
157167
158168export function createDevRunnerEnv({ mode, env, offset, envOverrides }) {
......@@ -169,12 +179,15 @@ export function createDevRunnerEnv({ mode, env, offset, envOverrides }) {
169179 ...envOverrides,
170180 };
171181
172 output.T3CODE_STATE_DIR = resolveStateDir(envOverrides);
182 output.T3CODE_STATE_DIR = resolveStateDir(env, envOverrides);
173183
174184 const parsedServerPort = Number(output.T3CODE_PORT);
175 if (Number.isInteger(parsedServerPort) && parsedServerPort > 0 && parsedServerPort <= 65535) {
176 output.VITE_WS_URL = `ws://localhost:${parsedServerPort}`;
185 if (!Number.isInteger(parsedServerPort) || parsedServerPort < 1 || parsedServerPort > 65535) {
186 throw new Error(
187 `Invalid T3CODE_PORT override: '${String(output.T3CODE_PORT)}'. Expected an integer between 1 and 65535.`,
188 );
177189 }
190 output.VITE_WS_URL = `ws://localhost:${parsedServerPort}`;
178191
179192 if (mode === "dev" || mode === "dev:server" || mode === "dev:web") {
180193 // Running server/web in browser mode should not inherit desktop launcher state.
scripts/dev-runner.test.ts+34-1
......@@ -42,7 +42,7 @@ describe("createDevRunnerEnv", () => {
4242 it("defaults state dir to ~/.t3/dev when not provided", () => {
4343 const env = createDevRunnerEnv({
4444 mode: "dev",
45 env: { T3CODE_STATE_DIR: "/tmp/prod-state" },
45 env: {},
4646 offset: 0,
4747 envOverrides: {},
4848 });
......@@ -50,6 +50,17 @@ describe("createDevRunnerEnv", () => {
5050 expect(env.T3CODE_STATE_DIR).toBe(DEFAULT_DEV_STATE_DIR);
5151 });
5252
53 it("uses existing env state dir when --state-dir is not provided", () => {
54 const env = createDevRunnerEnv({
55 mode: "dev:server",
56 env: { T3CODE_STATE_DIR: "/tmp/existing-state" },
57 offset: 0,
58 envOverrides: {},
59 });
60
61 expect(env.T3CODE_STATE_DIR).toBe("/tmp/existing-state");
62 });
63
5364 it("lets --state-dir override existing env state dir", () => {
5465 const env = createDevRunnerEnv({
5566 mode: "dev:server",
......@@ -61,6 +72,17 @@ describe("createDevRunnerEnv", () => {
6172 expect(env.T3CODE_STATE_DIR).toBe("/tmp/override-state");
6273 });
6374
75 it("treats whitespace-only --state-dir as missing and falls back to env/default", () => {
76 const env = createDevRunnerEnv({
77 mode: "dev:server",
78 env: { T3CODE_STATE_DIR: "/tmp/existing-state" },
79 offset: 0,
80 envOverrides: { T3CODE_STATE_DIR: " " },
81 });
82
83 expect(env.T3CODE_STATE_DIR).toBe("/tmp/existing-state");
84 });
85
6486 it("recomputes websocket url when port is overridden", () => {
6587 const env = createDevRunnerEnv({
6688 mode: "dev",
......@@ -89,4 +111,15 @@ describe("createDevRunnerEnv", () => {
89111 expect(env.T3CODE_NO_BROWSER).toBe("1");
90112 expect(env.T3CODE_AUTH_TOKEN).toBe("cli-token");
91113 });
114
115 it("fails fast for invalid port overrides", () => {
116 expect(() =>
117 createDevRunnerEnv({
118 mode: "dev",
119 env: {},
120 offset: 0,
121 envOverrides: { T3CODE_PORT: "not-a-port" },
122 }),
123 ).toThrow("Invalid T3CODE_PORT override");
124 });
92125});