@clo4/cli 0.0.0-stage → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +96 -2
- package/dist/index.d.ts +234 -0
- package/dist/index.js +1229 -0
- package/dist/index.js.map +1 -0
- package/dist/testing.d.ts +325 -0
- package/dist/testing.js +430 -0
- package/dist/testing.js.map +1 -0
- package/package.json +62 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["builtinUsageAction","maybeProcess"],"sources":["../src/util.ts","../src/errors.ts","../src/suggest.ts","../src/help.ts","../src/parse.ts","../src/completion.ts","../src/run.ts","../src/index.ts"],"sourcesContent":["import type { NonEmptyArray } from \"./types.js\";\n\nexport function isArray<T>(o: T | readonly T[]): o is readonly T[] {\n return Array.isArray(o);\n}\n\n/** Convert the value, if any, to an array with 0 or more elements */\nexport function makeArray<T>(thing: T | readonly T[] | undefined): T[] {\n if (thing === undefined) return [];\n if (isArray(thing)) {\n return thing.slice();\n }\n return [thing];\n}\n\n/**\n * Like {@link makeArray}, but without copying when the input is already an\n * array. Only safe when the caller treats the result as read-only — use it on\n * the hot path to avoid slicing read-only spec metadata.\n */\nexport function asArray<T>(thing: T | readonly T[] | undefined): readonly T[] {\n if (thing === undefined) return [];\n if (isArray(thing)) return thing;\n return [thing];\n}\n\n/** Convert the value to an array with at least one element */\nexport function makeArray1<T>(thing: T | NonEmptyArray<T>): [T, ...T[]] {\n if (isArray(thing)) {\n // We know that this array has at least one element in it\n return thing.slice() as [T, ...T[]];\n }\n return [thing];\n}\n\n/** Set many keys in a Map to the same value */\nexport function setEach<K, V>(map: Map<K, V>, keys: K | readonly K[], value: V): void {\n if (isArray(keys)) {\n for (const key of keys) {\n map.set(key, value);\n }\n } else {\n map.set(keys, value);\n }\n}\n\nexport function assert(expr: unknown, msg = \"\"): asserts expr {\n if (!expr) {\n throw new Error(msg);\n }\n}\n\n// Output {{{\n\ninterface WriteSyncFs {\n writeSync(fd: number, buffer: Uint8Array, offset: number, length: number): number;\n}\n\ninterface NodeProcess {\n getBuiltinModule?(id: \"node:fs\"): WriteSyncFs;\n stdout?: { write(data: Uint8Array): unknown };\n stderr?: { write(data: Uint8Array): unknown };\n}\n\nconst nodeProcess = (globalThis as { process?: NodeProcess }).process;\n\n/**\n * Write text to stdout (1) or stderr (2) with a synchronous `write` on the file\n * descriptor.\n *\n * The first `console.log` in a Node process builds the stdout stream, which\n * costs 1-3 ms. That's more than parsing takes, so all of this library's output\n * goes through here instead. Without `node:fs` it falls back to `console`.\n */\nfunction writeFd(fd: 1 | 2, text: string): void {\n const fs = nodeProcess?.getBuiltinModule?.(\"node:fs\");\n if (!fs) {\n (fd === 1 ? console.log : console.error)(text.endsWith(\"\\n\") ? text.slice(0, -1) : text);\n return;\n }\n const bytes = new TextEncoder().encode(text);\n let offset = 0;\n try {\n while (offset < bytes.length) {\n offset += fs.writeSync(fd, bytes, offset, bytes.length - offset);\n }\n } catch (error) {\n const code = (error as { code?: string }).code;\n // A non-blocking pipe that's full: let Node's stream queue the rest.\n if (code === \"EAGAIN\") {\n (fd === 1 ? nodeProcess?.stdout : nodeProcess?.stderr)?.write(bytes.subarray(offset));\n }\n // Anything else, like EPIPE from `cli --help | head -1`, is dropped, the\n // same as `console` does.\n }\n}\n\n/**\n * Where this library's output goes. Tests replace `write` to capture output.\n *\n * @internal\n */\nexport const output: { write: (fd: 1 | 2, text: string) => void } = { write: writeFd };\n\n/** Print a message to stdout, trimming trailing whitespace. */\nexport function print(text: string): void {\n output.write(1, `${text.trimEnd()}\\n`);\n}\n\n/** Print an error message to stderr with the shared `Error:` prefix. */\nexport function printActionError(message: string): void {\n output.write(2, `Error: ${message}\\n`);\n}\n\n// }}}\n\n/**\n * Returns the minimum number of arguments that satisfies the args.\n *\n * Accepts the raw spec value (a single arg, an array, or `undefined`) so the\n * hot path doesn't have to copy it into an array first.\n */\nexport function getMinArgs(\n args: { isOptional?: boolean } | readonly { isOptional?: boolean }[] | undefined,\n): number {\n if (args === undefined) return 0;\n if (!isArray(args)) return args.isOptional ? 0 : 1;\n let count = 0;\n for (let i = 0; i < args.length; i++) {\n if (args[i].isOptional) {\n break;\n }\n count++;\n }\n return count;\n}\n\n/** Returns the maximum number of arguments that satisfies the args. */\nexport function getMaxArgs(\n args: { isVariadic?: boolean } | readonly { isVariadic?: boolean }[] | undefined,\n): number {\n if (args === undefined) return 0;\n if (!isArray(args)) return args.isVariadic ? Infinity : 1;\n // Loop over the array backwards because variadic arguments are\n // more likely to be at the end of the array. They don't _need_\n // to be, but it's more idiomatic.\n for (let i = 0; i < args.length; i++) {\n if (args[args.length - 1 - i].isVariadic) {\n return Infinity;\n }\n }\n // None of the arguments are variadic, max is the number of args\n return args.length;\n}\n","import type { CommandPath } from \"./types.js\";\n\nconst repr = JSON.stringify as (str: string) => string;\n\nexport interface ErrorContext {\n path: CommandPath;\n}\n\nexport class ParseError extends Error {\n readonly context: ErrorContext;\n constructor(context: ErrorContext, ...args: ConstructorParameters<ErrorConstructor>) {\n super(...args);\n this.context = context;\n this.name = this.constructor.name;\n }\n}\n\nexport class UnknownOption extends ParseError {\n readonly index: number;\n readonly start: number;\n readonly end: number;\n readonly option: string;\n readonly validOptions: string[];\n constructor(\n found: { option: string; validOptions: string[]; index: number; start: number; end: number },\n context: ErrorContext,\n ) {\n const msg = `${repr(found.option)} looks like a flag, but is unknown in this context`;\n super(context, msg);\n this.option = found.option;\n this.validOptions = found.validOptions;\n this.index = found.index;\n this.start = found.start;\n this.end = found.end;\n }\n}\n\nexport class InvalidOptionArg extends ParseError {\n readonly index: number;\n readonly start: number;\n readonly end: number;\n readonly arg: string;\n readonly option: string;\n constructor(\n found: { option: string; arg: string; index: number; start: number; end: number },\n context: ErrorContext,\n ) {\n const msg = `Option ${found.option} doesn't take arguments`;\n super(context, msg);\n this.index = found.index;\n this.start = found.start;\n this.end = found.end;\n this.option = found.option;\n this.arg = found.arg;\n }\n}\n\nexport class TooManyArguments extends ParseError {\n readonly index: number;\n readonly value: string;\n constructor(found: { value: string; index: number }, context: ErrorContext) {\n const msg = `Too many arguments, ${repr(found.value)} was unexpected`;\n super(context, msg);\n this.index = found.index;\n this.value = found.value;\n }\n}\n\nexport class TooFewOptionArguments extends ParseError {\n constructor(min: number, max: number, context: ErrorContext) {\n const msg =\n min === max\n ? `Option needs ${min} argument${min === 1 ? \"\" : \"s\"}`\n : !Number.isFinite(max)\n ? `Option needs at least ${min} argument${min === 1 ? \"\" : \"s\"}`\n : `Option needs between ${min} and ${max} arguments`;\n super(context, msg);\n }\n}\n\nexport class TooFewArguments extends ParseError {\n constructor(min: number, max: number, context: ErrorContext) {\n const msg =\n min === max\n ? `Expected ${min} argument${min === 1 ? \"\" : \"s\"}`\n : !Number.isFinite(max)\n ? `Expected at least ${min} argument${min === 1 ? \"\" : \"s\"}`\n : `Expected between ${min} and ${max} arguments`;\n super(context, msg);\n }\n}\n\nexport class MissingRequiredOption extends ParseError {\n constructor(name: string, context: ErrorContext) {\n const msg = `Option ${name} is required, but wasn't found`;\n super(context, msg);\n }\n}\n","/**\n * \"Did you mean\" suggestions for unknown commands and options.\n *\n * This only runs after a mistake, but it's loaded on every run, so it's kept\n * small and does nothing until it's called.\n *\n * @module\n */\n\n/** How many `-` or `+` characters `name` starts with. */\nfunction dashCount(name: string): number {\n let i = 0;\n while (i < name.length && (name[i] === \"-\" || name[i] === \"+\")) i++;\n return i;\n}\n\n/** Whether every character of `short` appears in `long`, in order. */\nfunction isAbbreviation(short: string, long: string): boolean {\n let i = 0;\n for (let j = 0; j < long.length && i < short.length; j++) {\n if (long[j] === short[i]) i++;\n }\n return i === short.length;\n}\n\n/**\n * Levenshtein distance where swapping two adjacent characters also counts as\n * one edit (optimal string alignment). Returns `limit + 1` as soon as the\n * distance must be larger than `limit`.\n */\nfunction editDistance(a: string, b: string, limit: number): number {\n // Three rows of the usual table: two rows back, the previous row and this one.\n let before = new Uint32Array(b.length + 1);\n let previous = new Uint32Array(b.length + 1);\n let current = new Uint32Array(b.length + 1);\n for (let j = 0; j <= b.length; j++) previous[j] = j;\n\n for (let i = 1; i <= a.length; i++) {\n current[0] = i;\n let rowMin = i;\n for (let j = 1; j <= b.length; j++) {\n const substitution = previous[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1);\n let d = Math.min(previous[j] + 1, current[j - 1] + 1, substitution);\n if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {\n d = Math.min(d, before[j - 2] + 1);\n }\n current[j] = d;\n if (d < rowMin) rowMin = d;\n }\n // Every later row is at least this row's minimum.\n if (rowMin > limit) return limit + 1;\n const recycled = before;\n before = previous;\n previous = current;\n current = recycled;\n }\n return previous[b.length];\n}\n\n/**\n * The choice the user most likely meant by `input`, or `undefined` if none is\n * close enough to be worth suggesting. In order:\n *\n * 1. The only choice that starts with the input (`--verb` for `--verbose`).\n * 2. The only choice that contains every character of the input in order, for\n * inputs of 3 or more characters (`bld` for `build`).\n * 3. The choice with the fewest edits, allowing one edit per three characters\n * of the input. Leading dashes don't count toward the length or the edits.\n */\nexport function closestChoice(input: string, choices: readonly string[]): string | undefined {\n const inputDashes = dashCount(input);\n const bare = input.slice(inputDashes);\n\n if (bare.length >= 2) {\n let match: string | undefined;\n let count = 0;\n for (const choice of choices) {\n if (choice.startsWith(input)) {\n match = choice;\n count++;\n }\n }\n if (count === 1) return match;\n }\n\n if (bare.length >= 3) {\n let match: string | undefined;\n let count = 0;\n for (const choice of choices) {\n if (isAbbreviation(bare, choice.slice(dashCount(choice)))) {\n match = choice;\n count++;\n }\n }\n if (count === 1) return match;\n }\n\n let best: string | undefined;\n let limit = Math.floor(bare.length / 3);\n for (const choice of choices) {\n const other = choice.slice(dashCount(choice));\n // The length difference is a lower bound on the number of edits.\n if (Math.abs(other.length - bare.length) > limit) continue;\n const distance = editDistance(bare, other, limit);\n if (distance <= limit && (best === undefined || distance < limit)) {\n best = choice;\n // Later choices have to be strictly closer to replace this one.\n limit = distance;\n if (distance === 0) break;\n }\n }\n return best;\n}\n","import type { Action, Arg, Option, NonEmptyArray, SingleOrArray, Subcommand } from \"./types.js\";\nimport { closestChoice } from \"./suggest.js\";\nimport { makeArray, makeArray1, print, printActionError } from \"./util.js\";\n\nfunction getNamed<T extends { name: SingleOrArray<string> }>(named: readonly T[], name: string): T | null {\n return named.find((obj) => makeArray(obj.name).includes(name)) ?? null;\n}\n\nfunction getParserDirective<Key extends keyof NonNullable<Subcommand[\"parserDirectives\"]>>(\n path: readonly Subcommand[],\n key: Key,\n): NonNullable<Subcommand[\"parserDirectives\"]>[Key] | undefined {\n for (let index = path.length - 1; index >= 0; index -= 1) {\n const command = path[index];\n if (command?.parserDirectives && key in command.parserDirectives) {\n return command.parserDirectives[key];\n }\n }\n return undefined;\n}\n\nfunction dedent(str: string) {\n if (str[0] !== \"\\n\") return str;\n const lines = str.split(\"\\n\").slice(1, -1);\n const margin = lines[0].length - lines[0].trimStart().length;\n return lines.map((line) => line.slice(margin)).join(\"\\n\");\n}\n\nexport interface HelpConfig {\n /** Include the command description? Default: true. */\n description?: boolean;\n\n /** Include the usage summary? Default: true. */\n usage?: boolean;\n\n /** Ask if the user intended the input to be one of these choices. */\n didYouMean?: {\n input: string;\n choices: readonly string[];\n };\n}\n\n/** Get the help message used by the built-in help option and command. */\nexport function getHelp(path: NonEmptyArray<Subcommand>, config: HelpConfig = {}): string {\n const { description = true, usage = true, didYouMean } = config;\n const sections = getSections(path);\n if (didYouMean) {\n sections.didYouMean = closestChoice(didYouMean.input, didYouMean.choices);\n }\n if (!description) {\n sections.description = undefined;\n }\n if (!usage) {\n sections.usage = undefined;\n }\n return formatHelpSections(sections);\n}\n\n/**\n * Action that prints usage for commands where a subcommand must be provided.\n */\nexport const usage: Action = ({ path, args: [command], help }) => {\n if (command === undefined) {\n print(help());\n return 0;\n }\n\n if (command === \"\") {\n printActionError(`Expected a command, but the value was empty\\n\\n${help({ description: false })}`);\n return 1;\n }\n\n const subcommands = path\n .at(-1)\n ?.subcommands?.filter((cmd) => !cmd.hidden)\n .flatMap((cmd) => cmd.name);\n\n if (subcommands && subcommands.length > 0) {\n const matchPrefix = getParserDirective(path, \"subcommandsMatchUniquePrefix\");\n if (matchPrefix) {\n const possible = subcommands.filter((name) => name.startsWith(command));\n if (possible.length > 0) {\n printActionError(\n `Ambiguous command '${command}', could be: ${possible.join(\", \")}\\n\\n${help({\n description: false,\n })}`,\n );\n return 1;\n }\n }\n\n printActionError(\n `Unknown command '${command}'\\n\\n${help({\n description: false,\n didYouMean: {\n input: command,\n choices: subcommands,\n },\n })}`,\n );\n return 1;\n }\n\n printActionError(`Unknown command '${command}'\\n\\n${help({ description: false })}`);\n\n return 1;\n};\n\n/** A subcommand that prints help for its parent or a sibling command. */\nexport const helpCommand: Subcommand = {\n name: \"help\",\n description: \"Print a help message\",\n args: {\n name: \"command\",\n isOptional: true,\n },\n action({ path, args: [commandName], help }) {\n const helpRoot = path.slice(0, -1) as unknown as NonEmptyArray<Subcommand>;\n\n if (!commandName) {\n print(help({ path: helpRoot }));\n return 0;\n }\n\n const parent = path[path.length - 2];\n\n if (!parent.subcommands) {\n printActionError(\n `No subcommands, try using 'help' with nothing after it\\n\\n${help({\n description: false,\n path: helpRoot,\n })}`,\n );\n return 1;\n }\n\n const command = getNamed(parent.subcommands, commandName);\n if (!command) {\n const subcommands = parent.subcommands.filter((cmd) => !cmd.hidden).flatMap((cmd) => cmd.name);\n\n if (subcommands.length > 0) {\n printActionError(\n `There is no subcommand named '${commandName}'\\n\\n${help({\n path: helpRoot,\n didYouMean: {\n input: commandName,\n choices: subcommands,\n },\n })}`,\n );\n return 1;\n }\n\n printActionError(\n `There is no subcommand named '${commandName}'\\n\\n${help({\n description: false,\n path: helpRoot,\n })}`,\n );\n return 1;\n }\n\n print(help({ path: [...helpRoot, command] }));\n },\n};\n\n/** A persistent help option that prints help for the selected command. */\nexport const help: Option = {\n name: [\"-h\", \"--help\"],\n description: \"Print a help message\",\n isPersistent: true,\n action({ path }) {\n print(formatHelpSections(getSections(path)));\n return 0;\n },\n};\n\ntype HelpSections = {\n description?: string;\n usage?: string;\n didYouMean?: string;\n options: [formattedName: string, description: string][];\n persistentOptions: [formattedName: string, description: string][];\n subcommands: [formattedName: string, description: string][];\n};\n\nfunction getSubcommandPathString(commands: NonEmptyArray<Subcommand>): string {\n return commands.map((command) => getLongestString(makeArray1(command.name))).join(\" \");\n}\n\nfunction nonNullable<T>(value: T): value is NonNullable<T> {\n return value !== null && value !== undefined;\n}\n\nfunction getSections(commands: NonEmptyArray<Subcommand>): HelpSections {\n const command = commands[commands.length - 1];\n\n const description = command.description;\n const defaultDesc = \"No description\";\n\n const subcommands: HelpSections[\"subcommands\"] = command.subcommands\n ? command.subcommands\n .filter((subcommand) => !subcommand.hidden)\n .map((subcommand) => [\n makeArray1(subcommand.name)\n .sort((a, b) => a.length - b.length)\n .join(\", \"),\n subcommand.description ?? defaultDesc,\n ])\n : [];\n\n let persistentOptionObjects: Option[] = [];\n let optionObjects: Option[] = [];\n\n let persistentOptions: HelpSections[\"persistentOptions\"] = [];\n let options: HelpSections[\"options\"] = [];\n\n if (commands.length === 1 && subcommands.length === 0) {\n optionObjects = command.options ? command.options.filter((option) => !option.hidden) : [];\n options = optionObjects.map((option) => [optionToString(option), option.description ?? defaultDesc]);\n } else {\n persistentOptionObjects = commands\n .map((command) => command.options)\n .filter(nonNullable)\n .flat()\n .filter((option) => option.isPersistent && !option.hidden);\n\n persistentOptions = persistentOptionObjects.map((option) => [\n optionToString(option),\n option.description ?? defaultDesc,\n ]);\n\n optionObjects = (command.options ?? []).filter((option) => !option.hidden && !option.isPersistent);\n\n options = optionObjects.map((option) => [optionToString(option), option.description ?? defaultDesc]);\n }\n\n const usage = (() => {\n const parts = [getSubcommandPathString(commands)];\n const required = [\n ...optionObjects.filter((option) => option.isRequired),\n ...persistentOptionObjects.filter((option) => option.isRequired),\n ];\n for (const option of required) {\n parts.push(optionToString(option));\n }\n if (options.length || persistentOptions.length) {\n parts.push(\"[flags]\");\n }\n if (command.requiresSubcommand) {\n parts.push(\"<command>\");\n } else {\n const args = makeArray(command.args);\n if (args.length > 0) {\n parts.push(summarizeArguments(args));\n }\n }\n return parts.join(\" \");\n })();\n\n return {\n usage,\n description,\n persistentOptions,\n options,\n subcommands,\n };\n}\n\nexport function formatHelpSections(sections: HelpSections): string {\n const parts = [];\n\n const indent = \" \";\n\n if (sections.didYouMean) {\n parts.push(` Did you mean '${sections.didYouMean}'?`);\n }\n\n if (sections.description) {\n parts.push(dedent(sections.description));\n }\n\n if (sections.usage) {\n parts.push(`Usage:\\n${indent}${sections.usage}`);\n }\n\n const longestOptionName = Math.max(\n 0,\n ...sections.options.map(([name]) => name.length),\n ...sections.persistentOptions.map(([name]) => name.length),\n );\n const minSpacingBetweenNameAndDesc = 2;\n\n const formatOptions = (options: [string, string][]) => {\n const lines = [];\n const newline = indent + \" \".repeat(longestOptionName + minSpacingBetweenNameAndDesc);\n for (const [name, desc] of options) {\n const spaces = \" \".repeat(longestOptionName - name.length + minSpacingBetweenNameAndDesc);\n const [head, ...tail] = desc.split(\"\\n\");\n const description = [head, ...tail.map((line) => newline + line)].join(\"\\n\");\n lines.push(`${indent}${name}${spaces}${description}`);\n }\n return lines;\n };\n\n if (sections.subcommands.length > 0) {\n const lines = [\"Commands:\"];\n const longestName = Math.max(...sections.subcommands.map(([name]) => name.length));\n const newline = indent + \" \".repeat(longestName + minSpacingBetweenNameAndDesc);\n for (const [name, desc] of sections.subcommands) {\n const spaces = \" \".repeat(longestName - name.length + minSpacingBetweenNameAndDesc);\n const [head, ...tail] = desc.split(\"\\n\\n\")[0].split(\"\\n\");\n const description = [head, ...tail.map((line) => newline + line)].join(\"\\n\");\n lines.push(`${indent}${name}${spaces}${description}`);\n }\n parts.push(lines.join(\"\\n\"));\n }\n\n if (sections.options.length > 0) {\n const lines = [\"Flags:\", ...formatOptions(sections.options)];\n parts.push(lines.join(\"\\n\"));\n }\n\n if (sections.persistentOptions.length > 0) {\n const lines = [\"Global flags:\", ...formatOptions(sections.persistentOptions)];\n parts.push(lines.join(\"\\n\"));\n }\n return parts.join(\"\\n\\n\") + \"\\n\";\n}\n\nexport function getLongestString(strings: NonEmptyArray<string>): string {\n let longest = strings[0];\n for (let i = 1; i < strings.length; i++) {\n const string = strings[i];\n if (string.length > longest.length) {\n longest = string;\n }\n }\n return longest;\n}\n\nexport function optionToString(option: Option): string {\n const name = makeArray1(option.name)\n .sort((a, b) => a.length - b.length)\n .join(\", \");\n\n const optionArgs = makeArray(option.args);\n\n if (optionArgs.length === 0) {\n return name;\n }\n\n if (option.requiresSeparator) {\n const separator = option.requiresSeparator === true ? \"=\" : option.requiresSeparator;\n if (optionArgs[0].isOptional) {\n return `${name}[${separator}${optionArgs[0].name || \"argument\"}]`;\n }\n return `${name}${separator}<${optionArgs[0].name || \"argument\"}>`;\n }\n return `${name} ${summarizeArguments(optionArgs)}`;\n}\n\nexport function summarizeArguments(args: Arg[]) {\n return args.map((arg) => argToString(arg)).join(\" \");\n}\n\nexport function argToString(arg: Arg): string {\n const name = arg.name || \"argument\";\n let lhs = \"<\";\n let rhs = \">\";\n let suffix = \"\";\n if (arg.isOptional) {\n lhs = \"[\";\n rhs = \"]\";\n }\n if (arg.isVariadic) {\n suffix = \"...\";\n }\n return `${lhs}${name}${rhs}${suffix}`;\n}\n","import type { Action, CommandPath, Option, Spec, Subcommand } from \"./types.js\";\nimport { asArray, getMaxArgs, getMinArgs } from \"./util.js\";\nimport {\n InvalidOptionArg,\n MissingRequiredOption,\n ParseError,\n TooFewArguments,\n TooFewOptionArguments,\n TooManyArguments,\n UnknownOption,\n} from \"./errors.js\";\nimport type { ErrorContext } from \"./errors.js\";\nimport { usage as builtinUsageAction } from \"./help.js\";\n\nexport interface ParseResult {\n args: string[];\n argSeparatorIndex: number;\n options: Map<string, string[]>;\n path: CommandPath;\n actions: Action[];\n optionActions: Action[];\n}\n\n/** Everything {@link scan} learns about a command line. */\nexport interface ScanResult extends ParseResult {\n /** Every use of an option, in order. */\n seenOptions: Option[];\n /** Non-persistent options of the final command, in definition order. */\n localOptions: Option[];\n /**\n * Persistent options from every command on the path, in definition order.\n * A later option shadows an earlier one with the same name.\n */\n persistentOptions: Option[];\n /** The option that can still take a separate value, and how many it has. */\n openOption: { option: Option; valueCount: number } | null;\n}\n\nexport { getMaxArgs, getMinArgs };\n\nfunction hasName(names: string | readonly string[], name: string): boolean {\n return typeof names === \"string\" ? names === name : names.includes(name);\n}\n\n/**\n * Find the option `name` refers to. Local options win over persistent ones, and\n * within each list a later definition wins over an earlier one.\n */\nfunction findOption(local: readonly Option[], persistent: readonly Option[], name: string) {\n for (let i = local.length - 1; i >= 0; i--) {\n if (hasName(local[i].name, name)) return local[i];\n }\n for (let i = persistent.length - 1; i >= 0; i--) {\n if (hasName(persistent[i].name, name)) return persistent[i];\n }\n return null;\n}\n\n/** Every name that's valid as an option here, for \"did you mean\" suggestions. */\nfunction optionNames(local: readonly Option[], persistent: readonly Option[]): string[] {\n const names: string[] = [];\n for (const options of [local, persistent]) {\n const seen = new Set<string>();\n for (const option of options) {\n for (const name of asArray(option.name)) {\n if (!seen.has(name)) {\n seen.add(name);\n names.push(name);\n }\n }\n }\n }\n return names;\n}\n\n/**\n * Read a command line against a spec in one pass.\n *\n * This is the only code that decides what each input token is. With `strict`,\n * it throws on the first problem, which is what {@link parse} needs. Without\n * it, it never throws: it skips whatever is invalid and keeps going, so\n * completion can still read a line that's wrong at the moment.\n *\n * This runs once per process, so it's written for a cold start: one loop, few\n * helper functions and plain arrays, because every extra function is compiled\n * the first time it runs.\n */\nexport function scan(input: readonly string[], spec: Spec, strict: boolean): ScanResult {\n const path: [Spec, ...Subcommand[]] = [spec];\n const actions: Action[] = [];\n const optionActions: Action[] = [];\n const args: string[] = [];\n const options: Map<string, string[]> = new Map();\n const seenOptions: Option[] = [];\n let argSeparatorIndex = -1;\n\n // What the current command allows.\n let local: Option[] = [];\n const persistent: Option[] = [];\n const localRequired: Option[] = [];\n const persistentRequired: Option[] = [];\n let subcommands: readonly Subcommand[] | undefined;\n let commandArgsMin = 0;\n let commandArgsMax = 0;\n let separators: readonly string[] = [\"=\"];\n let posixCompliantOptions = true;\n let subcommandsMatchUniquePrefix = false;\n let optionsMustPrecedeArguments = false;\n let hasFoundArg = false;\n\n // The last option used, and how many more separate tokens it can take as\n // values. While it has room, a token that isn't an option or `--` becomes its\n // value. A subcommand's exact name ends it unless a value is required.\n let openOption: Option | null = null;\n let openOptionName = \"\";\n let valueCount = 0;\n let valueMin = 0;\n let separateValueMax = 0;\n\n // The values of the last option, checked against its arity when it ends.\n // Unlike the counts above, this includes values attached with a separator.\n // A repeatable option keeps adding to the same array, so this use's values\n // start at `valuesStart`.\n let values: string[] | null = null;\n let valuesStart = 0;\n let valuesMin = 0;\n let valuesMax = 0;\n let requiredSeparator: string | boolean = false;\n\n // How many times each repeatable option has been used, keyed by the array\n // its names share in `options`.\n const repeatCounts: Map<string[], number> = new Map();\n\n const ctx = (): ErrorContext => ({ path });\n\n // Make `command` the current command. Its non-persistent options replace the\n // previous command's, and its persistent options are added to the inherited ones.\n const enterCommand = (command: Spec | Subcommand) => {\n local = [];\n // The previous command's options aren't valid here, so neither are its\n // required ones.\n localRequired.length = 0;\n if (command.options) {\n for (const option of command.options) {\n if (option.isPersistent) {\n persistent.push(option);\n if (option.isRequired) persistentRequired.push(option);\n } else {\n local.push(option);\n if (option.isRequired) localRequired.push(option);\n }\n }\n }\n subcommands = command.subcommands;\n commandArgsMin = getMinArgs(command.args);\n commandArgsMax = getMaxArgs(command.args);\n if (command.action) {\n actions.push(command.action);\n } else if (command.requiresSubcommand) {\n actions.push(builtinUsageAction);\n }\n const directives = command.parserDirectives;\n if (directives) {\n if (directives.optionArgSeparators) {\n separators = asArray(directives.optionArgSeparators);\n }\n // A subcommand inherits each directive until it sets its own.\n if (typeof directives.subcommandsMatchUniquePrefix === \"boolean\") {\n subcommandsMatchUniquePrefix = directives.subcommandsMatchUniquePrefix;\n }\n if (typeof directives.optionsMustPrecedeArguments === \"boolean\") {\n optionsMustPrecedeArguments = directives.optionsMustPrecedeArguments;\n }\n if (typeof directives.flagsArePosixNoncompliant === \"boolean\") {\n posixCompliantOptions = !directives.flagsArePosixNoncompliant;\n }\n }\n };\n\n // Every token except an option's value, or an unknown option, ends the\n // previous option.\n const endOption = () => {\n if (strict && values && values.length - valuesStart < valuesMin) {\n throw new TooFewOptionArguments(valuesMin, valuesMax, ctx());\n }\n values = null;\n };\n\n const useOption = (option: Option, name: string) => {\n endOption();\n openOption = option;\n openOptionName = name;\n valueCount = 0;\n valueMin = getMinArgs(option.args);\n // Options that require a separator only take attached values.\n separateValueMax = option.requiresSeparator ? 0 : getMaxArgs(option.args);\n seenOptions.push(option);\n if (option.action) optionActions.push(option.action);\n const names = asArray(option.name);\n\n let optionValues: string[];\n if (option.isRepeatable) {\n // A repeatable option collects the values from every use. Without\n // arguments, each use adds an empty string, so the values count the uses.\n const maxRepeat = option.isRepeatable === true ? Infinity : option.isRepeatable;\n // The count carries over from a parent's identical option. A subcommand\n // option with a name of its own keeps a separate count.\n const existing = options.get(names[0]);\n let isSharedCount = true;\n for (const other of names) {\n if (options.get(other) !== existing) isSharedCount = false;\n }\n let uses = isSharedCount ? existing : undefined;\n if (!uses) {\n uses = [];\n for (const other of names) options.set(other, uses);\n }\n const count = repeatCounts.get(uses) ?? uses.length;\n if (strict && count >= maxRepeat) {\n throw new ParseError(ctx(), \"Too many repetitions\");\n }\n repeatCounts.set(uses, count + 1);\n if (!option.args) {\n uses.push(\"\");\n return;\n }\n optionValues = uses;\n } else {\n // The last use of an option wins, so a user can override a flag that a\n // shell alias already sets.\n optionValues = [];\n for (const other of names) options.set(other, optionValues);\n }\n\n valuesMin = valueMin;\n valuesMax = getMaxArgs(option.args);\n requiredSeparator = option.requiresSeparator ?? false;\n if (valuesMax > 0) {\n values = optionValues;\n valuesStart = optionValues.length;\n }\n };\n\n const addValue = (index: number, start: number, end: number, value: string, separator: string) => {\n valueCount += 1;\n if (!values) {\n if (strict) {\n throw new InvalidOptionArg({ option: openOptionName, arg: value, index, start, end }, ctx());\n }\n return;\n }\n if (strict && typeof requiredSeparator === \"string\" && separator !== requiredSeparator) {\n throw new ParseError(\n ctx(),\n `Incorrect separator, use '${requiredSeparator}' instead of '${separator}'`,\n );\n }\n values.push(value);\n };\n\n const addArg = (index: number, value: string) => {\n endOption();\n // If the final command requires a subcommand, providing too many arguments\n // is allowed because the user has made a typo (they were intending to use\n // a subcommand)\n if (strict && !path[path.length - 1].requiresSubcommand && args.length >= commandArgsMax) {\n throw new TooManyArguments({ value, index }, ctx());\n }\n args.push(value);\n };\n\n enterCommand(spec);\n\n tokens: for (let index = 0; index < input.length; index++) {\n const token = input[index];\n\n // \"--\" as a token disables option & subcommand parsing, so this needs\n // to be checked first.\n if (token === \"--\") {\n endOption();\n if (strict && args.length >= commandArgsMax) {\n throw new ParseError(ctx(), \"Unexpected argument '--', did you mean to use an option instead?\");\n }\n argSeparatorIndex = args.length;\n openOption = null;\n valueCount = valueMin = separateValueMax = 0;\n for (index += 1; index < input.length; index++) {\n addArg(index, input[index]);\n }\n break tokens;\n }\n\n const hasRoomForValue = valueCount < separateValueMax;\n\n // 1. Try to parse as a subcommand\n // A required or variadic option value takes priority over a subcommand.\n const valueIsRequired = valueCount < valueMin || (hasRoomForValue && separateValueMax === Infinity);\n if (!hasFoundArg && !valueIsRequired && subcommands) {\n // A literal match always wins. A short optional value could be a prefix\n // of a subcommand's name, so only an exact match can end an option that\n // still has room. An empty token is a prefix of every name, so it never\n // matches by prefix.\n const allowPrefix = subcommandsMatchUniquePrefix && !hasRoomForValue && token !== \"\";\n let command: Subcommand | null = null;\n let prefixCount = 0;\n commands: for (const candidate of subcommands) {\n const names = candidate.name;\n if (typeof names === \"string\") {\n if (names === token) {\n command = candidate;\n prefixCount = -1;\n break commands;\n }\n if (allowPrefix && names.startsWith(token)) {\n command = candidate;\n prefixCount += 1;\n }\n continue commands;\n }\n // Count each command at most once, however many of its names match.\n let prefixMatched = false;\n for (const name of names) {\n if (name === token) {\n command = candidate;\n prefixCount = -1;\n break commands;\n }\n if (allowPrefix && !prefixMatched && name.startsWith(token)) {\n prefixMatched = true;\n command = candidate;\n prefixCount += 1;\n }\n }\n }\n // -1 is an exact match. Otherwise only a unique prefix match counts.\n if (command && (prefixCount === -1 || prefixCount === 1)) {\n endOption();\n openOption = null;\n valueCount = valueMin = separateValueMax = 0;\n path.push(command);\n enterCommand(command);\n continue tokens;\n }\n }\n\n // 2. Try to parse as an option\n if (!(optionsMustPrecedeArguments && hasFoundArg)) {\n const first = token.charCodeAt(0);\n const isDoubleDash = first === 45 && token.charCodeAt(1) === 45;\n if (\n posixCompliantOptions &&\n token.length > 1 &&\n (first === 45 /* - */ || first === 43) /* + */ &&\n !isDoubleDash\n ) {\n const leadingChar = token[0];\n\n // 2.a. Parse as a single dash or plus with an arg\n // Try dash and plus options first if:\n // - the options exist\n // - the options take args\n // - the first non-leading character isn't an option\n const dashOption = findOption(local, persistent, leadingChar);\n if (dashOption?.args && !findOption(local, persistent, token.slice(0, 2))) {\n useOption(dashOption, leadingChar);\n addValue(index, 1, token.length, token.slice(1), \"\");\n continue tokens;\n }\n\n // 2.b. Parse as a chainable short option\n // If we fell through, the option wasn't `-` or `+`\n for (let char = 1; char < token.length; char++) {\n const optionName = leadingChar + token[char];\n const option = findOption(local, persistent, optionName);\n if (!option) {\n // An open option takes anything unknown as a value, like `-5`.\n if (char === 1 && valueCount < separateValueMax) {\n addValue(index, 0, token.length, token, \"\");\n continue tokens;\n }\n if (strict) {\n throw new UnknownOption(\n {\n option: optionName,\n validOptions: optionNames(local, persistent),\n index,\n start: char,\n end: char + 1,\n },\n ctx(),\n );\n }\n continue;\n }\n\n useOption(option, optionName);\n\n if (option.args && char < token.length - 1) {\n const remainingChars = token.slice(char + 1);\n let sep = \"\";\n for (const candidate of separators) {\n if (remainingChars.startsWith(candidate)) {\n sep = candidate;\n break;\n }\n }\n const argStart = char + sep.length + 1;\n addValue(index, argStart, token.length, token.slice(argStart), sep);\n break;\n }\n }\n continue tokens;\n }\n\n if (!posixCompliantOptions || (token.length > 2 && isDoubleDash)) {\n // 2.c. Parse as a long option or posix-noncompliant option\n\n // POSIX-noncompliant option means that there's nothing \"option-like\".\n // Any token can be an option if it matches an option name, and if it's\n // not an option then it's just a regular argument.\n\n // The token splits at the separator that appears first in it, so the\n // value can contain the other separators. When two separators start\n // at the same place, the longer one wins.\n let foundSep = \"\";\n let foundSepIndex = -1;\n for (const sep of separators) {\n const at = token.indexOf(sep);\n if (at === -1) continue;\n if (\n foundSepIndex === -1 ||\n at < foundSepIndex ||\n (at === foundSepIndex && sep.length > foundSep.length)\n ) {\n foundSep = sep;\n foundSepIndex = at;\n }\n }\n\n const optionName = foundSep ? token.slice(0, foundSepIndex) : token;\n const option = findOption(local, persistent, optionName);\n if (option) {\n useOption(option, optionName);\n if (foundSep) {\n const valueStart = foundSepIndex + foundSep.length;\n addValue(index, valueStart, token.length, token.slice(valueStart), foundSep);\n }\n continue tokens;\n }\n if (posixCompliantOptions) {\n if (valueCount < separateValueMax) {\n addValue(index, 0, token.length, token, \"\");\n continue tokens;\n }\n // The option is unknown and looks like a posix-compliant option, so\n // it's an unknown option instead of an arg.\n if (strict) {\n throw new UnknownOption(\n {\n option: optionName,\n validOptions: optionNames(local, persistent),\n index,\n start: 0,\n end: optionName.length,\n },\n ctx(),\n );\n }\n continue tokens;\n }\n // Posix noncompliant options fall through to be arguments\n }\n }\n\n if (valueCount < separateValueMax) {\n addValue(index, 0, token.length, token, \"\");\n continue tokens;\n }\n hasFoundArg = true;\n addArg(index, token);\n }\n\n if (strict) {\n const hasOptionAction = optionActions.length > 0;\n if (!hasOptionAction && args.length < commandArgsMin) {\n throw new TooFewArguments(commandArgsMin, commandArgsMax, ctx());\n }\n endOption();\n for (const option of seenOptions) {\n if (!option.dependsOn) continue;\n for (const name of option.dependsOn) {\n if (!options.has(name)) {\n throw new ParseError(\n ctx(),\n `${asArray(option.name).join(\"/\")} requires ${name}, add it to fix this error`,\n );\n }\n }\n }\n for (const option of seenOptions) {\n if (!option.exclusiveOn) continue;\n for (const name of option.exclusiveOn) {\n if (options.has(name)) {\n throw new ParseError(\n ctx(),\n `${asArray(option.name).join(\"/\")} can't be used together with ${name}`,\n );\n }\n }\n }\n if (!hasOptionAction) {\n for (const required of [localRequired, persistentRequired]) {\n for (const option of required) {\n for (const name of asArray(option.name)) {\n if (!options.has(name)) {\n throw new MissingRequiredOption(name, ctx());\n }\n }\n }\n }\n }\n }\n\n // TS narrows `openOption` to null because it's only assigned in closures.\n const open = openOption as Option | null;\n return {\n path,\n actions,\n optionActions,\n args,\n argSeparatorIndex,\n options,\n seenOptions,\n localOptions: local,\n persistentOptions: persistent,\n openOption: open && valueCount < separateValueMax ? { option: open, valueCount } : null,\n };\n}\n\n/**\n * Parse the input tokens using the given CLI spec.\n *\n * This returns a `ParseResult`, which contains the array of\n * subcommands used, the provided options, and the arguments.\n *\n * If parsing fails, this function throws.\n *\n * This function is exposed to make it easier to build a custom runner.\n */\nexport function parse(input: readonly string[], spec: Spec): ParseResult {\n return scan(input, spec, true);\n}\n","/**\n * Shell completion.\n *\n * The `completion` subcommand prints a short script for a supported shell. On\n * every Tab, that script runs the CLI's hidden `completion complete` command\n * with the command line typed so far. The CLI then works out the candidates\n * with the parser's own `scan`, so completion always matches what the parser\n * accepts at that position: subcommands, options with their\n * relationship rules, and argument values from `template`, `suggestions` and\n * `generators`.\n *\n * @module\n */\n\nimport type { Arg, Option, Spec, Subcommand, Template } from \"./types.js\";\nimport { asArray, makeArray, print, printActionError } from \"./util.js\";\nimport { scan } from \"./parse.js\";\n\n/** Shells that {@link getCompletion} can generate scripts for. */\nexport type Shell = \"bash\" | \"zsh\" | \"fish\";\n\nexport const SHELLS: readonly Shell[] = [\"bash\", \"zsh\", \"fish\"];\n\nfunction isShell(value: string): value is Shell {\n return (SHELLS as readonly string[]).includes(value);\n}\n\nconst firstLine = (description: string | undefined): string =>\n description ? description.split(\"\\n\", 1)[0].trim() : \"\";\n\n/** Turn an arbitrary name into a safe shell identifier fragment. */\nconst sanitize = (value: string): string => value.replace(/[^A-Za-z0-9]+/g, \"_\");\n\n/** Single-quote a string for bash/zsh. */\nfunction shQuote(value: string): string {\n return `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n}\n\n/** Single-quote a string for fish (only `\\` and `'` are special). */\nfunction fishQuote(value: string): string {\n return `'${value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"'\", \"\\\\'\")}'`;\n}\n\n// Runtime resolver {{{\n\n/** A single completion candidate. */\ninterface Candidate {\n value: string;\n description?: string;\n}\n\n/** The completion-relevant state of a partial command line. */\ninterface CompletionState {\n /** Commands from the root to the current one. */\n path: Subcommand[];\n current: Subcommand;\n /** Options usable at the current command (own + inherited persistent). */\n availableOptions: Option[];\n /** A option still expecting a separate-token value, or null. */\n pending: { option: Option; argIndex: number } | null;\n /** Positional args already consumed by the current command. */\n positionalIndex: number;\n /** Option names already present on the line. */\n presentNames: Set<string>;\n /** Times each option object has appeared. */\n countByOption: Map<Option, number>;\n /** A `--` separator was seen; only positionals follow. */\n forceArgs: boolean;\n /** A positional has been consumed by the current command. */\n sawPositional: boolean;\n}\n\n/**\n * Read the line typed so far with the parser in lenient mode, which skips\n * anything invalid instead of throwing.\n */\nfunction readLine(spec: Spec, before: readonly string[]): CompletionState {\n const scanned = scan(before, spec, false);\n const path = scanned.path as unknown as Subcommand[];\n\n // Positionals can't come before a subcommand, so every arg belongs to the\n // current command.\n const presentNames = new Set<string>();\n const countByOption = new Map<Option, number>();\n for (const option of scanned.seenOptions) {\n for (const name of makeArray(option.name)) presentNames.add(name);\n countByOption.set(option, (countByOption.get(option) ?? 0) + 1);\n }\n\n const open = scanned.openOption;\n const pending = open ? { option: open.option, argIndex: open.valueCount } : null;\n\n // An option is available if one of its names still refers to it: a later\n // option with the same name shadows an earlier one.\n const availableOptions: Option[] = [];\n const seen = new Set<Option>();\n for (const list of [scanned.localOptions, scanned.persistentOptions]) {\n const byName = new Map<string, Option>();\n for (const option of list) {\n for (const name of makeArray(option.name)) byName.set(name, option);\n }\n for (const option of byName.values()) {\n if (!seen.has(option)) {\n seen.add(option);\n availableOptions.push(option);\n }\n }\n }\n\n return {\n path,\n current: path[path.length - 1],\n availableOptions,\n pending,\n positionalIndex: scanned.args.length,\n presentNames,\n countByOption,\n forceArgs: scanned.argSeparatorIndex !== -1,\n sawPositional: scanned.args.length > 0,\n };\n}\n\n/** A directive's value in effect (the deepest command that sets it). */\nfunction directiveOnPath(\n path: readonly Subcommand[],\n key: \"optionsMustPrecedeArguments\" | \"flagsArePosixNoncompliant\",\n): boolean {\n for (let i = path.length - 1; i >= 0; i--) {\n const value = path[i].parserDirectives?.[key];\n if (typeof value === \"boolean\") return value;\n }\n return false;\n}\n\n/** The option-arg separators in effect (the deepest command that sets them). */\nfunction separatorsOnPath(path: readonly Subcommand[]): string[] {\n let separators = [\"=\"];\n for (const command of path) {\n const configured = command.parserDirectives?.optionArgSeparators;\n if (configured) separators = makeArray(configured);\n }\n return separators;\n}\n\n/** Enumerate filesystem entries matching `partial` for a path template. */\nasync function enumeratePaths(partial: string, template: Template): Promise<Candidate[]> {\n // Imported through a variable so the Node-free `src` build doesn't need\n // @types/node; this only runs inside the (Node-only) completion runtime.\n const specifier = \"node:fs\";\n const { readdirSync } = (await import(specifier)) as {\n readdirSync(path: string, options: { withFileTypes: true }): { name: string; isDirectory(): boolean }[];\n };\n const slash = partial.lastIndexOf(\"/\");\n const dir = slash >= 0 ? partial.slice(0, slash + 1) : \"\";\n const base = slash >= 0 ? partial.slice(slash + 1) : partial;\n const foldersOnly = template === \"folders\";\n let entries: { name: string; isDirectory(): boolean }[];\n try {\n entries = readdirSync(dir || \".\", { withFileTypes: true });\n } catch {\n return [];\n }\n const candidates: Candidate[] = [];\n for (const entry of entries as { name: string; isDirectory(): boolean }[]) {\n if (!entry.name.startsWith(base)) continue;\n const isDir = entry.isDirectory();\n if (foldersOnly && !isDir) continue;\n candidates.push({ value: `${dir}${entry.name}${isDir ? \"/\" : \"\"}` });\n }\n return candidates;\n}\n\n/** All candidate values for a single argument (suggestions/generators/template). */\nasync function argValues(arg: Arg, tokens: string[], partial: string): Promise<Candidate[]> {\n const candidates: Candidate[] = [];\n\n for (const suggestion of arg.suggestions ?? []) {\n candidates.push(\n typeof suggestion === \"string\"\n ? { value: suggestion }\n : { value: makeArray(suggestion.name)[0], description: suggestion.description },\n );\n }\n\n for (const generator of makeArray(arg.generators)) {\n if (!generator.custom) continue;\n const produced = await generator.custom([...tokens, partial]);\n for (const suggestion of produced) {\n candidates.push(\n typeof suggestion === \"string\"\n ? { value: suggestion }\n : { value: makeArray(suggestion.name)[0], description: suggestion.description },\n );\n }\n }\n\n if (arg.template) {\n candidates.push(...(await enumeratePaths(partial, arg.template)));\n }\n\n return candidates;\n}\n\n/** Pick the argument at an index, reusing a final variadic argument. */\nfunction argAt(args: readonly Arg[], index: number): Arg | undefined {\n if (args.length === 0) return undefined;\n if (index < args.length) return args[index];\n const last = args[args.length - 1];\n return last?.isVariadic ? last : undefined;\n}\n\n/** Pick the argument being completed at a positional index (honors variadic). */\nfunction positionalArg(command: Subcommand, index: number): Arg | undefined {\n return argAt(asArray(command.args) as readonly Arg[], index);\n}\n\n/** Decide which kinds of candidate the word being completed can use. */\nfunction wantedCandidates(state: CompletionState, req: CompletionRequest) {\n const posixNoncompliant = directiveOnPath(state.path, \"flagsArePosixNoncompliant\");\n const partialIsOption = !posixNoncompliant && (req.partial.startsWith(\"-\") || req.partial.startsWith(\"+\"));\n // When gating, a dashed word completes options only; everything else completes\n // commands/positionals. Posix-noncompliant options have no dash, so they're\n // exempt and always offered alongside the other candidates.\n return {\n wantValues: !(req.gateOptions && partialIsOption),\n wantOptions: !req.gateOptions || partialIsOption || posixNoncompliant,\n };\n}\n\n/** Inputs for the runtime completion resolver. */\nexport interface CompletionRequest {\n spec: Spec;\n /** Tokens after the program name, excluding the word being completed. */\n before: readonly string[];\n /** The word being completed. */\n partial: string;\n /** Only offer options once the word being completed starts with a dash. */\n gateOptions?: boolean;\n}\n\n/**\n * Resolve completion candidates for a partial command line, reading it with the\n * parser's `scan` for context. Dispatches between completing a option's value and\n * completing a fresh token (subcommand / positional / option).\n */\nexport async function completeRuntime(req: CompletionRequest): Promise<Candidate[]> {\n const state = readLine(req.spec, req.before);\n const separators = separatorsOnPath(state.path);\n\n const optionValue = await resolveOptionValue(state, req, separators);\n if (optionValue) return optionValue;\n\n return freshTokenCandidates(state, req, separators);\n}\n\n/**\n * Candidates when the word being completed is a option's value — either attached\n * (`--option=value`) or the separate token after a option that expects one. Returns\n * null when no option value is being completed.\n */\nasync function resolveOptionValue(\n state: CompletionState,\n req: CompletionRequest,\n separators: string[],\n): Promise<Candidate[] | null> {\n const tokens = [...req.before];\n\n // `--option<sep>value`: the partial already carries a separator.\n for (const separator of separators) {\n const at = req.partial.indexOf(separator);\n if (at <= 0) continue;\n const optionName = req.partial.slice(0, at);\n const option = state.availableOptions.find((candidate) => makeArray(candidate.name).includes(optionName));\n const arg = option && (asArray(option.args) as Arg[])[0];\n if (option && arg) {\n const valuePrefix = req.partial.slice(at + separator.length);\n const values = await argValues(arg, tokens, valuePrefix);\n return values.map((candidate) => ({\n value: `${optionName}${separator}${candidate.value}`,\n description: candidate.description,\n }));\n }\n }\n\n // The separate-token value of a option that expects one.\n if (state.pending) {\n const { option, argIndex } = state.pending;\n const args = asArray(option.args) as readonly Arg[];\n const arg = argAt(args, argIndex);\n if (argIndex < args.length) {\n return arg ? argValues(arg, tokens, req.partial) : [];\n }\n // Past its declared args, a variadic option takes another value or gives\n // way to the next option.\n const { wantValues, wantOptions } = wantedCandidates(state, req);\n return [\n ...(arg && wantValues ? await argValues(arg, tokens, req.partial) : []),\n ...(wantOptions ? allowedOptionCandidates(state, separators) : []),\n ];\n }\n\n return null;\n}\n\n/** Candidates when completing a fresh token: subcommand / positional / option. */\nasync function freshTokenCandidates(\n state: CompletionState,\n req: CompletionRequest,\n separators: string[],\n): Promise<Candidate[]> {\n const candidates: Candidate[] = [];\n const tokens = [...req.before];\n\n const { wantValues, wantOptions } = wantedCandidates(state, req);\n\n if (wantValues) {\n const positional = positionalArg(state.current, state.positionalIndex);\n if (positional) {\n candidates.push(...(await argValues(positional, tokens, req.partial)));\n }\n // After `--`, only positionals are valid.\n if (state.forceArgs) return candidates;\n\n // Subcommands — only while the parser would still match one.\n if (!state.sawPositional) {\n for (const sub of state.current.subcommands ?? []) {\n if (sub.hidden) continue;\n const description = firstLine(sub.description);\n for (const token of makeArray(sub.name)) {\n candidates.push({ value: token, description });\n }\n }\n }\n } else if (state.forceArgs) {\n // A dashed token after `--` is a literal argument, not a option.\n return candidates;\n }\n\n if (wantOptions) {\n candidates.push(...allowedOptionCandidates(state, separators));\n }\n\n return candidates;\n}\n\n/** Option candidates, unless options must precede arguments and one was seen. */\nfunction allowedOptionCandidates(state: CompletionState, separators: string[]): Candidate[] {\n const optionsBlocked = state.sawPositional && directiveOnPath(state.path, \"optionsMustPrecedeArguments\");\n return optionsBlocked ? [] : optionCandidates(state, separators);\n}\n\n/** Eligible option candidates after relationship filtering. */\nfunction optionCandidates(state: CompletionState, separators: string[]): Candidate[] {\n const required: Candidate[] = [];\n const optional: Candidate[] = [];\n\n for (const option of state.availableOptions) {\n if (option.hidden) continue;\n\n // Repeatable limits: drop a option that can't appear again.\n const count = state.countByOption.get(option) ?? 0;\n if (count > 0) {\n if (!option.isRepeatable) continue;\n if (typeof option.isRepeatable === \"number\" && count >= option.isRepeatable) {\n continue;\n }\n }\n\n // Mutual exclusion, both directions.\n if (option.exclusiveOn?.some((name) => state.presentNames.has(name))) continue;\n const conflicts = state.availableOptions.some(\n (other) =>\n other !== option &&\n makeArray(other.name).some((name) => state.presentNames.has(name)) &&\n other.exclusiveOn?.some((name) => makeArray(option.name).includes(name)),\n );\n if (conflicts) continue;\n\n let description = firstLine(option.description);\n if (option.dependsOn) {\n const needs = option.dependsOn.join(\", \");\n description = description ? `${description} (requires ${needs})` : `requires ${needs}`;\n }\n if (option.isRequired) {\n description = description ? `${description} [required]` : \"[required]\";\n }\n\n // requiresSeparator options can only take an attached value, so offer the\n // separator form so the next Tab completes the value.\n const sep =\n option.requiresSeparator === true\n ? separators[0]\n : typeof option.requiresSeparator === \"string\"\n ? option.requiresSeparator\n : undefined;\n\n const bucket = option.isRequired ? required : optional;\n for (const token of makeArray(option.name)) {\n bucket.push({ value: sep ? `${token}${sep}` : token, description });\n }\n }\n\n return [...required, ...optional];\n}\n\n/**\n * Render the thin shim that forwards the line to `completion complete`. The\n * binary is invoked as typed (so `./pack` works) and guarded so a missing\n * command degrades to no completion instead of an error.\n */\nfunction renderRuntimeShim(spec: Spec, shell: Shell): string {\n const id = sanitize(spec.name);\n const name = spec.name;\n if (shell === \"bash\") {\n return [\n `_${id}_complete() {`,\n ` local bin=\"\\${COMP_WORDS[0]}\"`,\n ` command -v \"$bin\" >/dev/null 2>&1 || return`,\n ` local cur=\"\\${COMP_WORDS[COMP_CWORD]}\"`,\n ` local out`,\n ` out=\"$(\"$bin\" completion complete --gate-options -- \"\\${COMP_WORDS[@]:1:COMP_CWORD-1}\" \"$cur\" 2>/dev/null | cut -f1)\"`,\n ` local IFS=$'\\\\n'`,\n ` COMPREPLY=( $(compgen -W \"$out\" -- \"$cur\") )`,\n `}`,\n `complete -F _${id}_complete ${shQuote(name)}`,\n ].join(\"\\n\");\n }\n if (shell === \"zsh\") {\n return [\n `#compdef ${name}`,\n `_${id}_complete() {`,\n ` local bin=\"$words[1]\"`,\n ` command -v \"$bin\" >/dev/null 2>&1 || return`,\n ` local -a lines`,\n ` lines=( \"\\${(@f)$(\"$bin\" completion complete -- \"\\${words[2,CURRENT-1]}\" \"\\${words[CURRENT]}\" 2>/dev/null)}\" )`,\n ` local -a disp`,\n ` local line`,\n ` for line in $lines; do disp+=( \"\\${line//$'\\\\t'/:}\" ); done`,\n ` _describe -t values ${shQuote(name)} disp`,\n `}`,\n `_${id}_complete \"$@\"`,\n ].join(\"\\n\");\n }\n // fish\n return [\n `function __${id}_complete`,\n ` set -l toks (commandline -opc)`,\n ` set -l cur (commandline -ct)`,\n ` set -l bin $toks[1]`,\n ` command -q -- $bin; or test -x \"$bin\"; or return`,\n ` $bin completion complete --gate-options -- $toks[2..-1] $cur 2>/dev/null`,\n `end`,\n `complete -c ${fishQuote(name)} -f -a '(__${id}_complete)'`,\n ].join(\"\\n\");\n}\n\n// }}}\n\n/** Generate a completion script for `shell` from a CLI spec. */\nexport function getCompletion(spec: Spec, shell: Shell): string {\n return renderRuntimeShim(spec, shell);\n}\n\n// Completion commands {{{\n\n/**\n * Hidden machine-facing subcommand the `--runtime` shim calls on every Tab.\n * The tokens after `--` are the command line; the last is the word being\n * completed. Prints `value\\tdescription` lines.\n */\nconst completeCommand: Subcommand = {\n name: \"complete\",\n description: \"Resolve completion candidates for a partial command line\",\n hidden: true,\n options: [\n {\n name: \"--gate-options\",\n description: \"Only suggest options after a leading dash\",\n },\n ],\n args: { name: \"tokens\", isVariadic: true, isOptional: true },\n async action({ path, args, options }) {\n const spec = path[0] as Spec;\n const partial = args.length > 0 ? args[args.length - 1] : \"\";\n const before = args.slice(0, -1);\n const candidates = await completeRuntime({\n spec,\n before,\n partial,\n gateOptions: options.has(\"--gate-options\"),\n });\n const lines = candidates.map((candidate) =>\n candidate.description ? `${candidate.value}\\t${candidate.description}` : candidate.value,\n );\n if (lines.length > 0) print(lines.join(\"\\n\"));\n return 0;\n },\n};\n\n// }}}\n\n/** A subcommand that prints a shell completion script for the whole CLI. */\nexport const completion: Subcommand = {\n name: \"completion\",\n description: \"Print a shell completion script\",\n args: {\n name: \"shell\",\n isOptional: true,\n suggestions: SHELLS,\n },\n subcommands: [completeCommand],\n action({ path: [spec], args: [shell], help }) {\n if (shell === undefined) {\n print(`Supported shells: ${SHELLS.join(\", \")}`);\n return 0;\n }\n\n if (!isShell(shell)) {\n printActionError(\n `Unsupported shell '${shell}'\\n\\n${help({\n description: false,\n didYouMean: { input: shell, choices: SHELLS as string[] },\n })}`,\n );\n return 1;\n }\n\n print(getCompletion(spec, shell));\n return 0;\n },\n};\n","import type { ActionInit, Spec } from \"./types.js\";\nimport { getHelp } from \"./help.js\";\nimport { ParseError, UnknownOption } from \"./errors.js\";\nimport { parse } from \"./parse.js\";\nimport { output } from \"./util.js\";\nimport type { ParseResult } from \"./parse.js\";\n\n/**\n * Parse argv and execute the selected action.\n *\n * The final command action runs unless a parsed option has an action. Option\n * actions take precedence so helpers like `--help` can run without satisfying\n * the selected command's required arguments.\n */\nexport async function run(spec: Spec, args: readonly string[] = defaultArgs()): Promise<number> {\n let result: ParseResult;\n\n try {\n result = parse(args, spec);\n } catch (error: unknown) {\n if (error instanceof UnknownOption) {\n const helpMessage = getHelp(error.context.path, {\n description: false,\n didYouMean: {\n input: error.option,\n choices: error.validOptions,\n },\n });\n printError(`${error.message}\\n\\n${helpMessage}`);\n } else if (error instanceof ParseError) {\n printError(`${error.message}\\n\\n${getHelp(error.context.path, { description: false })}`);\n } else {\n printError(`${error}`);\n }\n return 1;\n }\n\n const action = result.optionActions.at(-1) ?? result.actions.at(-1);\n if (!action) {\n return 1;\n }\n\n const options = result.options;\n const actionInit: ActionInit = {\n help: (helpOptions) => getHelp(helpOptions?.path ?? result.path, helpOptions),\n args: result.args,\n path: result.path,\n argSeparatorIndex: result.argSeparatorIndex,\n options: {\n options,\n has: (name) => options.has(name),\n get: (name) => options.get(name)?.[0],\n all: (name) => options.get(name),\n count: (name) => options.get(name)?.length ?? 0,\n },\n };\n\n let exitCode: number | void;\n try {\n const actionResult = action(actionInit);\n exitCode = typeof actionResult === \"object\" ? await actionResult : actionResult;\n } catch (error) {\n printError(error instanceof Error ? error.message : String(error));\n return 1;\n }\n\n return Math.min(Math.max(exitCode ?? 0, 0), 255);\n}\n\n/** Print `Error:` and the given values to stderr, separated by spaces. */\nexport function printError(...strings: unknown[]): void {\n output.write(2, `${[\"Error:\", ...strings].map(String).join(\" \")}\\n`);\n}\n\nfunction defaultArgs(): readonly string[] {\n const maybeProcess = globalThis as typeof globalThis & {\n process?: { argv?: readonly string[] };\n };\n return maybeProcess.process?.argv?.slice(2) ?? [];\n}\n","export type {\n Action,\n ActionInit,\n Arg,\n CommandPath,\n Generator,\n NonEmptyArray,\n Option,\n OptionArgs,\n SingleOrArray,\n SingleOrArrayOrEmpty,\n Spec,\n Subcommand,\n Suggestion,\n Template,\n} from \"./types.js\";\n\nexport { completion } from \"./completion.js\";\nexport type { Shell } from \"./completion.js\";\nexport { help, helpCommand } from \"./help.js\";\nexport { printError, run } from \"./run.js\";\n\nimport { completion } from \"./completion.js\";\nimport { help, helpCommand } from \"./help.js\";\nimport { printError, run } from \"./run.js\";\n\nexport default {\n completion,\n help,\n helpCommand,\n printError,\n run,\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declarative CLI spec types.
|
|
3
|
+
*
|
|
4
|
+
* The schema is intentionally small: define commands, positional args, options,
|
|
5
|
+
* and actions. Runtime values from argv are always strings.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
declare const kind: unique symbol;
|
|
10
|
+
/** An array with at least one value in it. */
|
|
11
|
+
type NonEmptyArray<T> = readonly [T, ...T[]];
|
|
12
|
+
/** A single value, or an array with at least two values. */
|
|
13
|
+
type SingleOrArray<T> = T | readonly [T, T, ...T[]];
|
|
14
|
+
/** A single value, or an array with either zero or at least two values. */
|
|
15
|
+
type SingleOrArrayOrEmpty<T> = T | [] | readonly [T, T, ...T[]];
|
|
16
|
+
/**
|
|
17
|
+
* An action associated with a subcommand or option.
|
|
18
|
+
*
|
|
19
|
+
* Actions can be sync or async. Returning `undefined` is treated as exit code 0.
|
|
20
|
+
*/
|
|
21
|
+
interface Action {
|
|
22
|
+
(init: ActionInit): Promise<number | void> | number | void;
|
|
23
|
+
/**
|
|
24
|
+
* This property never exists. It prevents accidental structural assignment
|
|
25
|
+
* between otherwise compatible exported interfaces.
|
|
26
|
+
*
|
|
27
|
+
* @ignore
|
|
28
|
+
*/
|
|
29
|
+
[kind]?: "Action";
|
|
30
|
+
}
|
|
31
|
+
/** A command path, starting with the root spec. */
|
|
32
|
+
type CommandPath = readonly [Spec, ...Subcommand[]];
|
|
33
|
+
/** Access parsed options. */
|
|
34
|
+
interface OptionArgs {
|
|
35
|
+
/** Escape hatch: the underlying map of option names to values. */
|
|
36
|
+
readonly options: Map<string, string[]>;
|
|
37
|
+
/** Get every argument supplied to a option. */
|
|
38
|
+
all(name: string): string[] | undefined;
|
|
39
|
+
/** Get the first argument supplied to a option. */
|
|
40
|
+
get(name: string): string | undefined;
|
|
41
|
+
/** Check whether a option was supplied. */
|
|
42
|
+
has(name: string): boolean;
|
|
43
|
+
/** Count option values, useful for repeatable options. */
|
|
44
|
+
count(name: string): number;
|
|
45
|
+
}
|
|
46
|
+
/** The data an action receives. */
|
|
47
|
+
interface ActionInit {
|
|
48
|
+
/** Options found for this invocation. */
|
|
49
|
+
options: OptionArgs;
|
|
50
|
+
/** Positional arguments found for the selected command. */
|
|
51
|
+
args: string[];
|
|
52
|
+
/** Commands used leading up to the selected action. */
|
|
53
|
+
path: CommandPath;
|
|
54
|
+
/** Index of the `--` argument separator, or -1 if it was not supplied. */
|
|
55
|
+
argSeparatorIndex: number;
|
|
56
|
+
/** Get help text for the currently executing command. */
|
|
57
|
+
help(config?: {
|
|
58
|
+
/** Include the command description? Default: true. */
|
|
59
|
+
description?: boolean;
|
|
60
|
+
/** Include the usage summary? Default: true. */
|
|
61
|
+
usage?: boolean;
|
|
62
|
+
/** Suggest the closest choice for an incorrect input. */
|
|
63
|
+
didYouMean?: {
|
|
64
|
+
input: string;
|
|
65
|
+
choices: readonly string[];
|
|
66
|
+
};
|
|
67
|
+
/** Alternative command path to render help for. */
|
|
68
|
+
path?: NonEmptyArray<Subcommand>;
|
|
69
|
+
}): string;
|
|
70
|
+
}
|
|
71
|
+
/** A top-level command. */
|
|
72
|
+
interface Spec extends Omit<Subcommand, "name"> {
|
|
73
|
+
/** Name of the CLI. */
|
|
74
|
+
name: string;
|
|
75
|
+
}
|
|
76
|
+
/** A subcommand that can be executed. */
|
|
77
|
+
interface Subcommand {
|
|
78
|
+
/** Name or aliases used for matching. */
|
|
79
|
+
name: SingleOrArray<string>;
|
|
80
|
+
/** Description shown in help. */
|
|
81
|
+
description?: string;
|
|
82
|
+
/** Positional arguments accepted by this command. */
|
|
83
|
+
args?: SingleOrArray<Arg>;
|
|
84
|
+
/** Options accepted by this command. */
|
|
85
|
+
options?: NonEmptyArray<Option>;
|
|
86
|
+
/** Subcommands of this command. */
|
|
87
|
+
subcommands?: NonEmptyArray<Subcommand>;
|
|
88
|
+
/** Direct parser behavior. */
|
|
89
|
+
parserDirectives?: {
|
|
90
|
+
/**
|
|
91
|
+
* Treat option names literally, disabling POSIX short-option chaining and
|
|
92
|
+
* unknown option errors for tokens that look option-like.
|
|
93
|
+
*/
|
|
94
|
+
flagsArePosixNoncompliant?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Once an argument has been found, all following tokens are arguments even
|
|
97
|
+
* if they match options.
|
|
98
|
+
*/
|
|
99
|
+
optionsMustPrecedeArguments?: boolean;
|
|
100
|
+
/** Separators that can attach a option argument to a option token. */
|
|
101
|
+
optionArgSeparators?: SingleOrArrayOrEmpty<string>;
|
|
102
|
+
/** Match subcommands by shortest unique prefix instead of exact name. */
|
|
103
|
+
subcommandsMatchUniquePrefix?: boolean;
|
|
104
|
+
};
|
|
105
|
+
/** Hide this command from help. */
|
|
106
|
+
hidden?: true;
|
|
107
|
+
/** Require a subcommand; without one, print usage. */
|
|
108
|
+
requiresSubcommand?: true;
|
|
109
|
+
/** Action to run when this command is selected. */
|
|
110
|
+
action?: Action;
|
|
111
|
+
/**
|
|
112
|
+
* This property never exists. It prevents accidental structural assignment
|
|
113
|
+
* between options and subcommands.
|
|
114
|
+
*
|
|
115
|
+
* @ignore
|
|
116
|
+
*/
|
|
117
|
+
[kind]?: "Subcommand";
|
|
118
|
+
}
|
|
119
|
+
/** A option that modifies or overrides command execution. */
|
|
120
|
+
interface Option {
|
|
121
|
+
/** Name or aliases, including any desired prefix such as `-`, `--`, or `/`. */
|
|
122
|
+
name: SingleOrArray<string>;
|
|
123
|
+
/** Description shown in help. */
|
|
124
|
+
description?: string;
|
|
125
|
+
/** Arguments this option accepts. */
|
|
126
|
+
args?: SingleOrArray<Arg>;
|
|
127
|
+
/** Allow this option to be used by descendant subcommands. */
|
|
128
|
+
isPersistent?: true;
|
|
129
|
+
/** Hide this option from help. */
|
|
130
|
+
hidden?: true;
|
|
131
|
+
/** Only allow arguments to be supplied with a separator. */
|
|
132
|
+
requiresSeparator?: true | string;
|
|
133
|
+
/**
|
|
134
|
+
* Allow this option to be supplied multiple times. `true` allows any number
|
|
135
|
+
* of uses, and a number is the most uses allowed. An option with arguments
|
|
136
|
+
* collects the values from every use, in order. Without arguments, each use
|
|
137
|
+
* adds an empty string, so `count()` returns the number of uses.
|
|
138
|
+
*/
|
|
139
|
+
isRepeatable?: true | number;
|
|
140
|
+
/** Require this option to be supplied before the selected action runs. */
|
|
141
|
+
isRequired?: true;
|
|
142
|
+
/** Fail parsing if these options are provided. */
|
|
143
|
+
exclusiveOn?: NonEmptyArray<string>;
|
|
144
|
+
/** Fail parsing if these options are not provided. */
|
|
145
|
+
dependsOn?: NonEmptyArray<string>;
|
|
146
|
+
/**
|
|
147
|
+
* Action performed when this option is provided.
|
|
148
|
+
*
|
|
149
|
+
* Option actions take precedence over command actions. The final parsed option
|
|
150
|
+
* action is selected.
|
|
151
|
+
*/
|
|
152
|
+
action?: Action;
|
|
153
|
+
/**
|
|
154
|
+
* This property never exists. It prevents accidental structural assignment
|
|
155
|
+
* between options and subcommands.
|
|
156
|
+
*
|
|
157
|
+
* @ignore
|
|
158
|
+
*/
|
|
159
|
+
[kind]?: "Option";
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* A built-in completion template.
|
|
163
|
+
*
|
|
164
|
+
* Resolves to the shell's native path completion. Completions only — no effect
|
|
165
|
+
* on parsing.
|
|
166
|
+
*/
|
|
167
|
+
type Template = "filepaths" | "folders" | ["folders", "filepaths"] | ["filepaths", "folders"];
|
|
168
|
+
/**
|
|
169
|
+
* A single completion suggestion.
|
|
170
|
+
*
|
|
171
|
+
* This is a deliberately small subset of the Fig `Suggestion` shape — just the
|
|
172
|
+
* fields the completion engine uses. Presentational fields (icon, priority,
|
|
173
|
+
* displayName, insertValue, type) are intentionally omitted.
|
|
174
|
+
*/
|
|
175
|
+
interface Suggestion {
|
|
176
|
+
/** Value(s) inserted when the suggestion is accepted. */
|
|
177
|
+
name: SingleOrArray<string>;
|
|
178
|
+
/** Additional information shown next to the suggestion. */
|
|
179
|
+
description?: string;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Generates dynamic completion suggestions.
|
|
183
|
+
*
|
|
184
|
+
* `custom` runs inside the CLI when the shell asks it for completions. It only
|
|
185
|
+
* affects completion and has no effect on parsing.
|
|
186
|
+
*/
|
|
187
|
+
interface Generator {
|
|
188
|
+
/** Produce suggestions from the current command-line tokens. */
|
|
189
|
+
custom?(tokens: string[]): (Suggestion | string)[] | Promise<(Suggestion | string)[]>;
|
|
190
|
+
}
|
|
191
|
+
/** Positional or option argument metadata. */
|
|
192
|
+
interface Arg {
|
|
193
|
+
/** Name shown in generated help. */
|
|
194
|
+
name?: string;
|
|
195
|
+
/** Description for documentation or future help output. */
|
|
196
|
+
description?: string;
|
|
197
|
+
/** Allow this argument to take unlimited values. */
|
|
198
|
+
isVariadic?: true;
|
|
199
|
+
/** Allow this argument to be omitted. */
|
|
200
|
+
isOptional?: true;
|
|
201
|
+
/** Completions: complete file or folder paths for this argument. */
|
|
202
|
+
template?: Template;
|
|
203
|
+
/** Completions: static suggestions offered while typing this argument. */
|
|
204
|
+
suggestions?: readonly (string | Suggestion)[];
|
|
205
|
+
/** Completions: dynamically generated suggestions for this argument. */
|
|
206
|
+
generators?: SingleOrArray<Generator>;
|
|
207
|
+
}
|
|
208
|
+
/** Asserts that required arguments do not come after an optional argument */
|
|
209
|
+
export declare function assertRequiredArgumentsDoNotFollowOptionalArguments(spec: Subcommand): void;
|
|
210
|
+
/** Asserts that `isRepeatable` is only assigned a positive integer */
|
|
211
|
+
export declare function assertRepeatableOptionsArePositiveIntegers(spec: Subcommand): void;
|
|
212
|
+
/** Asserts that options have unique names in their scope */
|
|
213
|
+
export declare function assertOptionsHaveLocallyUniqueNames(spec: Subcommand): void;
|
|
214
|
+
/** Asserts that options don't shadow a persistent option */
|
|
215
|
+
export declare function assertOptionsDoNotShadowPersistentOptions(spec: Subcommand): void;
|
|
216
|
+
/**
|
|
217
|
+
* Asserts that a subcommand's option isn't a different option with exactly the
|
|
218
|
+
* same names as one on a parent.
|
|
219
|
+
*
|
|
220
|
+
* Parsed values are looked up by name, so that parent's value would be
|
|
221
|
+
* unreadable. A shared name is fine when each option has a name of its own, and
|
|
222
|
+
* when the options are identical, such as an option kept in a constant.
|
|
223
|
+
*
|
|
224
|
+
* This skips persistent parent options, because
|
|
225
|
+
* {@link assertOptionsDoNotShadowPersistentOptions} covers those and
|
|
226
|
+
* `allowShadowingPersistentOptions` opts out of it.
|
|
227
|
+
*/
|
|
228
|
+
export declare function assertOptionsHaveDifferentNamesFromParents(spec: Subcommand): void;
|
|
229
|
+
/** Asserts that subcommands don't share a name with a sibling subcommand */
|
|
230
|
+
export declare function assertSubcommandsHaveLocallyUniqueNames(spec: Subcommand): void;
|
|
231
|
+
/**
|
|
232
|
+
* Asserts that option names starting with a single dash aren't longer
|
|
233
|
+
* than two characters, unless parserDirectives.flagsArePosixNoncompliant is
|
|
234
|
+
* set on an ancestor command.
|
|
235
|
+
*/
|
|
236
|
+
export declare function assertLongOptionNamesDoNotStartWithSingleDash(spec: Subcommand): void;
|
|
237
|
+
/**
|
|
238
|
+
* Asserts that all option names start with dashes
|
|
239
|
+
*/
|
|
240
|
+
export declare function assertOptionNamesStartWithDashes(spec: Subcommand): void;
|
|
241
|
+
/**
|
|
242
|
+
* Asserts that nothing is named exactly '--'
|
|
243
|
+
*/
|
|
244
|
+
export declare function assertNothingIsNamedDashDash(spec: Subcommand): void;
|
|
245
|
+
/**
|
|
246
|
+
* Asserts that no option arg separator is an empty string
|
|
247
|
+
*/
|
|
248
|
+
export declare function assertOptionArgSeparatorsHaveCharacters(spec: Subcommand): void;
|
|
249
|
+
/**
|
|
250
|
+
* Asserts that options named "+" or "-" takes one arg
|
|
251
|
+
*/
|
|
252
|
+
export declare function assertPlusMinusOptionsTakeOneArg(spec: Subcommand): void;
|
|
253
|
+
/**
|
|
254
|
+
* Asserts that names do not have leading or trailing whitespace
|
|
255
|
+
*/
|
|
256
|
+
export declare function assertNamesHaveNoExtraWhitespace(spec: Subcommand): void;
|
|
257
|
+
/**
|
|
258
|
+
* Asserts that everything has a description
|
|
259
|
+
*/
|
|
260
|
+
export declare function assertEverythingHasDescription(spec: Subcommand): void;
|
|
261
|
+
/**
|
|
262
|
+
* Asserts that descriptions have line length < 69
|
|
263
|
+
*/
|
|
264
|
+
export declare function assertDescriptionLineLengthUnder69(spec: Subcommand): void;
|
|
265
|
+
export declare function assertRequiresSeparatorTakesOneArg(spec: Subcommand): void;
|
|
266
|
+
export declare function assertCommonOptionsArePersistent(spec: Subcommand): void;
|
|
267
|
+
/**
|
|
268
|
+
* Asserts that references to other options by name actually refer to options
|
|
269
|
+
* that exist in scope
|
|
270
|
+
*/
|
|
271
|
+
export declare function assertOptionNameReferencesExist(spec: Subcommand): void;
|
|
272
|
+
/**
|
|
273
|
+
* Asserts that commands that will match subcommands by prefix do not take arguments
|
|
274
|
+
*/
|
|
275
|
+
export declare function assertPrefixMatchCommandsHaveNoArguments(spec: Subcommand): void;
|
|
276
|
+
export type TestNamingStyle = "sentence" | "function";
|
|
277
|
+
/** Options that can be provided to `test` */
|
|
278
|
+
export interface TestOptions {
|
|
279
|
+
/**
|
|
280
|
+
* Allows options to shadow persistent options.
|
|
281
|
+
*
|
|
282
|
+
* This behavior may be desirable if you want to override an option on a
|
|
283
|
+
* particular subcommand, but not for others.
|
|
284
|
+
*
|
|
285
|
+
* Be aware that this is not idiomatic.
|
|
286
|
+
*/
|
|
287
|
+
allowShadowingPersistentOptions?: boolean;
|
|
288
|
+
/**
|
|
289
|
+
* Allows subcommands and options to not have a description
|
|
290
|
+
*/
|
|
291
|
+
allowNoDescription?: boolean;
|
|
292
|
+
/**
|
|
293
|
+
* Allows descriptions to have lines over 68 characters long
|
|
294
|
+
*/
|
|
295
|
+
allowLongDescriptionLines?: boolean;
|
|
296
|
+
/**
|
|
297
|
+
* Allow commands to have `parserDirectives.subcommandsMatchUniquePrefix` with args
|
|
298
|
+
*
|
|
299
|
+
* This is not allowed by default because it's probably a mistake. It makes
|
|
300
|
+
* arguments ambiguous, users may not know if their invocation will run a
|
|
301
|
+
* subcommand or the command.
|
|
302
|
+
*/
|
|
303
|
+
allowMatchingSubcommandPrefixAndArgs?: boolean;
|
|
304
|
+
/**
|
|
305
|
+
* Change the naming style of the tests.
|
|
306
|
+
*
|
|
307
|
+
* - `sentence`: Use proper sentence casing, punctuation, etc
|
|
308
|
+
* - `function`: Use the name of the assert function that will be executed
|
|
309
|
+
*/
|
|
310
|
+
namingStyle?: TestNamingStyle;
|
|
311
|
+
}
|
|
312
|
+
export interface TestContextLike {
|
|
313
|
+
step(name: string, fn: () => unknown | Promise<unknown>): unknown | Promise<unknown>;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Validate your CLI in your test suite
|
|
317
|
+
*
|
|
318
|
+
* This enforces certain constraints that the type system cannot. The parser
|
|
319
|
+
* may ignore these issues, producing correct output that _appears_ to be
|
|
320
|
+
* wrong.
|
|
321
|
+
*/
|
|
322
|
+
export declare function test(spec: Subcommand, options?: TestOptions): (t?: TestContextLike) => Promise<void>;
|
|
323
|
+
export declare const testSpec: typeof test;
|
|
324
|
+
export {};
|
|
325
|
+
//# sourceMappingURL=testing.d.ts.map
|