chore: generate

This commit is contained in:
opencode-agent[bot]
2026-04-29 20:52:19 +00:00
parent 9db5890ce5
commit 1124ae17b4
5 changed files with 37 additions and 23 deletions
+1 -3
View File
@@ -30,9 +30,7 @@ export function headers(input: Request | HeadersInit | Record<string, string>, e
} }
export function websocketProtocols(input: Request | Record<string, string | undefined>) { export function websocketProtocols(input: Request | Record<string, string | undefined>) {
const value = input instanceof Request const value = input instanceof Request ? input.headers.get("sec-websocket-protocol") : input["sec-websocket-protocol"]
? input.headers.get("sec-websocket-protocol")
: input["sec-websocket-protocol"]
if (!value) return [] if (!value) return []
return value return value
.split(",") .split(",")
@@ -1,6 +1,13 @@
import { ProxyUtil } from "@/server/proxy-util" import { ProxyUtil } from "@/server/proxy-util"
import { Effect, Stream } from "effect" import { Effect, Stream } from "effect"
import { FetchHttpClient, HttpBody, HttpClient, HttpClientRequest, HttpServerRequest, HttpServerResponse } from "effect/unstable/http" import {
FetchHttpClient,
HttpBody,
HttpClient,
HttpClientRequest,
HttpServerRequest,
HttpServerResponse,
} from "effect/unstable/http"
import * as Socket from "effect/unstable/socket/Socket" import * as Socket from "effect/unstable/socket/Socket"
function webSource(request: HttpServerRequest.HttpServerRequest): Request | undefined { function webSource(request: HttpServerRequest.HttpServerRequest): Request | undefined {
@@ -35,7 +42,9 @@ export function websocket(
Effect.catchReason("SocketError", "SocketCloseError", (reason) => Effect.catchReason("SocketError", "SocketCloseError", (reason) =>
writeInbound(new Socket.CloseEvent(reason.code, reason.closeReason)).pipe(Effect.catch(() => Effect.void)), writeInbound(new Socket.CloseEvent(reason.code, reason.closeReason)).pipe(Effect.catch(() => Effect.void)),
), ),
Effect.catch(() => writeInbound(new Socket.CloseEvent(1011, "proxy error")).pipe(Effect.catch(() => Effect.void))), Effect.catch(() =>
writeInbound(new Socket.CloseEvent(1011, "proxy error")).pipe(Effect.catch(() => Effect.void)),
),
Effect.forkScoped, Effect.forkScoped,
) )
@@ -27,10 +27,13 @@ type RequestPlan = Data.TaggedEnum<{
}> }>
const RequestPlan = Data.taggedEnum<RequestPlan>() const RequestPlan = Data.taggedEnum<RequestPlan>()
export class WorkspaceRouteContext extends Context.Service<WorkspaceRouteContext, { export class WorkspaceRouteContext extends Context.Service<
readonly directory: string WorkspaceRouteContext,
readonly workspaceID?: WorkspaceID {
}>()("@opencode/ExperimentalHttpApiWorkspaceRouteContext") {} readonly directory: string
readonly workspaceID?: WorkspaceID
}
>()("@opencode/ExperimentalHttpApiWorkspaceRouteContext") {}
export class WorkspaceRoutingMiddleware extends HttpApiMiddleware.Service< export class WorkspaceRoutingMiddleware extends HttpApiMiddleware.Service<
WorkspaceRoutingMiddleware, WorkspaceRoutingMiddleware,
@@ -110,7 +113,10 @@ function proxyRemote(
if (headers["upgrade"]?.toLowerCase() === "websocket") return yield* HttpApiProxy.websocket(request, proxyURL) if (headers["upgrade"]?.toLowerCase() === "websocket") return yield* HttpApiProxy.websocket(request, proxyURL)
const response = yield* HttpApiProxy.http(proxyURL, target.headers, request) const response = yield* HttpApiProxy.http(proxyURL, target.headers, request)
const sync = Fence.parse(new Headers(response.headers)) const sync = Fence.parse(new Headers(response.headers))
if (sync) yield* Effect.promise(() => Fence.wait(workspace.id, sync, request.source instanceof Request ? request.source.signal : undefined)) if (sync)
yield* Effect.promise(() =>
Fence.wait(workspace.id, sync, request.source instanceof Request ? request.source.signal : undefined),
)
return response return response
}) })
} }
@@ -157,9 +163,7 @@ function routeWorkspace<E>(
MissingWorkspace: ({ workspaceID }) => Effect.succeed(missingWorkspaceResponse(workspaceID)), MissingWorkspace: ({ workspaceID }) => Effect.succeed(missingWorkspaceResponse(workspaceID)),
Remote: ({ request, workspace, target, url }) => proxyRemote(request, workspace, target, url), Remote: ({ request, workspace, target, url }) => proxyRemote(request, workspace, target, url),
Local: ({ directory, workspaceID }) => Local: ({ directory, workspaceID }) =>
effect.pipe( effect.pipe(Effect.provideService(WorkspaceRouteContext, WorkspaceRouteContext.of({ directory, workspaceID }))),
Effect.provideService(WorkspaceRouteContext, WorkspaceRouteContext.of({ directory, workspaceID })),
),
}) })
} }
@@ -90,9 +90,9 @@ const instanceApiRoutes = HttpApiBuilder.layer(InstanceHttpApi).pipe(
const rawInstanceRoutes = Layer.mergeAll(eventRoute, ptyConnectRoute).pipe( const rawInstanceRoutes = Layer.mergeAll(eventRoute, ptyConnectRoute).pipe(
Layer.provide( Layer.provide(
instanceRouterMiddleware.combine(workspaceRouterMiddleware).layer.pipe( instanceRouterMiddleware
Layer.provide(Socket.layerWebSocketConstructorGlobal), .combine(workspaceRouterMiddleware)
), .layer.pipe(Layer.provide(Socket.layerWebSocketConstructorGlobal)),
), ),
) )
const instanceRoutes = Layer.mergeAll(rawInstanceRoutes, instanceApiRoutes).pipe( const instanceRoutes = Layer.mergeAll(rawInstanceRoutes, instanceApiRoutes).pipe(
@@ -22,14 +22,17 @@ describe("HttpApi workspace proxy", () => {
Effect.gen(function* () { Effect.gen(function* () {
const req = yield* HttpServerRequest.HttpServerRequest const req = yield* HttpServerRequest.HttpServerRequest
const body = yield* req.text const body = yield* req.text
return yield* HttpServerResponse.json({ path: req.url, method: req.method, body }, { return yield* HttpServerResponse.json(
status: 201, { path: req.url, method: req.method, body },
headers: { {
"content-encoding": "identity", status: 201,
"content-length": "999", headers: {
"x-remote": "yes", "content-encoding": "identity",
"content-length": "999",
"x-remote": "yes",
},
}, },
}) )
}), }),
) )
const url = yield* serverUrl() const url = yield* serverUrl()