| 1 | import type { |
| 2 | ExecCommandError, |
| 3 | ExecResult, |
| 4 | } from "@distilled.cloud/fly-io/sprites"; |
| 5 | import type * as Effect from "effect/Effect"; |
| 6 | import * as Binding from "../Binding.ts"; |
| 7 | import type { RuntimeContext } from "../RuntimeContext.ts"; |
| 8 | import type { Sprite } from "./Sprite.ts"; |
| 9 | |
| 10 | export interface ExecRequest { |
| 11 | /** Command and args. */ |
| 12 | cmd: string[]; |
| 13 | /** Explicit path to the executable. */ |
| 14 | path?: string; |
| 15 | /** Read stdin from {@link body}. */ |
| 16 | stdin?: boolean; |
| 17 | /** Environment variables as `KEY=VALUE`. */ |
| 18 | env?: string[]; |
| 19 | /** Working directory. */ |
| 20 | dir?: string; |
| 21 | /** Stdin bytes when {@link stdin} is true. */ |
| 22 | body?: Uint8Array | string; |
| 23 | } |
| 24 | |
| 25 | /** |
| 26 | * Run a command on a {@link Sprite} via `POST /sprites/{name}/exec`. |
| 27 | * |
| 28 | * |
| 29 | * ### Exec a command |
| 30 | * Bind the client in init. Provide {@link ExecHttp}. The Sprite name |
| 31 | * is fixed by `Exec(box)`. Alchemy transports that name and the |
| 32 | * deployment's org token to the caller automatically. |
| 33 | * |
| 34 | * **Example:** List files |
| 35 | * ```typescript |
| 36 | * const exec = yield* Fly.Exec(Box); |
| 37 | * const result = yield* exec({ cmd: ["ls", "-la"] }); |
| 38 | * ``` |
| 39 | * |
| 40 | * @binding |
| 41 | * @product Sprite |
| 42 | */ |
| 43 | export interface Exec extends Binding.Service< |
| 44 | Exec, |
| 45 | "Fly.Exec", |
| 46 | ( |
| 47 | sprite: Sprite, |
| 48 | ) => Effect.Effect< |
| 49 | ( |
| 50 | request: ExecRequest, |
| 51 | ) => Effect.Effect<ExecResult, ExecCommandError, RuntimeContext> |
| 52 | > |
| 53 | > {} |
| 54 | |
| 55 | export const Exec = Binding.Service<Exec>("Fly.Exec"); |