import type { Promisable } from 'type-fest';
import type { ConfigurationHooks } from "./types/configure.js";
import type { Arguments, NullArguments, PreExecutionContext } from "./types/program.js";
/**
 * @internal
 */
export type RunProgramParametersWithAny = [commandModulesPath: string] | [commandModulesPath: string, configurationHooks: Promisable<ConfigurationHooks<any>>] | [commandModulesPath: string, preExecutionContext: Promisable<PreExecutionContext>] | [commandModulesPath: string, argv: string | string[]] | [commandModulesPath: string, argv: string | string[], configurationHooks: Promisable<ConfigurationHooks<any>>] | [commandModulesPath: string, argv: string | string[], preExecutionContext: Promisable<PreExecutionContext>];
/**
 * The available call signature parameters of the {@link runProgram} function.
 *
 * The first parameter is always the required `commandModulesPath` string,
 * optionally followed by `argv` string/array, and then either a * {@link ConfigurationHooks} or {@link PreExecutionContext} instance (or a
 * promise that returns them).
 */
export type RunProgramParameters = RunProgramParametersWithAny | [commandModulesPath: string, configurationHooks: Promisable<ConfigurationHooks>] | [commandModulesPath: string, argv: string | string[], configurationHooks: Promisable<ConfigurationHooks>];
/**
 * The return type of the {@link runProgram} function.
 */
export type RunProgramReturnType<CustomCliArguments extends Record<string, unknown>> = Promise<NullArguments | Arguments<CustomCliArguments> | undefined>;
/**
 * The available call signature parameters of the low-order function returned by
 * {@link makeRunner}.
 *
 * This is the same thing as {@link RunProgramParameters} but with the first
 * parameter (i.e. the `commandModulesPath` string) omitted.
 */
export type FactoriedRunProgramParameters = RunProgramParametersWithAny extends [infer _, ...infer Tail] ? Tail : [];
/**
 * The options accepted by the {@link makeRunner} function.
 */
export type MakeRunnerOptions = {
  /**
   * @see {@link runProgram}
   */
  commandModulesPath: string;
  /**
   * This is a special option exclusive to `makeRunner` that determines how
   * errors will be surfaced, which can be useful during testing.
   *
   * In production and during testing, Black Flag surfaces errors via
   * `process.stderr` (e.g. `console.error`), or whichever error handling
   * method was implemented in {@link ConfigureErrorHandlingEpilogue}. This is
   * the default behavior, and is what end-users will see and experience.
   *
   * However, by setting this option to `'throw'` instead of `'default'`,
   * exceptions that would normally cause {@link runProgram} to return
   * `undefined` (including framework errors) or `NullArguments` (such as
   * `GracefulEarlyExitError`) will instead be thrown after they are handled
   * by Black Flag.
   *
   * **Asserting expectations against how the CLI will actually behave in
   * production, which is what end-users will actually experience, should be
   * preferred over testing against an artificially surfaced error**. However,
   * surfacing errors in test cases that are failing unexpectedly can be
   * crucial when debugging. Discretion is advised.
   *
   * @default 'default'
   */
  errorHandlingBehavior?: 'default' | 'throw';
  /**
   * The {@link ConfigurationHooks} to be used by each low-order
   * invocation by default. Each low-order function can provide its own
   * {@link ConfigurationHooks} argument, which will be merged on top of
   * this option. A low-order function supplying a
   * {@link PreExecutionContext} argument instead will completely override
   * this option.
   *
   * Note: this option cannot be used with `preExecutionContext`.
   *
   * @see {@link runProgram}
   */
  configurationHooks?: Promisable<ConfigurationHooks<any>>;
  /**
   * The {@link PreExecutionContext} to be used by each low-order
   * invocation. Each low-order function can provide its own
   * {@link PreExecutionContext} or {@link ConfigurationHooks} argument,
   * both of which which will completely override this option.
   *
   * Note: this option cannot be used with `configurationHooks`.
   *
   * @see {@link runProgram}
   */
  preExecutionContext?: Promisable<PreExecutionContext>;
} & ({
  configurationHooks?: Promisable<ConfigurationHooks<any>>;
  preExecutionContext?: undefined;
} | {
  preExecutionContext?: Promisable<PreExecutionContext>;
  configurationHooks?: undefined;
});
/**
 * Create and return a {@link PreExecutionContext} containing fully-configured
 * {@link Program} instances and an {@link Executor} entry point function.
 *
 * Command auto-discovery will occur at `commandModulesPath`. An exception will
 * occur if no commands are loadable from the given `commandModulesPath`.
 *
 * **This function throws whenever an exception occurs**, making it not ideal as
 * an entry point for a CLI, but perhaps useful during testing. See
 * {@link runProgram} for a wrapper function that handles exceptions and sets
 * the exit code automatically.
 */
export declare function configureProgram(
/**
 * Command auto-discovery will occur at `commandModulesPath`. An exception will
 * occur if no commands are loadable from the given `commandModulesPath`.
 *
 * `'file://...'`-style URLs are also accepted.
 */
commandModulesPath: string, configurationHooks?: Promisable<ConfigurationHooks<any>>): Promise<PreExecutionContext>;
/**
 * A "high-order" factory function that returns a "low-order" curried
 * {@link runProgram} function that can be called multiple times while only
 * having to provide a subset of the required parameters.
 *
 * This is useful when unit/integration testing a CLI, which will likely require
 * multiple calls to `runProgram(...)`.
 *
 * **BE AWARE**: when an exception (e.g. bad CLI arguments) occurs in the
 * low-order function, `process.exitCode` is set to the appropriate value, the
 * {@link ConfigureErrorHandlingEpilogue} hook is triggered, and either
 * `NullArguments` (only if `GracefulEarlyExitError` was thrown) or `undefined`
 * is returned. Otherwise, upon success, `Arguments` is returned.
 *
 * In other words: **the promise returned by the low-order function will never
 * reject and no exception will ever be thrown.** Keep this in mind when writing
 * unit tests and see {@link runProgram} for more details.
 *
 * Ideally, testing for the presence of errors should be done by capturing
 * output sent to `process.stderr` (e.g. `console.error`)—or by interrogating
 * whichever error handling method was implemented in
 * {@link ConfigureErrorHandlingEpilogue}—since that is what end-users will see
 * and experience. That said, if it would be more optimal to test against an
 * actual thrown error, set `makeRunner`'s `errorHandlingBehavior` option to
 * `'throw'`.
 */
export declare function makeRunner<CustomCliArguments extends Record<string, unknown> = Record<string, unknown>>(options: MakeRunnerOptions): (...args: FactoriedRunProgramParameters) => RunProgramReturnType<CustomCliArguments>;
/**
 * Invokes the dynamically imported
 * `configureProgram(commandModulesPath).execute()` function.
 *
 * This function is suitable for a CLI entry point since it will **never throw
 * or reject no matter what.** Instead, when an exception occurs,
 * `process.exitCode` is set to the appropriate value, the
 * {@link ConfigureErrorHandlingEpilogue} hook is triggered, and either
 * `NullArguments` (only if `GracefulEarlyExitError` was thrown) or `undefined`
 * is returned.
 *
 * Note: It is always safe to invoke this form of `runProgram` as many times as
 * desired.
 *
 * @returns `NullArguments` if `GracefulEarlyExitError` is thrown, `undefined`
 * if any other exception occurs, or `Arguments` otherwise.
 */
export declare function runProgram<CustomCliArguments extends Record<string, unknown> = Record<string, unknown>>(commandModulesPath: string): RunProgramReturnType<CustomCliArguments>;
/**
 * Invokes the dynamically imported `configureProgram(commandModulesPath,
 * configurationHooks).execute()` function.
 *
 * This function is suitable for a CLI entry point since it will **never throw
 * or reject no matter what.** Instead, when an exception occurs,
 * `process.exitCode` is set to the appropriate value, the
 * {@link ConfigureErrorHandlingEpilogue} hook is triggered, and either
 * `NullArguments` (only if `GracefulEarlyExitError` was thrown) or `undefined`
 * is returned.
 *
 * Note: It is always safe to invoke this form of `runProgram` as many times as
 * desired.
 *
 * @returns `NullArguments` if `GracefulEarlyExitError` is thrown, `undefined`
 * if any other exception occurs, or `Arguments` otherwise.
 */
export declare function runProgram<CustomCliArguments extends Record<string, unknown> = Record<string, unknown>>(commandModulesPath: string, configurationHooks: Promisable<ConfigurationHooks>): RunProgramReturnType<CustomCliArguments>;
/**
 * Invokes the dynamically imported `configureProgram(commandModulesPath,
 * configurationHooks).execute()` function.
 *
 * This function is suitable for a CLI entry point since it will **never throw
 * or reject no matter what.** Instead, when an exception occurs,
 * `process.exitCode` is set to the appropriate value, the
 * {@link ConfigureErrorHandlingEpilogue} hook is triggered, and either
 * `NullArguments` (only if `GracefulEarlyExitError` was thrown) or `undefined`
 * is returned.
 *
 * Note: It is always safe to invoke this form of `runProgram` as many times as
 * desired.
 *
 * @returns `NullArguments` if `GracefulEarlyExitError` is thrown, `undefined`
 * if any other exception occurs, or `Arguments` otherwise.
 */
export declare function runProgram<CustomCliArguments extends Record<string, unknown> = Record<string, unknown>>(commandModulesPath: string, configurationHooks: Promisable<ConfigurationHooks<any>>): RunProgramReturnType<CustomCliArguments>;
/**
 * Invokes the `preExecutionContext.execute()` function.
 *
 * **WARNING: reusing the same `preExecutionContext` with multiple invocations
 * of `runProgram` will cause successive invocations to fail.** This is because
 * yargs does not support calling `yargs::parseAsync` more than once. If this is
 * unacceptable, do not pass `runProgram` a `preExecutionContext` property.
 *
 * This function is suitable for a CLI entry point since it will **never throw
 * or reject no matter what.** Instead, when an exception occurs,
 * `process.exitCode` is set to the appropriate value, the
 * {@link ConfigureErrorHandlingEpilogue} hook is triggered, and either
 * `NullArguments` (only if `GracefulEarlyExitError` was thrown) or `undefined`
 * is returned.
 *
 * @returns `NullArguments` if `GracefulEarlyExitError` is thrown, `undefined`
 * if any other exception occurs, or `Arguments` otherwise.
 */
export declare function runProgram<CustomCliArguments extends Record<string, unknown> = Record<string, unknown>>(commandModulesPath: string, preExecutionContext: Promisable<PreExecutionContext>): RunProgramReturnType<CustomCliArguments>;
/**
 * Invokes the dynamically imported
 * `configureProgram(commandModulesPath).execute(argv)` function. If `argv` is a
 * string, `argv = argv.split(' ')` is applied first.
 *
 * This function is suitable for a CLI entry point since it will **never throw
 * or reject no matter what.** Instead, when an exception occurs,
 * `process.exitCode` is set to the appropriate value, the
 * {@link ConfigureErrorHandlingEpilogue} hook is triggered, and either
 * `NullArguments` (only if `GracefulEarlyExitError` was thrown) or `undefined`
 * is returned.
 *
 * Note: It is always safe to invoke this form of `runProgram` as many times as
 * desired.
 *
 * @returns `NullArguments` if `GracefulEarlyExitError` is thrown, `undefined`
 * if any other exception occurs, or `Arguments` otherwise.
 */
export declare function runProgram<CustomCliArguments extends Record<string, unknown> = Record<string, unknown>>(commandModulesPath: string, argv: string | string[]): RunProgramReturnType<CustomCliArguments>;
/**
 * Invokes the dynamically imported `configureProgram(commandModulesPath,
 * configurationHooks).execute(argv)` function. If `argv` is a string, `argv =
 * argv.split(' ')` is applied first.
 *
 * This function is suitable for a CLI entry point since it will **never throw
 * or reject no matter what.** Instead, when an exception occurs,
 * `process.exitCode` is set to the appropriate value, the
 * {@link ConfigureErrorHandlingEpilogue} hook is triggered, and either
 * `NullArguments` (only if `GracefulEarlyExitError` was thrown) or `undefined`
 * is returned.
 *
 * Note: It is always safe to invoke this form of `runProgram` as many times as
 * desired.
 *
 * @returns `NullArguments` if `GracefulEarlyExitError` is thrown, `undefined`
 * if any other exception occurs, or `Arguments` otherwise.
 */
export declare function runProgram<CustomCliArguments extends Record<string, unknown> = Record<string, unknown>>(commandModulesPath: string, argv: string | string[], configurationHooks: Promisable<ConfigurationHooks>): RunProgramReturnType<CustomCliArguments>;
/**
 * Invokes the dynamically imported `configureProgram(commandModulesPath,
 * configurationHooks).execute(argv)` function. If `argv` is a string, `argv =
 * argv.split(' ')` is applied first.
 *
 * This function is suitable for a CLI entry point since it will **never throw
 * or reject no matter what.** Instead, when an exception occurs,
 * `process.exitCode` is set to the appropriate value, the
 * {@link ConfigureErrorHandlingEpilogue} hook is triggered, and either
 * `NullArguments` (only if `GracefulEarlyExitError` was thrown) or `undefined`
 * is returned.
 *
 * Note: It is always safe to invoke this form of `runProgram` as many times as
 * desired.
 *
 * @returns `NullArguments` if `GracefulEarlyExitError` is thrown, `undefined`
 * if any other exception occurs, or `Arguments` otherwise.
 */
export declare function runProgram<CustomCliArguments extends Record<string, unknown> = Record<string, unknown>>(commandModulesPath: string, argv: string | string[], configurationHooks: Promisable<ConfigurationHooks<any>>): RunProgramReturnType<CustomCliArguments>;
/**
 * Invokes the `preExecutionContext.execute(argv)` function. If `argv` is a
 * string, `argv = argv.split(' ')` is applied first.
 *
 * **WARNING: reusing the same `preExecutionContext` with multiple invocations
 * of `runProgram` will cause successive invocations to fail.** This is because
 * yargs does not support calling `yargs::parseAsync` more than once. If this is
 * unacceptable, do not pass `runProgram` a `preExecutionContext` property.
 *
 * This function is suitable for a CLI entry point since it will **never throw
 * or reject no matter what.** Instead, when an exception occurs,
 * `process.exitCode` is set to the appropriate value, the
 * {@link ConfigureErrorHandlingEpilogue} hook is triggered, and either
 * `NullArguments` (only if `GracefulEarlyExitError` was thrown) or `undefined`
 * is returned.
 *
 * @returns `NullArguments` if `GracefulEarlyExitError` is thrown, `undefined`
 * if any other exception occurs, or `Arguments` otherwise.
 */
export declare function runProgram<CustomCliArguments extends Record<string, unknown> = Record<string, unknown>>(commandModulesPath: string, argv: string | string[], preExecutionContext: Promisable<PreExecutionContext>): RunProgramReturnType<CustomCliArguments>;
/**
 * Run the given program with the configuration given in `args`.
 *
 * This function is suitable for a CLI entry point since it will **never throw
 * or reject no matter what.** Instead, when an exception occurs,
 * `process.exitCode` is set to the appropriate value, the
 * {@link ConfigureErrorHandlingEpilogue} hook is triggered, and either
 * `NullArguments` (only if `GracefulEarlyExitError` was thrown) or `undefined`
 * is returned.
 *
 * @returns `NullArguments` if `GracefulEarlyExitError` is thrown, `undefined`
 * if any other exception occurs, or `Arguments` otherwise.
 */
export declare function runProgram<CustomCliArguments extends Record<string, unknown> = Record<string, unknown>>(...args: RunProgramParameters): RunProgramReturnType<CustomCliArguments>;