import type { StdioOptions } from 'node:child_process';
import { AppError } from '@naturalcycles/js-lib/error/error.util.js';
import type { AnyObject, NumberOfMilliseconds } from '@naturalcycles/js-lib/types';
/**
 * Set of utility functions to work with Spawn / Exec.
 *
 * How to decide between Spawn and Exec?
 *
 * Long-running job that prints output, and no need to return the output - use Spawn.
 *
 * Short-running job, no need to print the output, might want to return the output - use Exec.
 *
 * Need to both print and return the output - use SpawnAsyncAndReturn.
 *
 * ***
 *
 * Spawn is good for long-running large-output processes, that continuously output data.
 * E.g running `jest`.
 *
 * Exec is the opposite - good for short-running processes that output small data.
 * Exec allows to return the output as a string.
 * Exec doesn't stream data during execution, so the output/error will only be printed
 * at the end.
 * Exec always uses the shell (there's no option to disable it).
 */
declare class Exec2 {
    /**
     * Reasons to use it:
     * - Sync
     * - Need to print output while running
     *
     * Limitations:
     * - Cannot return stdout/stderr (use exec, execAsync or spawnAsyncAndReturn for that)
     *
     * Defaults:
     *
     * shell: true
     * log: true
     */
    spawn(cmd: string, opt?: SpawnOptions): void;
    /**
     * Reasons to use it:
     *
     * - Sync
     * - Need to return output
     *
     * Limitations:
     * - Cannot print while running (use spawn or spawnAsync for that)
     *
     * Defaults:
     *
     * shell: true
     * log: false
     */
    exec(cmd: string, opt?: ExecOptions): string;
    /**
     * Reasons to use it:
     * - Async
     * - Need to print output while running
     *
     * Limitations:
     * - Cannot return stdout/stderr (use execAsync or spawnAsyncAndReturn for that)
     *
     * Defaults:
     *
     * shell: true
     * log: true
     */
    spawnAsync(cmd: string, opt?: SpawnOptions): Promise<void>;
    /**
     * Advanced/async version of Spawn.
     * Consider simpler `spawn` or `exec` first, which are also sync.
     *
     * spawnAsyncAndReturn features:
     *
     * 1. Async
     * 2. Allows to collect the output AND print it while running.
     * 3. Returns SpawnOutput with stdout, stderr and exitCode.
     * 4. Allows to not throw on error, but just return SpawnOutput for further inspection.
     *
     * Defaults:
     *
     * shell: true
     * printWhileRunning: true
     * collectOutputWhileRunning: true
     * throwOnNonZeroCode: true
     * log: true
     */
    spawnAsyncAndReturn(cmd: string, opt?: SpawnAsyncOptions): Promise<SpawnOutput>;
    private logStart;
    private logFinish;
}
export declare const exec2: Exec2;
export declare class SpawnError extends AppError<SpawnErrorData> {
    constructor(message: string, data: SpawnErrorData);
}
export interface SpawnErrorData extends SpawnOutput {
}
export interface SpawnOutput {
    /**
     * Exit code of the spawned process.
     * 0 means success, anything else means failure.
     */
    exitCode: number;
    stdout: string;
    stderr: string;
}
export interface SpawnAsyncOptions extends SpawnOptions {
    /**
     * Defaults to true.
     * If true - prints both stdout and stderr to console while running,
     * otherwise runs "silently".
     * Returns SpawnOutput in the same way, regardless of `printWhileRunning` setting.
     */
    printWhileRunning?: boolean;
    /**
     * Defaults to true.
     * If true - collects stdout and stderr while running, and return it in the end.
     * stdout/stderr are collected and returned regardless if it returns with error or not.
     * On success - stdout/stderr are available from `SpawnOutput`.
     * On error - stdout/stderr are available from `SpawnError.data`.
     */
    collectOutputWhileRunning?: boolean;
    /**
     * Defaults to true.
     * If true - throws SpawnError if non-zero code is returned.
     * SpawnError conveniently contains .data.stdout and .data.strerr for inspection.
     * If false - will not throw, but return SpawnOutput with stdout, stderr and exitCode.
     */
    throwOnNonZeroCode?: boolean;
}
export interface SpawnOptions {
    args?: string[];
    /**
     * Defaults to true.
     */
    logStart?: boolean;
    /**
     * Defaults to true.
     */
    logFinish?: boolean;
    /**
     * Defaults to true.
     * Controls/overrides both logStart and logFinish simultaneously.
     */
    log?: boolean;
    /**
     * Defaults to true.
     */
    shell?: boolean;
    /**
     * If specified - will be used as "command name" for logging purposes,
     * instead of "cmd + args"
     */
    name?: string;
    cwd?: string;
    env?: AnyObject;
    /**
     * Defaults to true.
     * Set to false to NOT pass `process.env` to the spawned process.
     */
    passProcessEnv?: boolean;
    /**
     * Defaults to "auto detect colors".
     * Set to false or true to override.
     */
    forceColor?: boolean;
    /**
     * Defaults to "inherit"
     */
    stdio?: StdioOptions;
}
export interface ExecOptions {
    /**
     * Defaults to false.
     */
    logStart?: boolean;
    /**
     * Defaults to false.
     */
    logFinish?: boolean;
    /**
     * Defaults to false.
     * Controls/overrides both logStart and logFinish simultaneously.
     */
    log?: boolean;
    /**
     * If specified - will be used as "command name" for logging purposes,
     * instead of "cmd + args"
     */
    name?: string;
    cwd?: string;
    timeout?: NumberOfMilliseconds;
    env?: AnyObject;
    /**
     * Defaults to false for security reasons.
     * Set to true to pass `process.env` to the spawned process.
     */
    passProcessEnv?: boolean;
    /**
     * Defaults to undefined.
     * beware that stdio: 'inherit', means we don't get the output returned.
     */
    stdio?: StdioOptions;
}
export {};
