mirror of
https://github.com/anomalyco/opencode.git
synced 2026-09-06 11:04:30 +00:00
74 lines
2.5 KiB
TypeScript
74 lines
2.5 KiB
TypeScript
import { expect } from "bun:test"
|
|
import { SdkPlugins } from "@opencode-ai/core/plugin/sdk"
|
|
import { define } from "@opencode-ai/plugin/effect/plugin"
|
|
import { Rpc } from "@opencode-ai/schema/rpc"
|
|
import { Context, Effect, Layer, Schema } from "effect"
|
|
import { HttpEffect, HttpRouter, HttpServer } from "effect/unstable/http"
|
|
import { tmpdirScoped } from "../../core/test/fixture/tmpdir"
|
|
import { it } from "../../core/test/lib/effect"
|
|
import { createEmbeddedRoutes } from "../src/routes"
|
|
|
|
const Broken = Rpc.define({
|
|
id: "broken",
|
|
methods: {
|
|
handler: { input: Schema.String, output: Schema.String },
|
|
schema: {
|
|
input: Schema.String.check(
|
|
Schema.makeFilter(() => {
|
|
throw new Error("private schema detail")
|
|
}),
|
|
),
|
|
output: Schema.String,
|
|
},
|
|
},
|
|
events: {},
|
|
})
|
|
|
|
for (const method of ["handler", "schema"] as const) {
|
|
it.live(`returns HTTP 500 without exposing the ${method} defect`, () =>
|
|
Effect.gen(function* () {
|
|
const directory = yield* tmpdirScoped()
|
|
const context = yield* Layer.build(
|
|
createEmbeddedRoutes({
|
|
database: { path: ":memory:" },
|
|
models: { fetch: false },
|
|
config: { directory: directory.path, project: false, content: "{}" },
|
|
fs: { filewatcher: false },
|
|
}).pipe(Layer.provide(HttpServer.layerServices)),
|
|
)
|
|
const sdk = Context.get(context, SdkPlugins.Service)
|
|
yield* sdk.register(
|
|
define({
|
|
id: "broken-rpc",
|
|
effect: (ctx) =>
|
|
ctx.rpc
|
|
.register(Broken, {
|
|
handler: () => Effect.die(new Error("private handler detail")),
|
|
schema: Effect.succeed,
|
|
})
|
|
.pipe(Effect.asVoid, Effect.orDie),
|
|
}),
|
|
)
|
|
const handler = Context.get(context, HttpRouter.HttpRouter)
|
|
.asHttpEffect()
|
|
.pipe(HttpEffect.toWebHandlerWith(context))
|
|
const url = new URL(`/api/rpc/broken/${method}`, "http://opencode.local")
|
|
url.searchParams.set("location[directory]", directory.path)
|
|
const response = yield* Effect.promise(() =>
|
|
handler(
|
|
new Request(url, {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({ input: "hello" }),
|
|
}),
|
|
),
|
|
)
|
|
expect(response.status).toBe(500)
|
|
expect(yield* Effect.promise(() => response.json())).toEqual({
|
|
_tag: "RpcInternalError",
|
|
type: "rpc.internal",
|
|
message: "RPC call failed",
|
|
})
|
|
}),
|
|
)
|
|
}
|