mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-09 21:58:28 +00:00
feat(client): generate complete protocol client (#34164)
This commit is contained in:
parent
61a7f6db35
commit
dfeb1b5051
11 changed files with 2612 additions and 199 deletions
|
|
@ -7,7 +7,7 @@ Private generation target for clients derived directly from OpenCode's authorita
|
|||
- `@opencode-ai/client`: zero-Effect Promise client using `fetch`.
|
||||
- `@opencode-ai/client/effect`: rich Effect network client using an environment-provided `HttpClient`.
|
||||
|
||||
The generated surface starts with the Session group from Server's concrete API. The build compiler reads `@opencode-ai/server/api`; the generated Effect runtime imports a client-local projection built from Protocol, with a generation-equivalence test preventing transport drift. Run `bun run generate` after changing the contract and `bun run check:generated` to detect committed-output drift.
|
||||
The generated surface includes every standard HTTP group from Server's concrete API. The build compiler reads `@opencode-ai/server/api`; the generated Effect runtime imports a client-local projection built from Protocol, with a generation-equivalence test preventing transport drift. Custom transports such as the PTY WebSocket connection remain outside the generic HTTP client. Run `bun run generate` after changing the contract and `bun run check:generated` to detect committed-output drift.
|
||||
|
||||
The Effect entrypoint uses canonical decoded values such as `Session.ID`, `Location.Ref`, and `Prompt`. These datatypes come from the lightweight `@opencode-ai/schema` package and are re-exported so callers depend only on the client surface. Protocol owns endpoint construction and middleware placement; Server supplies the concrete middleware keys used by the build-time API.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import { NodeFileSystem } from "@effect/platform-node"
|
||||
import { compile, emitEffectImported, emitPromise, write } from "@opencode-ai/httpapi-codegen"
|
||||
import { ClientApi } from "../src/contract"
|
||||
import { ClientApi, endpointNames, groupNames, omitEndpoints } from "../src/contract"
|
||||
import { Effect } from "effect"
|
||||
import { fileURLToPath } from "url"
|
||||
|
||||
const contract = compile(ClientApi, {
|
||||
groupNames: { "server.session": "sessions", "server.event": "events" },
|
||||
})
|
||||
const contract = compile(ClientApi, { groupNames, endpointNames, omitEndpoints })
|
||||
|
||||
await Effect.runPromise(
|
||||
Effect.all(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { makeDefaultApi } from "@opencode-ai/protocol/api"
|
||||
import { InvalidRequestError, SessionNotFoundError } from "@opencode-ai/protocol/errors"
|
||||
import { HttpApi, HttpApiMiddleware } from "effect/unstable/httpapi"
|
||||
import { HttpApiMiddleware } from "effect/unstable/httpapi"
|
||||
|
||||
class LocationMiddleware extends HttpApiMiddleware.Service<LocationMiddleware>()(
|
||||
"@opencode-ai/client/LocationMiddleware",
|
||||
|
|
@ -11,11 +11,43 @@ class SessionLocationMiddleware extends HttpApiMiddleware.Service<SessionLocatio
|
|||
{ error: [InvalidRequestError, SessionNotFoundError] },
|
||||
) {}
|
||||
|
||||
const Api = makeDefaultApi({
|
||||
export const ClientApi = makeDefaultApi({
|
||||
locationMiddleware: LocationMiddleware,
|
||||
sessionLocationMiddleware: SessionLocationMiddleware,
|
||||
})
|
||||
|
||||
export const SessionGroup = Api.groups["server.session"]
|
||||
export const EventGroup = Api.groups["server.event"]
|
||||
export const ClientApi = HttpApi.make("opencode-client").add(SessionGroup).add(EventGroup)
|
||||
export const groupNames = {
|
||||
"server.health": "health",
|
||||
"server.location": "location",
|
||||
"server.agent": "agents",
|
||||
"server.session": "sessions",
|
||||
"server.message": "messages",
|
||||
"server.model": "models",
|
||||
"server.provider": "providers",
|
||||
"server.integration": "integrations",
|
||||
"server.credential": "credentials",
|
||||
"server.permission": "permissions",
|
||||
"server.fs": "files",
|
||||
"server.command": "commands",
|
||||
"server.skill": "skills",
|
||||
"server.event": "events",
|
||||
"server.pty": "ptys",
|
||||
"server.question": "questions",
|
||||
"server.reference": "references",
|
||||
"server.projectCopy": "projectCopies",
|
||||
} as const
|
||||
|
||||
export const endpointNames = {
|
||||
"session.messages": "list",
|
||||
"integration.connect.key": "connectKey",
|
||||
"integration.connect.oauth": "connectOauth",
|
||||
"integration.attempt.status": "attemptStatus",
|
||||
"integration.attempt.complete": "attemptComplete",
|
||||
"integration.attempt.cancel": "attemptCancel",
|
||||
"permission.request.list": "listRequests",
|
||||
"permission.saved.list": "listSaved",
|
||||
"permission.saved.remove": "removeSaved",
|
||||
"question.request.list": "listRequests",
|
||||
} as const
|
||||
|
||||
export const omitEndpoints = new Set(["fs.read", "pty.connect", "pty.connectToken"])
|
||||
|
|
|
|||
|
|
@ -2,12 +2,24 @@
|
|||
// Core or Server. Preserve these datatype exports so internal model reorganizations do not require caller migrations.
|
||||
export * from "./generated-effect/index"
|
||||
export { Agent } from "@opencode-ai/schema/agent"
|
||||
export { Command } from "@opencode-ai/schema/command"
|
||||
export { Credential } from "@opencode-ai/schema/credential"
|
||||
export { FileSystem } from "@opencode-ai/schema/filesystem"
|
||||
export { Integration } from "@opencode-ai/schema/integration"
|
||||
export { Location } from "@opencode-ai/schema/location"
|
||||
export { Model } from "@opencode-ai/schema/model"
|
||||
export { Permission } from "@opencode-ai/schema/permission"
|
||||
export { PermissionSaved } from "@opencode-ai/schema/permission-saved"
|
||||
export { Project } from "@opencode-ai/schema/project"
|
||||
export { ProjectCopy } from "@opencode-ai/schema/project-copy"
|
||||
export { Provider } from "@opencode-ai/schema/provider"
|
||||
export { Pty } from "@opencode-ai/schema/pty"
|
||||
export { Question } from "@opencode-ai/schema/question"
|
||||
export { Reference } from "@opencode-ai/schema/reference"
|
||||
export { AbsolutePath, RelativePath } from "@opencode-ai/schema/schema"
|
||||
export { Session } from "@opencode-ai/schema/session"
|
||||
export { SessionInput } from "@opencode-ai/schema/session-input"
|
||||
export { SessionMessage } from "@opencode-ai/schema/session-message"
|
||||
export { Skill } from "@opencode-ai/schema/skill"
|
||||
export { Prompt } from "@opencode-ai/schema/prompt"
|
||||
export type { OpenCodeEvent } from "@opencode-ai/protocol/groups/event"
|
||||
|
|
|
|||
|
|
@ -13,202 +13,502 @@ const mapClientError = <E>(error: E) =>
|
|||
? new ClientError({ cause: error })
|
||||
: error
|
||||
|
||||
type Endpoint0_0Request = Parameters<RawClient["server.session"]["session.list"]>[0]
|
||||
type Endpoint0_0Input = {
|
||||
readonly workspace?: Endpoint0_0Request["query"]["workspace"]
|
||||
readonly limit?: Endpoint0_0Request["query"]["limit"]
|
||||
readonly order?: Endpoint0_0Request["query"]["order"]
|
||||
readonly search?: Endpoint0_0Request["query"]["search"]
|
||||
readonly directory?: Endpoint0_0Request["query"]["directory"]
|
||||
readonly project?: Endpoint0_0Request["query"]["project"]
|
||||
readonly subpath?: Endpoint0_0Request["query"]["subpath"]
|
||||
readonly cursor?: Endpoint0_0Request["query"]["cursor"]
|
||||
const Endpoint0_0 = (raw: RawClient["server.health"]) => () =>
|
||||
raw["health.get"]({}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup0 = (raw: RawClient["server.health"]) => ({ get: Endpoint0_0(raw) })
|
||||
|
||||
type Endpoint1_0Request = Parameters<RawClient["server.location"]["location.get"]>[0]
|
||||
type Endpoint1_0Input = { readonly location?: Endpoint1_0Request["query"]["location"] }
|
||||
const Endpoint1_0 = (raw: RawClient["server.location"]) => (input?: Endpoint1_0Input) =>
|
||||
raw["location.get"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup1 = (raw: RawClient["server.location"]) => ({ get: Endpoint1_0(raw) })
|
||||
|
||||
type Endpoint2_0Request = Parameters<RawClient["server.agent"]["agent.list"]>[0]
|
||||
type Endpoint2_0Input = { readonly location?: Endpoint2_0Request["query"]["location"] }
|
||||
const Endpoint2_0 = (raw: RawClient["server.agent"]) => (input?: Endpoint2_0Input) =>
|
||||
raw["agent.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup2 = (raw: RawClient["server.agent"]) => ({ list: Endpoint2_0(raw) })
|
||||
|
||||
type Endpoint3_0Request = Parameters<RawClient["server.session"]["session.list"]>[0]
|
||||
type Endpoint3_0Input = {
|
||||
readonly workspace?: Endpoint3_0Request["query"]["workspace"]
|
||||
readonly limit?: Endpoint3_0Request["query"]["limit"]
|
||||
readonly order?: Endpoint3_0Request["query"]["order"]
|
||||
readonly search?: Endpoint3_0Request["query"]["search"]
|
||||
readonly directory?: Endpoint3_0Request["query"]["directory"]
|
||||
readonly project?: Endpoint3_0Request["query"]["project"]
|
||||
readonly subpath?: Endpoint3_0Request["query"]["subpath"]
|
||||
readonly cursor?: Endpoint3_0Request["query"]["cursor"]
|
||||
}
|
||||
const Endpoint0_0 = (raw: RawClient["server.session"]) => (input?: Endpoint0_0Input) =>
|
||||
const Endpoint3_0 = (raw: RawClient["server.session"]) => (input?: Endpoint3_0Input) =>
|
||||
raw["session.list"]({
|
||||
query: {
|
||||
workspace: input?.workspace,
|
||||
limit: input?.limit,
|
||||
order: input?.order,
|
||||
search: input?.search,
|
||||
directory: input?.directory,
|
||||
project: input?.project,
|
||||
subpath: input?.subpath,
|
||||
cursor: input?.cursor,
|
||||
workspace: input?.["workspace"],
|
||||
limit: input?.["limit"],
|
||||
order: input?.["order"],
|
||||
search: input?.["search"],
|
||||
directory: input?.["directory"],
|
||||
project: input?.["project"],
|
||||
subpath: input?.["subpath"],
|
||||
cursor: input?.["cursor"],
|
||||
},
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint0_1Request = Parameters<RawClient["server.session"]["session.create"]>[0]
|
||||
type Endpoint0_1Input = {
|
||||
readonly id?: Endpoint0_1Request["payload"]["id"]
|
||||
readonly agent?: Endpoint0_1Request["payload"]["agent"]
|
||||
readonly model?: Endpoint0_1Request["payload"]["model"]
|
||||
readonly location?: Endpoint0_1Request["payload"]["location"]
|
||||
type Endpoint3_1Request = Parameters<RawClient["server.session"]["session.create"]>[0]
|
||||
type Endpoint3_1Input = {
|
||||
readonly id?: Endpoint3_1Request["payload"]["id"]
|
||||
readonly agent?: Endpoint3_1Request["payload"]["agent"]
|
||||
readonly model?: Endpoint3_1Request["payload"]["model"]
|
||||
readonly location?: Endpoint3_1Request["payload"]["location"]
|
||||
}
|
||||
const Endpoint0_1 = (raw: RawClient["server.session"]) => (input?: Endpoint0_1Input) =>
|
||||
const Endpoint3_1 = (raw: RawClient["server.session"]) => (input?: Endpoint3_1Input) =>
|
||||
raw["session.create"]({
|
||||
payload: { id: input?.id, agent: input?.agent, model: input?.model, location: input?.location },
|
||||
payload: { id: input?.["id"], agent: input?.["agent"], model: input?.["model"], location: input?.["location"] },
|
||||
}).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
const Endpoint0_2 = (raw: RawClient["server.session"]) => () =>
|
||||
const Endpoint3_2 = (raw: RawClient["server.session"]) => () =>
|
||||
raw["session.active"]({}).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
type Endpoint0_3Request = Parameters<RawClient["server.session"]["session.get"]>[0]
|
||||
type Endpoint0_3Input = { readonly sessionID: Endpoint0_3Request["params"]["sessionID"] }
|
||||
const Endpoint0_3 = (raw: RawClient["server.session"]) => (input: Endpoint0_3Input) =>
|
||||
raw["session.get"]({ params: { sessionID: input.sessionID } }).pipe(
|
||||
type Endpoint3_3Request = Parameters<RawClient["server.session"]["session.get"]>[0]
|
||||
type Endpoint3_3Input = { readonly sessionID: Endpoint3_3Request["params"]["sessionID"] }
|
||||
const Endpoint3_3 = (raw: RawClient["server.session"]) => (input: Endpoint3_3Input) =>
|
||||
raw["session.get"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
type Endpoint0_4Request = Parameters<RawClient["server.session"]["session.switchAgent"]>[0]
|
||||
type Endpoint0_4Input = {
|
||||
readonly sessionID: Endpoint0_4Request["params"]["sessionID"]
|
||||
readonly agent: Endpoint0_4Request["payload"]["agent"]
|
||||
type Endpoint3_4Request = Parameters<RawClient["server.session"]["session.switchAgent"]>[0]
|
||||
type Endpoint3_4Input = {
|
||||
readonly sessionID: Endpoint3_4Request["params"]["sessionID"]
|
||||
readonly agent: Endpoint3_4Request["payload"]["agent"]
|
||||
}
|
||||
const Endpoint0_4 = (raw: RawClient["server.session"]) => (input: Endpoint0_4Input) =>
|
||||
raw["session.switchAgent"]({ params: { sessionID: input.sessionID }, payload: { agent: input.agent } }).pipe(
|
||||
const Endpoint3_4 = (raw: RawClient["server.session"]) => (input: Endpoint3_4Input) =>
|
||||
raw["session.switchAgent"]({ params: { sessionID: input["sessionID"] }, payload: { agent: input["agent"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
)
|
||||
|
||||
type Endpoint0_5Request = Parameters<RawClient["server.session"]["session.switchModel"]>[0]
|
||||
type Endpoint0_5Input = {
|
||||
readonly sessionID: Endpoint0_5Request["params"]["sessionID"]
|
||||
readonly model: Endpoint0_5Request["payload"]["model"]
|
||||
type Endpoint3_5Request = Parameters<RawClient["server.session"]["session.switchModel"]>[0]
|
||||
type Endpoint3_5Input = {
|
||||
readonly sessionID: Endpoint3_5Request["params"]["sessionID"]
|
||||
readonly model: Endpoint3_5Request["payload"]["model"]
|
||||
}
|
||||
const Endpoint0_5 = (raw: RawClient["server.session"]) => (input: Endpoint0_5Input) =>
|
||||
raw["session.switchModel"]({ params: { sessionID: input.sessionID }, payload: { model: input.model } }).pipe(
|
||||
const Endpoint3_5 = (raw: RawClient["server.session"]) => (input: Endpoint3_5Input) =>
|
||||
raw["session.switchModel"]({ params: { sessionID: input["sessionID"] }, payload: { model: input["model"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
)
|
||||
|
||||
type Endpoint0_6Request = Parameters<RawClient["server.session"]["session.prompt"]>[0]
|
||||
type Endpoint0_6Input = {
|
||||
readonly sessionID: Endpoint0_6Request["params"]["sessionID"]
|
||||
readonly id?: Endpoint0_6Request["payload"]["id"]
|
||||
readonly prompt: Endpoint0_6Request["payload"]["prompt"]
|
||||
readonly delivery?: Endpoint0_6Request["payload"]["delivery"]
|
||||
readonly resume?: Endpoint0_6Request["payload"]["resume"]
|
||||
type Endpoint3_6Request = Parameters<RawClient["server.session"]["session.prompt"]>[0]
|
||||
type Endpoint3_6Input = {
|
||||
readonly sessionID: Endpoint3_6Request["params"]["sessionID"]
|
||||
readonly id?: Endpoint3_6Request["payload"]["id"]
|
||||
readonly prompt: Endpoint3_6Request["payload"]["prompt"]
|
||||
readonly delivery?: Endpoint3_6Request["payload"]["delivery"]
|
||||
readonly resume?: Endpoint3_6Request["payload"]["resume"]
|
||||
}
|
||||
const Endpoint0_6 = (raw: RawClient["server.session"]) => (input: Endpoint0_6Input) =>
|
||||
const Endpoint3_6 = (raw: RawClient["server.session"]) => (input: Endpoint3_6Input) =>
|
||||
raw["session.prompt"]({
|
||||
params: { sessionID: input.sessionID },
|
||||
payload: { id: input.id, prompt: input.prompt, delivery: input.delivery, resume: input.resume },
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: { id: input["id"], prompt: input["prompt"], delivery: input["delivery"], resume: input["resume"] },
|
||||
}).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
type Endpoint0_7Request = Parameters<RawClient["server.session"]["session.compact"]>[0]
|
||||
type Endpoint0_7Input = { readonly sessionID: Endpoint0_7Request["params"]["sessionID"] }
|
||||
const Endpoint0_7 = (raw: RawClient["server.session"]) => (input: Endpoint0_7Input) =>
|
||||
raw["session.compact"]({ params: { sessionID: input.sessionID } }).pipe(Effect.mapError(mapClientError))
|
||||
type Endpoint3_7Request = Parameters<RawClient["server.session"]["session.compact"]>[0]
|
||||
type Endpoint3_7Input = { readonly sessionID: Endpoint3_7Request["params"]["sessionID"] }
|
||||
const Endpoint3_7 = (raw: RawClient["server.session"]) => (input: Endpoint3_7Input) =>
|
||||
raw["session.compact"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint0_8Request = Parameters<RawClient["server.session"]["session.wait"]>[0]
|
||||
type Endpoint0_8Input = { readonly sessionID: Endpoint0_8Request["params"]["sessionID"] }
|
||||
const Endpoint0_8 = (raw: RawClient["server.session"]) => (input: Endpoint0_8Input) =>
|
||||
raw["session.wait"]({ params: { sessionID: input.sessionID } }).pipe(Effect.mapError(mapClientError))
|
||||
type Endpoint3_8Request = Parameters<RawClient["server.session"]["session.wait"]>[0]
|
||||
type Endpoint3_8Input = { readonly sessionID: Endpoint3_8Request["params"]["sessionID"] }
|
||||
const Endpoint3_8 = (raw: RawClient["server.session"]) => (input: Endpoint3_8Input) =>
|
||||
raw["session.wait"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint0_9Request = Parameters<RawClient["server.session"]["session.revert.stage"]>[0]
|
||||
type Endpoint0_9Input = {
|
||||
readonly sessionID: Endpoint0_9Request["params"]["sessionID"]
|
||||
readonly messageID: Endpoint0_9Request["payload"]["messageID"]
|
||||
readonly files?: Endpoint0_9Request["payload"]["files"]
|
||||
type Endpoint3_9Request = Parameters<RawClient["server.session"]["session.revert.stage"]>[0]
|
||||
type Endpoint3_9Input = {
|
||||
readonly sessionID: Endpoint3_9Request["params"]["sessionID"]
|
||||
readonly messageID: Endpoint3_9Request["payload"]["messageID"]
|
||||
readonly files?: Endpoint3_9Request["payload"]["files"]
|
||||
}
|
||||
const Endpoint0_9 = (raw: RawClient["server.session"]) => (input: Endpoint0_9Input) =>
|
||||
const Endpoint3_9 = (raw: RawClient["server.session"]) => (input: Endpoint3_9Input) =>
|
||||
raw["session.revert.stage"]({
|
||||
params: { sessionID: input.sessionID },
|
||||
payload: { messageID: input.messageID, files: input.files },
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: { messageID: input["messageID"], files: input["files"] },
|
||||
}).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
type Endpoint0_10Request = Parameters<RawClient["server.session"]["session.revert.clear"]>[0]
|
||||
type Endpoint0_10Input = { readonly sessionID: Endpoint0_10Request["params"]["sessionID"] }
|
||||
const Endpoint0_10 = (raw: RawClient["server.session"]) => (input: Endpoint0_10Input) =>
|
||||
raw["session.revert.clear"]({ params: { sessionID: input.sessionID } }).pipe(Effect.mapError(mapClientError))
|
||||
type Endpoint3_10Request = Parameters<RawClient["server.session"]["session.revert.clear"]>[0]
|
||||
type Endpoint3_10Input = { readonly sessionID: Endpoint3_10Request["params"]["sessionID"] }
|
||||
const Endpoint3_10 = (raw: RawClient["server.session"]) => (input: Endpoint3_10Input) =>
|
||||
raw["session.revert.clear"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint0_11Request = Parameters<RawClient["server.session"]["session.revert.commit"]>[0]
|
||||
type Endpoint0_11Input = { readonly sessionID: Endpoint0_11Request["params"]["sessionID"] }
|
||||
const Endpoint0_11 = (raw: RawClient["server.session"]) => (input: Endpoint0_11Input) =>
|
||||
raw["session.revert.commit"]({ params: { sessionID: input.sessionID } }).pipe(Effect.mapError(mapClientError))
|
||||
type Endpoint3_11Request = Parameters<RawClient["server.session"]["session.revert.commit"]>[0]
|
||||
type Endpoint3_11Input = { readonly sessionID: Endpoint3_11Request["params"]["sessionID"] }
|
||||
const Endpoint3_11 = (raw: RawClient["server.session"]) => (input: Endpoint3_11Input) =>
|
||||
raw["session.revert.commit"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint0_12Request = Parameters<RawClient["server.session"]["session.context"]>[0]
|
||||
type Endpoint0_12Input = { readonly sessionID: Endpoint0_12Request["params"]["sessionID"] }
|
||||
const Endpoint0_12 = (raw: RawClient["server.session"]) => (input: Endpoint0_12Input) =>
|
||||
raw["session.context"]({ params: { sessionID: input.sessionID } }).pipe(
|
||||
type Endpoint3_12Request = Parameters<RawClient["server.session"]["session.context"]>[0]
|
||||
type Endpoint3_12Input = { readonly sessionID: Endpoint3_12Request["params"]["sessionID"] }
|
||||
const Endpoint3_12 = (raw: RawClient["server.session"]) => (input: Endpoint3_12Input) =>
|
||||
raw["session.context"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
type Endpoint0_13Request = Parameters<RawClient["server.session"]["session.history"]>[0]
|
||||
type Endpoint0_13Input = {
|
||||
readonly sessionID: Endpoint0_13Request["params"]["sessionID"]
|
||||
readonly limit?: Endpoint0_13Request["query"]["limit"]
|
||||
readonly after?: Endpoint0_13Request["query"]["after"]
|
||||
type Endpoint3_13Request = Parameters<RawClient["server.session"]["session.history"]>[0]
|
||||
type Endpoint3_13Input = {
|
||||
readonly sessionID: Endpoint3_13Request["params"]["sessionID"]
|
||||
readonly limit?: Endpoint3_13Request["query"]["limit"]
|
||||
readonly after?: Endpoint3_13Request["query"]["after"]
|
||||
}
|
||||
const Endpoint0_13 = (raw: RawClient["server.session"]) => (input: Endpoint0_13Input) =>
|
||||
const Endpoint3_13 = (raw: RawClient["server.session"]) => (input: Endpoint3_13Input) =>
|
||||
raw["session.history"]({
|
||||
params: { sessionID: input.sessionID },
|
||||
query: { limit: input.limit, after: input.after },
|
||||
params: { sessionID: input["sessionID"] },
|
||||
query: { limit: input["limit"], after: input["after"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint0_14Request = Parameters<RawClient["server.session"]["session.events"]>[0]
|
||||
type Endpoint0_14Input = {
|
||||
readonly sessionID: Endpoint0_14Request["params"]["sessionID"]
|
||||
readonly after?: Endpoint0_14Request["query"]["after"]
|
||||
type Endpoint3_14Request = Parameters<RawClient["server.session"]["session.events"]>[0]
|
||||
type Endpoint3_14Input = {
|
||||
readonly sessionID: Endpoint3_14Request["params"]["sessionID"]
|
||||
readonly after?: Endpoint3_14Request["query"]["after"]
|
||||
}
|
||||
const Endpoint0_14 = (raw: RawClient["server.session"]) => (input: Endpoint0_14Input) =>
|
||||
const Endpoint3_14 = (raw: RawClient["server.session"]) => (input: Endpoint3_14Input) =>
|
||||
Stream.unwrap(
|
||||
raw["session.events"]({ params: { sessionID: input.sessionID }, query: { after: input.after } }).pipe(
|
||||
raw["session.events"]({ params: { sessionID: input["sessionID"] }, query: { after: input["after"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((stream) => stream.pipe(Stream.mapError(mapClientError))),
|
||||
),
|
||||
)
|
||||
|
||||
type Endpoint0_15Request = Parameters<RawClient["server.session"]["session.interrupt"]>[0]
|
||||
type Endpoint0_15Input = { readonly sessionID: Endpoint0_15Request["params"]["sessionID"] }
|
||||
const Endpoint0_15 = (raw: RawClient["server.session"]) => (input: Endpoint0_15Input) =>
|
||||
raw["session.interrupt"]({ params: { sessionID: input.sessionID } }).pipe(Effect.mapError(mapClientError))
|
||||
type Endpoint3_15Request = Parameters<RawClient["server.session"]["session.interrupt"]>[0]
|
||||
type Endpoint3_15Input = { readonly sessionID: Endpoint3_15Request["params"]["sessionID"] }
|
||||
const Endpoint3_15 = (raw: RawClient["server.session"]) => (input: Endpoint3_15Input) =>
|
||||
raw["session.interrupt"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint0_16Request = Parameters<RawClient["server.session"]["session.message"]>[0]
|
||||
type Endpoint0_16Input = {
|
||||
readonly sessionID: Endpoint0_16Request["params"]["sessionID"]
|
||||
readonly messageID: Endpoint0_16Request["params"]["messageID"]
|
||||
type Endpoint3_16Request = Parameters<RawClient["server.session"]["session.message"]>[0]
|
||||
type Endpoint3_16Input = {
|
||||
readonly sessionID: Endpoint3_16Request["params"]["sessionID"]
|
||||
readonly messageID: Endpoint3_16Request["params"]["messageID"]
|
||||
}
|
||||
const Endpoint0_16 = (raw: RawClient["server.session"]) => (input: Endpoint0_16Input) =>
|
||||
raw["session.message"]({ params: { sessionID: input.sessionID, messageID: input.messageID } }).pipe(
|
||||
const Endpoint3_16 = (raw: RawClient["server.session"]) => (input: Endpoint3_16Input) =>
|
||||
raw["session.message"]({ params: { sessionID: input["sessionID"], messageID: input["messageID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
const adaptGroup0 = (raw: RawClient["server.session"]) => ({
|
||||
list: Endpoint0_0(raw),
|
||||
create: Endpoint0_1(raw),
|
||||
active: Endpoint0_2(raw),
|
||||
get: Endpoint0_3(raw),
|
||||
switchAgent: Endpoint0_4(raw),
|
||||
switchModel: Endpoint0_5(raw),
|
||||
prompt: Endpoint0_6(raw),
|
||||
compact: Endpoint0_7(raw),
|
||||
wait: Endpoint0_8(raw),
|
||||
stage: Endpoint0_9(raw),
|
||||
clear: Endpoint0_10(raw),
|
||||
commit: Endpoint0_11(raw),
|
||||
context: Endpoint0_12(raw),
|
||||
history: Endpoint0_13(raw),
|
||||
events: Endpoint0_14(raw),
|
||||
interrupt: Endpoint0_15(raw),
|
||||
message: Endpoint0_16(raw),
|
||||
const adaptGroup3 = (raw: RawClient["server.session"]) => ({
|
||||
list: Endpoint3_0(raw),
|
||||
create: Endpoint3_1(raw),
|
||||
active: Endpoint3_2(raw),
|
||||
get: Endpoint3_3(raw),
|
||||
switchAgent: Endpoint3_4(raw),
|
||||
switchModel: Endpoint3_5(raw),
|
||||
prompt: Endpoint3_6(raw),
|
||||
compact: Endpoint3_7(raw),
|
||||
wait: Endpoint3_8(raw),
|
||||
stage: Endpoint3_9(raw),
|
||||
clear: Endpoint3_10(raw),
|
||||
commit: Endpoint3_11(raw),
|
||||
context: Endpoint3_12(raw),
|
||||
history: Endpoint3_13(raw),
|
||||
events: Endpoint3_14(raw),
|
||||
interrupt: Endpoint3_15(raw),
|
||||
message: Endpoint3_16(raw),
|
||||
})
|
||||
|
||||
const Endpoint1_0 = (raw: RawClient["server.event"]) => () =>
|
||||
type Endpoint4_0Request = Parameters<RawClient["server.message"]["session.messages"]>[0]
|
||||
type Endpoint4_0Input = {
|
||||
readonly sessionID: Endpoint4_0Request["params"]["sessionID"]
|
||||
readonly limit?: Endpoint4_0Request["query"]["limit"]
|
||||
readonly order?: Endpoint4_0Request["query"]["order"]
|
||||
readonly cursor?: Endpoint4_0Request["query"]["cursor"]
|
||||
}
|
||||
const Endpoint4_0 = (raw: RawClient["server.message"]) => (input: Endpoint4_0Input) =>
|
||||
raw["session.messages"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
query: { limit: input["limit"], order: input["order"], cursor: input["cursor"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup4 = (raw: RawClient["server.message"]) => ({ list: Endpoint4_0(raw) })
|
||||
|
||||
type Endpoint5_0Request = Parameters<RawClient["server.model"]["model.list"]>[0]
|
||||
type Endpoint5_0Input = { readonly location?: Endpoint5_0Request["query"]["location"] }
|
||||
const Endpoint5_0 = (raw: RawClient["server.model"]) => (input?: Endpoint5_0Input) =>
|
||||
raw["model.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup5 = (raw: RawClient["server.model"]) => ({ list: Endpoint5_0(raw) })
|
||||
|
||||
type Endpoint6_0Request = Parameters<RawClient["server.provider"]["provider.list"]>[0]
|
||||
type Endpoint6_0Input = { readonly location?: Endpoint6_0Request["query"]["location"] }
|
||||
const Endpoint6_0 = (raw: RawClient["server.provider"]) => (input?: Endpoint6_0Input) =>
|
||||
raw["provider.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint6_1Request = Parameters<RawClient["server.provider"]["provider.get"]>[0]
|
||||
type Endpoint6_1Input = {
|
||||
readonly providerID: Endpoint6_1Request["params"]["providerID"]
|
||||
readonly location?: Endpoint6_1Request["query"]["location"]
|
||||
}
|
||||
const Endpoint6_1 = (raw: RawClient["server.provider"]) => (input: Endpoint6_1Input) =>
|
||||
raw["provider.get"]({ params: { providerID: input["providerID"] }, query: { location: input["location"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
)
|
||||
|
||||
const adaptGroup6 = (raw: RawClient["server.provider"]) => ({ list: Endpoint6_0(raw), get: Endpoint6_1(raw) })
|
||||
|
||||
type Endpoint7_0Request = Parameters<RawClient["server.integration"]["integration.list"]>[0]
|
||||
type Endpoint7_0Input = { readonly location?: Endpoint7_0Request["query"]["location"] }
|
||||
const Endpoint7_0 = (raw: RawClient["server.integration"]) => (input?: Endpoint7_0Input) =>
|
||||
raw["integration.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint7_1Request = Parameters<RawClient["server.integration"]["integration.get"]>[0]
|
||||
type Endpoint7_1Input = {
|
||||
readonly integrationID: Endpoint7_1Request["params"]["integrationID"]
|
||||
readonly location?: Endpoint7_1Request["query"]["location"]
|
||||
}
|
||||
const Endpoint7_1 = (raw: RawClient["server.integration"]) => (input: Endpoint7_1Input) =>
|
||||
raw["integration.get"]({
|
||||
params: { integrationID: input["integrationID"] },
|
||||
query: { location: input["location"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint7_2Request = Parameters<RawClient["server.integration"]["integration.connect.key"]>[0]
|
||||
type Endpoint7_2Input = {
|
||||
readonly integrationID: Endpoint7_2Request["params"]["integrationID"]
|
||||
readonly location?: Endpoint7_2Request["query"]["location"]
|
||||
readonly key: Endpoint7_2Request["payload"]["key"]
|
||||
readonly label?: Endpoint7_2Request["payload"]["label"]
|
||||
}
|
||||
const Endpoint7_2 = (raw: RawClient["server.integration"]) => (input: Endpoint7_2Input) =>
|
||||
raw["integration.connect.key"]({
|
||||
params: { integrationID: input["integrationID"] },
|
||||
query: { location: input["location"] },
|
||||
payload: { key: input["key"], label: input["label"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint7_3Request = Parameters<RawClient["server.integration"]["integration.connect.oauth"]>[0]
|
||||
type Endpoint7_3Input = {
|
||||
readonly integrationID: Endpoint7_3Request["params"]["integrationID"]
|
||||
readonly location?: Endpoint7_3Request["query"]["location"]
|
||||
readonly methodID: Endpoint7_3Request["payload"]["methodID"]
|
||||
readonly inputs: Endpoint7_3Request["payload"]["inputs"]
|
||||
readonly label?: Endpoint7_3Request["payload"]["label"]
|
||||
}
|
||||
const Endpoint7_3 = (raw: RawClient["server.integration"]) => (input: Endpoint7_3Input) =>
|
||||
raw["integration.connect.oauth"]({
|
||||
params: { integrationID: input["integrationID"] },
|
||||
query: { location: input["location"] },
|
||||
payload: { methodID: input["methodID"], inputs: input["inputs"], label: input["label"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint7_4Request = Parameters<RawClient["server.integration"]["integration.attempt.status"]>[0]
|
||||
type Endpoint7_4Input = {
|
||||
readonly attemptID: Endpoint7_4Request["params"]["attemptID"]
|
||||
readonly location?: Endpoint7_4Request["query"]["location"]
|
||||
}
|
||||
const Endpoint7_4 = (raw: RawClient["server.integration"]) => (input: Endpoint7_4Input) =>
|
||||
raw["integration.attempt.status"]({
|
||||
params: { attemptID: input["attemptID"] },
|
||||
query: { location: input["location"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint7_5Request = Parameters<RawClient["server.integration"]["integration.attempt.complete"]>[0]
|
||||
type Endpoint7_5Input = {
|
||||
readonly attemptID: Endpoint7_5Request["params"]["attemptID"]
|
||||
readonly location?: Endpoint7_5Request["query"]["location"]
|
||||
readonly code?: Endpoint7_5Request["payload"]["code"]
|
||||
}
|
||||
const Endpoint7_5 = (raw: RawClient["server.integration"]) => (input: Endpoint7_5Input) =>
|
||||
raw["integration.attempt.complete"]({
|
||||
params: { attemptID: input["attemptID"] },
|
||||
query: { location: input["location"] },
|
||||
payload: { code: input["code"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint7_6Request = Parameters<RawClient["server.integration"]["integration.attempt.cancel"]>[0]
|
||||
type Endpoint7_6Input = {
|
||||
readonly attemptID: Endpoint7_6Request["params"]["attemptID"]
|
||||
readonly location?: Endpoint7_6Request["query"]["location"]
|
||||
}
|
||||
const Endpoint7_6 = (raw: RawClient["server.integration"]) => (input: Endpoint7_6Input) =>
|
||||
raw["integration.attempt.cancel"]({
|
||||
params: { attemptID: input["attemptID"] },
|
||||
query: { location: input["location"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup7 = (raw: RawClient["server.integration"]) => ({
|
||||
list: Endpoint7_0(raw),
|
||||
get: Endpoint7_1(raw),
|
||||
connectKey: Endpoint7_2(raw),
|
||||
connectOauth: Endpoint7_3(raw),
|
||||
attemptStatus: Endpoint7_4(raw),
|
||||
attemptComplete: Endpoint7_5(raw),
|
||||
attemptCancel: Endpoint7_6(raw),
|
||||
})
|
||||
|
||||
type Endpoint8_0Request = Parameters<RawClient["server.credential"]["credential.update"]>[0]
|
||||
type Endpoint8_0Input = {
|
||||
readonly credentialID: Endpoint8_0Request["params"]["credentialID"]
|
||||
readonly location?: Endpoint8_0Request["query"]["location"]
|
||||
readonly label: Endpoint8_0Request["payload"]["label"]
|
||||
}
|
||||
const Endpoint8_0 = (raw: RawClient["server.credential"]) => (input: Endpoint8_0Input) =>
|
||||
raw["credential.update"]({
|
||||
params: { credentialID: input["credentialID"] },
|
||||
query: { location: input["location"] },
|
||||
payload: { label: input["label"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint8_1Request = Parameters<RawClient["server.credential"]["credential.remove"]>[0]
|
||||
type Endpoint8_1Input = {
|
||||
readonly credentialID: Endpoint8_1Request["params"]["credentialID"]
|
||||
readonly location?: Endpoint8_1Request["query"]["location"]
|
||||
}
|
||||
const Endpoint8_1 = (raw: RawClient["server.credential"]) => (input: Endpoint8_1Input) =>
|
||||
raw["credential.remove"]({
|
||||
params: { credentialID: input["credentialID"] },
|
||||
query: { location: input["location"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup8 = (raw: RawClient["server.credential"]) => ({ update: Endpoint8_0(raw), remove: Endpoint8_1(raw) })
|
||||
|
||||
type Endpoint9_0Request = Parameters<RawClient["server.permission"]["permission.request.list"]>[0]
|
||||
type Endpoint9_0Input = { readonly location?: Endpoint9_0Request["query"]["location"] }
|
||||
const Endpoint9_0 = (raw: RawClient["server.permission"]) => (input?: Endpoint9_0Input) =>
|
||||
raw["permission.request.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint9_1Request = Parameters<RawClient["server.permission"]["permission.saved.list"]>[0]
|
||||
type Endpoint9_1Input = { readonly projectID?: Endpoint9_1Request["query"]["projectID"] }
|
||||
const Endpoint9_1 = (raw: RawClient["server.permission"]) => (input?: Endpoint9_1Input) =>
|
||||
raw["permission.saved.list"]({ query: { projectID: input?.["projectID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
type Endpoint9_2Request = Parameters<RawClient["server.permission"]["permission.saved.remove"]>[0]
|
||||
type Endpoint9_2Input = { readonly id: Endpoint9_2Request["params"]["id"] }
|
||||
const Endpoint9_2 = (raw: RawClient["server.permission"]) => (input: Endpoint9_2Input) =>
|
||||
raw["permission.saved.remove"]({ params: { id: input["id"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint9_3Request = Parameters<RawClient["server.permission"]["session.permission.create"]>[0]
|
||||
type Endpoint9_3Input = {
|
||||
readonly sessionID: Endpoint9_3Request["params"]["sessionID"]
|
||||
readonly id?: Endpoint9_3Request["payload"]["id"]
|
||||
readonly action: Endpoint9_3Request["payload"]["action"]
|
||||
readonly resources: Endpoint9_3Request["payload"]["resources"]
|
||||
readonly save?: Endpoint9_3Request["payload"]["save"]
|
||||
readonly metadata?: Endpoint9_3Request["payload"]["metadata"]
|
||||
readonly source?: Endpoint9_3Request["payload"]["source"]
|
||||
readonly agent?: Endpoint9_3Request["payload"]["agent"]
|
||||
}
|
||||
const Endpoint9_3 = (raw: RawClient["server.permission"]) => (input: Endpoint9_3Input) =>
|
||||
raw["session.permission.create"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: {
|
||||
id: input["id"],
|
||||
action: input["action"],
|
||||
resources: input["resources"],
|
||||
save: input["save"],
|
||||
metadata: input["metadata"],
|
||||
source: input["source"],
|
||||
agent: input["agent"],
|
||||
},
|
||||
}).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
type Endpoint9_4Request = Parameters<RawClient["server.permission"]["session.permission.list"]>[0]
|
||||
type Endpoint9_4Input = { readonly sessionID: Endpoint9_4Request["params"]["sessionID"] }
|
||||
const Endpoint9_4 = (raw: RawClient["server.permission"]) => (input: Endpoint9_4Input) =>
|
||||
raw["session.permission.list"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
type Endpoint9_5Request = Parameters<RawClient["server.permission"]["session.permission.get"]>[0]
|
||||
type Endpoint9_5Input = {
|
||||
readonly sessionID: Endpoint9_5Request["params"]["sessionID"]
|
||||
readonly requestID: Endpoint9_5Request["params"]["requestID"]
|
||||
}
|
||||
const Endpoint9_5 = (raw: RawClient["server.permission"]) => (input: Endpoint9_5Input) =>
|
||||
raw["session.permission.get"]({ params: { sessionID: input["sessionID"], requestID: input["requestID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
type Endpoint9_6Request = Parameters<RawClient["server.permission"]["session.permission.reply"]>[0]
|
||||
type Endpoint9_6Input = {
|
||||
readonly sessionID: Endpoint9_6Request["params"]["sessionID"]
|
||||
readonly requestID: Endpoint9_6Request["params"]["requestID"]
|
||||
readonly reply: Endpoint9_6Request["payload"]["reply"]
|
||||
readonly message?: Endpoint9_6Request["payload"]["message"]
|
||||
}
|
||||
const Endpoint9_6 = (raw: RawClient["server.permission"]) => (input: Endpoint9_6Input) =>
|
||||
raw["session.permission.reply"]({
|
||||
params: { sessionID: input["sessionID"], requestID: input["requestID"] },
|
||||
payload: { reply: input["reply"], message: input["message"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup9 = (raw: RawClient["server.permission"]) => ({
|
||||
listRequests: Endpoint9_0(raw),
|
||||
listSaved: Endpoint9_1(raw),
|
||||
removeSaved: Endpoint9_2(raw),
|
||||
create: Endpoint9_3(raw),
|
||||
list: Endpoint9_4(raw),
|
||||
get: Endpoint9_5(raw),
|
||||
reply: Endpoint9_6(raw),
|
||||
})
|
||||
|
||||
type Endpoint10_0Request = Parameters<RawClient["server.fs"]["fs.list"]>[0]
|
||||
type Endpoint10_0Input = {
|
||||
readonly location?: Endpoint10_0Request["query"]["location"]
|
||||
readonly path?: Endpoint10_0Request["query"]["path"]
|
||||
}
|
||||
const Endpoint10_0 = (raw: RawClient["server.fs"]) => (input?: Endpoint10_0Input) =>
|
||||
raw["fs.list"]({ query: { location: input?.["location"], path: input?.["path"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
)
|
||||
|
||||
type Endpoint10_1Request = Parameters<RawClient["server.fs"]["fs.find"]>[0]
|
||||
type Endpoint10_1Input = {
|
||||
readonly location?: Endpoint10_1Request["query"]["location"]
|
||||
readonly query: Endpoint10_1Request["query"]["query"]
|
||||
readonly type?: Endpoint10_1Request["query"]["type"]
|
||||
readonly limit?: Endpoint10_1Request["query"]["limit"]
|
||||
}
|
||||
const Endpoint10_1 = (raw: RawClient["server.fs"]) => (input: Endpoint10_1Input) =>
|
||||
raw["fs.find"]({
|
||||
query: { location: input["location"], query: input["query"], type: input["type"], limit: input["limit"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup10 = (raw: RawClient["server.fs"]) => ({ list: Endpoint10_0(raw), find: Endpoint10_1(raw) })
|
||||
|
||||
type Endpoint11_0Request = Parameters<RawClient["server.command"]["command.list"]>[0]
|
||||
type Endpoint11_0Input = { readonly location?: Endpoint11_0Request["query"]["location"] }
|
||||
const Endpoint11_0 = (raw: RawClient["server.command"]) => (input?: Endpoint11_0Input) =>
|
||||
raw["command.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup11 = (raw: RawClient["server.command"]) => ({ list: Endpoint11_0(raw) })
|
||||
|
||||
type Endpoint12_0Request = Parameters<RawClient["server.skill"]["skill.list"]>[0]
|
||||
type Endpoint12_0Input = { readonly location?: Endpoint12_0Request["query"]["location"] }
|
||||
const Endpoint12_0 = (raw: RawClient["server.skill"]) => (input?: Endpoint12_0Input) =>
|
||||
raw["skill.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup12 = (raw: RawClient["server.skill"]) => ({ list: Endpoint12_0(raw) })
|
||||
|
||||
const Endpoint13_0 = (raw: RawClient["server.event"]) => () =>
|
||||
Stream.unwrap(
|
||||
raw["event.subscribe"]({}).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
|
|
@ -216,11 +516,190 @@ const Endpoint1_0 = (raw: RawClient["server.event"]) => () =>
|
|||
),
|
||||
)
|
||||
|
||||
const adaptGroup1 = (raw: RawClient["server.event"]) => ({ subscribe: Endpoint1_0(raw) })
|
||||
const adaptGroup13 = (raw: RawClient["server.event"]) => ({ subscribe: Endpoint13_0(raw) })
|
||||
|
||||
type Endpoint14_0Request = Parameters<RawClient["server.pty"]["pty.list"]>[0]
|
||||
type Endpoint14_0Input = { readonly location?: Endpoint14_0Request["query"]["location"] }
|
||||
const Endpoint14_0 = (raw: RawClient["server.pty"]) => (input?: Endpoint14_0Input) =>
|
||||
raw["pty.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint14_1Request = Parameters<RawClient["server.pty"]["pty.create"]>[0]
|
||||
type Endpoint14_1Input = {
|
||||
readonly location?: Endpoint14_1Request["query"]["location"]
|
||||
readonly command?: Endpoint14_1Request["payload"]["command"]
|
||||
readonly args?: Endpoint14_1Request["payload"]["args"]
|
||||
readonly cwd?: Endpoint14_1Request["payload"]["cwd"]
|
||||
readonly title?: Endpoint14_1Request["payload"]["title"]
|
||||
readonly env?: Endpoint14_1Request["payload"]["env"]
|
||||
}
|
||||
const Endpoint14_1 = (raw: RawClient["server.pty"]) => (input?: Endpoint14_1Input) =>
|
||||
raw["pty.create"]({
|
||||
query: { location: input?.["location"] },
|
||||
payload: {
|
||||
command: input?.["command"],
|
||||
args: input?.["args"],
|
||||
cwd: input?.["cwd"],
|
||||
title: input?.["title"],
|
||||
env: input?.["env"],
|
||||
},
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint14_2Request = Parameters<RawClient["server.pty"]["pty.get"]>[0]
|
||||
type Endpoint14_2Input = {
|
||||
readonly ptyID: Endpoint14_2Request["params"]["ptyID"]
|
||||
readonly location?: Endpoint14_2Request["query"]["location"]
|
||||
}
|
||||
const Endpoint14_2 = (raw: RawClient["server.pty"]) => (input: Endpoint14_2Input) =>
|
||||
raw["pty.get"]({ params: { ptyID: input["ptyID"] }, query: { location: input["location"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
)
|
||||
|
||||
type Endpoint14_3Request = Parameters<RawClient["server.pty"]["pty.update"]>[0]
|
||||
type Endpoint14_3Input = {
|
||||
readonly ptyID: Endpoint14_3Request["params"]["ptyID"]
|
||||
readonly location?: Endpoint14_3Request["query"]["location"]
|
||||
readonly title?: Endpoint14_3Request["payload"]["title"]
|
||||
readonly size?: Endpoint14_3Request["payload"]["size"]
|
||||
}
|
||||
const Endpoint14_3 = (raw: RawClient["server.pty"]) => (input: Endpoint14_3Input) =>
|
||||
raw["pty.update"]({
|
||||
params: { ptyID: input["ptyID"] },
|
||||
query: { location: input["location"] },
|
||||
payload: { title: input["title"], size: input["size"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint14_4Request = Parameters<RawClient["server.pty"]["pty.remove"]>[0]
|
||||
type Endpoint14_4Input = {
|
||||
readonly ptyID: Endpoint14_4Request["params"]["ptyID"]
|
||||
readonly location?: Endpoint14_4Request["query"]["location"]
|
||||
}
|
||||
const Endpoint14_4 = (raw: RawClient["server.pty"]) => (input: Endpoint14_4Input) =>
|
||||
raw["pty.remove"]({ params: { ptyID: input["ptyID"] }, query: { location: input["location"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
)
|
||||
|
||||
const adaptGroup14 = (raw: RawClient["server.pty"]) => ({
|
||||
list: Endpoint14_0(raw),
|
||||
create: Endpoint14_1(raw),
|
||||
get: Endpoint14_2(raw),
|
||||
update: Endpoint14_3(raw),
|
||||
remove: Endpoint14_4(raw),
|
||||
})
|
||||
|
||||
type Endpoint15_0Request = Parameters<RawClient["server.question"]["question.request.list"]>[0]
|
||||
type Endpoint15_0Input = { readonly location?: Endpoint15_0Request["query"]["location"] }
|
||||
const Endpoint15_0 = (raw: RawClient["server.question"]) => (input?: Endpoint15_0Input) =>
|
||||
raw["question.request.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint15_1Request = Parameters<RawClient["server.question"]["session.question.list"]>[0]
|
||||
type Endpoint15_1Input = { readonly sessionID: Endpoint15_1Request["params"]["sessionID"] }
|
||||
const Endpoint15_1 = (raw: RawClient["server.question"]) => (input: Endpoint15_1Input) =>
|
||||
raw["session.question.list"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
)
|
||||
|
||||
type Endpoint15_2Request = Parameters<RawClient["server.question"]["session.question.reply"]>[0]
|
||||
type Endpoint15_2Input = {
|
||||
readonly sessionID: Endpoint15_2Request["params"]["sessionID"]
|
||||
readonly requestID: Endpoint15_2Request["params"]["requestID"]
|
||||
readonly answers: Endpoint15_2Request["payload"]["answers"]
|
||||
}
|
||||
const Endpoint15_2 = (raw: RawClient["server.question"]) => (input: Endpoint15_2Input) =>
|
||||
raw["session.question.reply"]({
|
||||
params: { sessionID: input["sessionID"], requestID: input["requestID"] },
|
||||
payload: { answers: input["answers"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint15_3Request = Parameters<RawClient["server.question"]["session.question.reject"]>[0]
|
||||
type Endpoint15_3Input = {
|
||||
readonly sessionID: Endpoint15_3Request["params"]["sessionID"]
|
||||
readonly requestID: Endpoint15_3Request["params"]["requestID"]
|
||||
}
|
||||
const Endpoint15_3 = (raw: RawClient["server.question"]) => (input: Endpoint15_3Input) =>
|
||||
raw["session.question.reject"]({ params: { sessionID: input["sessionID"], requestID: input["requestID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
)
|
||||
|
||||
const adaptGroup15 = (raw: RawClient["server.question"]) => ({
|
||||
listRequests: Endpoint15_0(raw),
|
||||
list: Endpoint15_1(raw),
|
||||
reply: Endpoint15_2(raw),
|
||||
reject: Endpoint15_3(raw),
|
||||
})
|
||||
|
||||
type Endpoint16_0Request = Parameters<RawClient["server.reference"]["reference.list"]>[0]
|
||||
type Endpoint16_0Input = { readonly location?: Endpoint16_0Request["query"]["location"] }
|
||||
const Endpoint16_0 = (raw: RawClient["server.reference"]) => (input?: Endpoint16_0Input) =>
|
||||
raw["reference.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup16 = (raw: RawClient["server.reference"]) => ({ list: Endpoint16_0(raw) })
|
||||
|
||||
type Endpoint17_0Request = Parameters<RawClient["server.projectCopy"]["projectCopy.create"]>[0]
|
||||
type Endpoint17_0Input = {
|
||||
readonly projectID: Endpoint17_0Request["params"]["projectID"]
|
||||
readonly location?: Endpoint17_0Request["query"]["location"]
|
||||
readonly strategy: Endpoint17_0Request["payload"]["strategy"]
|
||||
readonly directory: Endpoint17_0Request["payload"]["directory"]
|
||||
readonly name?: Endpoint17_0Request["payload"]["name"]
|
||||
}
|
||||
const Endpoint17_0 = (raw: RawClient["server.projectCopy"]) => (input: Endpoint17_0Input) =>
|
||||
raw["projectCopy.create"]({
|
||||
params: { projectID: input["projectID"] },
|
||||
query: { location: input["location"] },
|
||||
payload: { strategy: input["strategy"], directory: input["directory"], name: input["name"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint17_1Request = Parameters<RawClient["server.projectCopy"]["projectCopy.remove"]>[0]
|
||||
type Endpoint17_1Input = {
|
||||
readonly projectID: Endpoint17_1Request["params"]["projectID"]
|
||||
readonly location?: Endpoint17_1Request["query"]["location"]
|
||||
readonly directory: Endpoint17_1Request["payload"]["directory"]
|
||||
readonly force: Endpoint17_1Request["payload"]["force"]
|
||||
}
|
||||
const Endpoint17_1 = (raw: RawClient["server.projectCopy"]) => (input: Endpoint17_1Input) =>
|
||||
raw["projectCopy.remove"]({
|
||||
params: { projectID: input["projectID"] },
|
||||
query: { location: input["location"] },
|
||||
payload: { directory: input["directory"], force: input["force"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
type Endpoint17_2Request = Parameters<RawClient["server.projectCopy"]["projectCopy.refresh"]>[0]
|
||||
type Endpoint17_2Input = {
|
||||
readonly projectID: Endpoint17_2Request["params"]["projectID"]
|
||||
readonly location?: Endpoint17_2Request["query"]["location"]
|
||||
}
|
||||
const Endpoint17_2 = (raw: RawClient["server.projectCopy"]) => (input: Endpoint17_2Input) =>
|
||||
raw["projectCopy.refresh"]({
|
||||
params: { projectID: input["projectID"] },
|
||||
query: { location: input["location"] },
|
||||
}).pipe(Effect.mapError(mapClientError))
|
||||
|
||||
const adaptGroup17 = (raw: RawClient["server.projectCopy"]) => ({
|
||||
create: Endpoint17_0(raw),
|
||||
remove: Endpoint17_1(raw),
|
||||
refresh: Endpoint17_2(raw),
|
||||
})
|
||||
|
||||
const adaptClient = (raw: RawClient) => ({
|
||||
sessions: adaptGroup0(raw["server.session"]),
|
||||
events: adaptGroup1(raw["server.event"]),
|
||||
health: adaptGroup0(raw["server.health"]),
|
||||
location: adaptGroup1(raw["server.location"]),
|
||||
agents: adaptGroup2(raw["server.agent"]),
|
||||
sessions: adaptGroup3(raw["server.session"]),
|
||||
messages: adaptGroup4(raw["server.message"]),
|
||||
models: adaptGroup5(raw["server.model"]),
|
||||
providers: adaptGroup6(raw["server.provider"]),
|
||||
integrations: adaptGroup7(raw["server.integration"]),
|
||||
credentials: adaptGroup8(raw["server.credential"]),
|
||||
permissions: adaptGroup9(raw["server.permission"]),
|
||||
files: adaptGroup10(raw["server.fs"]),
|
||||
commands: adaptGroup11(raw["server.command"]),
|
||||
skills: adaptGroup12(raw["server.skill"]),
|
||||
events: adaptGroup13(raw["server.event"]),
|
||||
ptys: adaptGroup14(raw["server.pty"]),
|
||||
questions: adaptGroup15(raw["server.question"]),
|
||||
references: adaptGroup16(raw["server.reference"]),
|
||||
projectCopies: adaptGroup17(raw["server.projectCopy"]),
|
||||
})
|
||||
|
||||
export const make = (options?: { readonly baseUrl?: URL | string }) =>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
import type {
|
||||
HealthGetOutput,
|
||||
LocationGetInput,
|
||||
LocationGetOutput,
|
||||
AgentsListInput,
|
||||
AgentsListOutput,
|
||||
SessionsListInput,
|
||||
SessionsListOutput,
|
||||
SessionsCreateInput,
|
||||
|
|
@ -32,7 +37,81 @@ import type {
|
|||
SessionsInterruptOutput,
|
||||
SessionsMessageInput,
|
||||
SessionsMessageOutput,
|
||||
MessagesListInput,
|
||||
MessagesListOutput,
|
||||
ModelsListInput,
|
||||
ModelsListOutput,
|
||||
ProvidersListInput,
|
||||
ProvidersListOutput,
|
||||
ProvidersGetInput,
|
||||
ProvidersGetOutput,
|
||||
IntegrationsListInput,
|
||||
IntegrationsListOutput,
|
||||
IntegrationsGetInput,
|
||||
IntegrationsGetOutput,
|
||||
IntegrationsConnectKeyInput,
|
||||
IntegrationsConnectKeyOutput,
|
||||
IntegrationsConnectOauthInput,
|
||||
IntegrationsConnectOauthOutput,
|
||||
IntegrationsAttemptStatusInput,
|
||||
IntegrationsAttemptStatusOutput,
|
||||
IntegrationsAttemptCompleteInput,
|
||||
IntegrationsAttemptCompleteOutput,
|
||||
IntegrationsAttemptCancelInput,
|
||||
IntegrationsAttemptCancelOutput,
|
||||
CredentialsUpdateInput,
|
||||
CredentialsUpdateOutput,
|
||||
CredentialsRemoveInput,
|
||||
CredentialsRemoveOutput,
|
||||
PermissionsListRequestsInput,
|
||||
PermissionsListRequestsOutput,
|
||||
PermissionsListSavedInput,
|
||||
PermissionsListSavedOutput,
|
||||
PermissionsRemoveSavedInput,
|
||||
PermissionsRemoveSavedOutput,
|
||||
PermissionsCreateInput,
|
||||
PermissionsCreateOutput,
|
||||
PermissionsListInput,
|
||||
PermissionsListOutput,
|
||||
PermissionsGetInput,
|
||||
PermissionsGetOutput,
|
||||
PermissionsReplyInput,
|
||||
PermissionsReplyOutput,
|
||||
FilesListInput,
|
||||
FilesListOutput,
|
||||
FilesFindInput,
|
||||
FilesFindOutput,
|
||||
CommandsListInput,
|
||||
CommandsListOutput,
|
||||
SkillsListInput,
|
||||
SkillsListOutput,
|
||||
EventsSubscribeOutput,
|
||||
PtysListInput,
|
||||
PtysListOutput,
|
||||
PtysCreateInput,
|
||||
PtysCreateOutput,
|
||||
PtysGetInput,
|
||||
PtysGetOutput,
|
||||
PtysUpdateInput,
|
||||
PtysUpdateOutput,
|
||||
PtysRemoveInput,
|
||||
PtysRemoveOutput,
|
||||
QuestionsListRequestsInput,
|
||||
QuestionsListRequestsOutput,
|
||||
QuestionsListInput,
|
||||
QuestionsListOutput,
|
||||
QuestionsReplyInput,
|
||||
QuestionsReplyOutput,
|
||||
QuestionsRejectInput,
|
||||
QuestionsRejectOutput,
|
||||
ReferencesListInput,
|
||||
ReferencesListOutput,
|
||||
ProjectCopiesCreateInput,
|
||||
ProjectCopiesCreateOutput,
|
||||
ProjectCopiesRemoveInput,
|
||||
ProjectCopiesRemoveOutput,
|
||||
ProjectCopiesRefreshInput,
|
||||
ProjectCopiesRefreshOutput,
|
||||
} from "./types"
|
||||
import { ClientError } from "./client-error"
|
||||
|
||||
|
|
@ -168,6 +247,41 @@ export function make(options: ClientOptions) {
|
|||
})
|
||||
|
||||
return {
|
||||
health: {
|
||||
get: (requestOptions?: RequestOptions) =>
|
||||
request<HealthGetOutput>(
|
||||
{ method: "GET", path: `/api/health`, successStatus: 200, declaredStatuses: [401, 400], empty: false },
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
location: {
|
||||
get: (input?: LocationGetInput, requestOptions?: RequestOptions) =>
|
||||
request<LocationGetOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/location`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
agents: {
|
||||
list: (input?: AgentsListInput, requestOptions?: RequestOptions) =>
|
||||
request<AgentsListOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/agent`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
sessions: {
|
||||
list: (input?: SessionsListInput, requestOptions?: RequestOptions) =>
|
||||
request<SessionsListOutput>(
|
||||
|
|
@ -175,14 +289,14 @@ export function make(options: ClientOptions) {
|
|||
method: "GET",
|
||||
path: `/api/session`,
|
||||
query: {
|
||||
workspace: input?.workspace,
|
||||
limit: input?.limit,
|
||||
order: input?.order,
|
||||
search: input?.search,
|
||||
directory: input?.directory,
|
||||
project: input?.project,
|
||||
subpath: input?.subpath,
|
||||
cursor: input?.cursor,
|
||||
workspace: input?.["workspace"],
|
||||
limit: input?.["limit"],
|
||||
order: input?.["order"],
|
||||
search: input?.["search"],
|
||||
directory: input?.["directory"],
|
||||
project: input?.["project"],
|
||||
subpath: input?.["subpath"],
|
||||
cursor: input?.["cursor"],
|
||||
},
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401],
|
||||
|
|
@ -195,7 +309,12 @@ export function make(options: ClientOptions) {
|
|||
{
|
||||
method: "POST",
|
||||
path: `/api/session`,
|
||||
body: { id: input?.id, agent: input?.agent, model: input?.model, location: input?.location },
|
||||
body: {
|
||||
id: input?.["id"],
|
||||
agent: input?.["agent"],
|
||||
model: input?.["model"],
|
||||
location: input?.["location"],
|
||||
},
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
|
|
@ -229,7 +348,7 @@ export function make(options: ClientOptions) {
|
|||
{
|
||||
method: "POST",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/agent`,
|
||||
body: { agent: input.agent },
|
||||
body: { agent: input["agent"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: true,
|
||||
|
|
@ -241,7 +360,7 @@ export function make(options: ClientOptions) {
|
|||
{
|
||||
method: "POST",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/model`,
|
||||
body: { model: input.model },
|
||||
body: { model: input["model"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: true,
|
||||
|
|
@ -253,7 +372,7 @@ export function make(options: ClientOptions) {
|
|||
{
|
||||
method: "POST",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/prompt`,
|
||||
body: { id: input.id, prompt: input.prompt, delivery: input.delivery, resume: input.resume },
|
||||
body: { id: input["id"], prompt: input["prompt"], delivery: input["delivery"], resume: input["resume"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [409, 404, 400, 401],
|
||||
empty: false,
|
||||
|
|
@ -287,7 +406,7 @@ export function make(options: ClientOptions) {
|
|||
{
|
||||
method: "POST",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/revert/stage`,
|
||||
body: { messageID: input.messageID, files: input.files },
|
||||
body: { messageID: input["messageID"], files: input["files"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [404, 500, 400, 401],
|
||||
empty: false,
|
||||
|
|
@ -332,7 +451,7 @@ export function make(options: ClientOptions) {
|
|||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/history`,
|
||||
query: { limit: input.limit, after: input.after },
|
||||
query: { limit: input["limit"], after: input["after"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: false,
|
||||
|
|
@ -344,7 +463,7 @@ export function make(options: ClientOptions) {
|
|||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/event`,
|
||||
query: { after: input.after },
|
||||
query: { after: input["after"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: false,
|
||||
|
|
@ -374,6 +493,321 @@ export function make(options: ClientOptions) {
|
|||
requestOptions,
|
||||
).then((value) => value.data),
|
||||
},
|
||||
messages: {
|
||||
list: (input: MessagesListInput, requestOptions?: RequestOptions) =>
|
||||
request<MessagesListOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/message`,
|
||||
query: { limit: input["limit"], order: input["order"], cursor: input["cursor"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 404, 500, 401],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
models: {
|
||||
list: (input?: ModelsListInput, requestOptions?: RequestOptions) =>
|
||||
request<ModelsListOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/model`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [503, 401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
providers: {
|
||||
list: (input?: ProvidersListInput, requestOptions?: RequestOptions) =>
|
||||
request<ProvidersListOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/provider`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [503, 401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
get: (input: ProvidersGetInput, requestOptions?: RequestOptions) =>
|
||||
request<ProvidersGetOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/provider/${encodeURIComponent(input.providerID)}`,
|
||||
query: { location: input["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [404, 503, 401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
integrations: {
|
||||
list: (input?: IntegrationsListInput, requestOptions?: RequestOptions) =>
|
||||
request<IntegrationsListOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/integration`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
get: (input: IntegrationsGetInput, requestOptions?: RequestOptions) =>
|
||||
request<IntegrationsGetOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/integration/${encodeURIComponent(input.integrationID)}`,
|
||||
query: { location: input["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
connectKey: (input: IntegrationsConnectKeyInput, requestOptions?: RequestOptions) =>
|
||||
request<IntegrationsConnectKeyOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/integration/${encodeURIComponent(input.integrationID)}/connect/key`,
|
||||
query: { location: input["location"] },
|
||||
body: { key: input["key"], label: input["label"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [400, 401],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
connectOauth: (input: IntegrationsConnectOauthInput, requestOptions?: RequestOptions) =>
|
||||
request<IntegrationsConnectOauthOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/integration/${encodeURIComponent(input.integrationID)}/connect/oauth`,
|
||||
query: { location: input["location"] },
|
||||
body: { methodID: input["methodID"], inputs: input["inputs"], label: input["label"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
attemptStatus: (input: IntegrationsAttemptStatusInput, requestOptions?: RequestOptions) =>
|
||||
request<IntegrationsAttemptStatusOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/integration/attempt/${encodeURIComponent(input.attemptID)}`,
|
||||
query: { location: input["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
attemptComplete: (input: IntegrationsAttemptCompleteInput, requestOptions?: RequestOptions) =>
|
||||
request<IntegrationsAttemptCompleteOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/integration/attempt/${encodeURIComponent(input.attemptID)}/complete`,
|
||||
query: { location: input["location"] },
|
||||
body: { code: input["code"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [400, 401],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
attemptCancel: (input: IntegrationsAttemptCancelInput, requestOptions?: RequestOptions) =>
|
||||
request<IntegrationsAttemptCancelOutput>(
|
||||
{
|
||||
method: "DELETE",
|
||||
path: `/api/integration/attempt/${encodeURIComponent(input.attemptID)}`,
|
||||
query: { location: input["location"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
credentials: {
|
||||
update: (input: CredentialsUpdateInput, requestOptions?: RequestOptions) =>
|
||||
request<CredentialsUpdateOutput>(
|
||||
{
|
||||
method: "PATCH",
|
||||
path: `/api/credential/${encodeURIComponent(input.credentialID)}`,
|
||||
query: { location: input["location"] },
|
||||
body: { label: input["label"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
remove: (input: CredentialsRemoveInput, requestOptions?: RequestOptions) =>
|
||||
request<CredentialsRemoveOutput>(
|
||||
{
|
||||
method: "DELETE",
|
||||
path: `/api/credential/${encodeURIComponent(input.credentialID)}`,
|
||||
query: { location: input["location"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
permissions: {
|
||||
listRequests: (input?: PermissionsListRequestsInput, requestOptions?: RequestOptions) =>
|
||||
request<PermissionsListRequestsOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/permission/request`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
listSaved: (input?: PermissionsListSavedInput, requestOptions?: RequestOptions) =>
|
||||
request<{ readonly data: PermissionsListSavedOutput }>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/permission/saved`,
|
||||
query: { projectID: input?.["projectID"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
).then((value) => value.data),
|
||||
removeSaved: (input: PermissionsRemoveSavedInput, requestOptions?: RequestOptions) =>
|
||||
request<PermissionsRemoveSavedOutput>(
|
||||
{
|
||||
method: "DELETE",
|
||||
path: `/api/permission/saved/${encodeURIComponent(input.id)}`,
|
||||
successStatus: 204,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
create: (input: PermissionsCreateInput, requestOptions?: RequestOptions) =>
|
||||
request<{ readonly data: PermissionsCreateOutput }>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/permission`,
|
||||
body: {
|
||||
id: input["id"],
|
||||
action: input["action"],
|
||||
resources: input["resources"],
|
||||
save: input["save"],
|
||||
metadata: input["metadata"],
|
||||
source: input["source"],
|
||||
agent: input["agent"],
|
||||
},
|
||||
successStatus: 200,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
).then((value) => value.data),
|
||||
list: (input: PermissionsListInput, requestOptions?: RequestOptions) =>
|
||||
request<{ readonly data: PermissionsListOutput }>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/permission`,
|
||||
successStatus: 200,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
).then((value) => value.data),
|
||||
get: (input: PermissionsGetInput, requestOptions?: RequestOptions) =>
|
||||
request<{ readonly data: PermissionsGetOutput }>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/permission/${encodeURIComponent(input.requestID)}`,
|
||||
successStatus: 200,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
).then((value) => value.data),
|
||||
reply: (input: PermissionsReplyInput, requestOptions?: RequestOptions) =>
|
||||
request<PermissionsReplyOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/permission/${encodeURIComponent(input.requestID)}/reply`,
|
||||
body: { reply: input["reply"], message: input["message"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
files: {
|
||||
list: (input?: FilesListInput, requestOptions?: RequestOptions) =>
|
||||
request<FilesListOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/fs/list`,
|
||||
query: { location: input?.["location"], path: input?.["path"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
find: (input: FilesFindInput, requestOptions?: RequestOptions) =>
|
||||
request<FilesFindOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/fs/find`,
|
||||
query: { location: input["location"], query: input["query"], type: input["type"], limit: input["limit"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
commands: {
|
||||
list: (input?: CommandsListInput, requestOptions?: RequestOptions) =>
|
||||
request<CommandsListOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/command`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
skills: {
|
||||
list: (input?: SkillsListInput, requestOptions?: RequestOptions) =>
|
||||
request<SkillsListOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/skill`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
events: {
|
||||
subscribe: (requestOptions?: RequestOptions): AsyncIterable<EventsSubscribeOutput> =>
|
||||
sse<EventsSubscribeOutput>(
|
||||
|
|
@ -381,6 +815,178 @@ export function make(options: ClientOptions) {
|
|||
requestOptions,
|
||||
),
|
||||
},
|
||||
ptys: {
|
||||
list: (input?: PtysListInput, requestOptions?: RequestOptions) =>
|
||||
request<PtysListOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/pty`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
create: (input?: PtysCreateInput, requestOptions?: RequestOptions) =>
|
||||
request<PtysCreateOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/pty`,
|
||||
query: { location: input?.["location"] },
|
||||
body: {
|
||||
command: input?.["command"],
|
||||
args: input?.["args"],
|
||||
cwd: input?.["cwd"],
|
||||
title: input?.["title"],
|
||||
env: input?.["env"],
|
||||
},
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
get: (input: PtysGetInput, requestOptions?: RequestOptions) =>
|
||||
request<PtysGetOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/pty/${encodeURIComponent(input.ptyID)}`,
|
||||
query: { location: input["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [404, 401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
update: (input: PtysUpdateInput, requestOptions?: RequestOptions) =>
|
||||
request<PtysUpdateOutput>(
|
||||
{
|
||||
method: "PUT",
|
||||
path: `/api/pty/${encodeURIComponent(input.ptyID)}`,
|
||||
query: { location: input["location"] },
|
||||
body: { title: input["title"], size: input["size"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [404, 401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
remove: (input: PtysRemoveInput, requestOptions?: RequestOptions) =>
|
||||
request<PtysRemoveOutput>(
|
||||
{
|
||||
method: "DELETE",
|
||||
path: `/api/pty/${encodeURIComponent(input.ptyID)}`,
|
||||
query: { location: input["location"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [404, 401, 400],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
questions: {
|
||||
listRequests: (input?: QuestionsListRequestsInput, requestOptions?: RequestOptions) =>
|
||||
request<QuestionsListRequestsOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/question/request`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
list: (input: QuestionsListInput, requestOptions?: RequestOptions) =>
|
||||
request<{ readonly data: QuestionsListOutput }>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/question`,
|
||||
successStatus: 200,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
).then((value) => value.data),
|
||||
reply: (input: QuestionsReplyInput, requestOptions?: RequestOptions) =>
|
||||
request<QuestionsReplyOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/question/${encodeURIComponent(input.requestID)}/reply`,
|
||||
body: { answers: input["answers"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
reject: (input: QuestionsRejectInput, requestOptions?: RequestOptions) =>
|
||||
request<QuestionsRejectOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/question/${encodeURIComponent(input.requestID)}/reject`,
|
||||
successStatus: 204,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
references: {
|
||||
list: (input?: ReferencesListInput, requestOptions?: RequestOptions) =>
|
||||
request<ReferencesListOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/reference`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [401, 400],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
projectCopies: {
|
||||
create: (input: ProjectCopiesCreateInput, requestOptions?: RequestOptions) =>
|
||||
request<ProjectCopiesCreateOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/experimental/project/${encodeURIComponent(input.projectID)}/copy`,
|
||||
query: { location: input["location"] },
|
||||
body: { strategy: input["strategy"], directory: input["directory"], name: input["name"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
remove: (input: ProjectCopiesRemoveInput, requestOptions?: RequestOptions) =>
|
||||
request<ProjectCopiesRemoveOutput>(
|
||||
{
|
||||
method: "DELETE",
|
||||
path: `/experimental/project/${encodeURIComponent(input.projectID)}/copy`,
|
||||
query: { location: input["location"] },
|
||||
body: { directory: input["directory"], force: input["force"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [400, 401],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
refresh: (input: ProjectCopiesRefreshInput, requestOptions?: RequestOptions) =>
|
||||
request<ProjectCopiesRefreshOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/experimental/project/${encodeURIComponent(input.projectID)}/copy/refresh`,
|
||||
query: { location: input["location"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [400, 401],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -19,8 +19,7 @@ import { SessionMessage } from "@opencode-ai/schema/session-message"
|
|||
import { Workspace } from "@opencode-ai/schema/workspace"
|
||||
import { Api } from "@opencode-ai/server/api"
|
||||
import { compile, emitPromise } from "@opencode-ai/httpapi-codegen"
|
||||
import { HttpApi } from "effect/unstable/httpapi"
|
||||
import { EventGroup, SessionGroup } from "../src/contract"
|
||||
import { ClientApi, endpointNames, groupNames, omitEndpoints } from "../src/contract"
|
||||
|
||||
test("Core and Server reuse the authoritative Schema and Protocol values", () => {
|
||||
expect(AgentV2.ID).toBe(Agent.ID)
|
||||
|
|
@ -31,18 +30,16 @@ test("Core and Server reuse the authoritative Schema and Protocol values", () =>
|
|||
expect(CoreSessionMessage.Message).toBe(SessionMessage.Message)
|
||||
expect(CorePrompt).toBe(Prompt)
|
||||
expect(Api.groups["server.session"].identifier).toBe("server.session")
|
||||
expect(SessionGroup.identifier).toBe(Api.groups["server.session"].identifier)
|
||||
expect(EventGroup.identifier).toBe(Api.groups["server.event"].identifier)
|
||||
expect(Object.keys(ClientApi.groups)).toEqual(Object.keys(Api.groups))
|
||||
expect(Session.ID.create()).toStartWith("ses_")
|
||||
expect(Project.ID.global).toBe("global")
|
||||
expect(Provider.ID.anthropic).toBe("anthropic")
|
||||
expect(Workspace.ID.create()).toStartWith("wrk_")
|
||||
})
|
||||
|
||||
test("client and Server Session contracts generate identically", () => {
|
||||
const options = { groupNames: { "server.session": "sessions" } }
|
||||
const server = compile(HttpApi.make("server").add(Api.groups["server.session"]), options)
|
||||
const client = compile(HttpApi.make("client").add(SessionGroup), options)
|
||||
test("client and Server contracts generate identically", () => {
|
||||
const server = compile(Api, { groupNames, endpointNames, omitEndpoints })
|
||||
const client = compile(ClientApi, { groupNames, endpointNames, omitEndpoints })
|
||||
|
||||
expect(emitPromise(client)).toEqual(emitPromise(server))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,43 @@
|
|||
import { expect, test } from "bun:test"
|
||||
import { isSessionNotFoundError, isUnauthorizedError, OpenCode } from "../src"
|
||||
|
||||
test("exposes every standard HTTP API group", () => {
|
||||
const client = OpenCode.make({ baseUrl: "http://localhost:3000" })
|
||||
|
||||
expect(Object.keys(client)).toEqual([
|
||||
"health",
|
||||
"location",
|
||||
"agents",
|
||||
"sessions",
|
||||
"messages",
|
||||
"models",
|
||||
"providers",
|
||||
"integrations",
|
||||
"credentials",
|
||||
"permissions",
|
||||
"files",
|
||||
"commands",
|
||||
"skills",
|
||||
"events",
|
||||
"ptys",
|
||||
"questions",
|
||||
"references",
|
||||
"projectCopies",
|
||||
])
|
||||
expect(Object.keys(client.messages)).toEqual(["list"])
|
||||
expect(Object.keys(client.integrations)).toEqual([
|
||||
"list",
|
||||
"get",
|
||||
"connectKey",
|
||||
"connectOauth",
|
||||
"attemptStatus",
|
||||
"attemptComplete",
|
||||
"attemptCancel",
|
||||
])
|
||||
expect(Object.keys(client.files)).toEqual(["list", "find"])
|
||||
expect(Object.keys(client.ptys)).toEqual(["list", "create", "get", "update", "remove"])
|
||||
})
|
||||
|
||||
test("sessions.get returns the wire projection", async () => {
|
||||
const client = OpenCode.make({
|
||||
baseUrl: "http://localhost:3000",
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export type Endpoint = {
|
|||
readonly operation: Operation
|
||||
readonly input: ReadonlyArray<InputField & { readonly optional: boolean }>
|
||||
readonly unwrapData: boolean
|
||||
readonly errors: ReadonlyArray<Schema.Top>
|
||||
readonly errors: ReadonlyArray<{ readonly status: number; readonly schema: Schema.Top }>
|
||||
readonly successes: ReadonlyArray<Schema.Top>
|
||||
readonly effectPortable: boolean
|
||||
}
|
||||
|
|
@ -75,7 +75,11 @@ const manifestName = ".httpapi-codegen.json"
|
|||
|
||||
export function compile<Id extends string, Groups extends HttpApiGroup.Any>(
|
||||
api: HttpApi.HttpApi<Id, Groups>,
|
||||
options?: { readonly groupNames?: Readonly<Record<string, string>> },
|
||||
options?: {
|
||||
readonly groupNames?: Readonly<Record<string, string>>
|
||||
readonly endpointNames?: Readonly<Record<string, string>>
|
||||
readonly omitEndpoints?: ReadonlySet<string>
|
||||
},
|
||||
): Contract {
|
||||
const endpoints: Array<Endpoint> = []
|
||||
const portable = new Map<SchemaAST.AST, boolean>()
|
||||
|
|
@ -83,6 +87,7 @@ export function compile<Id extends string, Groups extends HttpApiGroup.Any>(
|
|||
HttpApi.reflect(api, {
|
||||
onGroup() {},
|
||||
onEndpoint({ endpoint, errors, group, middleware }) {
|
||||
if (options?.omitEndpoints?.has(endpoint.name)) return
|
||||
const groupName = options?.groupNames?.[group.identifier] ?? group.identifier
|
||||
const name = `${groupName}.${endpoint.name}`
|
||||
const required = Array.from(middleware).find((item) => item.requiredForClient)
|
||||
|
|
@ -103,8 +108,8 @@ export function compile<Id extends string, Groups extends HttpApiGroup.Any>(
|
|||
}
|
||||
const payloads = sourcePayloads.map((schema) => normalizeTransport(schema, "payload", endpoint, name)!)
|
||||
const success = normalizeTransport(successSchemas[0], "success", endpoint, name)!
|
||||
const errorSchemas = Array.from(errors.values()).flatMap((schemas) =>
|
||||
schemas.map((schema) => normalizeTransport(schema, "error", endpoint, name)!),
|
||||
const errorSchemas = Array.from(errors).flatMap(([status, schemas]) =>
|
||||
schemas.map((schema) => ({ status, ...normalizeTransport(schema, "error", endpoint, name)! })),
|
||||
)
|
||||
const inputs = [
|
||||
...inputFields(params?.schema, "params", name),
|
||||
|
|
@ -124,7 +129,7 @@ export function compile<Id extends string, Groups extends HttpApiGroup.Any>(
|
|||
...(headers === undefined ? [] : [[`${name}.headers`, headers.schema] as const]),
|
||||
...payloads.map((item) => [`${name}.payload`, item.schema] as const),
|
||||
...responseSchemas(success.schema, `${name}.success`),
|
||||
...errorSchemas.map((item) => [`${name}.error`, item.schema] as const),
|
||||
...errorSchemas.map((item) => [`${name}.error.${item.status}`, item.schema] as const),
|
||||
]
|
||||
const effectPortable =
|
||||
[params, query, headers, ...payloads, success, ...errorSchemas].every(
|
||||
|
|
@ -146,11 +151,11 @@ export function compile<Id extends string, Groups extends HttpApiGroup.Any>(
|
|||
input: inputs,
|
||||
unwrapData: isDataEnvelope(success.schema),
|
||||
successes: [success.schema],
|
||||
errors: errorSchemas.map((item) => item.schema),
|
||||
errors: errorSchemas.map((item) => ({ status: item.status, schema: item.schema })),
|
||||
effectPortable,
|
||||
operation: {
|
||||
group: groupName,
|
||||
name: clientEndpointName(endpoint.name),
|
||||
name: options?.endpointNames?.[endpoint.name] ?? clientEndpointName(endpoint.name),
|
||||
input: inputs.map(({ name, source }) => ({ name, source })),
|
||||
inputMode: inputs.length === 0 ? "none" : inputs.every((field) => field.optional) ? "optional" : "required",
|
||||
success: isStreamSchema(success.schema)
|
||||
|
|
@ -287,10 +292,10 @@ function assertPromiseEndpoint(endpoint: Endpoint) {
|
|||
throw new GenerationError({ reason: `Unsupported Promise success encoding: ${name}` })
|
||||
}
|
||||
for (const error of endpoint.errors) {
|
||||
if (taggedErrorFields(error) === undefined) {
|
||||
throw new GenerationError({ reason: `Promise error must be tagged: ${name}` })
|
||||
if (declaredErrorFields(error.schema) === undefined) {
|
||||
throw new GenerationError({ reason: `Promise error must have a literal discriminator: ${name}` })
|
||||
}
|
||||
if ((resolveHttpApiEncoding(error.ast)?._tag ?? "Json") !== "Json") {
|
||||
if ((resolveHttpApiEncoding(error.schema.ast)?._tag ?? "Json") !== "Json") {
|
||||
throw new GenerationError({ reason: `Unsupported Promise error encoding: ${name}` })
|
||||
}
|
||||
}
|
||||
|
|
@ -332,7 +337,7 @@ function renderImportedEffectFiles(
|
|||
const fields = item.input.filter((field) => field.source === source)
|
||||
if (fields.length === 0) return []
|
||||
return [
|
||||
`${source}: { ${fields.map((field) => `${JSON.stringify(field.name)}: input${item.operation.inputMode === "optional" ? "?." : "."}${field.name}`).join(", ")} }`,
|
||||
`${source}: { ${fields.map((field) => `${JSON.stringify(field.name)}: input${item.operation.inputMode === "optional" ? "?." : ""}[${JSON.stringify(field.name)}]`).join(", ")} }`,
|
||||
]
|
||||
})
|
||||
.join(", ")
|
||||
|
|
@ -429,8 +434,8 @@ function renderPromiseTypes(
|
|||
const errors = new Map(
|
||||
groups.flatMap((group) =>
|
||||
group.endpoints.flatMap((endpoint) =>
|
||||
endpoint.errors.flatMap((schema) => {
|
||||
const tagged = taggedErrorFields(schema)
|
||||
endpoint.errors.flatMap((error) => {
|
||||
const tagged = declaredErrorFields(error.schema)
|
||||
return tagged === undefined ? [] : [[tagged.tag, tagged] as const]
|
||||
}),
|
||||
),
|
||||
|
|
@ -440,7 +445,7 @@ function renderPromiseTypes(
|
|||
const fields = error.fields
|
||||
.map(([name, schema, optional]) => `readonly ${JSON.stringify(name)}${optional ? "?" : ""}: ${typeOf(schema)}`)
|
||||
.join("; ")
|
||||
return `export type ${error.identifier} = { readonly _tag: ${JSON.stringify(error.tag)}; ${fields} }\nexport const is${error.identifier} = (value: unknown): value is ${error.identifier} => typeof value === "object" && value !== null && "_tag" in value && value._tag === ${JSON.stringify(error.tag)}`
|
||||
return `export type ${error.identifier} = { readonly ${JSON.stringify(error.key)}: ${JSON.stringify(error.tag)}; ${fields} }\nexport const is${error.identifier} = (value: unknown): value is ${error.identifier} => typeof value === "object" && value !== null && ${JSON.stringify(error.key)} in value && value[${JSON.stringify(error.key)}] === ${JSON.stringify(error.tag)}`
|
||||
})
|
||||
const operations = groups
|
||||
.flatMap((group) =>
|
||||
|
|
@ -499,7 +504,8 @@ function renderPromiseClient(groups: ReadonlyArray<Group>) {
|
|||
? "requestOptions?: RequestOptions"
|
||||
: `input${endpoint.operation.inputMode === "optional" ? "?" : ""}: ${prefix}Input, requestOptions?: RequestOptions`
|
||||
const path = promisePath(endpoint.endpoint.path, endpoint.input)
|
||||
const access = (name: string) => `input${endpoint.operation.inputMode === "optional" ? "?." : "."}${name}`
|
||||
const access = (name: string) =>
|
||||
`input${endpoint.operation.inputMode === "optional" ? "?." : ""}[${JSON.stringify(name)}]`
|
||||
const part = (source: InputField["source"]) => {
|
||||
const inputs = endpoint.input.filter((field) => field.source === source)
|
||||
return inputs.length === 0
|
||||
|
|
@ -511,11 +517,7 @@ function renderPromiseClient(groups: ReadonlyArray<Group>) {
|
|||
endpoint.headers === undefined ? undefined : `headers: ${part("headers")}`,
|
||||
endpoint.payloads.length === 0 ? undefined : `body: ${part("payload")}`,
|
||||
].filter((value): value is string => value !== undefined)
|
||||
const declaredStatuses = [
|
||||
...new Set(
|
||||
endpoint.errors.map((schema) => resolveHttpApiStatus(schema.ast)).filter((status) => status !== undefined),
|
||||
),
|
||||
]
|
||||
const declaredStatuses = [...new Set(endpoint.errors.map((error) => error.status))]
|
||||
const descriptor = `{ method: ${JSON.stringify(endpoint.endpoint.method)}, path: ${path}${parts.length === 0 ? "" : `, ${parts.join(", ")}`}, successStatus: ${resolveHttpApiStatus(endpoint.successes[0].ast) ?? 200}, declaredStatuses: [${declaredStatuses.join(", ")}], empty: ${endpoint.operation.success === "void"} }`
|
||||
if (endpoint.operation.success === "stream") {
|
||||
const success = endpoint.successes[0]
|
||||
|
|
@ -567,9 +569,12 @@ function structuralType(schema: Schema.Top) {
|
|||
)
|
||||
const expand = (type: string, seen = new Set<string>()): string => {
|
||||
for (const [reference, value] of references) {
|
||||
if (!type.includes(reference)) continue
|
||||
if (seen.has(reference)) throw new GenerationError({ reason: "Recursive Promise types are not implemented" })
|
||||
type = type.replaceAll(reference, `(${expand(value, new Set([...seen, reference]))})`)
|
||||
const pattern = `(?<![A-Za-z0-9_$.'"])${reference.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![A-Za-z0-9_$.'"])`
|
||||
if (!new RegExp(pattern).test(type)) continue
|
||||
if (seen.has(reference)) {
|
||||
throw new GenerationError({ reason: `Recursive Promise types are not implemented: ${reference}` })
|
||||
}
|
||||
type = type.replace(new RegExp(pattern, "g"), `(${expand(value, new Set([...seen, reference]))})`)
|
||||
}
|
||||
return type
|
||||
}
|
||||
|
|
@ -579,6 +584,7 @@ function structuralType(schema: Schema.Top) {
|
|||
}
|
||||
|
||||
function promisePath(path: string, input: ReadonlyArray<InputField>) {
|
||||
if (path.includes("*")) throw new GenerationError({ reason: `Unsupported Promise path wildcard: ${path}` })
|
||||
const fields = new Set(input.filter((field) => field.source === "params").map((field) => field.name))
|
||||
const segments = path.split(/(:[A-Za-z_][A-Za-z0-9_]*)/g).filter(Boolean)
|
||||
const template = segments
|
||||
|
|
@ -932,18 +938,26 @@ function serializable(value: unknown): boolean {
|
|||
}
|
||||
|
||||
function taggedErrorFields(schema: Schema.Top) {
|
||||
const fields = declaredErrorFields(schema)
|
||||
return fields?.key === "_tag" ? fields : undefined
|
||||
}
|
||||
|
||||
function declaredErrorFields(schema: Schema.Top) {
|
||||
if (!SchemaAST.isDeclaration(schema.ast) || schema.ast.annotations?.["~effect/Schema/Class"] === undefined) {
|
||||
return undefined
|
||||
}
|
||||
const fields = schema.ast.typeParameters[0]
|
||||
if (!SchemaAST.isObjects(fields) || fields.indexSignatures.length > 0) return undefined
|
||||
const tag = fields.propertySignatures.find((field) => field.name === "_tag")?.type
|
||||
const key = fields.propertySignatures.find((field) => field.name === "_tag" || field.name === "name")?.name
|
||||
if (key !== "_tag" && key !== "name") return undefined
|
||||
const tag = fields.propertySignatures.find((field) => field.name === key)?.type
|
||||
if (tag === undefined || !SchemaAST.isLiteral(tag) || typeof tag.literal !== "string") return undefined
|
||||
return {
|
||||
key,
|
||||
tag: tag.literal,
|
||||
identifier: SchemaAST.resolveIdentifier(schema.ast) ?? tag.literal,
|
||||
fields: fields.propertySignatures.flatMap((field) =>
|
||||
field.name === "_tag" || typeof field.name !== "string"
|
||||
field.name === key || typeof field.name !== "string"
|
||||
? []
|
||||
: [[field.name, Schema.make(field.type), SchemaAST.isOptional(field.type)] as const],
|
||||
),
|
||||
|
|
@ -1014,7 +1028,7 @@ function renderGroup(group: Group, groupIndex: number) {
|
|||
const headers = addSlot(endpointHeaders, `${prefix}Headers`)
|
||||
const payloads = endpointPayloads.map((schema, index) => addSlot(schema, `${prefix}Payload${index}`)!)
|
||||
const success = renderSuccess(successes[0], `${prefix}Success`)
|
||||
const errorSlots = errors.map((schema, index) => addSlot(schema, `${prefix}Error${index}`)!)
|
||||
const errorSlots = errors.map((error, index) => addSlot(error.schema, `${prefix}Error${index}`)!)
|
||||
const options = [
|
||||
params === undefined ? undefined : `params: ${params.name}`,
|
||||
query === undefined ? undefined : `query: ${query.name}`,
|
||||
|
|
|
|||
|
|
@ -138,6 +138,48 @@ describe("HttpApiCodegen.generate", () => {
|
|||
expect(contract.groups[0]?.endpoints[0]?.operation).toMatchObject({ group: "sessions", name: "get" })
|
||||
})
|
||||
|
||||
test("supports explicit public endpoint names", () => {
|
||||
const source = HttpApi.make("test").add(
|
||||
HttpApiGroup.make("server.permission")
|
||||
.add(HttpApiEndpoint.get("permission.request.list", "/request", { success: Schema.String }))
|
||||
.add(HttpApiEndpoint.get("session.permission.list", "/session", { success: Schema.String })),
|
||||
)
|
||||
const contract = compileContract(source, {
|
||||
endpointNames: { "permission.request.list": "listRequests" },
|
||||
})
|
||||
|
||||
expect(contract.groups[0]?.endpoints.map((endpoint) => endpoint.operation.name)).toEqual(["listRequests", "list"])
|
||||
})
|
||||
|
||||
test("omits custom transport endpoints", () => {
|
||||
const source = HttpApi.make("test").add(
|
||||
HttpApiGroup.make("server.pty")
|
||||
.add(HttpApiEndpoint.get("pty.get", "/pty", { success: Schema.String }))
|
||||
.add(HttpApiEndpoint.get("pty.connect", "/pty/connect", { success: Schema.Boolean })),
|
||||
)
|
||||
const contract = compileContract(source, { omitEndpoints: new Set(["pty.connect"]) })
|
||||
|
||||
expect(contract.groups[0]?.endpoints.map((endpoint) => endpoint.endpoint.name)).toEqual(["pty.get"])
|
||||
})
|
||||
|
||||
test("uses bracket access for input field names", () => {
|
||||
const source = api(
|
||||
HttpApiEndpoint.post("token", "/token", {
|
||||
headers: { "x-example-token": Schema.Literal("1") },
|
||||
success: Schema.String,
|
||||
}),
|
||||
)
|
||||
const contract = compileContract(source)
|
||||
const promise = emitPromise(contract).files.find((file) => file.path === "client.ts")?.content
|
||||
const effect = emitEffectImported(contract, {
|
||||
module: "@example/api",
|
||||
endpoints: { "session.token": "Token" },
|
||||
}).files.find((file) => file.path === "client.ts")?.content
|
||||
|
||||
expect(promise).toContain('"x-example-token": input["x-example-token"]')
|
||||
expect(effect).toContain('"x-example-token": input["x-example-token"]')
|
||||
})
|
||||
|
||||
test("rejects consumer group name collisions", () => {
|
||||
const source = HttpApi.make("test")
|
||||
.add(HttpApiGroup.make("first").add(HttpApiEndpoint.get("one", "/one", { success: Schema.String })))
|
||||
|
|
@ -184,6 +226,33 @@ describe("HttpApiCodegen.generate", () => {
|
|||
)
|
||||
})
|
||||
|
||||
test("supports name-discriminated Promise errors", () => {
|
||||
class NamedError extends Schema.ErrorClass<NamedError>("NamedError")(
|
||||
{ name: Schema.Literal("NamedError"), message: Schema.String },
|
||||
{ httpApiStatus: 400 },
|
||||
) {}
|
||||
const output = emitPromise(
|
||||
compileContract(
|
||||
api(HttpApiEndpoint.get("get", "/session", { success: Schema.NumberFromString, error: NamedError })),
|
||||
),
|
||||
)
|
||||
const types = output.files.find((file) => file.path === "types.ts")?.content
|
||||
|
||||
expect(types).toContain('readonly "name": "NamedError"')
|
||||
expect(types).toContain('"name" in value && value["name"] === "NamedError"')
|
||||
})
|
||||
|
||||
test("preserves reflected default error statuses", () => {
|
||||
class MissingStatus extends Schema.TaggedErrorClass<MissingStatus>()("MissingStatus", {
|
||||
message: Schema.String,
|
||||
}) {}
|
||||
const output = emitPromise(
|
||||
compileContract(api(HttpApiEndpoint.get("get", "/session", { success: Schema.String, error: MissingStatus }))),
|
||||
)
|
||||
|
||||
expect(output.files.find((file) => file.path === "client.ts")?.content).toContain("declaredStatuses: [500]")
|
||||
})
|
||||
|
||||
test("erases brands from Promise wire types", () => {
|
||||
const output = emitPromise(
|
||||
compileContract(
|
||||
|
|
@ -218,6 +287,26 @@ describe("HttpApiCodegen.generate", () => {
|
|||
)
|
||||
})
|
||||
|
||||
test("expands Promise references only at identifier boundaries", () => {
|
||||
const Session = Schema.Struct({ name: Schema.Literal("Session"), id: Schema.String }).annotate({
|
||||
identifier: "Session",
|
||||
})
|
||||
const SessionID = Schema.String.annotate({ identifier: "SessionID" })
|
||||
const output = emitPromise(
|
||||
compileContract(
|
||||
api(
|
||||
HttpApiEndpoint.get("get", "/session", {
|
||||
success: Schema.Struct({ session: Session, sessionID: SessionID }),
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
expect(output.files.find((file) => file.path === "types.ts")?.content).toContain(
|
||||
'readonly "session": ({ readonly "name": "Session", readonly "id": string })',
|
||||
)
|
||||
})
|
||||
|
||||
test("emits Effect Json schemas as standalone Promise types", () => {
|
||||
const output = emitPromise(
|
||||
compileContract(
|
||||
|
|
@ -265,6 +354,22 @@ describe("HttpApiCodegen.generate", () => {
|
|||
),
|
||||
).toThrow("Unsupported Promise success encoding: session.text")
|
||||
|
||||
expect(() =>
|
||||
emitPromise(
|
||||
compileContract(
|
||||
api(
|
||||
HttpApiEndpoint.get("binary", "/binary", {
|
||||
success: Schema.Uint8Array.pipe(HttpApiSchema.asUint8Array()),
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
).toThrow("Unsupported Promise success encoding: session.binary")
|
||||
|
||||
expect(() =>
|
||||
emitPromise(compileContract(api(HttpApiEndpoint.get("read", "/file/*", { success: Schema.String })))),
|
||||
).toThrow("Unsupported Promise path wildcard: /file/*")
|
||||
|
||||
expect(() =>
|
||||
emitPromise(
|
||||
compileContract(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue