/** * Defines named options for command-line applications. * * A `Flag` describes how to read one named value from parsed command-line * input, validate it, and produce an `A`. Flags are useful for inputs such as * ports, verbosity switches, configuration files, output directories, choices, * secrets, and repeated values. The helpers here build flags with aliases, * defaults, optional values, prompts, configuration fallbacks, validation, and * value transformations. * * @stability unstable * @since 4.0.0 */ import type * as Config from "../Config.ts"; import type * as Effect from "../Effect.ts"; import { type LazyArg } from "../Function.ts"; import type * as Option from "../Option.ts"; import type * as Redacted_ from "../Redacted.ts"; import type * as Result from "../Result.ts"; import type * as Schema from "../Schema.ts"; import type * as CliError from "./CliError.ts"; import type { Environment } from "./Command.ts"; import * as Param from "./Param.ts"; import type * as Primitive from "./Primitive.ts"; /** * Represents a command-line flag. * * @stability unstable * @category models * @since 4.0.0 */ export interface Flag extends Param.Param { } /** * Creates a string flag that accepts text input. * * **Example** (Creating string flags) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const nameFlag = Flag.String("name") * // Usage: --name "John Doe" * nameFlag.kind // => "flag" * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const String: (name: string) => Flag; /** * Creates a boolean flag that can be enabled or disabled. * * **Example** (Creating boolean flags) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const verboseFlag = Flag.Boolean("verbose") * // Usage: --verbose (true) or --no-verbose (false) * // Omission fails unless the flag is made optional or given a fallback. * verboseFlag.kind // => "flag" * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const Boolean: (name: string) => Flag; /** * Creates an integer flag that accepts whole number input. * * **Example** (Creating integer flags) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const portFlag = Flag.Int("port") * // Usage: --port 8080 * portFlag.kind // => "flag" * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const Int: (name: string) => Flag; /** * Creates a float flag that accepts decimal number input. * * **Example** (Creating float flags) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const rateFlag = Flag.Finite("rate") * // Usage: --rate 3.14 * rateFlag.kind // => "flag" * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const Finite: (name: string) => Flag; /** * Creates a date flag that accepts date input in ISO format. * * **Example** (Creating date flags) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const startDateFlag = Flag.Date("start-date") * // Usage: --start-date 2023-12-25 * startDateFlag.kind // => "flag" * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const Date: (name: string) => Flag; /** * Constructs option parameters that represent a choice between several inputs. * Each tuple maps a string flag value to an associated typed value. * * **Example** (Creating flag choices with values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // simple enum like choice mapping directly to string union * const color = Flag.Literals("color", ["red", "green", "blue"]) * * // choice with custom value mapping * const logLevel = Flag.ChoiceWithValue("log-level", [ * ["debug", "Debug" as const], * ["info", "Info" as const], * ["error", "Error" as const] * ]) * const kinds = [color.kind, logLevel.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const ChoiceWithValue: >(name: string, choices: Choice) => Flag; /** * Accepts one of the provided strings. An empty array rejects all input. * * @see {@link ChoiceWithValue} for mapping accepted strings to different typed values * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const Literals: >(name: string, literals: Literals) => Flag; /** * Creates a path flag that accepts file system path input with validation options. * * **Example** (Creating path flags) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Basic path flag * const pathFlag = Flag.Path("config-path") * * // File-only path that must exist * const fileFlag = Flag.Path("input-file", { * pathType: "file", * mustExist: true * }) * * // Directory path with custom type name * const dirFlag = Flag.Path("output-dir", { * pathType: "directory", * typeName: "OUTPUT_DIRECTORY" * }) * const kinds = [pathFlag.kind, fileFlag.kind, dirFlag.kind] // => ["flag", "flag", "flag"] * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const Path: (name: string, options?: { readonly pathType?: "file" | "directory" | "either" | undefined; readonly mustExist?: boolean | undefined; readonly typeName?: string | undefined; }) => Flag; /** * Creates a file path flag that accepts file paths with optional existence validation. * * **Example** (Creating file flags) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Basic file flag * const inputFlag = Flag.File("input") * // Usage: --input ./data.json * * // File that must exist * const configFlag = Flag.File("config", { mustExist: true }) * // Usage: --config ./config.yaml (file must exist) * const kinds = [inputFlag.kind, configFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const File: (name: string, options?: { readonly mustExist?: boolean | undefined; }) => Flag; /** * Creates a directory path flag that accepts directory paths with optional existence validation. * * **Example** (Creating directory flags) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Basic directory flag * const outputFlag = Flag.Directory("output") * // Usage: --output ./build * * // Directory that must exist * const sourceFlag = Flag.Directory("source", { mustExist: true }) * // Usage: --source ./src (directory must exist) * const kinds = [outputFlag.kind, sourceFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const Directory: (name: string, options?: { readonly mustExist?: boolean | undefined; }) => Flag; /** * Creates a string flag whose parsed value is wrapped in `Redacted.Redacted` so * stringification and logging redact the value. * * **Gotchas** * * Values supplied on the command line may still be visible to the operating * system or shell history. * * **Example** (Creating redacted flags) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Path, Redacted, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * const passwordFlag = Flag.Redacted("password") * * const program = Effect.gen(function*() { * const [, password] = yield* passwordFlag.parse({ * arguments: [], * flags: { "password": ["abc123"] } * }) * return Redacted.value(password).length * }) * * await Effect.runPromise(program.pipe(Effect.provide(CliTestLayer))) // => 6 * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const Redacted: (name: string) => Flag>; /** * Creates a flag that reads and returns file content as a string. * * **Example** (Reading file text) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const config = Flag.FileText("config-file") * // --config-file ./app.json will read the file content * config.kind // => "flag" * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const FileText: (name: string) => Flag; /** * Creates a flag that reads and parses the content of the specified file. * * **Details** * * The parser that is utilized will depend on the specified `format`, or the * extension of the file passed on the command-line if no `format` is specified. * * **Example** (Parsing file contents) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Will use the extension of the file passed on the command line to determine * // the parser to use * const config = Flag.FileParse("config") * * // Will use the JSON parser * const jsonConfig = Flag.FileParse("json-config", { format: "json" }) * const kinds = [config.kind, jsonConfig.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const FileParse: (name: string, options?: Primitive.FileParseOptions | undefined) => Flag; /** * Creates a flag that reads and validates file content using the specified * schema. * * **Example** (Validating file contents) * * ```ts import.meta.vitest * import { Schema } from "effect" * import { Flag } from "effect/cli" * * const ConfigSchema = Schema.Struct({ * port: Schema.Number, * host: Schema.String * }) * * const config = Flag.FileSchema("config", ConfigSchema, { format: "json" }) * config.kind // => "flag" * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const FileSchema: (name: string, schema: Schema.ConstraintDecoder, options?: Primitive.FileSchemaOptions | undefined) => Flag; /** * Creates a flag that parses key=value pairs. * * **When to use** * * Use when you need a CLI flag that accepts one or more `key=value` * configuration entries. * * **Details** * * Requires at least one key=value pair. Multiple pairs are merged into a single * record. * * **Example** (Parsing key-value pairs) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const env = Flag.KeyValuePair("env") * // --env FOO=bar --env BAZ=qux will parse to { FOO: "bar", BAZ: "qux" } * env.kind // => "flag" * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const KeyValuePair: (name: string) => Flag>; /** * A flag that always fails to parse. * * **Example** (Creating sentinel flags) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const makeValueFlag = (includeValue: boolean) => * includeValue ? Flag.String("value") : Flag.Never * * makeValueFlag(true) === Flag.Never // => false * makeValueFlag(false) === Flag.Never // => true * ``` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const Never: Flag; /** * Adds an alias to a flag, allowing it to be referenced by multiple names. * * **Example** (Adding flag aliases) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Flag can be used as both --verbose and -v * const verboseFlag = Flag.Boolean("verbose").pipe( * Flag.withAlias("v") * ) * * // Multiple aliases can be chained * const helpFlag = Flag.Boolean("help").pipe( * Flag.withAlias("h"), * Flag.withAlias("?") * ) * const kinds = [verboseFlag.kind, helpFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category aliasing * @since 4.0.0 */ export declare const withAlias: { /** * Adds an alias to a flag, allowing it to be referenced by multiple names. * * **Example** (Adding flag aliases) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Flag can be used as both --verbose and -v * const verboseFlag = Flag.Boolean("verbose").pipe( * Flag.withAlias("v") * ) * * // Multiple aliases can be chained * const helpFlag = Flag.Boolean("help").pipe( * Flag.withAlias("h"), * Flag.withAlias("?") * ) * const kinds = [verboseFlag.kind, helpFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category aliasing * @since 4.0.0 */ (alias: string): (self: Flag) => Flag; /** * Adds an alias to a flag, allowing it to be referenced by multiple names. * * **Example** (Adding flag aliases) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Flag can be used as both --verbose and -v * const verboseFlag = Flag.Boolean("verbose").pipe( * Flag.withAlias("v") * ) * * // Multiple aliases can be chained * const helpFlag = Flag.Boolean("help").pipe( * Flag.withAlias("h"), * Flag.withAlias("?") * ) * const kinds = [verboseFlag.kind, helpFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category aliasing * @since 4.0.0 */ (self: Flag, alias: string): Flag; }; /** * Adds a description to a flag for help documentation. * * **Example** (Adding help descriptions) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const portFlag = Flag.Int("port").pipe( * Flag.withDescription("The port number to listen on") * ) * * const configFlag = Flag.File("config").pipe( * Flag.withDescription("Path to the configuration file") * ) * const kinds = [portFlag.kind, configFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category metadata * @since 4.0.0 */ export declare const withDescription: { /** * Adds a description to a flag for help documentation. * * **Example** (Adding help descriptions) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const portFlag = Flag.Int("port").pipe( * Flag.withDescription("The port number to listen on") * ) * * const configFlag = Flag.File("config").pipe( * Flag.withDescription("Path to the configuration file") * ) * const kinds = [portFlag.kind, configFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category metadata * @since 4.0.0 */ (description: string): (self: Flag) => Flag; /** * Adds a description to a flag for help documentation. * * **Example** (Adding help descriptions) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const portFlag = Flag.Int("port").pipe( * Flag.withDescription("The port number to listen on") * ) * * const configFlag = Flag.File("config").pipe( * Flag.withDescription("Path to the configuration file") * ) * const kinds = [portFlag.kind, configFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category metadata * @since 4.0.0 */ (self: Flag, description: string): Flag; }; /** * Lets a flag be given without a value, in which case `value` is used. * * **Details** * * Follows GNU-style optional values, like `--color[=WHEN]`. An explicit value * must be attached with `=` (`--watch=until-done` or `-w=until-done`). A bare * `--watch` is parsed as `--watch=`, so `value` is validated like any * other input. The flag never consumes the next token, so in `--watch build`, * `build` stays a positional argument or subcommand. The flag is still * required unless it is made optional or given a default. * * **Example** (Flag with an optional value) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const watch = Flag.Literals("watch", ["first-failure", "until-done"]).pipe( * Flag.withOptionalValue("first-failure"), * Flag.optional * ) * // --watch => Option.some("first-failure") * // --watch=until-done => Option.some("until-done") * // (absent) => Option.none() * // In help: --watch [=choice] * watch.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.1.0 */ export declare const withOptionalValue: { /** * Lets a flag be given without a value, in which case `value` is used. * * **Details** * * Follows GNU-style optional values, like `--color[=WHEN]`. An explicit value * must be attached with `=` (`--watch=until-done` or `-w=until-done`). A bare * `--watch` is parsed as `--watch=`, so `value` is validated like any * other input. The flag never consumes the next token, so in `--watch build`, * `build` stays a positional argument or subcommand. The flag is still * required unless it is made optional or given a default. * * **Example** (Flag with an optional value) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const watch = Flag.Literals("watch", ["first-failure", "until-done"]).pipe( * Flag.withOptionalValue("first-failure"), * Flag.optional * ) * // --watch => Option.some("first-failure") * // --watch=until-done => Option.some("until-done") * // (absent) => Option.none() * // In help: --watch [=choice] * watch.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.1.0 */ (value: string): (self: Flag) => Flag; /** * Lets a flag be given without a value, in which case `value` is used. * * **Details** * * Follows GNU-style optional values, like `--color[=WHEN]`. An explicit value * must be attached with `=` (`--watch=until-done` or `-w=until-done`). A bare * `--watch` is parsed as `--watch=`, so `value` is validated like any * other input. The flag never consumes the next token, so in `--watch build`, * `build` stays a positional argument or subcommand. The flag is still * required unless it is made optional or given a default. * * **Example** (Flag with an optional value) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const watch = Flag.Literals("watch", ["first-failure", "until-done"]).pipe( * Flag.withOptionalValue("first-failure"), * Flag.optional * ) * // --watch => Option.some("first-failure") * // --watch=until-done => Option.some("until-done") * // (absent) => Option.none() * // In help: --watch [=choice] * watch.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.1.0 */ (self: Flag, value: string): Flag; }; /** * Renames the negated form of a boolean flag, which defaults to `--no-`. * * **Details** * * The new name replaces the default, so `--no-` is no longer accepted * and shell completions offer the new name instead. Has no effect on * non-boolean flags. * * **Example** (Renaming a boolean flag's negation) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const validate = Flag.Boolean("validate").pipe( * Flag.withDefault(true), * Flag.withNegation("skip-validate") * ) * // --validate => true * // --skip-validate => false * // --no-validate => unrecognized flag * validate.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.1.0 */ export declare const withNegation: { /** * Renames the negated form of a boolean flag, which defaults to `--no-`. * * **Details** * * The new name replaces the default, so `--no-` is no longer accepted * and shell completions offer the new name instead. Has no effect on * non-boolean flags. * * **Example** (Renaming a boolean flag's negation) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const validate = Flag.Boolean("validate").pipe( * Flag.withDefault(true), * Flag.withNegation("skip-validate") * ) * // --validate => true * // --skip-validate => false * // --no-validate => unrecognized flag * validate.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.1.0 */ (name: string): (self: Flag) => Flag; /** * Renames the negated form of a boolean flag, which defaults to `--no-`. * * **Details** * * The new name replaces the default, so `--no-` is no longer accepted * and shell completions offer the new name instead. Has no effect on * non-boolean flags. * * **Example** (Renaming a boolean flag's negation) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const validate = Flag.Boolean("validate").pipe( * Flag.withDefault(true), * Flag.withNegation("skip-validate") * ) * // --validate => true * // --skip-validate => false * // --no-validate => unrecognized flag * validate.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.1.0 */ (self: Flag, name: string): Flag; }; /** * Removes the negated `--no-` form of a boolean flag. * * **Details** * * The negated form is then rejected as an unrecognized flag and left out of * shell completions. Has no effect on non-boolean flags. * * **Example** (Disabling a boolean flag's negation) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const unsafe = Flag.Boolean("unsafe").pipe( * Flag.withDefault(false), * Flag.withoutNegation * ) * // --unsafe => true * // --no-unsafe => unrecognized flag * unsafe.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.1.0 */ export declare const withoutNegation: (self: Flag) => Flag; /** * Sets a custom metavar (placeholder name) for the flag in help documentation. * * **Details** * * The metavar is displayed in usage text to indicate what value the user should * provide. For example, `--output FILE` shows `FILE` as the metavar. * * **Example** (Setting metavars) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const databaseFlag = Flag.String("database-url").pipe( * Flag.withMetavar("URL"), * Flag.withDescription("Database connection URL") * ) * // In help: --database-url URL * * const timeoutFlag = Flag.Int("timeout").pipe( * Flag.withMetavar("SECONDS") * ) * // In help: --timeout SECONDS * const kinds = [databaseFlag.kind, timeoutFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category metadata * @since 4.0.0 */ export declare const withMetavar: { /** * Sets a custom metavar (placeholder name) for the flag in help documentation. * * **Details** * * The metavar is displayed in usage text to indicate what value the user should * provide. For example, `--output FILE` shows `FILE` as the metavar. * * **Example** (Setting metavars) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const databaseFlag = Flag.String("database-url").pipe( * Flag.withMetavar("URL"), * Flag.withDescription("Database connection URL") * ) * // In help: --database-url URL * * const timeoutFlag = Flag.Int("timeout").pipe( * Flag.withMetavar("SECONDS") * ) * // In help: --timeout SECONDS * const kinds = [databaseFlag.kind, timeoutFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category metadata * @since 4.0.0 */ (metavar: string): (self: Flag) => Flag; /** * Sets a custom metavar (placeholder name) for the flag in help documentation. * * **Details** * * The metavar is displayed in usage text to indicate what value the user should * provide. For example, `--output FILE` shows `FILE` as the metavar. * * **Example** (Setting metavars) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const databaseFlag = Flag.String("database-url").pipe( * Flag.withMetavar("URL"), * Flag.withDescription("Database connection URL") * ) * // In help: --database-url URL * * const timeoutFlag = Flag.Int("timeout").pipe( * Flag.withMetavar("SECONDS") * ) * // In help: --timeout SECONDS * const kinds = [databaseFlag.kind, timeoutFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category metadata * @since 4.0.0 */ (self: Flag, metavar: string): Flag; }; /** * Hides a flag from generated help output and shell completions while keeping * it fully parseable on the command line. * * **When to use** * * Use when experimental or internal flags should be accepted but not advertised, such as * `--experimental-foo`, debug toggles, or escape hatches that are not yet committed to the * public CLI surface. * * **Example** (Hiding a flag from help) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Flag still parses --experimental-foo, but it does not appear in --help. * const experimental = Flag.Boolean("experimental-foo").pipe( * Flag.withHidden * ) * experimental.kind // => "flag" * ``` * * @stability unstable * @category metadata * @since 4.0.0 */ export declare const withHidden: (self: Flag) => Flag; /** * Makes a flag optional, returning an Option type that can be None if not provided. * * **Example** (Making flags optional) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Option, Path, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * const optionalPort = Flag.optional(Flag.Int("port")) * * const program = Effect.gen(function*() { * const [, port] = yield* optionalPort.parse({ * arguments: [], * flags: { "port": ["4000"] } * }) * return port * }) * * await Effect.runPromise(program.pipe(Effect.provide(CliTestLayer))) // => Option.some(4000) * ``` * * @stability unstable * @category optionality * @since 4.0.0 */ export declare const optional: (param: Flag) => Flag>; /** * Provides a default value for a flag when it's not specified. * * **Example** (Providing default values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const portFlag = Flag.Int("port").pipe( * Flag.withDefault(8080) * ) * // If --port is not provided, defaults to 8080 * * const hostFlag = Flag.String("host").pipe( * Flag.withDefault("localhost") * ) * // If --host is not provided, defaults to "localhost" * const kinds = [portFlag.kind, hostFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category optionality * @since 4.0.0 */ export declare const withDefault: { /** * Provides a default value for a flag when it's not specified. * * **Example** (Providing default values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const portFlag = Flag.Int("port").pipe( * Flag.withDefault(8080) * ) * // If --port is not provided, defaults to 8080 * * const hostFlag = Flag.String("host").pipe( * Flag.withDefault("localhost") * ) * // If --host is not provided, defaults to "localhost" * const kinds = [portFlag.kind, hostFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category optionality * @since 4.0.0 */ (defaultValue: B | Effect.Effect): (self: Flag) => Flag; /** * Provides a default value for a flag when it's not specified. * * **Example** (Providing default values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const portFlag = Flag.Int("port").pipe( * Flag.withDefault(8080) * ) * // If --port is not provided, defaults to 8080 * * const hostFlag = Flag.String("host").pipe( * Flag.withDefault("localhost") * ) * // If --host is not provided, defaults to "localhost" * const kinds = [portFlag.kind, hostFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category optionality * @since 4.0.0 */ (self: Flag, defaultValue: B | Effect.Effect): Flag; }; /** * Adds a fallback config that is loaded when a required flag is missing. * * **Example** (Falling back to config) * * ```ts import.meta.vitest * import { Config } from "effect" * import { Flag } from "effect/cli" * * const verbose = Flag.Boolean("verbose").pipe( * Flag.withFallbackConfig(Config.Boolean("VERBOSE")) * ) * verbose.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.0.0 */ export declare const withFallbackConfig: { /** * Adds a fallback config that is loaded when a required flag is missing. * * **Example** (Falling back to config) * * ```ts import.meta.vitest * import { Config } from "effect" * import { Flag } from "effect/cli" * * const verbose = Flag.Boolean("verbose").pipe( * Flag.withFallbackConfig(Config.Boolean("VERBOSE")) * ) * verbose.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.0.0 */ (config: Config.Config): (self: Flag) => Flag; /** * Adds a fallback config that is loaded when a required flag is missing. * * **Example** (Falling back to config) * * ```ts import.meta.vitest * import { Config } from "effect" * import { Flag } from "effect/cli" * * const verbose = Flag.Boolean("verbose").pipe( * Flag.withFallbackConfig(Config.Boolean("VERBOSE")) * ) * verbose.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.0.0 */ (self: Flag, config: Config.Config): Flag; }; /** * Adds a fallback prompt that is shown when a required flag is missing. * * **Example** (Falling back to prompts) * * ```ts import.meta.vitest * import { Flag, Prompt } from "effect/cli" * * const name = Flag.String("name").pipe( * Flag.withFallbackPrompt(Prompt.String({ message: "Name" })) * ) * name.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.0.0 */ export declare const withFallbackPrompt: { /** * Adds a fallback prompt that is shown when a required flag is missing. * * **Example** (Falling back to prompts) * * ```ts import.meta.vitest * import { Flag, Prompt } from "effect/cli" * * const name = Flag.String("name").pipe( * Flag.withFallbackPrompt(Prompt.String({ message: "Name" })) * ) * name.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.0.0 */ (prompt: Param.FallbackPrompt): (self: Flag) => Flag; /** * Adds a fallback prompt that is shown when a required flag is missing. * * **Example** (Falling back to prompts) * * ```ts import.meta.vitest * import { Flag, Prompt } from "effect/cli" * * const name = Flag.String("name").pipe( * Flag.withFallbackPrompt(Prompt.String({ message: "Name" })) * ) * name.kind // => "flag" * ``` * * @stability unstable * @category combinators * @since 4.0.0 */ (self: Flag, prompt: Param.FallbackPrompt): Flag; }; /** * Transforms the parsed value of a flag using a mapping function. * * **Example** (Mapping parsed values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Convert string to uppercase * const nameFlag = Flag.String("name").pipe( * Flag.map((name) => name.toUpperCase()) * ) * * // Convert port to URL * const urlFlag = Flag.Int("port").pipe( * Flag.map((port) => `http://localhost:${port}`) * ) * const kinds = [nameFlag.kind, urlFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category mapping * @since 4.0.0 */ export declare const map: { /** * Transforms the parsed value of a flag using a mapping function. * * **Example** (Mapping parsed values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Convert string to uppercase * const nameFlag = Flag.String("name").pipe( * Flag.map((name) => name.toUpperCase()) * ) * * // Convert port to URL * const urlFlag = Flag.Int("port").pipe( * Flag.map((port) => `http://localhost:${port}`) * ) * const kinds = [nameFlag.kind, urlFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category mapping * @since 4.0.0 */ (f: (a: A) => B): (self: Flag) => Flag; /** * Transforms the parsed value of a flag using a mapping function. * * **Example** (Mapping parsed values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Convert string to uppercase * const nameFlag = Flag.String("name").pipe( * Flag.map((name) => name.toUpperCase()) * ) * * // Convert port to URL * const urlFlag = Flag.Int("port").pipe( * Flag.map((port) => `http://localhost:${port}`) * ) * const kinds = [nameFlag.kind, urlFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category mapping * @since 4.0.0 */ (self: Flag, f: (a: A) => B): Flag; }; /** * Transforms the parsed value using an Effect that can perform IO operations. * * **Example** (Mapping parsed values effectfully) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * const upperName = Flag.String("name").pipe( * Flag.mapEffect((name) => Effect.succeed(name.toUpperCase())) * ) * * const [, value] = await Effect.runPromise( * upperName.parse({ * arguments: [], * flags: { name: ["alice"] } * }).pipe(Effect.provide(CliTestLayer)) * ) * value // => "ALICE" * ``` * * @stability unstable * @category mapping * @since 4.0.0 */ export declare const mapEffect: { /** * Transforms the parsed value using an Effect that can perform IO operations. * * **Example** (Mapping parsed values effectfully) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * const upperName = Flag.String("name").pipe( * Flag.mapEffect((name) => Effect.succeed(name.toUpperCase())) * ) * * const [, value] = await Effect.runPromise( * upperName.parse({ * arguments: [], * flags: { name: ["alice"] } * }).pipe(Effect.provide(CliTestLayer)) * ) * value // => "ALICE" * ``` * * @stability unstable * @category mapping * @since 4.0.0 */ (f: (a: A) => Effect.Effect): (self: Flag) => Flag; /** * Transforms the parsed value using an Effect that can perform IO operations. * * **Example** (Mapping parsed values effectfully) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * const upperName = Flag.String("name").pipe( * Flag.mapEffect((name) => Effect.succeed(name.toUpperCase())) * ) * * const [, value] = await Effect.runPromise( * upperName.parse({ * arguments: [], * flags: { name: ["alice"] } * }).pipe(Effect.provide(CliTestLayer)) * ) * value // => "ALICE" * ``` * * @stability unstable * @category mapping * @since 4.0.0 */ (self: Flag, f: (a: A) => Effect.Effect): Flag; }; /** * Transforms the parsed value using a function that might throw, with error handling. * * **Example** (Mapping thrown errors) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * // Parse JSON string with error handling * const jsonFlag = Flag.String("config").pipe( * Flag.mapTryCatch( * (json) => JSON.parse(json), * (error) => `Invalid JSON: ${error}` * ) * ) * * // Parse URL with error handling * const urlFlag = Flag.String("url").pipe( * Flag.mapTryCatch( * (url) => new URL(url), * (error) => `Invalid URL: ${error}` * ) * ) * * const [, value] = await Effect.runPromise( * jsonFlag.parse({ * arguments: [], * flags: { config: ['{"enabled":true}'] } * }).pipe(Effect.provide(CliTestLayer)) * ) * value // => { enabled: true } * ``` * * @stability unstable * @category mapping * @since 4.0.0 */ export declare const mapTryCatch: { /** * Transforms the parsed value using a function that might throw, with error handling. * * **Example** (Mapping thrown errors) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * // Parse JSON string with error handling * const jsonFlag = Flag.String("config").pipe( * Flag.mapTryCatch( * (json) => JSON.parse(json), * (error) => `Invalid JSON: ${error}` * ) * ) * * // Parse URL with error handling * const urlFlag = Flag.String("url").pipe( * Flag.mapTryCatch( * (url) => new URL(url), * (error) => `Invalid URL: ${error}` * ) * ) * * const [, value] = await Effect.runPromise( * jsonFlag.parse({ * arguments: [], * flags: { config: ['{"enabled":true}'] } * }).pipe(Effect.provide(CliTestLayer)) * ) * value // => { enabled: true } * ``` * * @stability unstable * @category mapping * @since 4.0.0 */ (f: (a: A) => B, onError: (error: unknown) => string): (self: Flag) => Flag; /** * Transforms the parsed value using a function that might throw, with error handling. * * **Example** (Mapping thrown errors) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * // Parse JSON string with error handling * const jsonFlag = Flag.String("config").pipe( * Flag.mapTryCatch( * (json) => JSON.parse(json), * (error) => `Invalid JSON: ${error}` * ) * ) * * // Parse URL with error handling * const urlFlag = Flag.String("url").pipe( * Flag.mapTryCatch( * (url) => new URL(url), * (error) => `Invalid URL: ${error}` * ) * ) * * const [, value] = await Effect.runPromise( * jsonFlag.parse({ * arguments: [], * flags: { config: ['{"enabled":true}'] } * }).pipe(Effect.provide(CliTestLayer)) * ) * value // => { enabled: true } * ``` * * @stability unstable * @category mapping * @since 4.0.0 */ (self: Flag, f: (a: A) => B, onError: (error: unknown) => string): Flag; }; /** * Ensures a flag is specified at least a minimum number of times. * * **Example** (Requiring repeated values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const sourceFlag = Flag.atLeast(Flag.File("source"), 2) * // Requires at least 2 source files * // Usage: --source file1.ts --source file2.ts * * const tagFlag = Flag.String("tag").pipe( * Flag.atLeast(1) * ) * // Requires at least 1 tag * const kinds = [sourceFlag.kind, tagFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category repetition * @since 4.0.0 */ export declare const atLeast: { /** * Ensures a flag is specified at least a minimum number of times. * * **Example** (Requiring repeated values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const sourceFlag = Flag.atLeast(Flag.File("source"), 2) * // Requires at least 2 source files * // Usage: --source file1.ts --source file2.ts * * const tagFlag = Flag.String("tag").pipe( * Flag.atLeast(1) * ) * // Requires at least 1 tag * const kinds = [sourceFlag.kind, tagFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category repetition * @since 4.0.0 */ (min: number): (self: Flag) => Flag>; /** * Ensures a flag is specified at least a minimum number of times. * * **Example** (Requiring repeated values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const sourceFlag = Flag.atLeast(Flag.File("source"), 2) * // Requires at least 2 source files * // Usage: --source file1.ts --source file2.ts * * const tagFlag = Flag.String("tag").pipe( * Flag.atLeast(1) * ) * // Requires at least 1 tag * const kinds = [sourceFlag.kind, tagFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category repetition * @since 4.0.0 */ (self: Flag, min: number): Flag>; }; /** * Ensures a flag is specified at most a maximum number of times. * * **Example** (Limiting repeated values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const warningFlag = Flag.atMost(Flag.String("warning"), 3) * // Allows up to 3 warning flags * // Usage: --warning w1 --warning w2 --warning w3 * * const debugFlag = Flag.String("debug").pipe( * Flag.atMost(1) * ) * // Allows at most 1 debug flag * const kinds = [warningFlag.kind, debugFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category repetition * @since 4.0.0 */ export declare const atMost: { /** * Ensures a flag is specified at most a maximum number of times. * * **Example** (Limiting repeated values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const warningFlag = Flag.atMost(Flag.String("warning"), 3) * // Allows up to 3 warning flags * // Usage: --warning w1 --warning w2 --warning w3 * * const debugFlag = Flag.String("debug").pipe( * Flag.atMost(1) * ) * // Allows at most 1 debug flag * const kinds = [warningFlag.kind, debugFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category repetition * @since 4.0.0 */ (max: number): (self: Flag) => Flag>; /** * Ensures a flag is specified at most a maximum number of times. * * **Example** (Limiting repeated values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const warningFlag = Flag.atMost(Flag.String("warning"), 3) * // Allows up to 3 warning flags * // Usage: --warning w1 --warning w2 --warning w3 * * const debugFlag = Flag.String("debug").pipe( * Flag.atMost(1) * ) * // Allows at most 1 debug flag * const kinds = [warningFlag.kind, debugFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category repetition * @since 4.0.0 */ (self: Flag, max: number): Flag>; }; /** * Ensures a flag is specified between a minimum and maximum number of times. * * **Example** (Bounding repeated values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const hostFlag = Flag.between(Flag.String("host"), 1, 3) * // Requires 1-3 host flags * // Usage: --host host1 --host host2 * * const excludeFlag = Flag.String("exclude").pipe( * Flag.between(0, 5) * ) * // Allows 0-5 exclude patterns * const kinds = [hostFlag.kind, excludeFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category repetition * @since 4.0.0 */ export declare const between: { /** * Ensures a flag is specified between a minimum and maximum number of times. * * **Example** (Bounding repeated values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const hostFlag = Flag.between(Flag.String("host"), 1, 3) * // Requires 1-3 host flags * // Usage: --host host1 --host host2 * * const excludeFlag = Flag.String("exclude").pipe( * Flag.between(0, 5) * ) * // Allows 0-5 exclude patterns * const kinds = [hostFlag.kind, excludeFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category repetition * @since 4.0.0 */ (min: number, max: number): (self: Flag) => Flag>; /** * Ensures a flag is specified between a minimum and maximum number of times. * * **Example** (Bounding repeated values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * const hostFlag = Flag.between(Flag.String("host"), 1, 3) * // Requires 1-3 host flags * // Usage: --host host1 --host host2 * * const excludeFlag = Flag.String("exclude").pipe( * Flag.between(0, 5) * ) * // Allows 0-5 exclude patterns * const kinds = [hostFlag.kind, excludeFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category repetition * @since 4.0.0 */ (self: Flag, min: number, max: number): Flag>; }; /** * Transforms and filters a flag value, failing with a custom error if the transformation returns None. * * **Example** (Filtering and transforming values) * * ```ts import.meta.vitest * import { Option } from "effect" * import { Flag } from "effect/cli" * * // Parse positive integers only * const positiveInt = Flag.Int("count").pipe( * Flag.filterMap( * (n) => n > 0 ? Option.some(n) : Option.none(), * (n) => `Expected positive integer, got ${n}` * ) * ) * * // Parse valid email addresses * const emailFlag = Flag.String("email").pipe( * Flag.filterMap( * (email) => email.includes("@") ? Option.some(email) : Option.none(), * (email) => `Invalid email address: ${email}` * ) * ) * const kinds = [positiveInt.kind, emailFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category filtering * @since 4.0.0 */ export declare const filterMap: { /** * Transforms and filters a flag value, failing with a custom error if the transformation returns None. * * **Example** (Filtering and transforming values) * * ```ts import.meta.vitest * import { Option } from "effect" * import { Flag } from "effect/cli" * * // Parse positive integers only * const positiveInt = Flag.Int("count").pipe( * Flag.filterMap( * (n) => n > 0 ? Option.some(n) : Option.none(), * (n) => `Expected positive integer, got ${n}` * ) * ) * * // Parse valid email addresses * const emailFlag = Flag.String("email").pipe( * Flag.filterMap( * (email) => email.includes("@") ? Option.some(email) : Option.none(), * (email) => `Invalid email address: ${email}` * ) * ) * const kinds = [positiveInt.kind, emailFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category filtering * @since 4.0.0 */ (f: (a: A) => Option.Option, onNone: (a: A) => string): (self: Flag) => Flag; /** * Transforms and filters a flag value, failing with a custom error if the transformation returns None. * * **Example** (Filtering and transforming values) * * ```ts import.meta.vitest * import { Option } from "effect" * import { Flag } from "effect/cli" * * // Parse positive integers only * const positiveInt = Flag.Int("count").pipe( * Flag.filterMap( * (n) => n > 0 ? Option.some(n) : Option.none(), * (n) => `Expected positive integer, got ${n}` * ) * ) * * // Parse valid email addresses * const emailFlag = Flag.String("email").pipe( * Flag.filterMap( * (email) => email.includes("@") ? Option.some(email) : Option.none(), * (email) => `Invalid email address: ${email}` * ) * ) * const kinds = [positiveInt.kind, emailFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category filtering * @since 4.0.0 */ (self: Flag, f: (a: A) => Option.Option, onNone: (a: A) => string): Flag; }; /** * Filters a flag value based on a predicate, failing with a custom error if the predicate returns false. * * **Example** (Filtering parsed values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Ensure port is in valid range * const portFlag = Flag.Int("port").pipe( * Flag.filter( * (port) => port >= 1 && port <= 65535, * (port) => `Port ${port} is out of range (1-65535)` * ) * ) * * // Ensure non-empty string * const nameFlag = Flag.String("name").pipe( * Flag.filter( * (name) => name.trim().length > 0, * () => "Name cannot be empty" * ) * ) * const kinds = [portFlag.kind, nameFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category filtering * @since 4.0.0 */ export declare const filter: { /** * Filters a flag value based on a predicate, failing with a custom error if the predicate returns false. * * **Example** (Filtering parsed values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Ensure port is in valid range * const portFlag = Flag.Int("port").pipe( * Flag.filter( * (port) => port >= 1 && port <= 65535, * (port) => `Port ${port} is out of range (1-65535)` * ) * ) * * // Ensure non-empty string * const nameFlag = Flag.String("name").pipe( * Flag.filter( * (name) => name.trim().length > 0, * () => "Name cannot be empty" * ) * ) * const kinds = [portFlag.kind, nameFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category filtering * @since 4.0.0 */ (predicate: (a: A) => boolean, onFalse: (a: A) => string): (self: Flag) => Flag; /** * Filters a flag value based on a predicate, failing with a custom error if the predicate returns false. * * **Example** (Filtering parsed values) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Ensure port is in valid range * const portFlag = Flag.Int("port").pipe( * Flag.filter( * (port) => port >= 1 && port <= 65535, * (port) => `Port ${port} is out of range (1-65535)` * ) * ) * * // Ensure non-empty string * const nameFlag = Flag.String("name").pipe( * Flag.filter( * (name) => name.trim().length > 0, * () => "Name cannot be empty" * ) * ) * const kinds = [portFlag.kind, nameFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category filtering * @since 4.0.0 */ (self: Flag, predicate: (a: A) => boolean, onFalse: (a: A) => string): Flag; }; /** * Provides an alternative flag if the first one fails to parse. * * **Example** (Falling back to another flag) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Try parsing as integer, fallback to string * const valueFlag = Flag.orElse( * Flag.Int("value"), * () => Flag.String("value") * ) * * // Multiple input sources with fallback * const configFlag = Flag.orElse( * Flag.File("config"), * () => Flag.String("config-url") * ) * const kinds = [valueFlag.kind, configFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category alternatives * @since 4.0.0 */ export declare const orElse: { /** * Provides an alternative flag if the first one fails to parse. * * **Example** (Falling back to another flag) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Try parsing as integer, fallback to string * const valueFlag = Flag.orElse( * Flag.Int("value"), * () => Flag.String("value") * ) * * // Multiple input sources with fallback * const configFlag = Flag.orElse( * Flag.File("config"), * () => Flag.String("config-url") * ) * const kinds = [valueFlag.kind, configFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category alternatives * @since 4.0.0 */ (that: LazyArg>): (self: Flag) => Flag; /** * Provides an alternative flag if the first one fails to parse. * * **Example** (Falling back to another flag) * * ```ts import.meta.vitest * import { Flag } from "effect/cli" * * // Try parsing as integer, fallback to string * const valueFlag = Flag.orElse( * Flag.Int("value"), * () => Flag.String("value") * ) * * // Multiple input sources with fallback * const configFlag = Flag.orElse( * Flag.File("config"), * () => Flag.String("config-url") * ) * const kinds = [valueFlag.kind, configFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category alternatives * @since 4.0.0 */ (self: Flag, that: LazyArg>): Flag; }; /** * Tries to parse with the first flag, then the second, returning a Result that indicates which succeeded. * * **Example** (Returning fallback results) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Path, Result, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * const sourceFlag = Flag.orElseResult( * Flag.String("source"), * () => Flag.String("source-url") * ) * * const program = Effect.gen(function*() { * const [, source] = yield* sourceFlag.parse({ * arguments: [], * flags: { "source-url": ["https://example.com"] } * }) * return source * }) * * await Effect.runPromise(program.pipe(Effect.provide(CliTestLayer))) // => Result.fail("https://example.com") * ``` * * @stability unstable * @category alternatives * @since 4.0.0 */ export declare const orElseResult: { /** * Tries to parse with the first flag, then the second, returning a Result that indicates which succeeded. * * **Example** (Returning fallback results) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Path, Result, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * const sourceFlag = Flag.orElseResult( * Flag.String("source"), * () => Flag.String("source-url") * ) * * const program = Effect.gen(function*() { * const [, source] = yield* sourceFlag.parse({ * arguments: [], * flags: { "source-url": ["https://example.com"] } * }) * return source * }) * * await Effect.runPromise(program.pipe(Effect.provide(CliTestLayer))) // => Result.fail("https://example.com") * ``` * * @stability unstable * @category alternatives * @since 4.0.0 */ (that: LazyArg>): (self: Flag) => Flag>; /** * Tries to parse with the first flag, then the second, returning a Result that indicates which succeeded. * * **Example** (Returning fallback results) * * ```ts import.meta.vitest * import { Effect, FileSystem, Layer, Path, Result, Stdio, Terminal } from "effect" * import { Flag } from "effect/cli" * import { ChildProcessSpawner } from "effect/process" * * const CliTestLayer = Layer.mergeAll( * FileSystem.layerNoop({}), * Path.layer, * Stdio.layerTest({}), * Layer.succeed(Terminal.Terminal, Terminal.make({ * columns: Effect.succeed(80), * rows: Effect.succeed(24), * readInput: Effect.die("unused"), * readLine: Effect.die("unused"), * display: () => Effect.void * })), * Layer.succeed( * ChildProcessSpawner.ChildProcessSpawner, * ChildProcessSpawner.make(() => Effect.die("unused")) * ) * ) * * const sourceFlag = Flag.orElseResult( * Flag.String("source"), * () => Flag.String("source-url") * ) * * const program = Effect.gen(function*() { * const [, source] = yield* sourceFlag.parse({ * arguments: [], * flags: { "source-url": ["https://example.com"] } * }) * return source * }) * * await Effect.runPromise(program.pipe(Effect.provide(CliTestLayer))) // => Result.fail("https://example.com") * ``` * * @stability unstable * @category alternatives * @since 4.0.0 */ (self: Flag, that: LazyArg>): Flag>; }; /** * Validates and transforms a flag value using a Schema codec. * * **Example** (Validating with schemas) * * ```ts import.meta.vitest * import { Schema } from "effect" * import { Flag } from "effect/cli" * * const isEmail = Schema.isPattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/, { * message: "Must be a valid email address" * }) * * // Parse and validate email with custom schema * const EmailSchema = Schema.String.pipe( * Schema.check(isEmail) * ) * * const emailFlag = Flag.String("email").pipe( * Flag.withSchema(EmailSchema) * ) * * // Parse JSON configuration with schema validation * const ConfigSchema = Schema.Struct({ * port: Schema.Number, * host: Schema.String, * ssl: Schema.optional(Schema.Boolean) * }).pipe(Schema.fromJsonString) * * const configFlag = Flag.String("config").pipe( * Flag.withSchema(ConfigSchema) * ) * const kinds = [emailFlag.kind, configFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category schemas * @since 4.0.0 */ export declare const withSchema: { /** * Validates and transforms a flag value using a Schema codec. * * **Example** (Validating with schemas) * * ```ts import.meta.vitest * import { Schema } from "effect" * import { Flag } from "effect/cli" * * const isEmail = Schema.isPattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/, { * message: "Must be a valid email address" * }) * * // Parse and validate email with custom schema * const EmailSchema = Schema.String.pipe( * Schema.check(isEmail) * ) * * const emailFlag = Flag.String("email").pipe( * Flag.withSchema(EmailSchema) * ) * * // Parse JSON configuration with schema validation * const ConfigSchema = Schema.Struct({ * port: Schema.Number, * host: Schema.String, * ssl: Schema.optional(Schema.Boolean) * }).pipe(Schema.fromJsonString) * * const configFlag = Flag.String("config").pipe( * Flag.withSchema(ConfigSchema) * ) * const kinds = [emailFlag.kind, configFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category schemas * @since 4.0.0 */ (schema: Schema.ConstraintCodec): (self: Flag) => Flag; /** * Validates and transforms a flag value using a Schema codec. * * **Example** (Validating with schemas) * * ```ts import.meta.vitest * import { Schema } from "effect" * import { Flag } from "effect/cli" * * const isEmail = Schema.isPattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/, { * message: "Must be a valid email address" * }) * * // Parse and validate email with custom schema * const EmailSchema = Schema.String.pipe( * Schema.check(isEmail) * ) * * const emailFlag = Flag.String("email").pipe( * Flag.withSchema(EmailSchema) * ) * * // Parse JSON configuration with schema validation * const ConfigSchema = Schema.Struct({ * port: Schema.Number, * host: Schema.String, * ssl: Schema.optional(Schema.Boolean) * }).pipe(Schema.fromJsonString) * * const configFlag = Flag.String("config").pipe( * Flag.withSchema(ConfigSchema) * ) * const kinds = [emailFlag.kind, configFlag.kind] // => ["flag", "flag"] * ``` * * @stability unstable * @category schemas * @since 4.0.0 */ (self: Flag, schema: Schema.ConstraintCodec): Flag; }; //# sourceMappingURL=Flag.d.ts.map