@black-flag/core
Version:
A declarative framework for building fluent, deeply hierarchical command line interfaces with yargs
189 lines • 8.33 kB
TypeScript
import { AppError } from 'named-app-errors';
import { FrameworkExitCode } from "./constant.js";
import type { ExecutionContext } from "./types/program.js";
/**
* Type guard for the internal Yargs `YError`.
*/
export declare function isYargsError(parameter: unknown): parameter is Error & {
name: 'YError';
};
export declare const $type: unique symbol;
/**
* Type guard for {@link CliError}.
*/
export declare function isCliError(parameter: unknown): parameter is CliError;
/**
* Type guard for {@link GracefulEarlyExitError}.
*/
export declare function isGracefulEarlyExitError(parameter: unknown): parameter is GracefulEarlyExitError;
/**
* Type guard for {@link CommandNotImplementedError}.
*/
export declare function isCommandNotImplementedError(parameter: unknown): parameter is CommandNotImplementedError;
/**
* Options available when constructing a new `CliError` object.
*/
export type CliErrorOptions = {
/**
* The exit code that will be returned when the application exits, given
* nothing else goes wrong in the interim.
*
* @default FrameworkExitCode.DefaultError
*/
suggestedExitCode?: number;
/**
* If `showHelp` is set to a string that isn't `"default"`, help text will be
* sent to stderr. Note that help text is always sent _before this exception
* finishes bubbling up to `ConfigureErrorHandlingEpilogue`_.
*
* Specifically, if `showHelp` is set to `"full"`, the full help text will be
* sent to stderr, including the entire `usage` string. If set to `"short"`
* (or `true`), the same help text will be sent to stderr except only the
* first line of usage will be included. In either case, help text will be
* sent to stderr regardless of the value of
* [ExecutionContext.state.showHelpOnFail](https://github.com/Xunnamius/black-flag/blob/main/docs/api/src/exports/util/type-aliases/ExecutionContext.md#showhelponfail).
*
* Alternatively, if set to `"default"`, the value of
* [ExecutionContext.state.showHelpOnFail](https://github.com/Xunnamius/black-flag/blob/main/docs/api/src/exports/util/type-aliases/ExecutionContext.md#showhelponfail)
* will be used. And if set to `false`, no help text will be sent to stderr
* due to this error regardless of the value of
* [ExecutionContext.state.showHelpOnFail](https://github.com/Xunnamius/black-flag/blob/main/docs/api/src/exports/util/type-aliases/ExecutionContext.md#showhelponfail).
*
* Note that, regardless of this `showHelp`, help text is always output when a
* parent command is invoked that (1) has one or more child commands and (2)
* lacks its own handler implementation or implements a handler that throws
* {@link CommandNotImplementedError}.
*
* @default "default"
*/
showHelp?: Extract<ExecutionContext['state']['showHelpOnFail'], object>['outputStyle'] | 'default' | boolean;
/**
* This option is similar in intent to Yargs's `exitProcess()` function,
* except applied more granularly.
*
* Normally, {@link runProgram} never throws and never calls `process.exit`,
* instead setting `process.exitCode` when an error occurs.
*
* However, it is at times prudent to kill Node.js as soon as possible after
* error handling happens. For example: the execa library struggles to abort
* concurrent subcommand promises in a timely manner, and doesn't prevent them
* from dumping output to stdout even after Black Flag has finished executing.
* To work around this, we can set `dangerouslyFatal` to `true`, forcing Black
* Flag to call `process.exit` immediately after error handling completes.
*
* More generally, enabling `dangerouslyFatal` is a quick way to get rid of
* strange behavior that can happen when your microtask queue isn't empty
* (i.e. the event loop still has work to do) by the time Black Flag's error
* handling code completes. **However, doing this without proper consideration
* of _why_ you still have hanging promises and/or other microtasks adding
* work to the event loop can lead to faulty/glitchy/flaky software and
* heisenbugs.** You will also have to specially handle `process.exit` when
* running unit/integration tests and executing command handlers within other
* command handlers. Tread carefully.
*
* @default false
*/
dangerouslyFatal?: boolean;
/**
* By default, if an `Error` object is passed to `CliError`, that
* `Error` instance will be passed through as `CliError.cause` and that
* instance's `Error.message` will be passed through as `CliError.message`.
*
* Use this option to override this default behavior and instead set
* `CliError.cause` manually.
*/
cause?: ErrorOptions['cause'];
};
/**
* Represents a CLI-specific error with suggested exit code and other
* properties. As `CliError` has built-in support for cause chaining, this class
* can be used as a simple wrapper around other errors.
*/
export declare class CliError extends AppError implements Required<Omit<CliErrorOptions, 'cause'>>, Pick<CliErrorOptions, 'cause'> {
suggestedExitCode: FrameworkExitCode;
showHelp: NonNullable<Exclude<CliErrorOptions["showHelp"], true>>;
dangerouslyFatal: boolean;
[$type]: string[];
/**
* Represents a CLI-specific error, optionally with suggested exit code and
* other context.
*/
constructor(reason?: Error | string, options?: CliErrorOptions);
/**
* This constructor syntax is used by subclasses when calling this constructor
* via `super`.
*/
constructor(reason: Error | string, options: CliErrorOptions, message: string, superOptions: ErrorOptions);
}
/**
* Represents trying to execute a CLI command that has not yet been implemented.
*/
export declare class CommandNotImplementedError extends CliError {
[$type]: string[];
/**
* Represents trying to execute a CLI command that has not yet been
* implemented.
*/
constructor(error?: Error, options?: CliErrorOptions);
}
/**
* Represents an exceptional event that should result in the immediate
* termination of the application but with an exit code indicating success
* (`0`).
*
* Note that {@link CliErrorOptions.dangerouslyFatal}, if given, is always
* ignored.
*/
export declare class GracefulEarlyExitError extends CliError {
[$type]: string[];
/**
* Represents an exceptional event that should result in the immediate
* termination of the application but with an exit code indicating success
* (`0`).
*
* Note that {@link CliErrorOptions.dangerouslyFatal}, if given, is always
* ignored.
*/
constructor(reason?: Error | string, options?: CliErrorOptions);
}
/**
* Represents a failed sanity check.
*/
export declare class AssertionFailedError extends CliError {
[$type]: string[];
/**
* Represents a failed sanity check.
*/
constructor(error: Error, options?: CliErrorOptions);
constructor(message: string, options?: CliErrorOptions);
constructor(errorOrMessage?: Error | string, options?: CliErrorOptions);
}
/**
* A collection of possible error and warning messages emitted by Black Flag.
*/
export declare const BfErrorMessage: {
GuruMeditation: () => string;
BuilderCalledOnInvalidPass(pass: "first-pass" | "second-pass"): string;
BuilderCannotBeAsync(commandName: string): string;
Generic(): string;
CommandNotImplemented(): string;
InvalidSubCommandInvocation(): string;
FrameworkError(error: unknown): string;
GracefulEarlyExit(): string;
ConfigLoadFailure(path: string): string;
InvalidConfigureArgumentsReturnType(): string;
InvalidConfigureExecutionEpilogueReturnType(): string;
InvalidConfigureExecutionContextReturnType(): string;
InvalidExecutionContextBadField(fieldName: string): string;
InvalidCharacters(str: string, violation: string): string;
PathIsNotDirectory(): string;
DuplicateCommandName(parentFullName: string | undefined, name1: string, type1: "name" | "alias", name2: string, type2: "name" | "alias"): string;
InvalidCommandExportBadStart(name: string): string;
InvalidCommandExportBadPositionals(name: string): string;
NoConfigurationLoaded(path: string): string;
BadConfigurationPath(path: unknown): string;
InvocationNotAllowed(name: string): string;
CannotExecuteMultipleTimes(): string;
BadParameterCombination(): string;
UseParseAsyncInstead(): string;
};