69 lines
2.4 KiB
TypeScript
69 lines
2.4 KiB
TypeScript
import { Database } from "@opencode-ai/core/database/database"
|
|
import { LocationServiceMap } from "@opencode-ai/core/location-layer"
|
|
import { Location } from "@opencode-ai/core/location"
|
|
import { AbsolutePath } from "@opencode-ai/core/schema"
|
|
import { SessionV2 } from "@opencode-ai/core/session"
|
|
import { SessionTable } from "@opencode-ai/core/session/sql"
|
|
import { WorkspaceV2 } from "@opencode-ai/core/workspace"
|
|
import { eq } from "drizzle-orm"
|
|
import { Effect, Layer, Schema } from "effect"
|
|
import { HttpRouter } from "effect/unstable/http"
|
|
import { HttpApiMiddleware } from "effect/unstable/httpapi"
|
|
import { InvalidRequestError, SessionNotFoundError } from "../errors"
|
|
import type { LocationServices } from "../groups/location"
|
|
|
|
export class SessionLocationMiddleware extends HttpApiMiddleware.Service<
|
|
SessionLocationMiddleware,
|
|
{
|
|
provides: LocationServices
|
|
}
|
|
>()("@opencode/HttpApiSessionLocation", {
|
|
error: [InvalidRequestError, SessionNotFoundError],
|
|
}) {}
|
|
|
|
const decodeSessionID = Schema.decodeUnknownEffect(SessionV2.ID)
|
|
|
|
export const sessionLocationLayer = Layer.effect(
|
|
SessionLocationMiddleware,
|
|
Effect.gen(function* () {
|
|
const { db } = yield* Database.Service
|
|
const locations = yield* LocationServiceMap
|
|
|
|
return SessionLocationMiddleware.of((effect) =>
|
|
Effect.gen(function* () {
|
|
const route = yield* HttpRouter.RouteContext
|
|
const sessionID = yield* decodeSessionID(route.params.sessionID).pipe(
|
|
Effect.mapError(
|
|
() =>
|
|
new InvalidRequestError({
|
|
message: "Invalid session ID",
|
|
field: "sessionID",
|
|
}),
|
|
),
|
|
)
|
|
const row = yield* db
|
|
.select({ directory: SessionTable.directory, workspaceID: SessionTable.workspace_id })
|
|
.from(SessionTable)
|
|
.where(eq(SessionTable.id, sessionID))
|
|
.get()
|
|
.pipe(Effect.orDie)
|
|
if (!row)
|
|
return yield* new SessionNotFoundError({
|
|
sessionID,
|
|
message: `Session not found: ${sessionID}`,
|
|
})
|
|
|
|
return yield* effect.pipe(
|
|
Effect.provide(
|
|
locations.get(
|
|
Location.Ref.make({
|
|
directory: AbsolutePath.make(row.directory),
|
|
workspaceID: row.workspaceID ? WorkspaceV2.ID.make(row.workspaceID) : undefined,
|
|
}),
|
|
),
|
|
),
|
|
)
|
|
}),
|
|
)
|
|
}),
|
|
)
|