dax
Version:
Cross platform shell tools inspired by zx.
677 lines • 28.9 kB
TypeScript
import * as dntShim from "../../../../../../_dnt.shims.js";
import { Path } from "../../../path/0.3.2/mod.js";
import { Buffer } from "../../../../@std/io/0.225.3/buffer.js";
import type { CommandHandler } from "./commandHandler.js";
import { Box, type Delay, LoggerTreeBox } from "./common.js";
import type { Signal } from "./signal.js";
import { ByteRingBuffer } from "./byteRingBuffer.js";
import { type ErrorTailOptions, PipedBuffer, type Reader, type ShellPipeReaderKind, type ShellPipeWriterKind, type TailDisplayOptions } from "./pipes.js";
import { type ShellOptionsState } from "./shell.js";
import { StreamFds } from "./shell.js";
type BufferStdio = "inherit" | "null" | "streamed" | Buffer;
/** Identifies one of the standard output streams of a command, or both
* of them when combined. */
export type StreamKind = "stdout" | "stderr" | "combined";
declare class Deferred<T> {
#private;
constructor(create: () => T | Promise<T>);
create(): T | Promise<T>;
}
interface ShellPipeWriterKindWithOptions {
kind: ShellPipeWriterKind;
options?: dntShim.StreamPipeOptions;
}
export interface CommandBuilderStateCommand {
text: string;
fds: StreamFds | undefined;
}
interface CommandBuilderState {
command: Readonly<CommandBuilderStateCommand> | undefined;
stdin: "inherit" | "null" | Box<Reader | dntShim.ReadableStream<Uint8Array> | "consumed"> | Deferred<dntShim.ReadableStream<Uint8Array> | Reader>;
combinedStdoutStderr: boolean;
stdout: ShellPipeWriterKindWithOptions;
stderr: ShellPipeWriterKindWithOptions;
tailDisplay: false | TailDisplayOptions;
errorTail: false | ErrorTailOptions;
noThrow: boolean | number[];
env: Record<string, string | undefined>;
commands: Record<string, CommandHandler>;
cwd: string | undefined;
clearEnv: boolean;
exportEnv: boolean;
printCommand: boolean;
printCommandLogger: LoggerTreeBox;
timeout: number | undefined;
signal: KillSignal | undefined;
encoding: string | undefined;
shellOptions: Partial<ShellOptionsState>;
beforeCommand: BeforeCommandCallback[] | undefined;
beforeCommandSync: BeforeCommandSyncCallback[] | undefined;
}
/** Synchronous variant of {@link BeforeCommandCallback}. Receives the current
* builder and returns a (possibly modified) builder synchronously, or returns
* nothing for a no-op.
*
* Unlike {@link BeforeCommandCallback}, this runs even on the `.spawn()` path
* since no async work is involved.
*/
export type BeforeCommandSyncCallback = (builder: CommandBuilder) => CommandBuilder | void;
/** Callback invoked before a command is spawned.
*
* Receives the current builder and may return a (possibly modified) builder
* to use for the spawn. Returning the builder unchanged — or returning
* nothing — is a no-op.
*
* The builder passed to the callback is wrapped in a Proxy that hides its
* `.then`, so it isn't detected as a thenable by the JavaScript Promise
* machinery. That makes it safe to `return builder.env(...)` from an `async`
* function without the runtime recursively unwrapping the thenable and
* triggering a spawn. Methods like `.env(...)` that return a new builder
* return another such wrapped Proxy.
*
* The return type is loose because TypeScript infers the async return type
* by following `PromiseLike` (the same logic the runtime uses), so e.g.
* `async b => b.env(...)` is inferred as `Promise<CommandResult>`.
*/
export type BeforeCommandCallback = (builder: CommandBuilder) => CommandBuilder | Promise<CommandBuilder> | Promise<CommandResult> | void | Promise<void>;
/** @internal */
export declare const getRegisteredCommandNamesSymbol: unique symbol;
/** @internal */
export declare const setCommandTextStateSymbol: unique symbol;
/**
* Underlying builder API for executing commands.
*
* This is what `$` uses to execute commands. Using this provides
* a way to provide a raw text command or an array of arguments.
*
* Command builders are immutable where each method call creates
* a new command builder.
*
* ```ts
* const builder = new CommandBuilder()
* .cwd("./src")
* .command("echo $MY_VAR");
*
* // outputs 5
* console.log(await builder.env("MY_VAR", "5").text());
* // outputs 6
* console.log(await builder.env("MY_VAR", "6").text());
* ```
*/
export declare class CommandBuilder implements PromiseLike<CommandResult> {
#private;
/** Spawns the command and returns a promise resolving to the command result.
*
* Allows awaiting a `CommandBuilder` directly without calling `.spawn()`.
*/
then<TResult1 = CommandResult, TResult2 = never>(onfulfilled?: ((value: CommandResult) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): PromiseLike<TResult1 | TResult2>;
/**
* Explicit way to spawn a command.
*
* This is an alias for awaiting the command builder or calling `.then(...)`
*/
spawn(): CommandChild;
/**
* Register a command.
*/
registerCommand(command: string, handleFn: CommandHandler): CommandBuilder;
/**
* Register multilple commands.
*/
registerCommands(commands: Record<string, CommandHandler>): CommandBuilder;
/**
* Unregister a command.
*/
unregisterCommand(command: string): CommandBuilder;
/** Sets the raw command to execute. */
command(command: string | string[]): CommandBuilder;
/** The command should not throw for the provided non-zero exit codes. */
noThrow(exclusionExitCode: number, ...additional: number[]): CommandBuilder;
/** The command should not throw when it fails or times out. */
noThrow(value?: boolean): CommandBuilder;
/** Registers a callback that runs just before each command is spawned.
*
* The callback receives the current builder and may return a (possibly
* modified) builder to use for the spawn. Useful for asynchronously
* resolving values such as auth tokens or env vars.
*
* ```ts
* $`./build.sh`.beforeCommand(async (builder) => {
* return builder.env("AUTH_TOKEN", await getAccessToken());
* });
* ```
*
* Multiple `.beforeCommand(...)` calls compose: each registered callback runs
* in the order it was added, with the builder produced by the previous one.
*
* The builder passed to the callback is in a special "passthrough" mode so
* its `.then(...)` resolves with the builder itself (instead of spawning) —
* this is what makes `return builder.env(...)` from an `async` function
* safe. If you construct a fresh `new CommandBuilder()` inside the callback,
* return it as `{ commandBuilder: ... }` to avoid an accidental spawn.
*
* Hooks are only resolved when the builder is awaited (or `.then()` is
* called). Calling `.spawn()` on a builder with registered hooks throws.
*/
beforeCommand(callback: BeforeCommandCallback): CommandBuilder;
/** Synchronous variant of {@link beforeCommand}. Unlike `.beforeCommand`,
* sync hooks also run on the `.spawn()` path, so they're suitable when you
* need streaming via `.spawn().stdout()` etc.
*
* The callback must return synchronously (`CommandBuilder` or nothing). The
* thenable-unwrapping concern doesn't apply here because the return value
* never passes through Promise machinery — `return builder.env(...)` is just
* a function return.
*
* ```ts
* const child = $`./build.sh`
* .beforeCommandSync((builder) => builder.env("BUILD_ID", crypto.randomUUID()))
* .spawn();
* ```
*
* Sync hooks always run before async hooks during a single resolution pass.
*/
beforeCommandSync(callback: BeforeCommandSyncCallback): CommandBuilder;
/** Sets the signal that will be passed to all commands
* created with this command builder.
*
* Accepts a `KillSignal` or a standard `AbortSignal`. When an
* `AbortSignal` is provided it is internally bridged to a
* `KillSignal` that sends `SIGTERM` on abort.
*/
signal(signal: KillSignal | AbortSignal): CommandBuilder;
/**
* Whether to capture a combined buffer of both stdout and stderr.
*
* This will set both stdout and stderr to "piped" if not already "piped"
* or "inheritPiped".
*/
captureCombined(value?: boolean): CommandBuilder;
/**
* Sets the stdin to use for the command.
*
* @remarks If multiple launches of a command occurs, then stdin will only be
* read from the first consumed reader or readable stream and error otherwise.
* For this reason, if you are setting stdin to something other than "inherit" or
* "null", then it's recommended to set this each time you spawn a command.
*/
stdin(reader: ShellPipeReaderKind): CommandBuilder;
/**
* Sets the stdin string to use for a command.
*
* @remarks See the remarks on stdin. The same applies here.
*/
stdinText(text: string): CommandBuilder;
/** Set the stdout kind. */
stdout(kind: ShellPipeWriterKind): CommandBuilder;
/** Set the stdout to pipe to the provided WritableStream with optional pipe options. */
stdout(kind: dntShim.WritableStream<Uint8Array>, options?: dntShim.StreamPipeOptions): CommandBuilder;
/** Set the stderr kind. */
stderr(kind: ShellPipeWriterKind): CommandBuilder;
/** Set the stderr to pipe to the provided WritableStream with optional pipe options. */
stderr(kind: dntShim.WritableStream<Uint8Array>, options?: dntShim.StreamPipeOptions): CommandBuilder;
/**
* Enables Docker-style partial scrolling for any `"inherit"` or
* `"inheritPiped"` output: only the last few lines are shown in a
* static region at the bottom of the terminal while the command
* runs. When both stdout and stderr are being displayed, they
* interleave into a single shared scrolling region with one header.
*
* On success the region is cleared (header promotes to scrollback);
* on error the retained tail is flushed above so the user can see
* what happened. Has no effect on non-TTY output or on streams
* routed elsewhere (piped, null, WritableStream, Path, etc.).
*
* Pass an options object to customize the visible line count or header.
*
* @example
* ```ts
* await $`./build.sh`.tailDisplay();
* await $`./build.sh`.tailDisplay({ maxLines: 2, header: false });
* await $`./build.sh`.tailDisplay({
* maxLines: "50%",
* header: ({ command }) => `building ${command}...`,
* });
* ```
*/
tailDisplay(value?: boolean): CommandBuilder;
/** Enables Docker-style partial scrolling with the provided options. */
tailDisplay(options: TailDisplayOptions): CommandBuilder;
/**
* Silently retains the trailing N bytes of stdout and/or stderr and
* appends them to the thrown `Error.message` if the command exits with
* a non-zero code. Targets the case where the stream is going somewhere
* the user can't see — piped to another command, redirected to a file,
* sent to a `WritableStream`, or discarded with `"null"` — so they
* still get a glimpse of what was written when the command fails.
*
* Streams routed to the terminal (`"inherit"` / `"inheritPiped"`) are
* skipped: the user already watched those bytes scroll by, so adding
* them to the error message would just be noise.
*
* Has no effect when the command succeeds (the buffer is discarded) or
* when `.noThrow()` swallows the failure.
*
* @example
* ```ts
* // when stdout is being captured for the return value (.text(),
* // .json(), .bytes(), etc.), errorTail surfaces it in the thrown
* // error if the command fails — without it the captured bytes vanish
* // along with the result you never got.
* const output = await $`./build.sh`.errorTail().text();
* const output = await $`./build.sh`.errorTail({ maxBytes: 16 * 1024 }).text();
* ```
*/
errorTail(value?: boolean): CommandBuilder;
/** Enables errorTail capture with the provided options. */
errorTail(options: ErrorTailOptions): CommandBuilder;
/** Pipes the current command to the provided command returning the
* provided command builder. When chaining, it's important to call this
* after you are done configuring the current command or else you will
* start modifying the provided command instead.
*
* @example
* ```ts
* const lineCount = await $`echo 1 && echo 2`
* .pipe($`wc -l`)
* .text();
* ```
*/
pipe(builder: CommandBuilder): CommandBuilder;
/** Sets multiple environment variables to use at the same time via an object literal. */
env(items: Record<string, string | undefined>): CommandBuilder;
/** Sets a single environment variable to use. */
env(name: string, value: string | undefined): CommandBuilder;
/** Sets the current working directory to use when executing this command. */
cwd(dirPath: string | URL | Path): CommandBuilder;
/**
* Exports the environment of the command to the executing process.
*
* So for example, changing the directory in a command or exporting
* an environment variable will actually change the environment
* of the executing process.
*
* ```ts
* await $`cd src && export SOME_VALUE=5`;
* console.log(process.env["SOME_VALUE"]); // 5
* console.log(process.cwd()); // will be in the src directory
* ```
*/
exportEnv(value?: boolean): CommandBuilder;
/**
* Clear environmental variables from parent process.
*
* Doesn't guarantee that only `env` variables are present, as the OS may
* set environmental variables for processes.
*/
clearEnv(value?: boolean): CommandBuilder;
/**
* Prints the command text before executing the command.
*
* For example:
*
* ```ts
* const text = "example";
* await $`echo ${text}`.printCommand();
* ```
*
* Outputs:
*
* ```
* > echo example
* example
* ```
*/
printCommand(value?: boolean): CommandBuilder;
/**
* Mutates the command builder to change the logger used
* for `printCommand()`.
*/
setPrintCommandLogger(logger: (...args: any[]) => void): void;
/**
* Ensures stdout and stderr are piped if they have the default behaviour or are inherited.
*
* ```ts
* // ensure both stdout and stderr is not logged to the console
* await $`echo 1`.quiet();
* // ensure stdout is not logged to the console
* await $`echo 1`.quiet("stdout");
* // ensure stderr is not logged to the console
* await $`echo 1`.quiet("stderr");
* ```
*/
quiet(kind?: StreamKind | "both"): CommandBuilder;
/**
* Specifies a timeout for the command. The command will exit with
* exit code `124` (timeout) if it times out.
*
* Note that when using `.noThrow()` this won't cause an error to
* be thrown when timing out.
*/
timeout(delay: Delay | undefined): CommandBuilder;
/**
* Sets stdout as quiet, spawns the command, and gets stdout as a Uint8Array.
*
* Shorthand for:
*
* ```ts
* const data = (await $`command`.quiet("stdout")).stdoutBytes;
* ```
*/
bytes(kind?: StreamKind): Promise<Uint8Array>;
/**
* Sets the text decoder encoding to use for decoding stdout and stderr.
*
* This can be useful when the command output uses a specific character encoding
* that differs from the default UTF-8 encoding.
*/
encoding(encoding?: string): CommandBuilder;
/**
* Sets whether pipefail is enabled. When enabled, a pipeline's exit code
* is the rightmost non-zero exit code, or 0 if all commands succeed.
*
* ```ts
* // without pipefail (default): exit code is from the last command (grep)
* const code1 = await $`false | grep foo`.noThrow().code(); // 1 (grep's exit code)
*
* // with pipefail: exit code is from the first failing command
* const code2 = await $`false | grep foo`.pipefail().noThrow().code(); // 1 (false's exit code)
* ```
*/
pipefail(value?: boolean): CommandBuilder;
/**
* Sets whether nullglob is enabled. When enabled, a glob pattern that
* matches no files expands to nothing (empty) rather than being passed
* through literally.
*
* Note: This also disables failglob since nullglob and failglob are
* mutually exclusive behaviors.
*
* ```ts
* // without nullglob (default): passes pattern literally
* await $`echo *.nonexistent`; // outputs "*.nonexistent"
*
* // with nullglob: expands to nothing
* await $`echo *.nonexistent`.nullglob(); // outputs empty line
* ```
*/
nullglob(value?: boolean): CommandBuilder;
/**
* Sets whether failglob is enabled. When enabled, a glob pattern
* that matches no files causes an error. When disabled (the default),
* unmatched patterns are passed through literally.
*
* ```ts
* // without failglob (default): passes pattern literally
* await $`echo *.nonexistent`; // outputs "*.nonexistent"
*
* // with failglob: throws error if no matches
* await $`echo *.nonexistent`.failglob(); // Error: glob: no matches found
* ```
*/
failglob(value?: boolean): CommandBuilder;
/**
* Sets whether globstar is enabled. When enabled (the default), the pattern `**`
* used in a pathname expansion context will match all files and zero or more
* directories and subdirectories. When disabled, `**` is treated as `*`.
*
* ```ts
* // with globstar (default): ** matches recursively
* await $`echo **\/*.ts`; // matches all .ts files in all subdirectories
*
* // without globstar: ** is treated as *
* await $`echo **\/*.ts`.globstar(false); // matches only .ts files one level deep
* ```
*/
globstar(value?: boolean): CommandBuilder;
/**
* Sets whether questionGlob is enabled. When enabled, `?` matches any
* single character in glob patterns. When disabled (the default), `?` is
* treated literally.
*
* This option is only available via the builder API, not via `shopt` or `set`.
*
* ```ts
* // without questionGlob (default): ? is literal
* await $`echo a?c`; // outputs "a?c"
*
* // with questionGlob: ? matches any single character
* await $`echo a?c`.questionGlob(); // matches files like "abc", "axc", etc.
* ```
*/
questionGlob(value?: boolean): CommandBuilder;
/**
* Sets the provided stream (stdout by default) as quiet, spawns the command, and gets the stream as a string without the last newline.
* Can be used to get stdout, stderr, or both.
*
* Shorthand for:
*
* ```ts
* const data = (await $`command`.quiet("stdout")).stdout.replace(/\r?\n$/, "");
* ```
*/
text(kind?: StreamKind): Promise<string>;
/**
* Gets the text as an array of lines.
*
* Lines are split the same way as {@link CommandBuilder.linesIter} (matches
* [Rust's `str::lines`](https://doc.rust-lang.org/std/primitive.str.html#method.lines)):
* line terminators are not included, a trailing blank line caused by a final
* line ending is excluded, and empty output yields no lines.
*/
lines(kind?: StreamKind): Promise<string[]>;
/**
* Streams the command's output and iterates over its lines without
* buffering everything into memory.
*
* Lines are split at `\n` or `\r\n`. Line terminators are not included.
* A trailing blank line caused by a final line ending is excluded (matches
* [Rust's `str::lines`](https://doc.rust-lang.org/std/primitive.str.html#method.lines)).
*
* If iteration is abandoned before the end of the output is reached, the
* child process is killed.
*
* ```ts
* for await (const line of $`cat big.txt`.linesIter()) {
* console.log(line);
* }
* ```
*/
linesIter(kind?: Exclude<StreamKind, "combined">): AsyncIterableIterator<string>;
/**
* Sets stream (stdout by default) as quiet, spawns the command, and gets stream as JSON.
*
* Shorthand for:
*
* ```ts
* const data = (await $`command`.quiet("stdout")).stdoutJson;
* ```
*/
json<TResult = any>(kind?: Exclude<StreamKind, "combined">): Promise<TResult>;
/**
* Helper to get the exit code without throwing on non-zero exit codes.
*
* Shorthand for:
*
* ```ts
* const code = (await $`command`.noThrow()).code;
* ```
*/
code(): Promise<number>;
/** @internal */
[getRegisteredCommandNamesSymbol](): string[];
/** @internal */
[setCommandTextStateSymbol](textState: CommandBuilderStateCommand): CommandBuilder;
}
/** A spawned command. Awaiting it resolves to a `CommandResult` and it
* exposes hooks to read piped output streams or send signals to the
* underlying child process. */
export declare class CommandChild extends Promise<CommandResult> {
#private;
/** @internal */
constructor(executor: (resolve: (value: CommandResult) => void, reject: (reason?: any) => void) => void, options?: {
pipedStdoutBuffer: PipedBuffer | undefined;
pipedStderrBuffer: PipedBuffer | undefined;
killSignalController: KillController | undefined;
});
/** Send a signal to the executing command's child process. Note that SIGTERM,
* SIGKILL, SIGABRT, SIGQUIT, SIGINT, or SIGSTOP will cause the entire command
* to be considered "aborted" and if part of a command runs after this has occurred
* it will return a 124 exit code. Other signals will just be forwarded to the command.
*
* Defaults to "SIGTERM".
*/
kill(signal?: Signal): void;
/** Returns a `ReadableStream` of the running child's stdout. Requires the
* stdout to have been set to `"piped"`. May only be consumed once. */
stdout(): dntShim.ReadableStream<Uint8Array>;
/** Returns a `ReadableStream` of the running child's stderr. Requires the
* stderr to have been set to `"piped"`. May only be consumed once. */
stderr(): dntShim.ReadableStream<Uint8Array>;
}
export declare function parseAndSpawnCommand(state: CommandBuilderState, callerStack?: string): CommandChild;
/** Error thrown when a command exits with a non-zero code (and `.noThrow()`
* is not set). Exposes structured properties (`exitCode`, `stdout`, `stderr`)
* so callers can inspect the failure programmatically. The human-readable
* `message` — including any captured error-tail output — is built lazily on
* first access so the formatting cost is skipped when the error is caught
* and only its properties are used. */
export declare class ShellError extends Error {
#private;
readonly name = "ShellError";
/** The process exit code. */
readonly exitCode: number;
/** Whether the command was killed because its timeout elapsed. */
readonly timedOut: boolean;
/** Whether the command was aborted via its kill signal. */
readonly aborted: boolean;
/** Captured trailing stdout text from the error-tail ring buffer.
* Empty string when stdout was not captured (e.g. routed to the
* terminal, or errorTail disabled for stdout). */
readonly stdout: string;
/** Captured trailing stderr text from the error-tail ring buffer.
* Empty string when stderr was not captured. */
readonly stderr: string;
/** @internal */
constructor(options: {
exitCode: number;
timedOut: boolean;
aborted: boolean;
stdoutRing: ByteRingBuffer | undefined;
stderrRing: ByteRingBuffer | undefined;
combinedRing: ByteRingBuffer | undefined;
});
get message(): string;
set message(value: string);
}
/** Result of running a command. */
export declare class CommandResult {
#private;
/** The exit code. */
readonly code: number;
/** @internal */
constructor(code: number, stdout: BufferStdio, stderr: BufferStdio, combined: Buffer | undefined, encoding: string | undefined);
/** Raw decoded stdout text. */
get stdout(): string;
/**
* Stdout text as JSON.
*
* @remarks Will throw if it can't be parsed as JSON.
*/
get stdoutJson(): any;
/** Raw stdout bytes. */
get stdoutBytes(): Uint8Array;
/** Raw decoded stdout text. */
get stderr(): string;
/**
* Stderr text as JSON.
*
* @remarks Will throw if it can't be parsed as JSON.
*/
get stderrJson(): any;
/** Raw stderr bytes. */
get stderrBytes(): Uint8Array;
/** Raw combined stdout and stderr text. */
get combined(): string;
/** Raw combined stdout and stderr bytes. */
get combinedBytes(): Uint8Array;
}
/** Escapes a single argument for safe interpolation into a shell command. */
export declare function escapeArg(arg: string): string;
/** Wraps a value so that it is interpolated into a template literal command
* without being shell-escaped. Use {@link rawArg} to construct one. */
export declare class RawArg<T> {
#private;
/** Creates a new `RawArg` wrapping the provided value. */
constructor(value: T);
/** The wrapped value that will be used as-is during template substitution. */
get value(): T;
}
/** Creates a `RawArg` wrapping the provided value so it bypasses shell
* argument escaping when interpolated into a template literal command. */
export declare function rawArg<T>(arg: T): RawArg<T>;
interface KillSignalState {
abortedCode: number | undefined;
listeners: ((signal: Signal) => void)[];
}
/** Similar to an AbortController, but for sending signals to commands. */
export declare class KillController {
#private;
constructor();
/** The associated `KillSignal` to attach to commands. */
get signal(): KillSignal;
/** Send a signal to the downstream child process. Note that SIGTERM,
* SIGKILL, SIGABRT, SIGQUIT, SIGINT, or SIGSTOP will cause all the commands
* to be considered "aborted" and will return a 124 exit code, while other
* signals will just be forwarded to the commands.
*/
kill(signal?: Signal): void;
}
/** Listener for when a KillSignal is killed. */
export type KillSignalListener = (signal: Signal) => void;
/** Similar to `AbortSignal`, but for OS signals.
*
* A `KillSignal` is considered aborted if its controller
* receives SIGTERM, SIGKILL, SIGABRT, SIGQUIT, SIGINT, or SIGSTOP.
*
* These can be created via a `KillController`.
*/
export declare class KillSignal {
#private;
/** @internal */
constructor(symbol: Symbol, state: KillSignalState);
/** Returns if the command signal has ever received a SIGTERM,
* SIGKILL, SIGABRT, SIGQUIT, SIGINT, or SIGSTOP
*/
get aborted(): boolean;
/** Gets the exit code to use if aborted. */
get abortedExitCode(): number | undefined;
/**
* Causes the provided kill signal to be triggered when this
* signal receives a signal.
*/
linkChild(killSignal: KillSignal): {
unsubscribe(): void;
};
/** Registers a listener that will be invoked whenever a signal is sent. */
addListener(listener: KillSignalListener): void;
/** Removes a previously registered listener. */
removeListener(listener: KillSignalListener): void;
}
export declare function getSignalAbortCode(signal: Signal): number | undefined;
export declare function template(strings: TemplateStringsArray, exprs: TemplateExpr[]): CommandBuilderStateCommand;
export declare function templateRaw(strings: TemplateStringsArray, exprs: TemplateExpr[]): CommandBuilderStateCommand;
/** A template expression that can be substituted into a command outside of
* an input/output redirect context. */
export type NonRedirectTemplateExpr = string | number | boolean | Path | Uint8Array | CommandResult | RawArg<NonRedirectTemplateExpr> | {
toString(): string;
catch?: never;
};
/** Any value that may be interpolated into a `$` template literal command. */
export type TemplateExpr = NonRedirectTemplateExpr | NonRedirectTemplateExpr[] | dntShim.ReadableStream<Uint8Array> | {
[readable: symbol]: () => dntShim.ReadableStream<Uint8Array>;
} | (() => dntShim.ReadableStream<Uint8Array>) | {
[writable: symbol]: () => dntShim.WritableStream<Uint8Array>;
} | dntShim.WritableStream<Uint8Array> | (() => dntShim.WritableStream<Uint8Array>);
export {};
//# sourceMappingURL=command.d.ts.map