| 1 | /** |
| 2 | * Process stdio for Deno applications. |
| 3 | * |
| 4 | * This module provides Effect's `Stdio` service using Deno's native process |
| 5 | * arguments and Web Streams. Standard input remains open, and standard output |
| 6 | * and error output are not closed unless requested through `endOnDone`. |
| 7 | * |
| 8 | * @since 4.0.0 |
| 9 | */ |
| 10 | import * as Effect from "effect/Effect" |
| 11 | import * as Layer from "effect/Layer" |
| 12 | import * as Sink from "effect/Sink" |
| 13 | import * as Stdio from "effect/Stdio" |
| 14 | import * as Stream from "effect/Stream" |
| 15 | import { handleError } from "./internal/error.ts" |
| 16 | |
| 17 | const encoder = new TextEncoder() |
| 18 | |
| 19 | const output = ( |
| 20 | evaluate: () => WritableStream<Uint8Array>, |
| 21 | method: "stdout" | "stderr", |
| 22 | options?: { readonly endOnDone?: boolean | undefined } |
| 23 | ) => |
| 24 | Sink.fromWritableStream({ |
| 25 | evaluate, |
| 26 | onError: handleError("Stdio", method), |
| 27 | closeOnDone: options?.endOnDone ?? false |
| 28 | }).pipe( |
| 29 | Sink.mapInput((input: string | Uint8Array) => typeof input === "string" ? encoder.encode(input) : input) |
| 30 | ) |
| 31 | |
| 32 | /** |
| 33 | * Provides the `Stdio` service backed by `Deno.args`, `Deno.stdin`, |
| 34 | * `Deno.stdout`, and `Deno.stderr`. |
| 35 | * |
| 36 | * @category layers |
| 37 | * @since 4.0.0 |
| 38 | */ |
| 39 | export const layer: Layer.Layer<Stdio.Stdio> = Layer.succeed( |
| 40 | Stdio.Stdio, |
| 41 | Stdio.make({ |
| 42 | args: Effect.sync(() => Deno.args), |
| 43 | stdinIsTerminal: Effect.sync(() => Deno.stdin.isTerminal()), |
| 44 | stdoutIsTerminal: Effect.sync(() => Deno.stdout.isTerminal()), |
| 45 | stdout: (options) => output(() => Deno.stdout.writable, "stdout", options), |
| 46 | stderr: (options) => output(() => Deno.stderr.writable, "stderr", options), |
| 47 | stdin: Stream.fromReadableStream({ |
| 48 | evaluate: () => Deno.stdin.readable, |
| 49 | onError: handleError("Stdio", "stdin"), |
| 50 | releaseLockOnEnd: true |
| 51 | }) |
| 52 | }) |
| 53 | ) |