1import type {
2 ExecCommandError,
3 ExecResult,
4} from "@distilled.cloud/fly-io/sprites";
5import type * as Effect from "effect/Effect";
6import * as Binding from "../Binding.ts";
7import type { RuntimeContext } from "../RuntimeContext.ts";
8import type { Sprite } from "./Sprite.ts";
9
10export 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 */
43export 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
55export const Exec = Binding.Service<Exec>("Fly.Exec");