feat(pty): expose shells and connect tokens
This commit is contained in:
parent
9de001d92f
commit
dbe7b937ef
6 changed files with 50 additions and 4 deletions
|
|
@ -78,6 +78,7 @@ export class ExitedError extends Schema.TaggedErrorClass<ExitedError>()("Pty.Exi
|
|||
}) {}
|
||||
|
||||
export interface Interface {
|
||||
readonly shells: () => Effect.Effect<ReadonlyArray<Pty.Shell>>
|
||||
readonly list: () => Effect.Effect<Info[]>
|
||||
readonly get: (id: PtyID) => Effect.Effect<Info, NotFoundError>
|
||||
readonly create: (input: CreateInput) => Effect.Effect<Info>
|
||||
|
|
@ -158,6 +159,10 @@ export const layer = (options?: ShellSelect.Options) => Layer.effect(
|
|||
return Array.from(sessions.values()).map((session) => session.info)
|
||||
})
|
||||
|
||||
const shells = Effect.fn("Pty.shells")(function* () {
|
||||
return yield* Effect.promise(() => ShellSelect.list(options))
|
||||
})
|
||||
|
||||
const get = Effect.fn("Pty.get")(function* (id: PtyID) {
|
||||
return (yield* requireSession(id)).info
|
||||
})
|
||||
|
|
@ -309,7 +314,7 @@ export const layer = (options?: ShellSelect.Options) => Layer.effect(
|
|||
}
|
||||
})
|
||||
|
||||
return Service.of({ list, get, create, update, remove, write, attach })
|
||||
return Service.of({ shells, list, get, create, update, remove, write, attach })
|
||||
}),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,18 @@ const waitForOutput = (output: Queue.Queue<string>, text: string) =>
|
|||
}),
|
||||
)
|
||||
|
||||
describe("Pty.shells", () => {
|
||||
it.live("lists available shells", () =>
|
||||
Effect.gen(function* () {
|
||||
const pty = yield* Pty.Service
|
||||
const shells = yield* pty.shells()
|
||||
|
||||
expect(shells.length).toBeGreaterThan(0)
|
||||
expect(shells.every((shell) => shell.path && shell.name && typeof shell.acceptable === "boolean")).toBe(true)
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
describe("pty", () => {
|
||||
it.live("returns typed not found errors for missing sessions", () =>
|
||||
Effect.gen(function* () {
|
||||
|
|
|
|||
|
|
@ -63,5 +63,5 @@ export const groupNames = {
|
|||
"server.path": "path",
|
||||
} as const
|
||||
|
||||
export const promiseOmitEndpoints = new Set(["pty.connect", "pty.connectToken"])
|
||||
export const effectOmitEndpoints = new Set(["fs.read", "pty.connect", "pty.connectToken"])
|
||||
export const promiseOmitEndpoints = new Set(["pty.connect"])
|
||||
export const effectOmitEndpoints = new Set(["fs.read", "pty.connect"])
|
||||
|
|
|
|||
|
|
@ -19,6 +19,20 @@ export function hasPtyConnectTicketURL(url: URL) {
|
|||
}
|
||||
|
||||
export const PtyGroup = HttpApiGroup.make("server.pty")
|
||||
.add(
|
||||
HttpApiEndpoint.get("pty.shells", "/api/pty/shells", {
|
||||
query: LocationQuery,
|
||||
success: Location.response(Schema.Array(Pty.Shell)),
|
||||
})
|
||||
.annotateMerge(locationQueryOpenApi)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "v2.pty.shells",
|
||||
summary: "List available shells",
|
||||
description: "List shells available for interactive terminal sessions.",
|
||||
}),
|
||||
),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.get("pty.list", "/api/pty", {
|
||||
query: LocationQuery,
|
||||
|
|
@ -101,13 +115,14 @@ export const PtyGroup = HttpApiGroup.make("server.pty")
|
|||
HttpApiEndpoint.post("pty.connectToken", "/api/pty/:ptyID/connect-token", {
|
||||
params: { ptyID: Pty.ID },
|
||||
query: LocationQuery,
|
||||
headers: Schema.Struct({ [PTY_CONNECT_TOKEN_HEADER]: Schema.optional(Schema.String) }),
|
||||
success: Location.response(PtyTicket.ConnectToken),
|
||||
error: [ForbiddenError, PtyNotFoundError],
|
||||
})
|
||||
.annotateMerge(locationQueryOpenApi)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "v2.pty.connect.token",
|
||||
identifier: "v2.pty.connectToken",
|
||||
summary: "Create PTY WebSocket token",
|
||||
description: "Create a short-lived single-use ticket for opening a PTY WebSocket connection.",
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -56,3 +56,10 @@ export const UpdateInput = Schema.Struct({
|
|||
),
|
||||
})
|
||||
export interface UpdateInput extends Schema.Schema.Type<typeof UpdateInput> {}
|
||||
|
||||
export const Shell = Schema.Struct({
|
||||
path: Schema.String,
|
||||
name: Schema.String,
|
||||
acceptable: Schema.Boolean,
|
||||
}).annotate({ identifier: "Pty.Shell" })
|
||||
export interface Shell extends Schema.Schema.Type<typeof Shell> {}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,13 @@ export const PtyHandler = HttpApiBuilder.group(Api, "server.pty", (handlers) =>
|
|||
const environment = yield* PtyEnvironment.Service
|
||||
|
||||
return handlers
|
||||
.handle(
|
||||
"pty.shells",
|
||||
Effect.fn(function* () {
|
||||
const pty = yield* Pty.Service
|
||||
return yield* response(pty.shells())
|
||||
}),
|
||||
)
|
||||
.handle(
|
||||
"pty.list",
|
||||
Effect.fn(function* () {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue