From 2ed67ecf6c7760535eaa984df13baaabfe62e5a0 Mon Sep 17 00:00:00 2001 From: Yuhan Lei Date: Sun, 31 May 2026 21:53:19 +0800 Subject: [PATCH] refactor(server): effectify global config route handlers --- .../opencode/src/server/instance/global.ts | 15 +++- .../test/server/global-config-routes.test.ts | 70 +++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 packages/opencode/test/server/global-config-routes.test.ts diff --git a/packages/opencode/src/server/instance/global.ts b/packages/opencode/src/server/instance/global.ts index cea4dffbd..095daf55e 100644 --- a/packages/opencode/src/server/instance/global.ts +++ b/packages/opencode/src/server/instance/global.ts @@ -392,7 +392,13 @@ export function createGlobalRoutes(options: GlobalRoutesOptions = {}) { }, }), async (c) => { - return c.json(await Config.getGlobal()) + const config = await AppRuntime.runPromise( + Effect.gen(function* () { + const service = yield* Config.Service + return yield* service.getGlobal() + }), + ) + return c.json(config) }, ) .patch( @@ -416,7 +422,12 @@ export function createGlobalRoutes(options: GlobalRoutesOptions = {}) { validator("json", Config.Info.zod), async (c) => { const config = c.req.valid("json") - const next = await Config.updateGlobal(config) + const next = await AppRuntime.runPromise( + Effect.gen(function* () { + const service = yield* Config.Service + return yield* service.updateGlobal(config) + }), + ) return c.json(next) }, ) diff --git a/packages/opencode/test/server/global-config-routes.test.ts b/packages/opencode/test/server/global-config-routes.test.ts new file mode 100644 index 000000000..6f84b7ccf --- /dev/null +++ b/packages/opencode/test/server/global-config-routes.test.ts @@ -0,0 +1,70 @@ +import { afterEach, describe, expect, test } from "bun:test" +import fs from "fs/promises" +import path from "path" +import { Hono } from "hono" +import { Config } from "../../src/config" +import { AppRuntime } from "../../src/effect/app-runtime" +import { Global } from "../../src/global" +import { Instance } from "../../src/project/instance" +import { GlobalRoutes } from "../../src/server/instance/global" +import { tmpdir } from "../fixture/fixture" +import { withConfigDepsLock } from "../shared/config-deps-lock" + +afterEach(async () => { + await Instance.disposeAll() +}) + +async function invalidateConfig() { + await AppRuntime.runPromise(Config.Service.use((svc) => svc.invalidate(true))) +} + +async function withIsolatedGlobalConfig(fn: (globalDir: string) => Promise) { + await using global = await tmpdir() + const previousRuntime = process.env.PAWWORK_RUNTIME_NAMESPACE + const previousHome = process.env.PAWWORK_HOME + const previousConfigDir = process.env.PAWWORK_CONFIG_DIR + const previousConfig = Global.Path.config + + process.env.PAWWORK_RUNTIME_NAMESPACE = "pawwork" + process.env.PAWWORK_HOME = global.path + delete process.env.PAWWORK_CONFIG_DIR + ;(Global.Path as { config: string }).config = global.path + await invalidateConfig() + + try { + return await fn(global.path) + } finally { + ;(Global.Path as { config: string }).config = previousConfig + if (previousRuntime === undefined) delete process.env.PAWWORK_RUNTIME_NAMESPACE + else process.env.PAWWORK_RUNTIME_NAMESPACE = previousRuntime + if (previousHome === undefined) delete process.env.PAWWORK_HOME + else process.env.PAWWORK_HOME = previousHome + if (previousConfigDir === undefined) delete process.env.PAWWORK_CONFIG_DIR + else process.env.PAWWORK_CONFIG_DIR = previousConfigDir + await invalidateConfig() + } +} + +describe("global config routes", () => { + test("gets and patches global config through the route runtime", async () => { + await withConfigDepsLock(async () => { + await withIsolatedGlobalConfig(async (globalDir) => { + const app = new Hono().route("/global", GlobalRoutes()) + + const before = await app.request("/global/config") + expect(before.status).toBe(200) + + const response = await app.request("/global/config", { + method: "PATCH", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ model: "test/model" }), + }) + const body = await response.json() + + expect(response.status).toBe(200) + expect(body.model).toBe("test/model") + expect(JSON.parse(await fs.readFile(path.join(globalDir, "pawwork.json"), "utf8")).model).toBe("test/model") + }) + }) + }) +})