1332 lines · 45.2 KB · TypeScript
RawDownload
// @effect-diagnostics nodeBuiltinImport:off - builds real worktree layouts on disk.import * as NodeServices from "@effect/platform-node/NodeServices";import * as NodeFS from "node:fs";import * as NodeOS from "node:os";import * as NodePath from "node:path";import * as NetService from "@t3tools/shared/Net";import {  HostProcessEnvironment,  HostProcessPlatform,  HostProcessWorkingDirectory,} from "@t3tools/shared/hostProcess";import { assert, describe, it } from "@effect/vitest";import * as ConfigProvider from "effect/ConfigProvider";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as Path from "effect/Path";import * as PlatformError from "effect/PlatformError";import * as Sink from "effect/Sink";import * as Stream from "effect/Stream";import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; import {  checkPortAvailabilityOnHosts,  createDevRunnerEnv,  devPortProbeHosts,  findFirstAvailableOffset,  getDevRunnerModeArgs,  isBrowserAllowedPort,  resolveModePortOffsets,  resolveOffset,  runDevRunnerWithInput,} from "./dev-runner.ts"; const emptyConfigLayer = ConfigProvider.layer(ConfigProvider.fromEnv({ env: {} }));const netServiceLayer = Layer.succeed(NetService.NetService, {  canListenOnHost: () => Effect.succeed(true),  isPortAvailableOnLoopback: () => Effect.succeed(true),  hasListenerOnHost: () => Effect.succeed(false),  reserveLoopbackPort: () => Effect.succeed(49_152),  findAvailablePort: (port) => Effect.succeed(port),}); function mockProcess(exit: number | PlatformError.PlatformError) {  return ChildProcessSpawner.makeHandle({    pid: ChildProcessSpawner.ProcessId(1),    exitCode:      typeof exit === "number"        ? Effect.succeed(ChildProcessSpawner.ExitCode(exit))        : Effect.fail(exit),    isRunning: Effect.succeed(false),    kill: () => Effect.void,    unref: Effect.succeed(Effect.void),    stdin: Sink.drain,    stdout: Stream.empty,    stderr: Stream.empty,    all: Stream.empty,    getInputFd: () => Sink.drain,    getOutputFd: () => Stream.empty,  });} const devServerInput = {  mode: "dev:server",  t3Home: "/tmp/t3code-dev-runner",  browser: undefined,  autoBootstrapProjectFromCwd: undefined,  logWebSocketEvents: undefined,  host: undefined,  port: 13_773,  devUrl: undefined,  dryRun: false,  share: false,  runArgs: ["--inspect", "secret-token-value"],} as const; it.layer(NodeServices.layer)("dev-runner", (it) => {  it.effect("accepts a dry run without the optional browser flag", () =>    Effect.gen(function* () {      const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;      const path = yield* Path.Path;      const output = yield* spawner.string(        ChildProcess.make(process.execPath, ["scripts/dev-runner.ts", "dev", "--dry-run"], {          cwd: path.resolve(import.meta.dirname, ".."),        }),      );       assert.include(output, "[dev-runner] mode=dev");    }),  );   describe("getDevRunnerModeArgs", () => {    it.effect("lets Vite+ honor the desktop dev task graph", () =>      Effect.sync(() => {        assert.deepStrictEqual(getDevRunnerModeArgs("dev:desktop"), [          "run",          "--filter=@t3tools/desktop",          "--filter=@t3tools/web",          "dev",        ]);      }),    );     it.effect("places Vite+ run flags before the task name", () =>      Effect.sync(() => {        assert.deepStrictEqual(getDevRunnerModeArgs("dev"), [          "run",          "--filter=@t3tools/contracts",          "--filter=@t3tools/web",          "--filter=t3",          "--parallel",          "dev",        ]);      }),    );  });   describe("resolveOffset", () => {    it.effect("uses explicit T3CODE_PORT_OFFSET when provided", () =>      Effect.gen(function* () {        const result = yield* resolveOffset({ portOffset: 12, devInstance: undefined });        assert.deepStrictEqual(result, {          offset: 12,          source: "T3CODE_PORT_OFFSET=12",        });      }),    );     it.effect("hashes non-numeric instance values", () =>      Effect.gen(function* () {        const result = yield* resolveOffset({          portOffset: undefined,          devInstance: "feature-branch",        });        assert.ok(result.offset >= 1);        assert.ok(result.offset <= 3000);      }),    );     it.effect("returns structured context for a negative port offset", () =>      Effect.gen(function* () {        const error = yield* resolveOffset({ portOffset: -1, devInstance: undefined }).pipe(          Effect.flip,        );         assert.equal(error._tag, "DevRunnerInvalidPortOffsetError");        assert.equal(error.configKey, "T3CODE_PORT_OFFSET");        assert.equal(error.portOffset, -1);        assert.equal(error.minimum, 0);        assert.ok(!("cause" in error));      }),    );  });   describe("createDevRunnerEnv", () => {    it.effect("leaves the shared home implicit and disables browser auto-open", () =>      Effect.gen(function* () {        const env = yield* createDevRunnerEnv({          mode: "dev",          baseEnv: {},          serverOffset: 0,          webOffset: 0,          t3Home: undefined,          browser: undefined,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: undefined,          host: undefined,          port: undefined,          devUrl: undefined,        });         assert.equal(env.T3CODE_HOME, undefined);        assert.equal(env.T3CODE_NO_BROWSER, "1");      }),    );     it.effect("allows browser auto-open to be explicitly enabled", () =>      Effect.gen(function* () {        const env = yield* createDevRunnerEnv({          mode: "dev",          baseEnv: {},          serverOffset: 0,          webOffset: 0,          t3Home: undefined,          browser: true,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: undefined,          host: undefined,          port: undefined,          devUrl: undefined,        });         assert.equal(env.T3CODE_NO_BROWSER, "0");      }),    );     it.effect("requires the browser flag even when the environment enables auto-open", () =>      Effect.gen(function* () {        const env = yield* createDevRunnerEnv({          mode: "dev",          baseEnv: { T3CODE_NO_BROWSER: "0" },          serverOffset: 0,          webOffset: 0,          t3Home: undefined,          browser: false,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: undefined,          host: undefined,          port: undefined,          devUrl: undefined,        });         assert.equal(env.T3CODE_NO_BROWSER, "1");      }),    );     it.effect("supports explicit typed overrides", () =>      Effect.gen(function* () {        const path = yield* Path.Path;        const env = yield* createDevRunnerEnv({          mode: "dev:server",          baseEnv: {},          serverOffset: 0,          webOffset: 0,          t3Home: "/tmp/custom-t3",          browser: false,          autoBootstrapProjectFromCwd: false,          logWebSocketEvents: true,          host: "0.0.0.0",          port: 4222,          devUrl: new URL("http://localhost:7331"),        });         assert.equal(env.T3CODE_HOME, path.resolve("/tmp/custom-t3"));        assert.equal(env.T3CODE_PORT, "4222");        assert.equal(env.VITE_HTTP_URL, "http://localhost:4222");        assert.equal(env.VITE_WS_URL, "ws://localhost:4222");        assert.equal(env.T3CODE_NO_BROWSER, "1");        assert.equal(env.T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD, "0");        assert.equal(env.T3CODE_LOG_WS_EVENTS, "1");        assert.equal(env.T3CODE_HOST, "0.0.0.0");        assert.equal(env.VITE_DEV_SERVER_URL, "http://localhost:7331/");      }),    );     it.effect("strips inherited service-launcher context", () =>      Effect.gen(function* () {        const env = yield* createDevRunnerEnv({          mode: "dev",          baseEnv: {            T3_SERVICE_LAUNCHER_CONTEXT: '{"childVersion":"9.9.9"}',            T3_BOOT_SERVICE_UNIT: "t3code.service",          },          serverOffset: 0,          webOffset: 0,          t3Home: undefined,          browser: undefined,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: undefined,          host: undefined,          port: undefined,          devUrl: undefined,        });         assert.equal(env.T3_SERVICE_LAUNCHER_CONTEXT, undefined);        assert.equal(env.T3_BOOT_SERVICE_UNIT, undefined);      }),    );     it.effect("does not force websocket logging on in dev mode when unset", () =>      Effect.gen(function* () {        const env = yield* createDevRunnerEnv({          mode: "dev",          baseEnv: {            T3CODE_LOG_WS_EVENTS: "keep-me-out",          },          serverOffset: 0,          webOffset: 0,          t3Home: undefined,          browser: undefined,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: undefined,          host: undefined,          port: undefined,          devUrl: undefined,        });         assert.equal(env.T3CODE_MODE, "web");        assert.equal(env.T3CODE_LOG_WS_EVENTS, undefined);      }),    );     it.effect("forwards explicit websocket logging false without coercing it away", () =>      Effect.gen(function* () {        const env = yield* createDevRunnerEnv({          mode: "dev",          baseEnv: {            T3CODE_LOG_WS_EVENTS: "1",          },          serverOffset: 0,          webOffset: 0,          t3Home: undefined,          browser: undefined,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: false,          host: undefined,          port: undefined,          devUrl: undefined,        });         assert.equal(env.T3CODE_LOG_WS_EVENTS, "0");      }),    );     it.effect("uses custom t3Home when provided", () =>      Effect.gen(function* () {        const path = yield* Path.Path;        const env = yield* createDevRunnerEnv({          mode: "dev",          baseEnv: {},          serverOffset: 0,          webOffset: 0,          t3Home: "/tmp/my-t3",          browser: undefined,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: undefined,          host: undefined,          port: undefined,          devUrl: undefined,        });         assert.equal(env.T3CODE_HOME, path.resolve("/tmp/my-t3"));      }),    );     it.effect("pins desktop dev to a stable backend port and websocket url", () =>      Effect.gen(function* () {        const path = yield* Path.Path;        const env = yield* createDevRunnerEnv({          mode: "dev:desktop",          baseEnv: {            T3CODE_PORT: "13773",            T3CODE_MODE: "web",            T3CODE_NO_BROWSER: "0",            T3CODE_HOST: "0.0.0.0",            VITE_DEV_SERVER_URL: "http://127.0.0.1:8526",            VITE_WS_URL: "ws://localhost:13773",          },          serverOffset: 0,          webOffset: 0,          t3Home: "/tmp/my-t3",          browser: true,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: undefined,          host: "127.0.0.1",          port: 4222,          devUrl: undefined,        });         assert.equal(env.T3CODE_HOME, path.resolve("/tmp/my-t3"));        assert.equal(env.PORT, "5733");        assert.equal(env.VITE_DEV_SERVER_URL, "http://127.0.0.1:5733");        assert.equal(env.HOST, "127.0.0.1");        assert.equal(env.T3CODE_PORT, "4222");        assert.equal(env.VITE_HTTP_URL, "http://127.0.0.1:4222");        assert.equal(env.T3CODE_MODE, undefined);        assert.equal(env.T3CODE_NO_BROWSER, undefined);        assert.equal(env.T3CODE_HOST, undefined);        assert.equal(env.VITE_WS_URL, "ws://127.0.0.1:4222");      }),    );     it.effect("defaults dev server mode to the higher backend port range", () =>      Effect.gen(function* () {        const env = yield* createDevRunnerEnv({          mode: "dev",          baseEnv: {},          serverOffset: 0,          webOffset: 0,          t3Home: undefined,          browser: undefined,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: undefined,          host: undefined,          port: undefined,          devUrl: undefined,        });         assert.equal(env.T3CODE_PORT, "13773");        assert.equal(env.PORT, "5733");      }),    );     // Browser dev is single-origin: Vite proxies the backend, and the client    // resolves it from window.location.origin. Baking a localhost URL here is    // what breaks sharing a dev server to another device.    for (const mode of ["dev", "dev:web"] as const) {      it.effect(`leaves the client backend URLs unset in ${mode} mode`, () =>        Effect.gen(function* () {          const env = yield* createDevRunnerEnv({            mode,            baseEnv: {              VITE_HTTP_URL: "http://localhost:1234",              VITE_WS_URL: "ws://localhost:1234",            },            serverOffset: 0,            webOffset: 0,            t3Home: undefined,            browser: undefined,            autoBootstrapProjectFromCwd: undefined,            logWebSocketEvents: undefined,            host: undefined,            port: undefined,            devUrl: undefined,          });           assert.equal(env.VITE_HTTP_URL, undefined);          assert.equal(env.VITE_WS_URL, undefined);          assert.equal(env.T3CODE_PORT, "13773");          // Deleting the keys is not sufficient — vite.config.ts merges          // `.env`/`.env.local` underneath this env and would revive them, so          // the intent has to be stated positively.          assert.equal(env.T3CODE_SINGLE_ORIGIN_DEV, "1");        }),      );    }     // Desktop pins the renderer at loopback deliberately; an ambient marker    // must not make Vite discard those URLs.    it.effect("clears the single-origin marker in dev:desktop mode", () =>      Effect.gen(function* () {        const env = yield* createDevRunnerEnv({          mode: "dev:desktop",          baseEnv: { T3CODE_SINGLE_ORIGIN_DEV: "1" },          serverOffset: 0,          webOffset: 0,          t3Home: undefined,          browser: undefined,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: undefined,          host: undefined,          port: undefined,          devUrl: undefined,        });         assert.equal(env.T3CODE_SINGLE_ORIGIN_DEV, undefined);        assert.equal(env.VITE_HTTP_URL, "http://127.0.0.1:13773");      }),    );     it.effect("clears the single-origin marker in dev:server mode", () =>      Effect.gen(function* () {        const env = yield* createDevRunnerEnv({          mode: "dev:server",          baseEnv: { T3CODE_SINGLE_ORIGIN_DEV: "1" },          serverOffset: 0,          webOffset: 0,          t3Home: undefined,          browser: undefined,          autoBootstrapProjectFromCwd: undefined,          logWebSocketEvents: undefined,          host: undefined,          port: undefined,          devUrl: undefined,        });         assert.equal(env.T3CODE_SINGLE_ORIGIN_DEV, undefined);        assert.equal(env.VITE_HTTP_URL, "http://localhost:13773");      }),    );     // HOST is Vite's bind address and gates the HMR pin in vite.config.ts. An    // inherited one would survive into browser dev and point HMR at the wrong    // interface — invisible over a shared origin, since the page still loads.    for (const mode of ["dev", "dev:web"] as const) {      it.effect(`drops an inherited HOST in ${mode} mode`, () =>        Effect.gen(function* () {          const env = yield* createDevRunnerEnv({            mode,            baseEnv: { HOST: "0.0.0.0" },            serverOffset: 0,            webOffset: 0,            t3Home: undefined,            browser: undefined,            autoBootstrapProjectFromCwd: undefined,            logWebSocketEvents: undefined,            host: undefined,            port: undefined,            devUrl: undefined,          });           assert.equal(env.HOST, undefined);        }),      );    }     // --host configures the *backend* (T3CODE_HOST). It must not become Vite's    // bind address by way of an inherited HOST that happens to agree with it.    it.effect("drops an inherited HOST even when --host is given", () =>      Effect.gen(function* () {        const env = yield* createDevRunnerEnv({

Lines 1–500 of 1332.