| author | |
| committer | |
| log | b39c629dcc9801abf82df5c770dfd6555cd2719c |
| tree | ffd139ac6fa95e986a39954508c5780f32330d92 |
| parent | b95cc59e79b15528a61774d0750d86e7199b0c0b |
- 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 ports2 files changed, 52 insertions(+), 6 deletions(-)
scripts/dev-runner.mjs+18-5| ... | ... | @@ -151,8 +151,18 @@ export function parseDevRunnerArgs(rawArgs) { |
| 151 | 151 | }; |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | function resolveStateDir(envOverrides) { | |
| 155 | return envOverrides.T3CODE_STATE_DIR ?? DEFAULT_DEV_STATE_DIR; | |
| 154 | function 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; | |
| 156 | 166 | } |
| 157 | 167 | |
| 158 | 168 | export function createDevRunnerEnv({ mode, env, offset, envOverrides }) { |
| ... | ... | @@ -169,12 +179,15 @@ export function createDevRunnerEnv({ mode, env, offset, envOverrides }) { |
| 169 | 179 | ...envOverrides, |
| 170 | 180 | }; |
| 171 | 181 | |
| 172 | output.T3CODE_STATE_DIR = resolveStateDir(envOverrides); | |
| 182 | output.T3CODE_STATE_DIR = resolveStateDir(env, envOverrides); | |
| 173 | 183 | |
| 174 | 184 | 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 | ); | |
| 177 | 189 | } |
| 190 | output.VITE_WS_URL = `ws://localhost:${parsedServerPort}`; | |
| 178 | 191 | |
| 179 | 192 | if (mode === "dev" || mode === "dev:server" || mode === "dev:web") { |
| 180 | 193 | // 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", () => { |
| 42 | 42 | it("defaults state dir to ~/.t3/dev when not provided", () => { |
| 43 | 43 | const env = createDevRunnerEnv({ |
| 44 | 44 | mode: "dev", |
| 45 | env: { T3CODE_STATE_DIR: "/tmp/prod-state" }, | |
| 45 | env: {}, | |
| 46 | 46 | offset: 0, |
| 47 | 47 | envOverrides: {}, |
| 48 | 48 | }); |
| ... | ... | @@ -50,6 +50,17 @@ describe("createDevRunnerEnv", () => { |
| 50 | 50 | expect(env.T3CODE_STATE_DIR).toBe(DEFAULT_DEV_STATE_DIR); |
| 51 | 51 | }); |
| 52 | 52 | |
| 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 | ||
| 53 | 64 | it("lets --state-dir override existing env state dir", () => { |
| 54 | 65 | const env = createDevRunnerEnv({ |
| 55 | 66 | mode: "dev:server", |
| ... | ... | @@ -61,6 +72,17 @@ describe("createDevRunnerEnv", () => { |
| 61 | 72 | expect(env.T3CODE_STATE_DIR).toBe("/tmp/override-state"); |
| 62 | 73 | }); |
| 63 | 74 | |
| 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 | ||
| 64 | 86 | it("recomputes websocket url when port is overridden", () => { |
| 65 | 87 | const env = createDevRunnerEnv({ |
| 66 | 88 | mode: "dev", |
| ... | ... | @@ -89,4 +111,15 @@ describe("createDevRunnerEnv", () => { |
| 89 | 111 | expect(env.T3CODE_NO_BROWSER).toBe("1"); |
| 90 | 112 | expect(env.T3CODE_AUTH_TOKEN).toBe("cli-token"); |
| 91 | 113 | }); |
| 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 | }); | |
| 92 | 125 | }); |