| /** | |
| * Defines structured errors for the unstable CLI parser and runner. | |
| * | |
| * CLI errors describe problems such as unknown or duplicate flags, missing | |
| * flags or arguments, invalid values, unknown subcommands, user handler | |
| * failures, and requests to show command help. This module includes the | |
| * `CliError` union, the `isCliError` guard, schema-backed error classes with | |
| * display messages, and the `NonShowHelpErrors` union used when parse or | |
| * validation errors should be shown with help output. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| import * as Predicate from "../../Predicate.js"; | |
| import * as Runtime from "../../Runtime.js"; | |
| import * as Schema from "../../Schema.js"; | |
| /** | |
| * @category type IDs | |
| * @since 4.0.0 | |
| */ | |
| const TypeId = "~effect/cli/CliError"; | |
| /** | |
| * Type guard to check if a value is a CLI error. | |
| * | |
| * **Example** (Checking CLI errors) | |
| * | |
| * ```ts | |
| * import { Effect } from "effect" | |
| * import { CliError } from "effect/unstable/cli" | |
| * | |
| * const handleError = (error: unknown) => { | |
| * if (CliError.isCliError(error)) { | |
| * console.log("CLI Error:", error.message) | |
| * return Effect.succeed("Handled CLI error") | |
| * } | |
| * return Effect.fail("Unknown error") | |
| * } | |
| * | |
| * // Example usage in error handling | |
| * const program = Effect.gen(function*() { | |
| * const result = yield* Effect.try({ | |
| * try: () => ({ success: true }), | |
| * catch: (error) => error | |
| * }) | |
| * handleError(result) | |
| * }) | |
| * ``` | |
| * | |
| * @category guards | |
| * @since 4.0.0 | |
| */ | |
| export const isCliError = u => Predicate.hasProperty(u, TypeId); | |
| /** | |
| * Error thrown when an unrecognized option is encountered. | |
| * | |
| * **Example** (Creating unrecognized option errors) | |
| * | |
| * ```ts | |
| * import { Effect } from "effect" | |
| * import { CliError } from "effect/unstable/cli" | |
| * | |
| * // Creating an unrecognized option error | |
| * const unrecognizedError = new CliError.UnrecognizedOption({ | |
| * option: "--unknown-flag", | |
| * command: ["deploy", "production"], | |
| * suggestions: ["--verbose", "--force"] | |
| * }) | |
| * | |
| * console.log(unrecognizedError.message) | |
| * // "Unrecognized flag: --unknown-flag in command deploy production | |
| * // | |
| * // Did you mean this? | |
| * // --verbose | |
| * // --force" | |
| * | |
| * // In CLI parsing context | |
| * const parseCommand = Effect.gen(function*() { | |
| * // If parsing encounters unknown flag | |
| * return yield* unrecognizedError | |
| * }) | |
| * ``` | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export class UnrecognizedOption extends /*#__PURE__*/Schema.ErrorClass(`${TypeId}/UnrecognizedOption`)({ | |
| _tag: /*#__PURE__*/Schema.tag("UnrecognizedOption"), | |
| option: Schema.String, | |
| command: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String)), | |
| suggestions: /*#__PURE__*/Schema.Array(Schema.String) | |
| }) { | |
| /** | |
| * Marks this value as a CLI parsing error for runtime guards. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| [TypeId] = TypeId; | |
| /** | |
| * Formats the unrecognized option with command context and suggestions. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| get message() { | |
| const suggestionText = this.suggestions.length > 0 ? `\n\n Did you mean this?\n ${this.suggestions.join("\n ")}` : ""; | |
| const baseMessage = this.command ? `Unrecognized flag: ${this.option} in command ${this.command.join(" ")}` : `Unrecognized flag: ${this.option}`; | |
| return baseMessage + suggestionText; | |
| } | |
| } | |
| /** | |
| * Error thrown when duplicate option names are detected between parent and child commands. | |
| * | |
| * **Example** (Creating duplicate option errors) | |
| * | |
| * ```ts | |
| * import { CliError } from "effect/unstable/cli" | |
| * | |
| * const duplicateError = new CliError.DuplicateOption({ | |
| * option: "--verbose", | |
| * parentCommand: "myapp", | |
| * childCommand: "deploy" | |
| * }) | |
| * | |
| * console.log(duplicateError.message) | |
| * // "Duplicate flag name "--verbose" in parent command "myapp" and subcommand "deploy". | |
| * // Parent will always claim this flag (Mode A semantics). Consider renaming one of them to avoid confusion." | |
| * ``` | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export class DuplicateOption extends /*#__PURE__*/Schema.ErrorClass(`${TypeId}/DuplicateOption`)({ | |
| _tag: /*#__PURE__*/Schema.tag("DuplicateOption"), | |
| option: Schema.String, | |
| parentCommand: Schema.String, | |
| childCommand: Schema.String | |
| }) { | |
| /** | |
| * Marks this value as a CLI configuration error for runtime guards. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| [TypeId] = TypeId; | |
| /** | |
| * Explains which parent and child commands define the duplicate option. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| get message() { | |
| return `Duplicate flag name "${this.option}" in parent command "${this.parentCommand}" and subcommand "${this.childCommand}". ` + `Parent will always claim this flag (Mode A semantics). Consider renaming one of them to avoid confusion.`; | |
| } | |
| } | |
| /** | |
| * Error thrown when a required option is missing. | |
| * | |
| * **Example** (Creating missing option errors) | |
| * | |
| * ```ts | |
| * import { Effect } from "effect" | |
| * import { CliError } from "effect/unstable/cli" | |
| * | |
| * const missingOptionError = new CliError.MissingOption({ | |
| * option: "api-key" | |
| * }) | |
| * | |
| * console.log(missingOptionError.message) | |
| * // "Missing required flag: --api-key" | |
| * | |
| * // In validation context | |
| * const validateRequiredOptions = (options: Record<string, string | undefined>) => | |
| * Effect.gen(function*() { | |
| * const apiKey = options["api-key"] | |
| * if (!apiKey) { | |
| * return yield* missingOptionError | |
| * } | |
| * return apiKey | |
| * }) | |
| * ``` | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export class MissingOption extends /*#__PURE__*/Schema.ErrorClass(`${TypeId}/MissingOption`)({ | |
| _tag: /*#__PURE__*/Schema.tag("MissingOption"), | |
| option: Schema.String | |
| }) { | |
| /** | |
| * Marks this value as a missing CLI option error for runtime guards. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| [TypeId] = TypeId; | |
| /** | |
| * Formats the missing required flag for display. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| get message() { | |
| return `Missing required flag: --${this.option}`; | |
| } | |
| } | |
| /** | |
| * Error thrown when a required positional argument is missing. | |
| * | |
| * **Example** (Creating missing argument errors) | |
| * | |
| * ```ts | |
| * import { Effect } from "effect" | |
| * import { CliError } from "effect/unstable/cli" | |
| * | |
| * const missingArgError = new CliError.MissingArgument({ | |
| * argument: "target" | |
| * }) | |
| * | |
| * console.log(missingArgError.message) | |
| * // "Missing required argument: target" | |
| * | |
| * // In argument parsing | |
| * const parseArguments = (args: Array<string>) => | |
| * Effect.gen(function*() { | |
| * if (args.length === 0) { | |
| * return yield* missingArgError | |
| * } | |
| * return args[0] | |
| * }) | |
| * ``` | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export class MissingArgument extends /*#__PURE__*/Schema.ErrorClass(`${TypeId}/MissingArgument`)({ | |
| _tag: /*#__PURE__*/Schema.tag("MissingArgument"), | |
| argument: Schema.String | |
| }) { | |
| /** | |
| * Marks this value as a missing CLI argument error for runtime guards. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| [TypeId] = TypeId; | |
| /** | |
| * Formats the missing required positional argument for display. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| get message() { | |
| return `Missing required argument: ${this.argument}`; | |
| } | |
| } | |
| /** | |
| * Error thrown when an option or argument value is invalid. | |
| * | |
| * **Example** (Creating invalid value errors) | |
| * | |
| * ```ts | |
| * import { Effect } from "effect" | |
| * import { CliError } from "effect/unstable/cli" | |
| * | |
| * const invalidValueError = new CliError.InvalidValue({ | |
| * option: "port", | |
| * value: "abc123", | |
| * expected: "integer between 1 and 65535", | |
| * kind: "flag" | |
| * }) | |
| * | |
| * console.log(invalidValueError.message) | |
| * // "Invalid value for flag --port: "abc123". Expected: integer between 1 and 65535" | |
| * | |
| * // For positional arguments | |
| * const invalidArgError = new CliError.InvalidValue({ | |
| * option: "count", | |
| * value: "abc", | |
| * expected: "integer", | |
| * kind: "argument" | |
| * }) | |
| * | |
| * console.log(invalidArgError.message) | |
| * // "Invalid value for argument <count>: "abc". Expected: integer" | |
| * ``` | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export class InvalidValue extends /*#__PURE__*/Schema.ErrorClass(`${TypeId}/InvalidValue`)({ | |
| _tag: /*#__PURE__*/Schema.tag("InvalidValue"), | |
| option: Schema.String, | |
| value: Schema.String, | |
| expected: Schema.String, | |
| kind: /*#__PURE__*/Schema.Union([/*#__PURE__*/Schema.Literal("flag"), /*#__PURE__*/Schema.Literal("argument")]) | |
| }) { | |
| /** | |
| * Marks this value as an invalid CLI value error for runtime guards. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| [TypeId] = TypeId; | |
| /** | |
| * Formats the invalid flag or argument value with the expected input. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| get message() { | |
| if (this.kind === "argument") { | |
| return `Invalid value for argument <${this.option}>: "${this.value}". Expected: ${this.expected}`; | |
| } | |
| return `Invalid value for flag --${this.option}: "${this.value}". Expected: ${this.expected}`; | |
| } | |
| } | |
| /** | |
| * Error thrown when an unknown subcommand is encountered. | |
| * | |
| * **Example** (Creating unknown subcommand errors) | |
| * | |
| * ```ts | |
| * import { Effect } from "effect" | |
| * import { CliError } from "effect/unstable/cli" | |
| * | |
| * const unknownSubcommandError = new CliError.UnknownSubcommand({ | |
| * subcommand: "deplyo", // typo | |
| * parent: ["myapp"], | |
| * suggestions: ["deploy", "destroy"] | |
| * }) | |
| * | |
| * console.log(unknownSubcommandError.message) | |
| * // "Unknown subcommand "deplyo" for "myapp" | |
| * // | |
| * // Did you mean this? | |
| * // deploy | |
| * // destroy" | |
| * | |
| * // In subcommand parsing | |
| * const parseSubcommand = (subcommand: string) => | |
| * Effect.gen(function*() { | |
| * const validCommands = ["deploy", "destroy", "status"] | |
| * if (!validCommands.includes(subcommand)) { | |
| * return yield* unknownSubcommandError | |
| * } | |
| * return subcommand | |
| * }) | |
| * ``` | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export class UnknownSubcommand extends /*#__PURE__*/Schema.ErrorClass(`${TypeId}/UnknownSubcommand`)({ | |
| _tag: /*#__PURE__*/Schema.tag("UnknownSubcommand"), | |
| subcommand: Schema.String, | |
| parent: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String)), | |
| suggestions: /*#__PURE__*/Schema.Array(Schema.String) | |
| }) { | |
| /** | |
| * Marks this value as an unknown CLI subcommand error for runtime guards. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| [TypeId] = TypeId; | |
| /** | |
| * Formats the unknown subcommand with parent command context and suggestions. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| get message() { | |
| const suggestionText = this.suggestions.length > 0 ? `\n\n Did you mean this?\n ${this.suggestions.join("\n ")}` : ""; | |
| return this.parent ? `Unknown subcommand "${this.subcommand}" for "${this.parent.join(" ")}"${suggestionText}` : `Unknown subcommand "${this.subcommand}"${suggestionText}`; | |
| } | |
| } | |
| /** | |
| * Error wrapper for user handler failures in the CLI error channel. | |
| * | |
| * **Example** (Wrapping user errors) | |
| * | |
| * ```ts | |
| * import { Effect } from "effect" | |
| * import { CliError } from "effect/unstable/cli" | |
| * | |
| * // Wrapping user errors | |
| * const userError = new CliError.UserError({ | |
| * cause: new Error("Database connection failed") | |
| * }) | |
| * | |
| * // In command handler | |
| * const deployCommand = Effect.gen(function*() { | |
| * const result = yield* Effect.try({ | |
| * try: () => ({ deployed: true }), | |
| * catch: (error) => new CliError.UserError({ cause: error }) | |
| * }) | |
| * return result | |
| * }) | |
| * | |
| * // In error handling | |
| * const handleError = (error: CliError.CliError): Effect.Effect<number> => { | |
| * if (error._tag === "UserError") { | |
| * console.log("Command failed:", error.cause) | |
| * return Effect.succeed(1) // Exit code 1 | |
| * } | |
| * return Effect.succeed(0) | |
| * } | |
| * ``` | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export class UserError extends /*#__PURE__*/Schema.ErrorClass(`${TypeId}/UserError`)({ | |
| _tag: /*#__PURE__*/Schema.tag("UserError"), | |
| cause: /*#__PURE__*/Schema.Defect() | |
| }) { | |
| /** | |
| * Marks this value as a user handler error for runtime guards. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| [TypeId] = TypeId; | |
| } | |
| /** | |
| * Schema for concrete CLI errors that can be reported together with help output. | |
| * | |
| * **Details** | |
| * | |
| * This excludes `ShowHelp` itself, allowing parse and validation errors to be | |
| * stored in `ShowHelp.errors` without nesting another help-control value. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export const NonShowHelpErrors = /*#__PURE__*/Schema.Union([UnrecognizedOption, DuplicateOption, MissingOption, MissingArgument, InvalidValue, UnknownSubcommand, UserError]); | |
| /** | |
| * Error data requesting CLI help rendering for a command path. | |
| * | |
| * **Details** | |
| * | |
| * It is used for explicit help requests and for parse or validation failures | |
| * that should be shown with help text. When `errors` is non-empty, the runtime | |
| * exit code is `1`; otherwise it is `0`. | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export class ShowHelp extends /*#__PURE__*/Schema.ErrorClass(`${TypeId}/ShowHelp`)({ | |
| _tag: /*#__PURE__*/Schema.tag("ShowHelp"), | |
| commandPath: /*#__PURE__*/Schema.Array(Schema.String), | |
| errors: /*#__PURE__*/Schema.Array(NonShowHelpErrors) | |
| }) { | |
| [TypeId] = TypeId; | |
| [Runtime.errorExitCode] = this.errors.length ? 1 : 0; | |
| [Runtime.errorReported] = false; | |
| get message() { | |
| return "Help requested"; | |
| } | |
| } | |
| //# sourceMappingURL=CliError.js.map |
Xet Storage Details
- Size:
- 13.1 kB
- Xet hash:
- 1a3d71706ab5b725550c35c90981bd386ad83b585d7406185bc541798370ad45
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.