318 lines · 10.1 KB · TypeScript
RawDownload
import os from "node:os"; import { assert, expect, it } from "@effect/vitest";import { ConfigProvider, Effect, FileSystem, Layer, Option, Path } from "effect"; import { NetService } from "@t3tools/shared/Net";import * as NodeServices from "@effect/platform-node/NodeServices";import { deriveServerPaths } from "./config";import { resolveServerConfig } from "./cli"; it.layer(NodeServices.layer)("cli config resolution", (it) => {  const openBootstrapFd = Effect.fn(function* (payload: Record<string, unknown>) {    const fs = yield* FileSystem.FileSystem;    const filePath = yield* fs.makeTempFileScoped({ prefix: "t3-bootstrap-", suffix: ".ndjson" });    yield* fs.writeFileString(filePath, `${JSON.stringify(payload)}\n`);    const { fd } = yield* fs.open(filePath, { flag: "r" });    return fd;  });   it.effect("falls back to effect/config values when flags are omitted", () =>    Effect.gen(function* () {      const { join } = yield* Path.Path;      const baseDir = join(os.tmpdir(), "t3-cli-config-env-base");      const derivedPaths = yield* deriveServerPaths(baseDir, new URL("http://127.0.0.1:5173"));      const resolved = yield* resolveServerConfig(        {          mode: Option.none(),          port: Option.none(),          host: Option.none(),          baseDir: Option.none(),          devUrl: Option.none(),          noBrowser: Option.none(),          authToken: Option.none(),          bootstrapFd: Option.none(),          autoBootstrapProjectFromCwd: Option.none(),          logWebSocketEvents: Option.none(),        },        Option.none(),      ).pipe(        Effect.provide(          Layer.mergeAll(            ConfigProvider.layer(              ConfigProvider.fromEnv({                env: {                  T3CODE_LOG_LEVEL: "Warn",                  T3CODE_MODE: "desktop",                  T3CODE_PORT: "4001",                  T3CODE_HOST: "0.0.0.0",                  T3CODE_HOME: baseDir,                  VITE_DEV_SERVER_URL: "http://127.0.0.1:5173",                  T3CODE_NO_BROWSER: "true",                  T3CODE_AUTH_TOKEN: "env-token",                  T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD: "false",                  T3CODE_LOG_WS_EVENTS: "true",                },              }),            ),            NetService.layer,          ),        ),      );       expect(resolved).toEqual({        logLevel: "Warn",        mode: "desktop",        port: 4001,        cwd: process.cwd(),        baseDir,        ...derivedPaths,        host: "0.0.0.0",        staticDir: undefined,        devUrl: new URL("http://127.0.0.1:5173"),        noBrowser: true,        authToken: "env-token",        autoBootstrapProjectFromCwd: false,        logWebSocketEvents: true,      });    }),  );   it.effect("uses CLI flags when provided", () =>    Effect.gen(function* () {      const { join } = yield* Path.Path;      const baseDir = join(os.tmpdir(), "t3-cli-config-flags-base");      const derivedPaths = yield* deriveServerPaths(baseDir, new URL("http://127.0.0.1:4173"));      const resolved = yield* resolveServerConfig(        {          mode: Option.some("web"),          port: Option.some(8788),          host: Option.some("127.0.0.1"),          baseDir: Option.some(baseDir),          devUrl: Option.some(new URL("http://127.0.0.1:4173")),          noBrowser: Option.some(true),          authToken: Option.some("flag-token"),          bootstrapFd: Option.none(),          autoBootstrapProjectFromCwd: Option.some(true),          logWebSocketEvents: Option.some(true),        },        Option.some("Debug"),      ).pipe(        Effect.provide(          Layer.mergeAll(            ConfigProvider.layer(              ConfigProvider.fromEnv({                env: {                  T3CODE_LOG_LEVEL: "Warn",                  T3CODE_MODE: "desktop",                  T3CODE_PORT: "4001",                  T3CODE_HOST: "0.0.0.0",                  T3CODE_HOME: join(os.tmpdir(), "ignored-base"),                  VITE_DEV_SERVER_URL: "http://127.0.0.1:5173",                  T3CODE_NO_BROWSER: "false",                  T3CODE_AUTH_TOKEN: "ignored-token",                  T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD: "false",                  T3CODE_LOG_WS_EVENTS: "false",                },              }),            ),            NetService.layer,          ),        ),      );       expect(resolved).toEqual({        logLevel: "Debug",        mode: "web",        port: 8788,        cwd: process.cwd(),        baseDir,        ...derivedPaths,        host: "127.0.0.1",        staticDir: undefined,        devUrl: new URL("http://127.0.0.1:4173"),        noBrowser: true,        authToken: "flag-token",        autoBootstrapProjectFromCwd: true,        logWebSocketEvents: true,      });    }),  );   it.effect("uses bootstrap envelope values as fallbacks when flags and env are absent", () =>    Effect.gen(function* () {      const { join } = yield* Path.Path;      const baseDir = "/tmp/t3-bootstrap-home";      const fd = yield* openBootstrapFd({        mode: "desktop",        port: 4888,        host: "127.0.0.2",        t3Home: baseDir,        devUrl: "http://127.0.0.1:5173",        noBrowser: true,        authToken: "bootstrap-token",        autoBootstrapProjectFromCwd: false,        logWebSocketEvents: true,      });      const derivedPaths = yield* deriveServerPaths(baseDir, new URL("http://127.0.0.1:5173"));       const resolved = yield* resolveServerConfig(        {          mode: Option.none(),          port: Option.none(),          host: Option.none(),          baseDir: Option.none(),          devUrl: Option.none(),          noBrowser: Option.none(),          authToken: Option.none(),          bootstrapFd: Option.none(),          autoBootstrapProjectFromCwd: Option.none(),          logWebSocketEvents: Option.none(),        },        Option.none(),      ).pipe(        Effect.provide(          Layer.mergeAll(            ConfigProvider.layer(              ConfigProvider.fromEnv({                env: {                  T3CODE_BOOTSTRAP_FD: String(fd),                },              }),            ),            NetService.layer,          ),        ),      );       expect(resolved).toEqual({        logLevel: "Info",        mode: "desktop",        port: 4888,        cwd: process.cwd(),        baseDir,        ...derivedPaths,        host: "127.0.0.2",        staticDir: undefined,        devUrl: new URL("http://127.0.0.1:5173"),        noBrowser: true,        authToken: "bootstrap-token",        autoBootstrapProjectFromCwd: false,        logWebSocketEvents: true,      });      assert.equal(join(baseDir, "dev"), resolved.stateDir);    }),  );   it.effect("creates derived runtime directories during config resolution", () =>    Effect.gen(function* () {      const fs = yield* FileSystem.FileSystem;      const path = yield* Path.Path;      const baseDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-cli-config-dirs-" });       const resolved = yield* resolveServerConfig(        {          mode: Option.some("desktop"),          port: Option.some(4888),          host: Option.none(),          baseDir: Option.some(baseDir),          devUrl: Option.some(new URL("http://127.0.0.1:5173")),          noBrowser: Option.none(),          authToken: Option.none(),          bootstrapFd: Option.none(),          autoBootstrapProjectFromCwd: Option.none(),          logWebSocketEvents: Option.none(),        },        Option.none(),      ).pipe(        Effect.provide(          Layer.mergeAll(            ConfigProvider.layer(ConfigProvider.fromEnv({ env: {} })),            NetService.layer,          ),        ),      );       for (const directory of [        resolved.stateDir,        resolved.logsDir,        resolved.providerLogsDir,        resolved.terminalLogsDir,        resolved.attachmentsDir,        resolved.worktreesDir,        path.dirname(resolved.serverLogPath),      ]) {        expect(yield* fs.exists(directory)).toBe(true);      }    }),  );   it.effect("applies flag then env precedence over bootstrap envelope values", () =>    Effect.gen(function* () {      const { join } = yield* Path.Path;      const baseDir = join(os.tmpdir(), "t3-cli-config-env-wins");      const fd = yield* openBootstrapFd({        mode: "desktop",        port: 4888,        host: "127.0.0.2",        t3Home: "/tmp/t3-bootstrap-home",        devUrl: "http://127.0.0.1:5173",        noBrowser: false,        authToken: "bootstrap-token",        autoBootstrapProjectFromCwd: false,        logWebSocketEvents: false,      });      const derivedPaths = yield* deriveServerPaths(baseDir, new URL("http://127.0.0.1:4173"));       const resolved = yield* resolveServerConfig(        {          mode: Option.none(),          port: Option.some(8788),          host: Option.some("127.0.0.1"),          baseDir: Option.none(),          devUrl: Option.some(new URL("http://127.0.0.1:4173")),          noBrowser: Option.none(),          authToken: Option.some("flag-token"),          bootstrapFd: Option.none(),          autoBootstrapProjectFromCwd: Option.none(),          logWebSocketEvents: Option.none(),        },        Option.some("Debug"),      ).pipe(        Effect.provide(          Layer.mergeAll(            ConfigProvider.layer(              ConfigProvider.fromEnv({                env: {                  T3CODE_MODE: "web",                  T3CODE_BOOTSTRAP_FD: String(fd),                  T3CODE_HOME: baseDir,                  T3CODE_NO_BROWSER: "true",                  T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD: "true",                  T3CODE_LOG_WS_EVENTS: "true",                },              }),            ),            NetService.layer,          ),        ),      );       expect(resolved).toEqual({        logLevel: "Debug",        mode: "web",        port: 8788,        cwd: process.cwd(),        baseDir,        ...derivedPaths,        host: "127.0.0.1",        staticDir: undefined,        devUrl: new URL("http://127.0.0.1:4173"),        noBrowser: true,        authToken: "flag-token",        autoBootstrapProjectFromCwd: true,        logWebSocketEvents: true,      });    }),  );});