@avandar/acclimate 0.3.0 → 0.3.2

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/dist/index.cjs CHANGED
@@ -343,25 +343,27 @@ function _generateHelpTextHelper(cli, options) {
343
343
  function generateHelpText(cli) {
344
344
  return generateTerminalMessage(_generateHelpTextHelper(cli, { level: 1 }));
345
345
  }
346
- var COLOR_TOKEN_REGEX2 = /\|[a-zA-Z_]+\|/g;
347
- function messageHasPunctuation(message) {
348
- const stripped = message.replace(COLOR_TOKEN_REGEX2, "").trimEnd();
349
- return stripped.endsWith(":") || stripped.endsWith("?");
350
- }
351
346
  async function requestTerminalInput(options) {
352
- const { message, params, options: promptOptions } = options;
353
- const notice = promptOptions.required ? "" : " |gray|(press Enter to leave empty)|reset|";
354
- const booleanNotice = promptOptions.type === "boolean" ? " |reset|(y/n)" : "";
355
- const promptMessage = `${message}${booleanNotice}${notice}`;
356
- const promptText = messageHasPunctuation(message) ? `${promptMessage} ` : `${promptMessage}: `;
357
- const prompt = generateTerminalMessage(promptText, params);
347
+ const {
348
+ message,
349
+ params,
350
+ responseOptions: { required, type, defaultValue }
351
+ } = options;
352
+ const notice = defaultValue !== void 0 ? " |gray|(press Enter to use default)|reset|" : required ? "" : " |gray|(press Enter to leave empty)|reset|";
353
+ const defaultNotice = defaultValue !== void 0 ? ` [default: ${defaultValue}]` : "";
354
+ const booleanNotice = type === "boolean" ? " |reset|(y/n)" : "";
355
+ const promptMessage = `${message}${defaultNotice}${booleanNotice}${notice} `;
356
+ const prompt = generateTerminalMessage(promptMessage, params);
358
357
  const rl = promises.createInterface({ input: process$1.stdin, output: process$1.stdout });
359
358
  try {
360
359
  while (true) {
361
360
  const answer = await rl.question(prompt);
362
361
  const trimmed = answer.trim();
363
362
  if (trimmed.length === 0) {
364
- if (promptOptions.required) {
363
+ if (defaultValue !== void 0) {
364
+ return typeof defaultValue === "string" ? defaultValue : typeof defaultValue === "number" ? String(defaultValue) : defaultValue ? "true" : "false";
365
+ }
366
+ if (required) {
365
367
  process$1.stdout.write(
366
368
  generateTerminalMessage(
367
369
  "|red|This value is required.|reset| Please enter a value.\n"
@@ -371,7 +373,7 @@ async function requestTerminalInput(options) {
371
373
  }
372
374
  return void 0;
373
375
  }
374
- if (promptOptions.type === "boolean") {
376
+ if (type === "boolean") {
375
377
  const normalized = trimmed.toLowerCase();
376
378
  if (normalized === "y" || normalized === "yes") {
377
379
  return "true";
@@ -471,7 +473,11 @@ async function askForValue(options) {
471
473
  return requestTerminalInput({
472
474
  message: coloredMessage,
473
475
  params: {},
474
- options: { required: argConfig.required, type: argConfig.type }
476
+ responseOptions: {
477
+ required: argConfig.required,
478
+ type: argConfig.type,
479
+ defaultValue: argConfig.defaultValue
480
+ }
475
481
  });
476
482
  }
477
483
  async function _runCLIHelper(options) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/CLIError.ts","../src/AcclimateCLI/AcclimateCLI.ts","../src/AcclimateCLI/createCLI/defaultCLIState.ts","../src/AcclimateCLI/createCLI/createCLI.ts","../src/generateTerminalMessage/generateTerminalMessage.ts","../src/AcclimateCLI/generateHelpText/generateHelpText.ts","../src/requestTerminalInput/requestTerminalInput.ts","../src/AcclimateCLI/runCLI/runCLI.ts","../src/Acclimate.ts"],"names":["match","COLOR_TOKEN_REGEX","createInterface","stdin","stdout","camelCase"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { CLIParamDataType } from \"./AcclimateCLI/AcclimateCLI.types\";\n\ntype CLIErrorInfo =\n | {\n code: \"already_run\";\n details: undefined;\n }\n | {\n code: \"unknown_command\";\n details: { commandName: string };\n }\n | {\n code: \"invalid_positional_arg_config\";\n details: { positionalArgName: string };\n }\n | {\n code: \"too_many_positional_args\";\n details: { count: number };\n }\n | {\n code: \"missing_required_positional_arg\";\n details: { positionalArgName: string };\n }\n | {\n code: \"missing_required_option\";\n details: { optionName: string };\n }\n | {\n code: \"unknown_option\";\n details: {\n optionName: string;\n };\n }\n | {\n code: \"invalid_cli_param_value\";\n details: {\n paramName: string;\n paramValue: CLIParamDataType;\n };\n }\n | { code: \"unknown_error\"; details: undefined };\n\ntype CLIErrorOptions = { cliName: string; message: string } & CLIErrorInfo;\n\nexport class CLIError extends Error {\n static invalidCLIParamValue(options: {\n cliName: string;\n paramName: string;\n paramValue: CLIParamDataType;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ?? `Invalid value for CLI param \"${options.paramName}\"`,\n code: \"invalid_cli_param_value\",\n details: { paramName: options.paramName, paramValue: options.paramValue },\n });\n }\n static missingRequiredOption(options: {\n cliName: string;\n optionName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ?? `Required option \"${options.optionName}\" is missing`,\n code: \"missing_required_option\",\n details: { optionName: options.optionName },\n });\n }\n\n static missingRequiredPositionalArg(options: {\n cliName: string;\n positionalArgName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ??\n `Required positional argument \"${options.positionalArgName}\" is missing`,\n code: \"missing_required_positional_arg\",\n details: { positionalArgName: options.positionalArgName },\n });\n }\n\n static unknownOption(options: {\n cliName: string;\n optionName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? `Option \"${options.optionName}\" not found`,\n code: \"unknown_option\",\n details: { optionName: options.optionName },\n });\n }\n\n static tooManyPositionalArgs(options: {\n cliName: string;\n count: number;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? \"Too many positional arguments provided.\",\n code: \"too_many_positional_args\",\n details: { count: options.count },\n });\n }\n\n static invalidPositionalArgConfig(options: {\n cliName: string;\n positionalArgName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ??\n `Positional argument configuration for \"${options.positionalArgName}\" is invalid`,\n code: \"invalid_positional_arg_config\",\n details: { positionalArgName: options.positionalArgName },\n });\n }\n\n static unknownCommand(options: {\n cliName: string;\n commandName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? `Command \"${options.commandName}\" not found`,\n code: \"unknown_command\",\n details: { commandName: options.commandName },\n });\n }\n\n static alreadyRun(options: {\n cliName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? \"CLI has already been run\",\n code: \"already_run\",\n details: undefined,\n });\n }\n\n constructor(options: CLIErrorOptions) {\n super(`❌ Error running ${options.cliName}: ${options.message}`);\n }\n}\n","import { CLIError } from \"@/CLIError\";\nimport type {\n AddEntry,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionParam,\n CLIPositionalParam,\n CLIPositionalParamName,\n CLIState,\n FullCLIArgValues,\n IAcclimateCLI,\n} from \"./AcclimateCLI.types\";\nimport type { EmptyObject, Simplify } from \"type-fest\";\n\nexport function AcclimateCLI<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, IAcclimateCLI> | EmptyObject,\n>(\n state: CLIState<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n> {\n const cliName = state.name;\n return {\n state,\n\n getName: () => {\n return cliName;\n },\n\n action: (\n action: (\n args: Simplify<\n FullCLIArgValues<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams\n >\n >,\n ) => void,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n > => {\n return AcclimateCLI({\n ...state,\n action,\n });\n },\n\n description: (\n description: string,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n > => {\n return AcclimateCLI({\n ...state,\n description,\n });\n },\n\n addPositionalArg: <\n PName extends CLIPositionalParamName,\n P extends CLIPositionalParam<PName>,\n >(\n param: P,\n ) => {\n if (\n param.required &&\n state.positionalArgs.some((p) => {\n return !p.required;\n })\n ) {\n throw CLIError.invalidPositionalArgConfig({\n cliName,\n positionalArgName: param.name,\n message:\n \"Required positional arguments must be before optional positional arguments\",\n });\n }\n\n return AcclimateCLI({\n ...state,\n positionalArgs: [\n ...state.positionalArgs,\n { ...param, required: param.required ?? true },\n ],\n } as unknown as CLIState<\n AddEntry<TPositionalParams, P[\"name\"], P>,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >);\n },\n\n addGlobalOption: <P extends CLIOptionParam>(param: P) => {\n const newAliases = (param.aliases ?? []).reduce(\n (acc, alias) => {\n acc[alias] = param.name;\n return acc;\n },\n {} as Record<`-${string}` | `--${string}`, `--${string}`>,\n );\n return AcclimateCLI<\n TPositionalParams,\n TOptionParams,\n AddEntry<TGlobalOptionParams, P[\"name\"], P>,\n TCommands\n >({\n ...state,\n aliases: { ...state.aliases, ...newAliases },\n globalOptionArgs: {\n ...state.globalOptionArgs,\n [param.name]: param,\n },\n } as unknown as CLIState<\n TPositionalParams,\n TOptionParams,\n AddEntry<TGlobalOptionParams, P[\"name\"], P>,\n TCommands\n >);\n },\n\n addOption: <P extends CLIOptionParam>(param: P) => {\n const newAliases = (param.aliases ?? []).reduce(\n (acc, alias) => {\n acc[alias] = param.name;\n return acc;\n },\n {} as Record<`-${string}` | `--${string}`, `--${string}`>,\n );\n return AcclimateCLI<\n TPositionalParams,\n AddEntry<TOptionParams, P[\"name\"], P>,\n TGlobalOptionParams,\n TCommands\n >({\n ...state,\n aliases: { ...state.aliases, ...newAliases },\n optionArgs: { ...state.optionArgs, [param.name]: param },\n } as unknown as CLIState<\n TPositionalParams,\n AddEntry<TOptionParams, P[\"name\"], P>,\n TGlobalOptionParams,\n TCommands\n >);\n },\n\n addCommand: <C extends CLICommandName, CommandCLI extends IAcclimateCLI>(\n commandName: C,\n cli: CommandCLI,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n AddEntry<TCommands, C, CommandCLI>\n > => {\n return AcclimateCLI({\n ...state,\n commands: {\n ...state.commands,\n [commandName]: cli,\n },\n } as unknown as CLIState<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n AddEntry<TCommands, C, CommandCLI>\n >);\n },\n\n getCommandCLI: <C extends Extract<keyof TCommands, CLICommandName>>(\n commandName: C,\n ): C extends keyof TCommands ? TCommands[C] : never => {\n const cmd = state.commands[commandName];\n if (!cmd) {\n throw CLIError.unknownCommand({\n cliName,\n commandName,\n message: `Command \"${commandName}\" not found`,\n });\n }\n return cmd as C extends keyof TCommands ? TCommands[C] : never;\n },\n };\n}\n","import type { CLIState } from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nexport const defaultCLIState: Omit<\n CLIState<EmptyObject, EmptyObject, EmptyObject, EmptyObject>,\n \"name\"\n> = {\n aliases: {},\n description: undefined,\n commands: {},\n positionalArgs: [],\n optionArgs: {},\n globalOptionArgs: {},\n action: undefined,\n};\n","import { AcclimateCLI } from \"../AcclimateCLI\";\nimport { defaultCLIState } from \"./defaultCLIState\";\nimport type { IAcclimateCLI } from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\n/**\n * Builder function to create a new CLI instance with a given name.\n *\n * @param name - The name of the CLI.\n * @returns A new CLI instance.\n */\nexport function createCLI(\n name: string,\n): IAcclimateCLI<EmptyObject, EmptyObject, EmptyObject, EmptyObject> {\n return AcclimateCLI({ ...defaultCLIState, name });\n}\n","const COLOR_CODES: Record<string, string> = {\n reset: \"\\x1b[0m\",\n black: \"\\x1b[30m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n bright_black: \"\\x1b[90m\",\n gray: \"\\x1b[90m\",\n grey: \"\\x1b[90m\",\n bright_red: \"\\x1b[91m\",\n bright_green: \"\\x1b[92m\",\n bright_yellow: \"\\x1b[93m\",\n bright_blue: \"\\x1b[94m\",\n bright_magenta: \"\\x1b[95m\",\n bright_cyan: \"\\x1b[96m\",\n bright_white: \"\\x1b[97m\",\n};\n\nconst PARAM_TOKEN_REGEX = /\\$([a-zA-Z0-9_]+)\\$/g;\nconst COLOR_TOKEN_REGEX = /\\|([a-zA-Z_]+)\\|/g;\n\n/**\n * Replaces `$token$` placeholders with values from `params`.\n * If a token does not exist in `params`, the placeholder is left unchanged.\n */\nfunction interpolateParams(\n message: string,\n params: Record<string, string | undefined>,\n) {\n return message.replace(PARAM_TOKEN_REGEX, (match, key: string) => {\n void match;\n const value = params[key];\n if (value === undefined) {\n return \"\";\n }\n return value;\n });\n}\n\nfunction applyColors(message: string) {\n return message.replace(COLOR_TOKEN_REGEX, (match, colorName: string) => {\n const code = COLOR_CODES[colorName.toLowerCase()];\n return code ?? match;\n });\n}\n\n/**\n * Outputs a message intended to be passed directly to `console.log`\n *\n * Supports interpolation using `$varName$` as tokens.\n *\n * Colors can be changed within a message `|<COLOR_NAME>|` tokens.\n * Supported colors are:\n * - black\n * - red\n * - green\n * - yellow\n * - blue\n * - magenta\n * - cyan\n * - white\n * - bright_black|gray|grey\n * - bright_red\n * - bright_green\n * - bright_yellow\n * - bright_blue\n * - bright_magenta\n * - bright_cyan\n * - bright_white\n *\n * The color remains active until another color token is found,\n * or if |reset| is found (which resets the terminal color to the default).\n *\n * @example\n *\n * Acclimate.log(\"Hello $name$\", { name: \"Pablo\" });\n * // \"Hello Pablo\"\n *\n * Acclimate.log(\"|red|Error:|reset| There was an error.\")\n * // \"Error: There was an error.\"\n * // ^ the \"Error:\" portion will be red\n *\n */\nexport function generateTerminalMessage(\n message: string,\n params: Record<string, string | undefined> = {},\n): string {\n const hasColorToken = Boolean(message.match(COLOR_TOKEN_REGEX));\n const endsWithReset = message.trimEnd().endsWith(\"|reset|\");\n const withReset =\n hasColorToken && !endsWithReset ? `${message}|reset|` : message;\n const interpolated = interpolateParams(withReset, params);\n return applyColors(interpolated);\n}\n","import { generateTerminalMessage } from \"@/generateTerminalMessage\";\nimport type {\n AnyCLI,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionParam,\n CLIParam,\n CLIPositionalParam,\n CLIPositionalParamName,\n IAcclimateCLI,\n} from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nconst _SECTION_TITLES = [\n \"Positional Arguments\",\n \"Options\",\n \"Global Options\",\n \"Commands\",\n] as const;\n\ntype SectionTitle = (typeof _SECTION_TITLES)[number];\n\ntype CLIParamWithRequired = CLIParam<string> & {\n required: boolean;\n aliases?: readonly string[];\n};\n\nfunction formatSectionTitle(title: SectionTitle): string {\n return `|bright_yellow|${title}|reset|`;\n}\n\nfunction formatNoneLine(): string {\n return \" |gray|None|reset|\";\n}\n\nfunction formatDefaultValue(\n value: CLIParamWithRequired[\"defaultValue\"],\n): string {\n return `|gray|[default: ${JSON.stringify(value)}]|reset|`;\n}\n\nfunction formatParamLine(param: CLIParamWithRequired): string {\n const description = param.description ?? \"No description\";\n const requiredLabel =\n param.required ? \"|red|required|reset|\" : \"|gray|optional|reset|\";\n const defaultLabel =\n param.defaultValue !== undefined ?\n formatDefaultValue(param.defaultValue)\n : undefined;\n const aliasList =\n param.aliases && param.aliases.length > 0 ? param.aliases.join(\", \") : \"\";\n const displayName = aliasList ? `${param.name}, ${aliasList}` : param.name;\n\n const segments = [\n ` |bright_white|${displayName}|reset|`,\n `(${param.type})|reset| ${requiredLabel}`,\n `- |gray|${description}|reset|`,\n defaultLabel,\n ].filter(Boolean);\n\n return segments.join(\" \");\n}\n\nfunction formatSection(\n title: SectionTitle,\n params: readonly CLIParamWithRequired[],\n): string[] {\n if (params.length === 0) {\n return [formatSectionTitle(title), formatNoneLine()];\n }\n\n return [formatSectionTitle(title), ...params.map(formatParamLine)];\n}\n\nfunction formatCommandLine(options: {\n name: string;\n description?: string;\n}): string {\n const { name, description } = options;\n const label = description ?? \"No description\";\n return ` |bright_white|${name}|reset| - |gray|${label}|reset|`;\n}\n\nfunction formatAvailableCommandsLine(commands: string[]): string {\n const label =\n commands.length === 0 ?\n \"None\"\n : commands\n .map((cmd) => {\n return cmd;\n })\n .join(\", \");\n return `|bright_yellow|Available Commands:|reset| |gray|${label}|reset|`;\n}\n\nfunction _generateHelpTextHelper<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n options: { level: 1 | 2 },\n): string {\n const name = cli.getName();\n const description = cli.state.description;\n const level = Number(options.level);\n\n const positionalParams = cli.state\n .positionalArgs as readonly CLIParamWithRequired[];\n const optionParams = Object.values(\n cli.state.optionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ) as readonly CLIParamWithRequired[];\n const globalOptionParams = Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ) as readonly CLIParamWithRequired[];\n const sortedCommands = Object.entries(cli.state.commands).sort(([a], [b]) => {\n return a.localeCompare(b);\n });\n const commandNames = sortedCommands.map(([commandName]) => {\n return commandName;\n });\n\n const headerLines = [`|bright_cyan|${name}|reset|`];\n if (description !== undefined) {\n headerLines.push(` |gray|${description}|reset|`);\n }\n\n let commandSection: string[];\n if (level === 2) {\n commandSection = [\n formatSectionTitle(\"Commands\"),\n ` ${formatAvailableCommandsLine(commandNames)}`,\n ];\n } else if (sortedCommands.length === 0) {\n commandSection = [formatSectionTitle(\"Commands\"), formatNoneLine()];\n } else {\n commandSection = [\n formatSectionTitle(\"Commands\"),\n ...sortedCommands.map(([commandName, commandCLI]) => {\n return formatCommandLine({\n name: commandName,\n description: commandCLI.state.description,\n });\n }),\n ];\n }\n\n const sections = [\n formatSection(\"Positional Arguments\", positionalParams),\n formatSection(\"Options\", optionParams),\n formatSection(\"Global Options\", globalOptionParams),\n commandSection,\n ];\n\n const lines = [...headerLines, \"\"];\n sections.forEach((section, idx) => {\n lines.push(...section);\n if (idx < sections.length - 1) {\n lines.push(\"\");\n }\n });\n\n if (level === 1) {\n const subCommandHelpText = sortedCommands.map(([, commandCLI]) => {\n return _generateHelpTextHelper(commandCLI, { level: 2 });\n });\n if (subCommandHelpText.length > 0) {\n subCommandHelpText.forEach((text) => {\n lines.push(\"\", ...text.split(\"\\n\"));\n });\n }\n }\n\n const indent = \" \".repeat(Math.max(0, level - 1));\n return lines\n .map((line) => {\n return line === \"\" ? \"\" : `${indent}${line}`;\n })\n .join(\"\\n\");\n}\n\nexport function generateHelpText<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n): string {\n return generateTerminalMessage(_generateHelpTextHelper(cli, { level: 1 }));\n}\n","import { stdin, stdout } from \"node:process\";\nimport { createInterface } from \"node:readline/promises\";\nimport { generateTerminalMessage } from \"@/generateTerminalMessage\";\n\nconst COLOR_TOKEN_REGEX = /\\|[a-zA-Z_]+\\|/g;\n\ntype RequestTerminalInputOptions = {\n message: string;\n params: Record<string, string>;\n options: {\n required: boolean;\n type?: \"string\" | \"number\" | \"boolean\";\n };\n};\n\nfunction messageHasPunctuation(message: string): boolean {\n const stripped = message.replace(COLOR_TOKEN_REGEX, \"\").trimEnd();\n return stripped.endsWith(\":\") || stripped.endsWith(\"?\");\n}\n\n/**\n * Prompt the user for terminal input, optionally enforcing a non-empty value.\n */\nexport async function requestTerminalInput(\n options: RequestTerminalInputOptions,\n): Promise<string | undefined> {\n const { message, params, options: promptOptions } = options;\n const notice =\n promptOptions.required ? \"\" : \" |gray|(press Enter to leave empty)|reset|\";\n const booleanNotice = promptOptions.type === \"boolean\" ? \" |reset|(y/n)\" : \"\";\n const promptMessage = `${message}${booleanNotice}${notice}`;\n const promptText =\n messageHasPunctuation(message) ? `${promptMessage} ` : `${promptMessage}: `;\n const prompt = generateTerminalMessage(promptText, params);\n\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n while (true) {\n const answer = await rl.question(prompt);\n const trimmed = answer.trim();\n if (trimmed.length === 0) {\n if (promptOptions.required) {\n stdout.write(\n generateTerminalMessage(\n \"|red|This value is required.|reset| Please enter a value.\\n\",\n ),\n );\n continue;\n }\n return undefined;\n }\n if (promptOptions.type === \"boolean\") {\n const normalized = trimmed.toLowerCase();\n if (normalized === \"y\" || normalized === \"yes\") {\n return \"true\";\n }\n if (normalized === \"n\" || normalized === \"no\") {\n return \"false\";\n }\n stdout.write(\n generateTerminalMessage(\n \"|red|That was not a valid response.|reset| Please enter y or n.\\n\",\n ),\n );\n continue;\n }\n return answer;\n }\n } finally {\n rl.close();\n }\n}\n","import { camelCase } from \"change-case\";\nimport { match } from \"ts-pattern\";\nimport { generateHelpText } from \"@/AcclimateCLI/generateHelpText/generateHelpText\";\nimport { CLIError } from \"@/CLIError\";\nimport { requestTerminalInput } from \"@/requestTerminalInput\";\nimport type {\n AnyCLI,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionAlias,\n CLIOptionParam,\n CLIParam,\n CLIParamDataType,\n CLIPositionalParam,\n CLIPositionalParamName,\n CLIState,\n FullCLIArgValues,\n IAcclimateCLI,\n ValueOfParam,\n} from \"@/AcclimateCLI/AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nfunction _isValidFullOptionName(name: string): name is CLIFullOptionName {\n return name.startsWith(\"--\");\n}\n\nfunction _isValidOptionAlias(name: string): name is CLIOptionAlias {\n return name.startsWith(\"-\");\n}\n\nfunction isEmptyObject(obj: object): obj is EmptyObject {\n return Object.keys(obj).length === 0;\n}\n\nfunction _validateParsedValue<\n P extends CLIParam<string>,\n PValue extends ValueOfParam<P>,\n>(options: { parsedValue: PValue; paramConfig: P; cliName: string }): PValue {\n const { parsedValue, paramConfig, cliName } = options;\n if (paramConfig.validator) {\n const validator = paramConfig.validator as (\n value: PValue,\n ) => boolean | string;\n const validationResult = validator(parsedValue);\n if (validationResult === true) {\n return parsedValue;\n }\n throw CLIError.invalidCLIParamValue({\n cliName,\n paramName: paramConfig.name,\n paramValue: parsedValue,\n message:\n typeof validationResult === \"string\" ? validationResult : undefined,\n });\n }\n return parsedValue;\n}\n\nfunction _parseAndValidateValue<\n P extends CLIParam<string>,\n PValue extends ValueOfParam<P>,\n>(options: {\n cliName: string;\n inputValue: string | undefined;\n defaultValue: PValue | undefined;\n paramConfig: P;\n}): PValue | undefined {\n const { cliName, inputValue, defaultValue, paramConfig } = options;\n if (inputValue === undefined) {\n if (defaultValue === undefined) {\n return undefined;\n }\n return _validateParsedValue({\n cliName,\n parsedValue: defaultValue,\n paramConfig,\n });\n }\n\n const parsedValue =\n paramConfig.parser ?\n (paramConfig.parser(inputValue) as PValue)\n // if no parser was set, we use the default parser\n : (match(paramConfig.type)\n .with(\"boolean\", () => {\n return inputValue === \"false\" ? false : true;\n })\n .with(\"number\", () => {\n return Number.parseInt(inputValue, 10);\n })\n .with(\"string\", () => {\n return inputValue;\n })\n .exhaustive(() => {\n return inputValue;\n }) as PValue);\n return _validateParsedValue({\n cliName,\n parsedValue,\n paramConfig,\n });\n}\n\nfunction _replaceAliases<\n TGlobalOptionArgs extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TOptionArgs extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TPositionalArgs extends\n | Record<CLIPositionalParamName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>({\n aliasedOptionArgs,\n cli,\n}: {\n aliasedOptionArgs: Record<CLIOptionAlias, string>;\n cli: IAcclimateCLI<\n TGlobalOptionArgs,\n TOptionArgs,\n TPositionalArgs,\n TCommands\n >;\n}): Record<CLIOptionAlias, string> {\n const aliasMap = cli.state.aliases;\n return Object.entries(aliasedOptionArgs).reduce(\n (acc, [aliasKey, value]) => {\n const alias = aliasKey as CLIOptionAlias;\n const optionName = aliasMap[alias] ?? alias;\n acc[optionName] = value;\n return acc;\n },\n {} as Record<CLIOptionAlias, string>,\n );\n}\n\ntype CLIParamWithRequired = CLIParam<string> & {\n required: boolean;\n};\n\nasync function askForValue(options: {\n argConfig: CLIParamWithRequired;\n}): Promise<string | undefined> {\n const { argConfig } = options;\n const askIfEmpty = argConfig.askIfEmpty;\n const description =\n argConfig.description ? ` (${argConfig.description})` : \"\";\n const baseMessage =\n typeof askIfEmpty === \"object\" ?\n askIfEmpty.message\n : `Please enter a value for ${argConfig.name}${description}`;\n const coloredMessage = `|bright_cyan|${baseMessage}|reset|`;\n return requestTerminalInput({\n message: coloredMessage,\n params: {},\n options: { required: argConfig.required, type: argConfig.type },\n });\n}\n\nasync function _runCLIHelper<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(options: {\n rawPositionalArgs: string[];\n rawOptionArgs: Record<CLIOptionAlias, string>;\n rawGlobalOptionArgs: Record<CLIFullOptionName, string>;\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >;\n}): Promise<void> {\n const { rawGlobalOptionArgs, rawOptionArgs, rawPositionalArgs, cli } = {\n ...options,\n rawGlobalOptionArgs: _replaceAliases({\n aliasedOptionArgs: options.rawGlobalOptionArgs,\n cli: options.cli,\n }),\n rawOptionArgs: _replaceAliases({\n aliasedOptionArgs: options.rawOptionArgs,\n\n // TODO(jpsyx): fix that this does not have the CLI may not have all\n cli: options.cli,\n }),\n };\n\n // is the first argument a command?\n const firstArg = rawPositionalArgs[0];\n if (\n firstArg &&\n !isEmptyObject(cli.state.commands) &&\n cli.state.commands[firstArg]\n ) {\n // add the parent's global options to the sub-command\n const commandCLI = Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ).reduce(\n (newCmd, argConfig) => {\n return newCmd.addGlobalOption(argConfig);\n },\n cli.getCommandCLI(firstArg as Extract<keyof TCommands, string>) as AnyCLI,\n );\n\n // run the sub-command\n return _runCLIHelper({\n rawPositionalArgs: rawPositionalArgs.slice(1),\n rawOptionArgs,\n rawGlobalOptionArgs,\n cli: commandCLI,\n });\n }\n\n const cliName = cli.getName();\n\n // build the positional arguments dictionary\n // first check that we haven't supplied too many positional arguments\n if (rawPositionalArgs.length > cli.state.positionalArgs.length) {\n throw CLIError.tooManyPositionalArgs({\n cliName,\n count: rawPositionalArgs.length,\n });\n }\n\n // parse positional arguments\n const parsedPositionalArgs: Record<string, CLIParamDataType> = {};\n for (const [idx, argConfig] of cli.state.positionalArgs.entries()) {\n let rawVal = rawPositionalArgs[idx];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredPositionalArg({\n cliName,\n positionalArgName: argConfig.name,\n });\n }\n\n parsedPositionalArgs[argConfig.name] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // parse the options\n const parsedOptionArgs: Record<string, CLIParamDataType> = {};\n for (const argConfig of Object.values(\n cli.state.optionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n )) {\n let rawVal = rawOptionArgs[argConfig.name];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredOption({\n cliName,\n optionName: argConfig.name,\n });\n }\n\n parsedOptionArgs[camelCase(argConfig.name)] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // parse the global options\n const parsedGlobalOptionArgs: Record<string, CLIParamDataType> = {};\n for (const argConfig of Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n )) {\n let rawVal = rawGlobalOptionArgs[argConfig.name];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredOption({\n cliName,\n optionName: argConfig.name,\n });\n }\n parsedGlobalOptionArgs[camelCase(argConfig.name)] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // run the action\n const action = cli.state.action;\n if (action) {\n action({\n ...parsedPositionalArgs,\n ...parsedOptionArgs,\n ...parsedGlobalOptionArgs,\n } as FullCLIArgValues<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams\n >);\n return;\n }\n\n console.log(generateHelpText(cli));\n}\n\n/**\n * Run a CLI instance given an array of inputs.\n *\n * @param options - The options for running the CLI.\n */\nexport async function runCLI(options: {\n input: string[];\n cli: AnyCLI;\n}): Promise<void> {\n const { input, cli } = options;\n const firstOptionIdx = input.findIndex((token) => {\n return token.startsWith(\"-\");\n });\n\n const [rawPositionalArgs, rest] =\n firstOptionIdx === -1 ?\n [input, []]\n : [input.slice(0, firstOptionIdx), input.slice(firstOptionIdx)];\n\n const rawOptionArgs: Record<CLIOptionAlias, string> = {};\n const rawGlobalOptionArgs: Record<CLIFullOptionName, string> = {};\n let currentAlias: CLIOptionAlias | undefined;\n let currentVals: string[] = [];\n\n const { aliases, globalOptionArgs } = cli.state as CLIState<\n Record<CLIFullOptionName, CLIOptionParam>,\n Record<CLIFullOptionName, CLIOptionParam>,\n Record<CLIPositionalParamName, CLIOptionParam>,\n Record<CLICommandName, AnyCLI>\n >;\n\n for (const argVal of rest.concat(\"-\")) {\n if (_isValidOptionAlias(argVal)) {\n if (currentAlias) {\n const rawValue = currentVals.join(\" \");\n const optionName = aliases[currentAlias] ?? currentAlias;\n if (\n _isValidFullOptionName(optionName) &&\n !isEmptyObject(globalOptionArgs) &&\n globalOptionArgs[optionName]\n ) {\n rawGlobalOptionArgs[optionName] = rawValue;\n } else {\n rawOptionArgs[optionName] = rawValue;\n }\n }\n currentAlias = argVal;\n currentVals = [];\n } else {\n currentVals.push(argVal);\n }\n }\n\n await _runCLIHelper({\n rawPositionalArgs,\n rawOptionArgs,\n rawGlobalOptionArgs,\n cli,\n });\n}\n","import { createCLI } from \"./AcclimateCLI\";\nimport { runCLI } from \"./AcclimateCLI/runCLI/runCLI\";\nimport { generateTerminalMessage } from \"./generateTerminalMessage\";\nimport { requestTerminalInput } from \"./requestTerminalInput\";\nimport type { AnyCLI, IAcclimateCLI } from \"./AcclimateCLI/AcclimateCLI.types\";\n\ntype Acclimate = {\n /**\n * Create a new Acclimate CLI instance.\n *\n * @param name - The name of the CLI.\n * @returns A new CLI instance.\n */\n createCLI: (name: string) => IAcclimateCLI;\n\n /**\n * Run a CLI instance.\n *\n * It can only be run once. Calling any other methods after `.run()` will\n * throw an error.\n *\n * @param cli - The CLI instance to run.\n */\n run: (cli: AnyCLI) => void;\n\n /**\n * Outputs a message with `console.log`.\n * Supports interpolation using `$varName$` as tokens.\n *\n * Colors can be changed within a message `|<COLOR_NAME>|` tokens.\n * Supported colors are:\n * - black\n * - red\n * - green\n * - yellow\n * - blue\n * - magenta\n * - cyan\n * - white\n * - bright_black|gray|grey\n * - bright_red\n * - bright_green\n * - bright_yellow\n * - bright_blue\n * - bright_magenta\n * - bright_cyan\n * - bright_white\n *\n * The color remains active until another color token is found,\n * or if |reset| is found (which resets the terminal color to the default).\n *\n * @example\n *\n * Acclimate.log(\"Hello $name$\", { name: \"Pablo\" });\n * // \"Hello Pablo\"\n *\n * Acclimate.log(\"|red|Error:|reset| There was an error.\")\n * // \"Error: There was an error.\"\n * // ^ the \"Error:\" portion will be red\n *\n */\n log: (message: string, params?: Record<string, string | undefined>) => void;\n\n /**\n * Prompt the user for interactive input in the terminal.\n *\n * @param options - Prompt configuration.\n * @returns The user's response, or undefined when left empty and optional.\n */\n requestInput: (options: {\n message: string;\n params: Record<string, string>;\n options: { required: boolean; type?: \"string\" | \"number\" | \"boolean\" };\n }) => Promise<string | undefined>;\n};\n\nexport const Acclimate: Acclimate = {\n createCLI,\n run: (cli: AnyCLI) => {\n void runCLI({ cli, input: process.argv.slice(2) });\n },\n log: (message: string, params: Record<string, string | undefined> = {}) => {\n console.log(generateTerminalMessage(message, params));\n },\n requestInput: (options) => {\n return requestTerminalInput(options);\n },\n};\n"]}
1
+ {"version":3,"sources":["../src/CLIError.ts","../src/AcclimateCLI/AcclimateCLI.ts","../src/AcclimateCLI/createCLI/defaultCLIState.ts","../src/AcclimateCLI/createCLI/createCLI.ts","../src/generateTerminalMessage/generateTerminalMessage.ts","../src/AcclimateCLI/generateHelpText/generateHelpText.ts","../src/requestTerminalInput/requestTerminalInput.ts","../src/AcclimateCLI/runCLI/runCLI.ts","../src/Acclimate.ts"],"names":["match","createInterface","stdin","stdout","camelCase"],"mappings":";;;;;;;;AA4CO,IAAM,QAAA,GAAN,MAAM,SAAA,SAAiB,KAAA,CAAM;AAAA,EAClC,OAAO,qBAAqB,OAAA,EAKf;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EACE,OAAA,CAAQ,OAAA,IAAW,CAAA,6BAAA,EAAgC,QAAQ,SAAS,CAAA,CAAA,CAAA;AAAA,MACtE,IAAA,EAAM,yBAAA;AAAA,MACN,SAAS,EAAE,SAAA,EAAW,QAAQ,SAAA,EAAW,UAAA,EAAY,QAAQ,UAAA;AAAW,KACzE,CAAA;AAAA,EACH;AAAA,EACA,OAAO,sBAAsB,OAAA,EAIhB;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EACE,OAAA,CAAQ,OAAA,IAAW,CAAA,iBAAA,EAAoB,QAAQ,UAAU,CAAA,YAAA,CAAA;AAAA,MAC3D,IAAA,EAAM,yBAAA;AAAA,MACN,OAAA,EAAS,EAAE,UAAA,EAAY,OAAA,CAAQ,UAAA;AAAW,KAC3C,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,6BAA6B,OAAA,EAIvB;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EACE,OAAA,CAAQ,OAAA,IACR,CAAA,8BAAA,EAAiC,QAAQ,iBAAiB,CAAA,YAAA,CAAA;AAAA,MAC5D,IAAA,EAAM,iCAAA;AAAA,MACN,OAAA,EAAS,EAAE,iBAAA,EAAmB,OAAA,CAAQ,iBAAA;AAAkB,KACzD,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,cAAc,OAAA,EAIR;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EAAS,OAAA,CAAQ,OAAA,IAAW,CAAA,QAAA,EAAW,QAAQ,UAAU,CAAA,WAAA,CAAA;AAAA,MACzD,IAAA,EAAM,gBAAA;AAAA,MACN,OAAA,EAAS,EAAE,UAAA,EAAY,OAAA,CAAQ,UAAA;AAAW,KAC3C,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,sBAAsB,OAAA,EAIhB;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EAAS,QAAQ,OAAA,IAAW,yCAAA;AAAA,MAC5B,IAAA,EAAM,0BAAA;AAAA,MACN,OAAA,EAAS,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA;AAAM,KACjC,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,2BAA2B,OAAA,EAIrB;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EACE,OAAA,CAAQ,OAAA,IACR,CAAA,uCAAA,EAA0C,QAAQ,iBAAiB,CAAA,YAAA,CAAA;AAAA,MACrE,IAAA,EAAM,+BAAA;AAAA,MACN,OAAA,EAAS,EAAE,iBAAA,EAAmB,OAAA,CAAQ,iBAAA;AAAkB,KACzD,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,eAAe,OAAA,EAIT;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EAAS,OAAA,CAAQ,OAAA,IAAW,CAAA,SAAA,EAAY,QAAQ,WAAW,CAAA,WAAA,CAAA;AAAA,MAC3D,IAAA,EAAM,iBAAA;AAAA,MACN,OAAA,EAAS,EAAE,WAAA,EAAa,OAAA,CAAQ,WAAA;AAAY,KAC7C,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,WAAW,OAAA,EAGL;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EAAS,QAAQ,OAAA,IAAW,0BAAA;AAAA,MAC5B,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AAAA,EAEA,YAAY,OAAA,EAA0B;AACpC,IAAA,KAAA,CAAM,wBAAmB,OAAA,CAAQ,OAAO,CAAA,EAAA,EAAK,OAAA,CAAQ,OAAO,CAAA,CAAE,CAAA;AAAA,EAChE;AACF,CAAA;;;AC/IO,SAAS,aAUd,KAAA,EAWA;AACA,EAAA,MAAM,UAAU,KAAA,CAAM,IAAA;AACtB,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IAEA,SAAS,MAAM;AACb,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAA,EAAQ,CACN,MAAA,KAcG;AACH,MAAA,OAAO,YAAA,CAAa;AAAA,QAClB,GAAG,KAAA;AAAA,QACH;AAAA,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,WAAA,EAAa,CACX,WAAA,KAMG;AACH,MAAA,OAAO,YAAA,CAAa;AAAA,QAClB,GAAG,KAAA;AAAA,QACH;AAAA,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,gBAAA,EAAkB,CAIhB,KAAA,KACG;AACH,MAAA,IACE,MAAM,QAAA,IACN,KAAA,CAAM,cAAA,CAAe,IAAA,CAAK,CAAC,CAAA,KAAM;AAC/B,QAAA,OAAO,CAAC,CAAA,CAAE,QAAA;AAAA,MACZ,CAAC,CAAA,EACD;AACA,QAAA,MAAM,SAAS,0BAAA,CAA2B;AAAA,UACxC,OAAA;AAAA,UACA,mBAAmB,KAAA,CAAM,IAAA;AAAA,UACzB,OAAA,EACE;AAAA,SACH,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,YAAA,CAAa;AAAA,QAClB,GAAG,KAAA;AAAA,QACH,cAAA,EAAgB;AAAA,UACd,GAAG,KAAA,CAAM,cAAA;AAAA,UACT,EAAE,GAAG,KAAA,EAAO,QAAA,EAAU,KAAA,CAAM,YAAY,IAAA;AAAK;AAC/C,OAMD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,eAAA,EAAiB,CAA2B,KAAA,KAAa;AACvD,MAAA,MAAM,UAAA,GAAA,CAAc,KAAA,CAAM,OAAA,IAAW,EAAC,EAAG,MAAA;AAAA,QACvC,CAAC,KAAK,KAAA,KAAU;AACd,UAAA,GAAA,CAAI,KAAK,IAAI,KAAA,CAAM,IAAA;AACnB,UAAA,OAAO,GAAA;AAAA,QACT,CAAA;AAAA,QACA;AAAC,OACH;AACA,MAAA,OAAO,YAAA,CAKL;AAAA,QACA,GAAG,KAAA;AAAA,QACH,SAAS,EAAE,GAAG,KAAA,CAAM,OAAA,EAAS,GAAG,UAAA,EAAW;AAAA,QAC3C,gBAAA,EAAkB;AAAA,UAChB,GAAG,KAAA,CAAM,gBAAA;AAAA,UACT,CAAC,KAAA,CAAM,IAAI,GAAG;AAAA;AAChB,OAMD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,SAAA,EAAW,CAA2B,KAAA,KAAa;AACjD,MAAA,MAAM,UAAA,GAAA,CAAc,KAAA,CAAM,OAAA,IAAW,EAAC,EAAG,MAAA;AAAA,QACvC,CAAC,KAAK,KAAA,KAAU;AACd,UAAA,GAAA,CAAI,KAAK,IAAI,KAAA,CAAM,IAAA;AACnB,UAAA,OAAO,GAAA;AAAA,QACT,CAAA;AAAA,QACA;AAAC,OACH;AACA,MAAA,OAAO,YAAA,CAKL;AAAA,QACA,GAAG,KAAA;AAAA,QACH,SAAS,EAAE,GAAG,KAAA,CAAM,OAAA,EAAS,GAAG,UAAA,EAAW;AAAA,QAC3C,UAAA,EAAY,EAAE,GAAG,KAAA,CAAM,YAAY,CAAC,KAAA,CAAM,IAAI,GAAG,KAAA;AAAM,OAMxD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,UAAA,EAAY,CACV,WAAA,EACA,GAAA,KAMG;AACH,MAAA,OAAO,YAAA,CAAa;AAAA,QAClB,GAAG,KAAA;AAAA,QACH,QAAA,EAAU;AAAA,UACR,GAAG,KAAA,CAAM,QAAA;AAAA,UACT,CAAC,WAAW,GAAG;AAAA;AACjB,OAMD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,aAAA,EAAe,CACb,WAAA,KACqD;AACrD,MAAA,MAAM,GAAA,GAAM,KAAA,CAAM,QAAA,CAAS,WAAW,CAAA;AACtC,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,SAAS,cAAA,CAAe;AAAA,UAC5B,OAAA;AAAA,UACA,WAAA;AAAA,UACA,OAAA,EAAS,YAAY,WAAW,CAAA,WAAA;AAAA,SACjC,CAAA;AAAA,MACH;AACA,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,GACF;AACF;;;ACzMO,IAAM,eAAA,GAGT;AAAA,EACF,SAAS,EAAC;AAAA,EACV,WAAA,EAAa,MAAA;AAAA,EACb,UAAU,EAAC;AAAA,EACX,gBAAgB,EAAC;AAAA,EACjB,YAAY,EAAC;AAAA,EACb,kBAAkB,EAAC;AAAA,EACnB,MAAA,EAAQ;AACV,CAAA;;;ACHO,SAAS,UACd,IAAA,EACmE;AACnE,EAAA,OAAO,YAAA,CAAa,EAAE,GAAG,eAAA,EAAiB,MAAM,CAAA;AAClD;;;ACfA,IAAM,WAAA,GAAsC;AAAA,EAC1C,KAAA,EAAO,SAAA;AAAA,EACP,KAAA,EAAO,UAAA;AAAA,EACP,GAAA,EAAK,UAAA;AAAA,EACL,KAAA,EAAO,UAAA;AAAA,EACP,MAAA,EAAQ,UAAA;AAAA,EACR,IAAA,EAAM,UAAA;AAAA,EACN,OAAA,EAAS,UAAA;AAAA,EACT,IAAA,EAAM,UAAA;AAAA,EACN,KAAA,EAAO,UAAA;AAAA,EACP,YAAA,EAAc,UAAA;AAAA,EACd,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,UAAA;AAAA,EACN,UAAA,EAAY,UAAA;AAAA,EACZ,YAAA,EAAc,UAAA;AAAA,EACd,aAAA,EAAe,UAAA;AAAA,EACf,WAAA,EAAa,UAAA;AAAA,EACb,cAAA,EAAgB,UAAA;AAAA,EAChB,WAAA,EAAa,UAAA;AAAA,EACb,YAAA,EAAc;AAChB,CAAA;AAEA,IAAM,iBAAA,GAAoB,sBAAA;AAC1B,IAAM,iBAAA,GAAoB,mBAAA;AAM1B,SAAS,iBAAA,CACP,SACA,MAAA,EACA;AACA,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,iBAAA,EAAmB,CAACA,QAAO,GAAA,KAAgB;AAEhE,IAAA,MAAM,KAAA,GAAQ,OAAO,GAAG,CAAA;AACxB,IAAA,IAAI,UAAU,MAAA,EAAW;AACvB,MAAA,OAAO,EAAA;AAAA,IACT;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAC,CAAA;AACH;AAEA,SAAS,YAAY,OAAA,EAAiB;AACpC,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,iBAAA,EAAmB,CAACA,QAAO,SAAA,KAAsB;AACtE,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,SAAA,CAAU,WAAA,EAAa,CAAA;AAChD,IAAA,OAAO,IAAA,IAAQA,MAAAA;AAAA,EACjB,CAAC,CAAA;AACH;AAuCO,SAAS,uBAAA,CACd,OAAA,EACA,MAAA,GAA6C,EAAC,EACtC;AACR,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,OAAA,CAAQ,KAAA,CAAM,iBAAiB,CAAC,CAAA;AAC9D,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,OAAA,EAAQ,CAAE,SAAS,SAAS,CAAA;AAC1D,EAAA,MAAM,YACJ,aAAA,IAAiB,CAAC,aAAA,GAAgB,CAAA,EAAG,OAAO,CAAA,OAAA,CAAA,GAAY,OAAA;AAC1D,EAAA,MAAM,YAAA,GAAe,iBAAA,CAAkB,SAAA,EAAW,MAAM,CAAA;AACxD,EAAA,OAAO,YAAY,YAAY,CAAA;AACjC;;;ACtEA,SAAS,mBAAmB,KAAA,EAA6B;AACvD,EAAA,OAAO,kBAAkB,KAAK,CAAA,OAAA,CAAA;AAChC;AAEA,SAAS,cAAA,GAAyB;AAChC,EAAA,OAAO,qBAAA;AACT;AAEA,SAAS,mBACP,KAAA,EACQ;AACR,EAAA,OAAO,CAAA,gBAAA,EAAmB,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA,QAAA,CAAA;AACjD;AAEA,SAAS,gBAAgB,KAAA,EAAqC;AAC5D,EAAA,MAAM,WAAA,GAAc,MAAM,WAAA,IAAe,gBAAA;AACzC,EAAA,MAAM,aAAA,GACJ,KAAA,CAAM,QAAA,GAAW,sBAAA,GAAyB,uBAAA;AAC5C,EAAA,MAAM,eACJ,KAAA,CAAM,YAAA,KAAiB,SACrB,kBAAA,CAAmB,KAAA,CAAM,YAAY,CAAA,GACrC,MAAA;AACJ,EAAA,MAAM,SAAA,GACJ,KAAA,CAAM,OAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,MAAA,GAAS,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,GAAI,EAAA;AACzE,EAAA,MAAM,WAAA,GAAc,YAAY,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,SAAS,KAAK,KAAA,CAAM,IAAA;AAEtE,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,mBAAmB,WAAW,CAAA,OAAA,CAAA;AAAA,IAC9B,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,CAAA,SAAA,EAAY,aAAa,CAAA,CAAA;AAAA,IACvC,WAAW,WAAW,CAAA,OAAA,CAAA;AAAA,IACtB;AAAA,GACF,CAAE,OAAO,OAAO,CAAA;AAEhB,EAAA,OAAO,QAAA,CAAS,KAAK,GAAG,CAAA;AAC1B;AAEA,SAAS,aAAA,CACP,OACA,MAAA,EACU;AACV,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,OAAO,CAAC,kBAAA,CAAmB,KAAK,CAAA,EAAG,gBAAgB,CAAA;AAAA,EACrD;AAEA,EAAA,OAAO,CAAC,mBAAmB,KAAK,CAAA,EAAG,GAAG,MAAA,CAAO,GAAA,CAAI,eAAe,CAAC,CAAA;AACnE;AAEA,SAAS,kBAAkB,OAAA,EAGhB;AACT,EAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAY,GAAI,OAAA;AAC9B,EAAA,MAAM,QAAQ,WAAA,IAAe,gBAAA;AAC7B,EAAA,OAAO,CAAA,gBAAA,EAAmB,IAAI,CAAA,gBAAA,EAAmB,KAAK,CAAA,OAAA,CAAA;AACxD;AAEA,SAAS,4BAA4B,QAAA,EAA4B;AAC/D,EAAA,MAAM,KAAA,GACJ,SAAS,MAAA,KAAW,CAAA,GAClB,SACA,QAAA,CACG,GAAA,CAAI,CAAC,GAAA,KAAQ;AACZ,IAAA,OAAO,GAAA;AAAA,EACT,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAChB,EAAA,OAAO,mDAAmD,KAAK,CAAA,OAAA,CAAA;AACjE;AAEA,SAAS,uBAAA,CAUP,KAMA,OAAA,EACQ;AACR,EAAA,MAAM,IAAA,GAAO,IAAI,OAAA,EAAQ;AACzB,EAAA,MAAM,WAAA,GAAc,IAAI,KAAA,CAAM,WAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA;AAElC,EAAA,MAAM,gBAAA,GAAmB,IAAI,KAAA,CAC1B,cAAA;AACH,EAAA,MAAM,eAAe,MAAA,CAAO,MAAA;AAAA,IAC1B,IAAI,KAAA,CAAM;AAAA,GACZ;AACA,EAAA,MAAM,qBAAqB,MAAA,CAAO,MAAA;AAAA,IAChC,IAAI,KAAA,CAAM;AAAA,GACZ;AACA,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,MAAM,QAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA,KAAM;AAC3E,IAAA,OAAO,CAAA,CAAE,cAAc,CAAC,CAAA;AAAA,EAC1B,CAAC,CAAA;AACD,EAAA,MAAM,eAAe,cAAA,CAAe,GAAA,CAAI,CAAC,CAAC,WAAW,CAAA,KAAM;AACzD,IAAA,OAAO,WAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,aAAA,EAAgB,IAAI,CAAA,OAAA,CAAS,CAAA;AAClD,EAAA,IAAI,gBAAgB,MAAA,EAAW;AAC7B,IAAA,WAAA,CAAY,IAAA,CAAK,CAAA,QAAA,EAAW,WAAW,CAAA,OAAA,CAAS,CAAA;AAAA,EAClD;AAEA,EAAA,IAAI,cAAA;AACJ,EAAA,IAAI,UAAU,CAAA,EAAG;AACf,IAAA,cAAA,GAAiB;AAAA,MACf,mBAAmB,UAAU,CAAA;AAAA,MAC7B,CAAA,EAAA,EAAK,2BAAA,CAA4B,YAAY,CAAC,CAAA;AAAA,KAChD;AAAA,EACF,CAAA,MAAA,IAAW,cAAA,CAAe,MAAA,KAAW,CAAA,EAAG;AACtC,IAAA,cAAA,GAAiB,CAAC,kBAAA,CAAmB,UAAU,CAAA,EAAG,gBAAgB,CAAA;AAAA,EACpE,CAAA,MAAO;AACL,IAAA,cAAA,GAAiB;AAAA,MACf,mBAAmB,UAAU,CAAA;AAAA,MAC7B,GAAG,cAAA,CAAe,GAAA,CAAI,CAAC,CAAC,WAAA,EAAa,UAAU,CAAA,KAAM;AACnD,QAAA,OAAO,iBAAA,CAAkB;AAAA,UACvB,IAAA,EAAM,WAAA;AAAA,UACN,WAAA,EAAa,WAAW,KAAA,CAAM;AAAA,SAC/B,CAAA;AAAA,MACH,CAAC;AAAA,KACH;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,aAAA,CAAc,wBAAwB,gBAAgB,CAAA;AAAA,IACtD,aAAA,CAAc,WAAW,YAAY,CAAA;AAAA,IACrC,aAAA,CAAc,kBAAkB,kBAAkB,CAAA;AAAA,IAClD;AAAA,GACF;AAEA,EAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,WAAA,EAAa,EAAE,CAAA;AACjC,EAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,EAAS,GAAA,KAAQ;AACjC,IAAA,KAAA,CAAM,IAAA,CAAK,GAAG,OAAO,CAAA;AACrB,IAAA,IAAI,GAAA,GAAM,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAC7B,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,IACf;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAI,UAAU,CAAA,EAAG;AACf,IAAA,MAAM,qBAAqB,cAAA,CAAe,GAAA,CAAI,CAAC,GAAG,UAAU,CAAA,KAAM;AAChE,MAAA,OAAO,uBAAA,CAAwB,UAAA,EAAY,EAAE,KAAA,EAAO,GAAG,CAAA;AAAA,IACzD,CAAC,CAAA;AACD,IAAA,IAAI,kBAAA,CAAmB,SAAS,CAAA,EAAG;AACjC,MAAA,kBAAA,CAAmB,OAAA,CAAQ,CAAC,IAAA,KAAS;AACnC,QAAA,KAAA,CAAM,KAAK,EAAA,EAAI,GAAG,IAAA,CAAK,KAAA,CAAM,IAAI,CAAC,CAAA;AAAA,MACpC,CAAC,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,OAAO,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG,KAAA,GAAQ,CAAC,CAAC,CAAA;AACnD,EAAA,OAAO,KAAA,CACJ,GAAA,CAAI,CAAC,IAAA,KAAS;AACb,IAAA,OAAO,SAAS,EAAA,GAAK,EAAA,GAAK,CAAA,EAAG,MAAM,GAAG,IAAI,CAAA,CAAA;AAAA,EAC5C,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AACd;AAEO,SAAS,iBAUd,GAAA,EAMQ;AACR,EAAA,OAAO,wBAAwB,uBAAA,CAAwB,GAAA,EAAK,EAAE,KAAA,EAAO,CAAA,EAAG,CAAC,CAAA;AAC3E;AC1MA,eAAsB,qBAAqB,OAAA,EAeX;AAC9B,EAAA,MAAM;AAAA,IACJ,OAAA;AAAA,IACA,MAAA;AAAA,IACA,eAAA,EAAiB,EAAE,QAAA,EAAU,IAAA,EAAM,YAAA;AAAa,GAClD,GAAI,OAAA;AACJ,EAAA,MAAM,MAAA,GACJ,YAAA,KAAiB,MAAA,GAAY,4CAAA,GAC3B,WAAW,EAAA,GACX,4CAAA;AACJ,EAAA,MAAM,aAAA,GACJ,YAAA,KAAiB,MAAA,GAAY,CAAA,WAAA,EAAc,YAAY,CAAA,CAAA,CAAA,GAAM,EAAA;AAC/D,EAAA,MAAM,aAAA,GAAgB,IAAA,KAAS,SAAA,GAAY,eAAA,GAAkB,EAAA;AAC7D,EAAA,MAAM,aAAA,GAAgB,GAAG,OAAO,CAAA,EAAG,aAAa,CAAA,EAAG,aAAa,GAAG,MAAM,CAAA,CAAA,CAAA;AACzE,EAAA,MAAM,MAAA,GAAS,uBAAA,CAAwB,aAAA,EAAe,MAAM,CAAA;AAE5D,EAAA,MAAM,KAAKC,wBAAA,CAAgB,EAAE,OAAOC,eAAA,EAAO,MAAA,EAAQC,kBAAQ,CAAA;AAC3D,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,EAAM;AACX,MAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,QAAA,CAAS,MAAM,CAAA;AACvC,MAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAC5B,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,QAAA,IAAI,iBAAiB,KAAA,CAAA,EAAW;AAE9B,UAAA,OACE,OAAO,YAAA,KAAiB,QAAA,GAAW,YAAA,GACjC,OAAO,YAAA,KAAiB,QAAA,GAAW,MAAA,CAAO,YAAY,CAAA,GACtD,YAAA,GAAe,MAAA,GACf,OAAA;AAAA,QAEN;AAEA,QAAA,IAAI,QAAA,EAAU;AACZ,UAAAA,gBAAA,CAAO,KAAA;AAAA,YACL,uBAAA;AAAA,cACE;AAAA;AACF,WACF;AACA,UAAA;AAAA,QACF;AACA,QAAA,OAAO,KAAA,CAAA;AAAA,MACT;AACA,MAAA,IAAI,SAAS,SAAA,EAAW;AACtB,QAAA,MAAM,UAAA,GAAa,QAAQ,WAAA,EAAY;AACvC,QAAA,IAAI,UAAA,KAAe,GAAA,IAAO,UAAA,KAAe,KAAA,EAAO;AAC9C,UAAA,OAAO,MAAA;AAAA,QACT;AACA,QAAA,IAAI,UAAA,KAAe,GAAA,IAAO,UAAA,KAAe,IAAA,EAAM;AAC7C,UAAA,OAAO,OAAA;AAAA,QACT;AACA,QAAAA,gBAAA,CAAO,KAAA;AAAA,UACL,uBAAA;AAAA,YACE;AAAA;AACF,SACF;AACA,QAAA;AAAA,MACF;AACA,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA,SAAE;AACA,IAAA,EAAA,CAAG,KAAA,EAAM;AAAA,EACX;AACF;;;AC9DA,SAAS,uBAAuB,IAAA,EAAyC;AACvE,EAAA,OAAO,IAAA,CAAK,WAAW,IAAI,CAAA;AAC7B;AAEA,SAAS,oBAAoB,IAAA,EAAsC;AACjE,EAAA,OAAO,IAAA,CAAK,WAAW,GAAG,CAAA;AAC5B;AAEA,SAAS,cAAc,GAAA,EAAiC;AACtD,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,MAAA,KAAW,CAAA;AACrC;AAEA,SAAS,qBAGP,OAAA,EAA2E;AAC3E,EAAA,MAAM,EAAE,WAAA,EAAa,WAAA,EAAa,OAAA,EAAQ,GAAI,OAAA;AAC9C,EAAA,IAAI,YAAY,SAAA,EAAW;AACzB,IAAA,MAAM,YAAY,WAAA,CAAY,SAAA;AAG9B,IAAA,MAAM,gBAAA,GAAmB,UAAU,WAAW,CAAA;AAC9C,IAAA,IAAI,qBAAqB,IAAA,EAAM;AAC7B,MAAA,OAAO,WAAA;AAAA,IACT;AACA,IAAA,MAAM,SAAS,oBAAA,CAAqB;AAAA,MAClC,OAAA;AAAA,MACA,WAAW,WAAA,CAAY,IAAA;AAAA,MACvB,UAAA,EAAY,WAAA;AAAA,MACZ,OAAA,EACE,OAAO,gBAAA,KAAqB,QAAA,GAAW,gBAAA,GAAmB;AAAA,KAC7D,CAAA;AAAA,EACH;AACA,EAAA,OAAO,WAAA;AACT;AAEA,SAAS,uBAGP,OAAA,EAKqB;AACrB,EAAA,MAAM,EAAE,OAAA,EAAS,UAAA,EAAY,YAAA,EAAc,aAAY,GAAI,OAAA;AAC3D,EAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,IAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,OAAO,oBAAA,CAAqB;AAAA,MAC1B,OAAA;AAAA,MACA,WAAA,EAAa,YAAA;AAAA,MACb;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,WAAA,GACJ,WAAA,CAAY,MAAA,GACT,WAAA,CAAY,MAAA,CAAO,UAAU,CAAA,GAE7BH,eAAA,CAAM,WAAA,CAAY,IAAI,CAAA,CACpB,IAAA,CAAK,WAAW,MAAM;AACrB,IAAA,OAAO,UAAA,KAAe,UAAU,KAAA,GAAQ,IAAA;AAAA,EAC1C,CAAC,CAAA,CACA,IAAA,CAAK,QAAA,EAAU,MAAM;AACpB,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,UAAA,EAAY,EAAE,CAAA;AAAA,EACvC,CAAC,CAAA,CACA,IAAA,CAAK,QAAA,EAAU,MAAM;AACpB,IAAA,OAAO,UAAA;AAAA,EACT,CAAC,CAAA,CACA,UAAA,CAAW,MAAM;AAChB,IAAA,OAAO,UAAA;AAAA,EACT,CAAC,CAAA;AACP,EAAA,OAAO,oBAAA,CAAqB;AAAA,IAC1B,OAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH;AAEA,SAAS,eAAA,CASP;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA,EAQmC;AACjC,EAAA,MAAM,QAAA,GAAW,IAAI,KAAA,CAAM,OAAA;AAC3B,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,iBAAiB,CAAA,CAAE,MAAA;AAAA,IACvC,CAAC,GAAA,EAAK,CAAC,QAAA,EAAU,KAAK,CAAA,KAAM;AAC1B,MAAA,MAAM,KAAA,GAAQ,QAAA;AACd,MAAA,MAAM,UAAA,GAAa,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA;AACtC,MAAA,GAAA,CAAI,UAAU,CAAA,GAAI,KAAA;AAClB,MAAA,OAAO,GAAA;AAAA,IACT,CAAA;AAAA,IACA;AAAC,GACH;AACF;AAMA,eAAe,YAAY,OAAA,EAEK;AAC9B,EAAA,MAAM,EAAE,WAAU,GAAI,OAAA;AACtB,EAAA,MAAM,aAAa,SAAA,CAAU,UAAA;AAC7B,EAAA,MAAM,cACJ,SAAA,CAAU,WAAA,GAAc,CAAA,EAAA,EAAK,SAAA,CAAU,WAAW,CAAA,CAAA,CAAA,GAAM,EAAA;AAC1D,EAAA,MAAM,WAAA,GACJ,OAAO,UAAA,KAAe,QAAA,GACpB,UAAA,CAAW,UACX,CAAA,yBAAA,EAA4B,SAAA,CAAU,IAAI,CAAA,EAAG,WAAW,CAAA,CAAA;AAC5D,EAAA,MAAM,cAAA,GAAiB,gBAAgB,WAAW,CAAA,OAAA,CAAA;AAClD,EAAA,OAAO,oBAAA,CAAqB;AAAA,IAC1B,OAAA,EAAS,cAAA;AAAA,IACT,QAAQ,EAAC;AAAA,IACT,eAAA,EAAiB;AAAA,MACf,UAAU,SAAA,CAAU,QAAA;AAAA,MACpB,MAAM,SAAA,CAAU,IAAA;AAAA,MAChB,cAAc,SAAA,CAAU;AAAA;AAC1B,GACD,CAAA;AACH;AAEA,eAAe,cASb,OAAA,EAUgB;AAChB,EAAA,MAAM,EAAE,mBAAA,EAAqB,aAAA,EAAe,iBAAA,EAAmB,KAAI,GAAI;AAAA,IACrE,GAAG,OAAA;AAAA,IACH,qBAAqB,eAAA,CAAgB;AAAA,MACnC,mBAAmB,OAAA,CAAQ,mBAAA;AAAA,MAC3B,KAAK,OAAA,CAAQ;AAAA,KACd,CAAA;AAAA,IACD,eAAe,eAAA,CAAgB;AAAA,MAC7B,mBAAmB,OAAA,CAAQ,aAAA;AAAA;AAAA,MAG3B,KAAK,OAAA,CAAQ;AAAA,KACd;AAAA,GACH;AAGA,EAAA,MAAM,QAAA,GAAW,kBAAkB,CAAC,CAAA;AACpC,EAAA,IACE,QAAA,IACA,CAAC,aAAA,CAAc,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA,IACjC,GAAA,CAAI,KAAA,CAAM,QAAA,CAAS,QAAQ,CAAA,EAC3B;AAEA,IAAA,MAAM,aAAa,MAAA,CAAO,MAAA;AAAA,MACxB,IAAI,KAAA,CAAM;AAAA,KACZ,CAAE,MAAA;AAAA,MACA,CAAC,QAAQ,SAAA,KAAc;AACrB,QAAA,OAAO,MAAA,CAAO,gBAAgB,SAAS,CAAA;AAAA,MACzC,CAAA;AAAA,MACA,GAAA,CAAI,cAAc,QAA4C;AAAA,KAChE;AAGA,IAAA,OAAO,aAAA,CAAc;AAAA,MACnB,iBAAA,EAAmB,iBAAA,CAAkB,KAAA,CAAM,CAAC,CAAA;AAAA,MAC5C,aAAA;AAAA,MACA,mBAAA;AAAA,MACA,GAAA,EAAK;AAAA,KACN,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAI5B,EAAA,IAAI,iBAAA,CAAkB,MAAA,GAAS,GAAA,CAAI,KAAA,CAAM,eAAe,MAAA,EAAQ;AAC9D,IAAA,MAAM,SAAS,qBAAA,CAAsB;AAAA,MACnC,OAAA;AAAA,MACA,OAAO,iBAAA,CAAkB;AAAA,KAC1B,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,uBAAyD,EAAC;AAChE,EAAA,KAAA,MAAW,CAAC,KAAK,SAAS,CAAA,IAAK,IAAI,KAAA,CAAM,cAAA,CAAe,SAAQ,EAAG;AACjE,IAAA,IAAI,MAAA,GAAS,kBAAkB,GAAG,CAAA;AAClC,IAAA,IAAI,SAAA,CAAU,UAAA,IAAc,MAAA,KAAW,MAAA,EAAW;AAChD,MAAA,MAAA,GAAS,MAAM,WAAA,CAAY,EAAE,SAAA,EAAW,CAAA;AAAA,IAC1C;AAEA,IAAA,IAAI,SAAA,CAAU,QAAA,IAAY,MAAA,KAAW,MAAA,EAAW;AAC9C,MAAA,MAAM,SAAS,4BAAA,CAA6B;AAAA,QAC1C,OAAA;AAAA,QACA,mBAAmB,SAAA,CAAU;AAAA,OAC9B,CAAA;AAAA,IACH;AAEA,IAAA,oBAAA,CAAqB,SAAA,CAAU,IAAI,CAAA,GAAI,sBAAA,CAAuB;AAAA,MAC5D,OAAA;AAAA,MACA,UAAA,EAAY,MAAA;AAAA,MACZ,cAAc,SAAA,CAAU,YAAA;AAAA,MACxB,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,mBAAqD,EAAC;AAC5D,EAAA,KAAA,MAAW,aAAa,MAAA,CAAO,MAAA;AAAA,IAC7B,IAAI,KAAA,CAAM;AAAA,GACZ,EAAG;AACD,IAAA,IAAI,MAAA,GAAS,aAAA,CAAc,SAAA,CAAU,IAAI,CAAA;AACzC,IAAA,IAAI,SAAA,CAAU,UAAA,IAAc,MAAA,KAAW,MAAA,EAAW;AAChD,MAAA,MAAA,GAAS,MAAM,WAAA,CAAY,EAAE,SAAA,EAAW,CAAA;AAAA,IAC1C;AAEA,IAAA,IAAI,SAAA,CAAU,QAAA,IAAY,MAAA,KAAW,MAAA,EAAW;AAC9C,MAAA,MAAM,SAAS,qBAAA,CAAsB;AAAA,QACnC,OAAA;AAAA,QACA,YAAY,SAAA,CAAU;AAAA,OACvB,CAAA;AAAA,IACH;AAEA,IAAA,gBAAA,CAAiBI,oBAAA,CAAU,SAAA,CAAU,IAAI,CAAC,IAAI,sBAAA,CAAuB;AAAA,MACnE,OAAA;AAAA,MACA,UAAA,EAAY,MAAA;AAAA,MACZ,cAAc,SAAA,CAAU,YAAA;AAAA,MACxB,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,yBAA2D,EAAC;AAClE,EAAA,KAAA,MAAW,aAAa,MAAA,CAAO,MAAA;AAAA,IAC7B,IAAI,KAAA,CAAM;AAAA,GACZ,EAAG;AACD,IAAA,IAAI,MAAA,GAAS,mBAAA,CAAoB,SAAA,CAAU,IAAI,CAAA;AAC/C,IAAA,IAAI,SAAA,CAAU,UAAA,IAAc,MAAA,KAAW,MAAA,EAAW;AAChD,MAAA,MAAA,GAAS,MAAM,WAAA,CAAY,EAAE,SAAA,EAAW,CAAA;AAAA,IAC1C;AAEA,IAAA,IAAI,SAAA,CAAU,QAAA,IAAY,MAAA,KAAW,MAAA,EAAW;AAC9C,MAAA,MAAM,SAAS,qBAAA,CAAsB;AAAA,QACnC,OAAA;AAAA,QACA,YAAY,SAAA,CAAU;AAAA,OACvB,CAAA;AAAA,IACH;AACA,IAAA,sBAAA,CAAuBA,oBAAA,CAAU,SAAA,CAAU,IAAI,CAAC,IAAI,sBAAA,CAAuB;AAAA,MACzE,OAAA;AAAA,MACA,UAAA,EAAY,MAAA;AAAA,MACZ,cAAc,SAAA,CAAU,YAAA;AAAA,MACxB,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,MAAA,GAAS,IAAI,KAAA,CAAM,MAAA;AACzB,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAA,CAAO;AAAA,MACL,GAAG,oBAAA;AAAA,MACH,GAAG,gBAAA;AAAA,MACH,GAAG;AAAA,KAKJ,CAAA;AACD,IAAA;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,GAAA,CAAI,gBAAA,CAAiB,GAAG,CAAC,CAAA;AACnC;AAOA,eAAsB,OAAO,OAAA,EAGX;AAChB,EAAA,MAAM,EAAE,KAAA,EAAO,GAAA,EAAI,GAAI,OAAA;AACvB,EAAA,MAAM,cAAA,GAAiB,KAAA,CAAM,SAAA,CAAU,CAAC,KAAA,KAAU;AAChD,IAAA,OAAO,KAAA,CAAM,WAAW,GAAG,CAAA;AAAA,EAC7B,CAAC,CAAA;AAED,EAAA,MAAM,CAAC,mBAAmB,IAAI,CAAA,GAC5B,mBAAmB,EAAA,GACjB,CAAC,OAAO,EAAE,IACV,CAAC,KAAA,CAAM,MAAM,CAAA,EAAG,cAAc,GAAG,KAAA,CAAM,KAAA,CAAM,cAAc,CAAC,CAAA;AAEhE,EAAA,MAAM,gBAAgD,EAAC;AACvD,EAAA,MAAM,sBAAyD,EAAC;AAChE,EAAA,IAAI,YAAA;AACJ,EAAA,IAAI,cAAwB,EAAC;AAE7B,EAAA,MAAM,EAAE,OAAA,EAAS,gBAAA,EAAiB,GAAI,GAAA,CAAI,KAAA;AAO1C,EAAA,KAAA,MAAW,MAAA,IAAU,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA,EAAG;AACrC,IAAA,IAAI,mBAAA,CAAoB,MAAM,CAAA,EAAG;AAC/B,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,MAAM,QAAA,GAAW,WAAA,CAAY,IAAA,CAAK,GAAG,CAAA;AACrC,QAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,YAAY,CAAA,IAAK,YAAA;AAC5C,QAAA,IACE,sBAAA,CAAuB,UAAU,CAAA,IACjC,CAAC,cAAc,gBAAgB,CAAA,IAC/B,gBAAA,CAAiB,UAAU,CAAA,EAC3B;AACA,UAAA,mBAAA,CAAoB,UAAU,CAAA,GAAI,QAAA;AAAA,QACpC,CAAA,MAAO;AACL,UAAA,aAAA,CAAc,UAAU,CAAA,GAAI,QAAA;AAAA,QAC9B;AAAA,MACF;AACA,MAAA,YAAA,GAAe,MAAA;AACf,MAAA,WAAA,GAAc,EAAC;AAAA,IACjB,CAAA,MAAO;AACL,MAAA,WAAA,CAAY,KAAK,MAAM,CAAA;AAAA,IACzB;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,CAAc;AAAA,IAClB,iBAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH;;;ACxSO,IAAM,SAAA,GAAuB;AAAA,EAClC,SAAA;AAAA,EACA,GAAA,EAAK,CAAC,GAAA,KAAgB;AACpB,IAAA,KAAK,MAAA,CAAO,EAAE,GAAA,EAAK,KAAA,EAAO,QAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA;AAAA,EACnD,CAAA;AAAA,EACA,GAAA,EAAK,CAAC,OAAA,EAAiB,MAAA,GAA6C,EAAC,KAAM;AACzE,IAAA,OAAA,CAAQ,GAAA,CAAI,uBAAA,CAAwB,OAAA,EAAS,MAAM,CAAC,CAAA;AAAA,EACtD,CAAA;AAAA,EACA,YAAA,EAAc,CAAC,OAAA,KAAY;AACzB,IAAA,OAAO,qBAAqB,OAAO,CAAA;AAAA,EACrC;AACF","file":"index.cjs","sourcesContent":["import type { CLIParamDataType } from \"./AcclimateCLI/AcclimateCLI.types\";\n\ntype CLIErrorInfo =\n | {\n code: \"already_run\";\n details: undefined;\n }\n | {\n code: \"unknown_command\";\n details: { commandName: string };\n }\n | {\n code: \"invalid_positional_arg_config\";\n details: { positionalArgName: string };\n }\n | {\n code: \"too_many_positional_args\";\n details: { count: number };\n }\n | {\n code: \"missing_required_positional_arg\";\n details: { positionalArgName: string };\n }\n | {\n code: \"missing_required_option\";\n details: { optionName: string };\n }\n | {\n code: \"unknown_option\";\n details: {\n optionName: string;\n };\n }\n | {\n code: \"invalid_cli_param_value\";\n details: {\n paramName: string;\n paramValue: CLIParamDataType;\n };\n }\n | { code: \"unknown_error\"; details: undefined };\n\ntype CLIErrorOptions = { cliName: string; message: string } & CLIErrorInfo;\n\nexport class CLIError extends Error {\n static invalidCLIParamValue(options: {\n cliName: string;\n paramName: string;\n paramValue: CLIParamDataType;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ?? `Invalid value for CLI param \"${options.paramName}\"`,\n code: \"invalid_cli_param_value\",\n details: { paramName: options.paramName, paramValue: options.paramValue },\n });\n }\n static missingRequiredOption(options: {\n cliName: string;\n optionName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ?? `Required option \"${options.optionName}\" is missing`,\n code: \"missing_required_option\",\n details: { optionName: options.optionName },\n });\n }\n\n static missingRequiredPositionalArg(options: {\n cliName: string;\n positionalArgName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ??\n `Required positional argument \"${options.positionalArgName}\" is missing`,\n code: \"missing_required_positional_arg\",\n details: { positionalArgName: options.positionalArgName },\n });\n }\n\n static unknownOption(options: {\n cliName: string;\n optionName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? `Option \"${options.optionName}\" not found`,\n code: \"unknown_option\",\n details: { optionName: options.optionName },\n });\n }\n\n static tooManyPositionalArgs(options: {\n cliName: string;\n count: number;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? \"Too many positional arguments provided.\",\n code: \"too_many_positional_args\",\n details: { count: options.count },\n });\n }\n\n static invalidPositionalArgConfig(options: {\n cliName: string;\n positionalArgName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ??\n `Positional argument configuration for \"${options.positionalArgName}\" is invalid`,\n code: \"invalid_positional_arg_config\",\n details: { positionalArgName: options.positionalArgName },\n });\n }\n\n static unknownCommand(options: {\n cliName: string;\n commandName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? `Command \"${options.commandName}\" not found`,\n code: \"unknown_command\",\n details: { commandName: options.commandName },\n });\n }\n\n static alreadyRun(options: {\n cliName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? \"CLI has already been run\",\n code: \"already_run\",\n details: undefined,\n });\n }\n\n constructor(options: CLIErrorOptions) {\n super(`❌ Error running ${options.cliName}: ${options.message}`);\n }\n}\n","import { CLIError } from \"@/CLIError\";\nimport type {\n AddEntry,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionParam,\n CLIPositionalParam,\n CLIPositionalParamName,\n CLIState,\n FullCLIArgValues,\n IAcclimateCLI,\n} from \"./AcclimateCLI.types\";\nimport type { EmptyObject, Simplify } from \"type-fest\";\n\nexport function AcclimateCLI<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, IAcclimateCLI> | EmptyObject,\n>(\n state: CLIState<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n> {\n const cliName = state.name;\n return {\n state,\n\n getName: () => {\n return cliName;\n },\n\n action: (\n action: (\n args: Simplify<\n FullCLIArgValues<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams\n >\n >,\n ) => void,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n > => {\n return AcclimateCLI({\n ...state,\n action,\n });\n },\n\n description: (\n description: string,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n > => {\n return AcclimateCLI({\n ...state,\n description,\n });\n },\n\n addPositionalArg: <\n PName extends CLIPositionalParamName,\n P extends CLIPositionalParam<PName>,\n >(\n param: P,\n ) => {\n if (\n param.required &&\n state.positionalArgs.some((p) => {\n return !p.required;\n })\n ) {\n throw CLIError.invalidPositionalArgConfig({\n cliName,\n positionalArgName: param.name,\n message:\n \"Required positional arguments must be before optional positional arguments\",\n });\n }\n\n return AcclimateCLI({\n ...state,\n positionalArgs: [\n ...state.positionalArgs,\n { ...param, required: param.required ?? true },\n ],\n } as unknown as CLIState<\n AddEntry<TPositionalParams, P[\"name\"], P>,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >);\n },\n\n addGlobalOption: <P extends CLIOptionParam>(param: P) => {\n const newAliases = (param.aliases ?? []).reduce(\n (acc, alias) => {\n acc[alias] = param.name;\n return acc;\n },\n {} as Record<`-${string}` | `--${string}`, `--${string}`>,\n );\n return AcclimateCLI<\n TPositionalParams,\n TOptionParams,\n AddEntry<TGlobalOptionParams, P[\"name\"], P>,\n TCommands\n >({\n ...state,\n aliases: { ...state.aliases, ...newAliases },\n globalOptionArgs: {\n ...state.globalOptionArgs,\n [param.name]: param,\n },\n } as unknown as CLIState<\n TPositionalParams,\n TOptionParams,\n AddEntry<TGlobalOptionParams, P[\"name\"], P>,\n TCommands\n >);\n },\n\n addOption: <P extends CLIOptionParam>(param: P) => {\n const newAliases = (param.aliases ?? []).reduce(\n (acc, alias) => {\n acc[alias] = param.name;\n return acc;\n },\n {} as Record<`-${string}` | `--${string}`, `--${string}`>,\n );\n return AcclimateCLI<\n TPositionalParams,\n AddEntry<TOptionParams, P[\"name\"], P>,\n TGlobalOptionParams,\n TCommands\n >({\n ...state,\n aliases: { ...state.aliases, ...newAliases },\n optionArgs: { ...state.optionArgs, [param.name]: param },\n } as unknown as CLIState<\n TPositionalParams,\n AddEntry<TOptionParams, P[\"name\"], P>,\n TGlobalOptionParams,\n TCommands\n >);\n },\n\n addCommand: <C extends CLICommandName, CommandCLI extends IAcclimateCLI>(\n commandName: C,\n cli: CommandCLI,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n AddEntry<TCommands, C, CommandCLI>\n > => {\n return AcclimateCLI({\n ...state,\n commands: {\n ...state.commands,\n [commandName]: cli,\n },\n } as unknown as CLIState<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n AddEntry<TCommands, C, CommandCLI>\n >);\n },\n\n getCommandCLI: <C extends Extract<keyof TCommands, CLICommandName>>(\n commandName: C,\n ): C extends keyof TCommands ? TCommands[C] : never => {\n const cmd = state.commands[commandName];\n if (!cmd) {\n throw CLIError.unknownCommand({\n cliName,\n commandName,\n message: `Command \"${commandName}\" not found`,\n });\n }\n return cmd as C extends keyof TCommands ? TCommands[C] : never;\n },\n };\n}\n","import type { CLIState } from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nexport const defaultCLIState: Omit<\n CLIState<EmptyObject, EmptyObject, EmptyObject, EmptyObject>,\n \"name\"\n> = {\n aliases: {},\n description: undefined,\n commands: {},\n positionalArgs: [],\n optionArgs: {},\n globalOptionArgs: {},\n action: undefined,\n};\n","import { AcclimateCLI } from \"../AcclimateCLI\";\nimport { defaultCLIState } from \"./defaultCLIState\";\nimport type { IAcclimateCLI } from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\n/**\n * Builder function to create a new CLI instance with a given name.\n *\n * @param name - The name of the CLI.\n * @returns A new CLI instance.\n */\nexport function createCLI(\n name: string,\n): IAcclimateCLI<EmptyObject, EmptyObject, EmptyObject, EmptyObject> {\n return AcclimateCLI({ ...defaultCLIState, name });\n}\n","const COLOR_CODES: Record<string, string> = {\n reset: \"\\x1b[0m\",\n black: \"\\x1b[30m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n bright_black: \"\\x1b[90m\",\n gray: \"\\x1b[90m\",\n grey: \"\\x1b[90m\",\n bright_red: \"\\x1b[91m\",\n bright_green: \"\\x1b[92m\",\n bright_yellow: \"\\x1b[93m\",\n bright_blue: \"\\x1b[94m\",\n bright_magenta: \"\\x1b[95m\",\n bright_cyan: \"\\x1b[96m\",\n bright_white: \"\\x1b[97m\",\n};\n\nconst PARAM_TOKEN_REGEX = /\\$([a-zA-Z0-9_]+)\\$/g;\nconst COLOR_TOKEN_REGEX = /\\|([a-zA-Z_]+)\\|/g;\n\n/**\n * Replaces `$token$` placeholders with values from `params`.\n * If a token does not exist in `params`, the placeholder is left unchanged.\n */\nfunction interpolateParams(\n message: string,\n params: Record<string, string | undefined>,\n) {\n return message.replace(PARAM_TOKEN_REGEX, (match, key: string) => {\n void match;\n const value = params[key];\n if (value === undefined) {\n return \"\";\n }\n return value;\n });\n}\n\nfunction applyColors(message: string) {\n return message.replace(COLOR_TOKEN_REGEX, (match, colorName: string) => {\n const code = COLOR_CODES[colorName.toLowerCase()];\n return code ?? match;\n });\n}\n\n/**\n * Outputs a message intended to be passed directly to `console.log`\n *\n * Supports interpolation using `$varName$` as tokens.\n *\n * Colors can be changed within a message `|<COLOR_NAME>|` tokens.\n * Supported colors are:\n * - black\n * - red\n * - green\n * - yellow\n * - blue\n * - magenta\n * - cyan\n * - white\n * - bright_black|gray|grey\n * - bright_red\n * - bright_green\n * - bright_yellow\n * - bright_blue\n * - bright_magenta\n * - bright_cyan\n * - bright_white\n *\n * The color remains active until another color token is found,\n * or if |reset| is found (which resets the terminal color to the default).\n *\n * @example\n *\n * Acclimate.log(\"Hello $name$\", { name: \"Pablo\" });\n * // \"Hello Pablo\"\n *\n * Acclimate.log(\"|red|Error:|reset| There was an error.\")\n * // \"Error: There was an error.\"\n * // ^ the \"Error:\" portion will be red\n *\n */\nexport function generateTerminalMessage(\n message: string,\n params: Record<string, string | undefined> = {},\n): string {\n const hasColorToken = Boolean(message.match(COLOR_TOKEN_REGEX));\n const endsWithReset = message.trimEnd().endsWith(\"|reset|\");\n const withReset =\n hasColorToken && !endsWithReset ? `${message}|reset|` : message;\n const interpolated = interpolateParams(withReset, params);\n return applyColors(interpolated);\n}\n","import { generateTerminalMessage } from \"@/generateTerminalMessage\";\nimport type {\n AnyCLI,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionParam,\n CLIParam,\n CLIPositionalParam,\n CLIPositionalParamName,\n IAcclimateCLI,\n} from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nconst _SECTION_TITLES = [\n \"Positional Arguments\",\n \"Options\",\n \"Global Options\",\n \"Commands\",\n] as const;\n\ntype SectionTitle = (typeof _SECTION_TITLES)[number];\n\ntype CLIParamWithRequired = CLIParam<string> & {\n required: boolean;\n aliases?: readonly string[];\n};\n\nfunction formatSectionTitle(title: SectionTitle): string {\n return `|bright_yellow|${title}|reset|`;\n}\n\nfunction formatNoneLine(): string {\n return \" |gray|None|reset|\";\n}\n\nfunction formatDefaultValue(\n value: CLIParamWithRequired[\"defaultValue\"],\n): string {\n return `|gray|[default: ${JSON.stringify(value)}]|reset|`;\n}\n\nfunction formatParamLine(param: CLIParamWithRequired): string {\n const description = param.description ?? \"No description\";\n const requiredLabel =\n param.required ? \"|red|required|reset|\" : \"|gray|optional|reset|\";\n const defaultLabel =\n param.defaultValue !== undefined ?\n formatDefaultValue(param.defaultValue)\n : undefined;\n const aliasList =\n param.aliases && param.aliases.length > 0 ? param.aliases.join(\", \") : \"\";\n const displayName = aliasList ? `${param.name}, ${aliasList}` : param.name;\n\n const segments = [\n ` |bright_white|${displayName}|reset|`,\n `(${param.type})|reset| ${requiredLabel}`,\n `- |gray|${description}|reset|`,\n defaultLabel,\n ].filter(Boolean);\n\n return segments.join(\" \");\n}\n\nfunction formatSection(\n title: SectionTitle,\n params: readonly CLIParamWithRequired[],\n): string[] {\n if (params.length === 0) {\n return [formatSectionTitle(title), formatNoneLine()];\n }\n\n return [formatSectionTitle(title), ...params.map(formatParamLine)];\n}\n\nfunction formatCommandLine(options: {\n name: string;\n description?: string;\n}): string {\n const { name, description } = options;\n const label = description ?? \"No description\";\n return ` |bright_white|${name}|reset| - |gray|${label}|reset|`;\n}\n\nfunction formatAvailableCommandsLine(commands: string[]): string {\n const label =\n commands.length === 0 ?\n \"None\"\n : commands\n .map((cmd) => {\n return cmd;\n })\n .join(\", \");\n return `|bright_yellow|Available Commands:|reset| |gray|${label}|reset|`;\n}\n\nfunction _generateHelpTextHelper<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n options: { level: 1 | 2 },\n): string {\n const name = cli.getName();\n const description = cli.state.description;\n const level = Number(options.level);\n\n const positionalParams = cli.state\n .positionalArgs as readonly CLIParamWithRequired[];\n const optionParams = Object.values(\n cli.state.optionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ) as readonly CLIParamWithRequired[];\n const globalOptionParams = Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ) as readonly CLIParamWithRequired[];\n const sortedCommands = Object.entries(cli.state.commands).sort(([a], [b]) => {\n return a.localeCompare(b);\n });\n const commandNames = sortedCommands.map(([commandName]) => {\n return commandName;\n });\n\n const headerLines = [`|bright_cyan|${name}|reset|`];\n if (description !== undefined) {\n headerLines.push(` |gray|${description}|reset|`);\n }\n\n let commandSection: string[];\n if (level === 2) {\n commandSection = [\n formatSectionTitle(\"Commands\"),\n ` ${formatAvailableCommandsLine(commandNames)}`,\n ];\n } else if (sortedCommands.length === 0) {\n commandSection = [formatSectionTitle(\"Commands\"), formatNoneLine()];\n } else {\n commandSection = [\n formatSectionTitle(\"Commands\"),\n ...sortedCommands.map(([commandName, commandCLI]) => {\n return formatCommandLine({\n name: commandName,\n description: commandCLI.state.description,\n });\n }),\n ];\n }\n\n const sections = [\n formatSection(\"Positional Arguments\", positionalParams),\n formatSection(\"Options\", optionParams),\n formatSection(\"Global Options\", globalOptionParams),\n commandSection,\n ];\n\n const lines = [...headerLines, \"\"];\n sections.forEach((section, idx) => {\n lines.push(...section);\n if (idx < sections.length - 1) {\n lines.push(\"\");\n }\n });\n\n if (level === 1) {\n const subCommandHelpText = sortedCommands.map(([, commandCLI]) => {\n return _generateHelpTextHelper(commandCLI, { level: 2 });\n });\n if (subCommandHelpText.length > 0) {\n subCommandHelpText.forEach((text) => {\n lines.push(\"\", ...text.split(\"\\n\"));\n });\n }\n }\n\n const indent = \" \".repeat(Math.max(0, level - 1));\n return lines\n .map((line) => {\n return line === \"\" ? \"\" : `${indent}${line}`;\n })\n .join(\"\\n\");\n}\n\nexport function generateHelpText<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n): string {\n return generateTerminalMessage(_generateHelpTextHelper(cli, { level: 1 }));\n}\n","import { stdin, stdout } from \"node:process\";\nimport { createInterface } from \"node:readline/promises\";\nimport { generateTerminalMessage } from \"@/generateTerminalMessage\";\n\n/**\n * Prompt the user for terminal input, optionally enforcing a non-empty value.\n */\nexport async function requestTerminalInput(options: {\n message: string;\n params: Record<string, string>;\n responseOptions: {\n required: boolean;\n type?: \"string\" | \"number\" | \"boolean\";\n\n /*\n * Default value to use if the user enters an empty response.\n *\n * If the option is `required` and the user doesn't supply a value, we will\n * not show an error if there is a `defaultValue` we can use.\n */\n defaultValue?: string | number | boolean;\n };\n}): Promise<string | undefined> {\n const {\n message,\n params,\n responseOptions: { required, type, defaultValue },\n } = options;\n const notice =\n defaultValue !== undefined ? \" |gray|(press Enter to use default)|reset|\"\n : required ? \"\"\n : \" |gray|(press Enter to leave empty)|reset|\";\n const defaultNotice =\n defaultValue !== undefined ? ` [default: ${defaultValue}]` : \"\";\n const booleanNotice = type === \"boolean\" ? \" |reset|(y/n)\" : \"\";\n const promptMessage = `${message}${defaultNotice}${booleanNotice}${notice} `;\n const prompt = generateTerminalMessage(promptMessage, params);\n\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n while (true) {\n const answer = await rl.question(prompt);\n const trimmed = answer.trim();\n if (trimmed.length === 0) {\n if (defaultValue !== undefined) {\n // use the default value, parsed to a string\n return (\n typeof defaultValue === \"string\" ? defaultValue\n : typeof defaultValue === \"number\" ? String(defaultValue)\n : defaultValue ? \"true\"\n : \"false\"\n );\n }\n\n if (required) {\n stdout.write(\n generateTerminalMessage(\n \"|red|This value is required.|reset| Please enter a value.\\n\",\n ),\n );\n continue;\n }\n return undefined;\n }\n if (type === \"boolean\") {\n const normalized = trimmed.toLowerCase();\n if (normalized === \"y\" || normalized === \"yes\") {\n return \"true\";\n }\n if (normalized === \"n\" || normalized === \"no\") {\n return \"false\";\n }\n stdout.write(\n generateTerminalMessage(\n \"|red|That was not a valid response.|reset| Please enter y or n.\\n\",\n ),\n );\n continue;\n }\n return answer;\n }\n } finally {\n rl.close();\n }\n}\n","import { camelCase } from \"change-case\";\nimport { match } from \"ts-pattern\";\nimport { generateHelpText } from \"@/AcclimateCLI/generateHelpText/generateHelpText\";\nimport { CLIError } from \"@/CLIError\";\nimport { requestTerminalInput } from \"@/requestTerminalInput\";\nimport type {\n AnyCLI,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionAlias,\n CLIOptionParam,\n CLIParam,\n CLIParamDataType,\n CLIPositionalParam,\n CLIPositionalParamName,\n CLIState,\n FullCLIArgValues,\n IAcclimateCLI,\n ValueOfParam,\n} from \"@/AcclimateCLI/AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nfunction _isValidFullOptionName(name: string): name is CLIFullOptionName {\n return name.startsWith(\"--\");\n}\n\nfunction _isValidOptionAlias(name: string): name is CLIOptionAlias {\n return name.startsWith(\"-\");\n}\n\nfunction isEmptyObject(obj: object): obj is EmptyObject {\n return Object.keys(obj).length === 0;\n}\n\nfunction _validateParsedValue<\n P extends CLIParam<string>,\n PValue extends ValueOfParam<P>,\n>(options: { parsedValue: PValue; paramConfig: P; cliName: string }): PValue {\n const { parsedValue, paramConfig, cliName } = options;\n if (paramConfig.validator) {\n const validator = paramConfig.validator as (\n value: PValue,\n ) => boolean | string;\n const validationResult = validator(parsedValue);\n if (validationResult === true) {\n return parsedValue;\n }\n throw CLIError.invalidCLIParamValue({\n cliName,\n paramName: paramConfig.name,\n paramValue: parsedValue,\n message:\n typeof validationResult === \"string\" ? validationResult : undefined,\n });\n }\n return parsedValue;\n}\n\nfunction _parseAndValidateValue<\n P extends CLIParam<string>,\n PValue extends ValueOfParam<P>,\n>(options: {\n cliName: string;\n inputValue: string | undefined;\n defaultValue: PValue | undefined;\n paramConfig: P;\n}): PValue | undefined {\n const { cliName, inputValue, defaultValue, paramConfig } = options;\n if (inputValue === undefined) {\n if (defaultValue === undefined) {\n return undefined;\n }\n return _validateParsedValue({\n cliName,\n parsedValue: defaultValue,\n paramConfig,\n });\n }\n\n const parsedValue =\n paramConfig.parser ?\n (paramConfig.parser(inputValue) as PValue)\n // if no parser was set, we use the default parser\n : (match(paramConfig.type)\n .with(\"boolean\", () => {\n return inputValue === \"false\" ? false : true;\n })\n .with(\"number\", () => {\n return Number.parseInt(inputValue, 10);\n })\n .with(\"string\", () => {\n return inputValue;\n })\n .exhaustive(() => {\n return inputValue;\n }) as PValue);\n return _validateParsedValue({\n cliName,\n parsedValue,\n paramConfig,\n });\n}\n\nfunction _replaceAliases<\n TGlobalOptionArgs extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TOptionArgs extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TPositionalArgs extends\n | Record<CLIPositionalParamName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>({\n aliasedOptionArgs,\n cli,\n}: {\n aliasedOptionArgs: Record<CLIOptionAlias, string>;\n cli: IAcclimateCLI<\n TGlobalOptionArgs,\n TOptionArgs,\n TPositionalArgs,\n TCommands\n >;\n}): Record<CLIOptionAlias, string> {\n const aliasMap = cli.state.aliases;\n return Object.entries(aliasedOptionArgs).reduce(\n (acc, [aliasKey, value]) => {\n const alias = aliasKey as CLIOptionAlias;\n const optionName = aliasMap[alias] ?? alias;\n acc[optionName] = value;\n return acc;\n },\n {} as Record<CLIOptionAlias, string>,\n );\n}\n\ntype CLIParamWithRequired = CLIParam<string> & {\n required: boolean;\n};\n\nasync function askForValue(options: {\n argConfig: CLIParamWithRequired;\n}): Promise<string | undefined> {\n const { argConfig } = options;\n const askIfEmpty = argConfig.askIfEmpty;\n const description =\n argConfig.description ? ` (${argConfig.description})` : \"\";\n const baseMessage =\n typeof askIfEmpty === \"object\" ?\n askIfEmpty.message\n : `Please enter a value for ${argConfig.name}${description}`;\n const coloredMessage = `|bright_cyan|${baseMessage}|reset|`;\n return requestTerminalInput({\n message: coloredMessage,\n params: {},\n responseOptions: {\n required: argConfig.required,\n type: argConfig.type,\n defaultValue: argConfig.defaultValue,\n },\n });\n}\n\nasync function _runCLIHelper<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(options: {\n rawPositionalArgs: string[];\n rawOptionArgs: Record<CLIOptionAlias, string>;\n rawGlobalOptionArgs: Record<CLIFullOptionName, string>;\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >;\n}): Promise<void> {\n const { rawGlobalOptionArgs, rawOptionArgs, rawPositionalArgs, cli } = {\n ...options,\n rawGlobalOptionArgs: _replaceAliases({\n aliasedOptionArgs: options.rawGlobalOptionArgs,\n cli: options.cli,\n }),\n rawOptionArgs: _replaceAliases({\n aliasedOptionArgs: options.rawOptionArgs,\n\n // TODO(jpsyx): fix that this does not have the CLI may not have all\n cli: options.cli,\n }),\n };\n\n // is the first argument a command?\n const firstArg = rawPositionalArgs[0];\n if (\n firstArg &&\n !isEmptyObject(cli.state.commands) &&\n cli.state.commands[firstArg]\n ) {\n // add the parent's global options to the sub-command\n const commandCLI = Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ).reduce(\n (newCmd, argConfig) => {\n return newCmd.addGlobalOption(argConfig);\n },\n cli.getCommandCLI(firstArg as Extract<keyof TCommands, string>) as AnyCLI,\n );\n\n // run the sub-command\n return _runCLIHelper({\n rawPositionalArgs: rawPositionalArgs.slice(1),\n rawOptionArgs,\n rawGlobalOptionArgs,\n cli: commandCLI,\n });\n }\n\n const cliName = cli.getName();\n\n // build the positional arguments dictionary\n // first check that we haven't supplied too many positional arguments\n if (rawPositionalArgs.length > cli.state.positionalArgs.length) {\n throw CLIError.tooManyPositionalArgs({\n cliName,\n count: rawPositionalArgs.length,\n });\n }\n\n // parse positional arguments\n const parsedPositionalArgs: Record<string, CLIParamDataType> = {};\n for (const [idx, argConfig] of cli.state.positionalArgs.entries()) {\n let rawVal = rawPositionalArgs[idx];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredPositionalArg({\n cliName,\n positionalArgName: argConfig.name,\n });\n }\n\n parsedPositionalArgs[argConfig.name] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // parse the options\n const parsedOptionArgs: Record<string, CLIParamDataType> = {};\n for (const argConfig of Object.values(\n cli.state.optionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n )) {\n let rawVal = rawOptionArgs[argConfig.name];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredOption({\n cliName,\n optionName: argConfig.name,\n });\n }\n\n parsedOptionArgs[camelCase(argConfig.name)] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // parse the global options\n const parsedGlobalOptionArgs: Record<string, CLIParamDataType> = {};\n for (const argConfig of Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n )) {\n let rawVal = rawGlobalOptionArgs[argConfig.name];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredOption({\n cliName,\n optionName: argConfig.name,\n });\n }\n parsedGlobalOptionArgs[camelCase(argConfig.name)] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // run the action\n const action = cli.state.action;\n if (action) {\n action({\n ...parsedPositionalArgs,\n ...parsedOptionArgs,\n ...parsedGlobalOptionArgs,\n } as FullCLIArgValues<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams\n >);\n return;\n }\n\n console.log(generateHelpText(cli));\n}\n\n/**\n * Run a CLI instance given an array of inputs.\n *\n * @param options - The options for running the CLI.\n */\nexport async function runCLI(options: {\n input: string[];\n cli: AnyCLI;\n}): Promise<void> {\n const { input, cli } = options;\n const firstOptionIdx = input.findIndex((token) => {\n return token.startsWith(\"-\");\n });\n\n const [rawPositionalArgs, rest] =\n firstOptionIdx === -1 ?\n [input, []]\n : [input.slice(0, firstOptionIdx), input.slice(firstOptionIdx)];\n\n const rawOptionArgs: Record<CLIOptionAlias, string> = {};\n const rawGlobalOptionArgs: Record<CLIFullOptionName, string> = {};\n let currentAlias: CLIOptionAlias | undefined;\n let currentVals: string[] = [];\n\n const { aliases, globalOptionArgs } = cli.state as CLIState<\n Record<CLIFullOptionName, CLIOptionParam>,\n Record<CLIFullOptionName, CLIOptionParam>,\n Record<CLIPositionalParamName, CLIOptionParam>,\n Record<CLICommandName, AnyCLI>\n >;\n\n for (const argVal of rest.concat(\"-\")) {\n if (_isValidOptionAlias(argVal)) {\n if (currentAlias) {\n const rawValue = currentVals.join(\" \");\n const optionName = aliases[currentAlias] ?? currentAlias;\n if (\n _isValidFullOptionName(optionName) &&\n !isEmptyObject(globalOptionArgs) &&\n globalOptionArgs[optionName]\n ) {\n rawGlobalOptionArgs[optionName] = rawValue;\n } else {\n rawOptionArgs[optionName] = rawValue;\n }\n }\n currentAlias = argVal;\n currentVals = [];\n } else {\n currentVals.push(argVal);\n }\n }\n\n await _runCLIHelper({\n rawPositionalArgs,\n rawOptionArgs,\n rawGlobalOptionArgs,\n cli,\n });\n}\n","import { createCLI } from \"./AcclimateCLI\";\nimport { runCLI } from \"./AcclimateCLI/runCLI/runCLI\";\nimport { generateTerminalMessage } from \"./generateTerminalMessage\";\nimport { requestTerminalInput } from \"./requestTerminalInput\";\nimport type { AnyCLI, IAcclimateCLI } from \"./AcclimateCLI/AcclimateCLI.types\";\n\ntype Acclimate = {\n /**\n * Create a new Acclimate CLI instance.\n *\n * @param name - The name of the CLI.\n * @returns A new CLI instance.\n */\n createCLI: (name: string) => IAcclimateCLI;\n\n /**\n * Run a CLI instance.\n *\n * It can only be run once. Calling any other methods after `.run()` will\n * throw an error.\n *\n * @param cli - The CLI instance to run.\n */\n run: (cli: AnyCLI) => void;\n\n /**\n * Outputs a message with `console.log`.\n * Supports interpolation using `$varName$` as tokens.\n *\n * Colors can be changed within a message `|<COLOR_NAME>|` tokens.\n * Supported colors are:\n * - black\n * - red\n * - green\n * - yellow\n * - blue\n * - magenta\n * - cyan\n * - white\n * - bright_black|gray|grey\n * - bright_red\n * - bright_green\n * - bright_yellow\n * - bright_blue\n * - bright_magenta\n * - bright_cyan\n * - bright_white\n *\n * The color remains active until another color token is found,\n * or if |reset| is found (which resets the terminal color to the default).\n *\n * @example\n *\n * Acclimate.log(\"Hello $name$\", { name: \"Pablo\" });\n * // \"Hello Pablo\"\n *\n * Acclimate.log(\"|red|Error:|reset| There was an error.\")\n * // \"Error: There was an error.\"\n * // ^ the \"Error:\" portion will be red\n *\n */\n log: (message: string, params?: Record<string, string | undefined>) => void;\n\n /**\n * Prompt the user for interactive input in the terminal.\n *\n * @param options - Prompt configuration.\n * @returns The user's response, or undefined when left empty and optional.\n */\n requestInput: (options: {\n message: string;\n params: Record<string, string>;\n responseOptions: {\n required: boolean;\n type?: \"string\" | \"number\" | \"boolean\";\n\n /*\n * Default value to use if the user enters an empty response.\n *\n * If the option is `required` and the user doesn't supply a value, we will\n * not show an error if there is a `defaultValue` we can use.\n */\n defaultValue?: string | number | boolean;\n };\n }) => Promise<string | undefined>;\n};\n\nexport const Acclimate: Acclimate = {\n createCLI,\n run: (cli: AnyCLI) => {\n void runCLI({ cli, input: process.argv.slice(2) });\n },\n log: (message: string, params: Record<string, string | undefined> = {}) => {\n console.log(generateTerminalMessage(message, params));\n },\n requestInput: (options) => {\n return requestTerminalInput(options);\n },\n};\n"]}
package/dist/index.d.cts CHANGED
@@ -266,9 +266,10 @@ type Acclimate = {
266
266
  requestInput: (options: {
267
267
  message: string;
268
268
  params: Record<string, string>;
269
- options: {
269
+ responseOptions: {
270
270
  required: boolean;
271
271
  type?: "string" | "number" | "boolean";
272
+ defaultValue?: string | number | boolean;
272
273
  };
273
274
  }) => Promise<string | undefined>;
274
275
  };
package/dist/index.d.ts CHANGED
@@ -266,9 +266,10 @@ type Acclimate = {
266
266
  requestInput: (options: {
267
267
  message: string;
268
268
  params: Record<string, string>;
269
- options: {
269
+ responseOptions: {
270
270
  required: boolean;
271
271
  type?: "string" | "number" | "boolean";
272
+ defaultValue?: string | number | boolean;
272
273
  };
273
274
  }) => Promise<string | undefined>;
274
275
  };
package/dist/index.js CHANGED
@@ -341,25 +341,27 @@ function _generateHelpTextHelper(cli, options) {
341
341
  function generateHelpText(cli) {
342
342
  return generateTerminalMessage(_generateHelpTextHelper(cli, { level: 1 }));
343
343
  }
344
- var COLOR_TOKEN_REGEX2 = /\|[a-zA-Z_]+\|/g;
345
- function messageHasPunctuation(message) {
346
- const stripped = message.replace(COLOR_TOKEN_REGEX2, "").trimEnd();
347
- return stripped.endsWith(":") || stripped.endsWith("?");
348
- }
349
344
  async function requestTerminalInput(options) {
350
- const { message, params, options: promptOptions } = options;
351
- const notice = promptOptions.required ? "" : " |gray|(press Enter to leave empty)|reset|";
352
- const booleanNotice = promptOptions.type === "boolean" ? " |reset|(y/n)" : "";
353
- const promptMessage = `${message}${booleanNotice}${notice}`;
354
- const promptText = messageHasPunctuation(message) ? `${promptMessage} ` : `${promptMessage}: `;
355
- const prompt = generateTerminalMessage(promptText, params);
345
+ const {
346
+ message,
347
+ params,
348
+ responseOptions: { required, type, defaultValue }
349
+ } = options;
350
+ const notice = defaultValue !== void 0 ? " |gray|(press Enter to use default)|reset|" : required ? "" : " |gray|(press Enter to leave empty)|reset|";
351
+ const defaultNotice = defaultValue !== void 0 ? ` [default: ${defaultValue}]` : "";
352
+ const booleanNotice = type === "boolean" ? " |reset|(y/n)" : "";
353
+ const promptMessage = `${message}${defaultNotice}${booleanNotice}${notice} `;
354
+ const prompt = generateTerminalMessage(promptMessage, params);
356
355
  const rl = createInterface({ input: stdin, output: stdout });
357
356
  try {
358
357
  while (true) {
359
358
  const answer = await rl.question(prompt);
360
359
  const trimmed = answer.trim();
361
360
  if (trimmed.length === 0) {
362
- if (promptOptions.required) {
361
+ if (defaultValue !== void 0) {
362
+ return typeof defaultValue === "string" ? defaultValue : typeof defaultValue === "number" ? String(defaultValue) : defaultValue ? "true" : "false";
363
+ }
364
+ if (required) {
363
365
  stdout.write(
364
366
  generateTerminalMessage(
365
367
  "|red|This value is required.|reset| Please enter a value.\n"
@@ -369,7 +371,7 @@ async function requestTerminalInput(options) {
369
371
  }
370
372
  return void 0;
371
373
  }
372
- if (promptOptions.type === "boolean") {
374
+ if (type === "boolean") {
373
375
  const normalized = trimmed.toLowerCase();
374
376
  if (normalized === "y" || normalized === "yes") {
375
377
  return "true";
@@ -469,7 +471,11 @@ async function askForValue(options) {
469
471
  return requestTerminalInput({
470
472
  message: coloredMessage,
471
473
  params: {},
472
- options: { required: argConfig.required, type: argConfig.type }
474
+ responseOptions: {
475
+ required: argConfig.required,
476
+ type: argConfig.type,
477
+ defaultValue: argConfig.defaultValue
478
+ }
473
479
  });
474
480
  }
475
481
  async function _runCLIHelper(options) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/CLIError.ts","../src/AcclimateCLI/AcclimateCLI.ts","../src/AcclimateCLI/createCLI/defaultCLIState.ts","../src/AcclimateCLI/createCLI/createCLI.ts","../src/generateTerminalMessage/generateTerminalMessage.ts","../src/AcclimateCLI/generateHelpText/generateHelpText.ts","../src/requestTerminalInput/requestTerminalInput.ts","../src/AcclimateCLI/runCLI/runCLI.ts","../src/Acclimate.ts"],"names":["match","COLOR_TOKEN_REGEX"],"mappings":";;;;;;AA4CO,IAAM,QAAA,GAAN,MAAM,SAAA,SAAiB,KAAA,CAAM;AAAA,EAClC,OAAO,qBAAqB,OAAA,EAKf;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EACE,OAAA,CAAQ,OAAA,IAAW,CAAA,6BAAA,EAAgC,QAAQ,SAAS,CAAA,CAAA,CAAA;AAAA,MACtE,IAAA,EAAM,yBAAA;AAAA,MACN,SAAS,EAAE,SAAA,EAAW,QAAQ,SAAA,EAAW,UAAA,EAAY,QAAQ,UAAA;AAAW,KACzE,CAAA;AAAA,EACH;AAAA,EACA,OAAO,sBAAsB,OAAA,EAIhB;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EACE,OAAA,CAAQ,OAAA,IAAW,CAAA,iBAAA,EAAoB,QAAQ,UAAU,CAAA,YAAA,CAAA;AAAA,MAC3D,IAAA,EAAM,yBAAA;AAAA,MACN,OAAA,EAAS,EAAE,UAAA,EAAY,OAAA,CAAQ,UAAA;AAAW,KAC3C,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,6BAA6B,OAAA,EAIvB;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EACE,OAAA,CAAQ,OAAA,IACR,CAAA,8BAAA,EAAiC,QAAQ,iBAAiB,CAAA,YAAA,CAAA;AAAA,MAC5D,IAAA,EAAM,iCAAA;AAAA,MACN,OAAA,EAAS,EAAE,iBAAA,EAAmB,OAAA,CAAQ,iBAAA;AAAkB,KACzD,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,cAAc,OAAA,EAIR;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EAAS,OAAA,CAAQ,OAAA,IAAW,CAAA,QAAA,EAAW,QAAQ,UAAU,CAAA,WAAA,CAAA;AAAA,MACzD,IAAA,EAAM,gBAAA;AAAA,MACN,OAAA,EAAS,EAAE,UAAA,EAAY,OAAA,CAAQ,UAAA;AAAW,KAC3C,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,sBAAsB,OAAA,EAIhB;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EAAS,QAAQ,OAAA,IAAW,yCAAA;AAAA,MAC5B,IAAA,EAAM,0BAAA;AAAA,MACN,OAAA,EAAS,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA;AAAM,KACjC,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,2BAA2B,OAAA,EAIrB;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EACE,OAAA,CAAQ,OAAA,IACR,CAAA,uCAAA,EAA0C,QAAQ,iBAAiB,CAAA,YAAA,CAAA;AAAA,MACrE,IAAA,EAAM,+BAAA;AAAA,MACN,OAAA,EAAS,EAAE,iBAAA,EAAmB,OAAA,CAAQ,iBAAA;AAAkB,KACzD,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,eAAe,OAAA,EAIT;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EAAS,OAAA,CAAQ,OAAA,IAAW,CAAA,SAAA,EAAY,QAAQ,WAAW,CAAA,WAAA,CAAA;AAAA,MAC3D,IAAA,EAAM,iBAAA;AAAA,MACN,OAAA,EAAS,EAAE,WAAA,EAAa,OAAA,CAAQ,WAAA;AAAY,KAC7C,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,WAAW,OAAA,EAGL;AACX,IAAA,OAAO,IAAI,SAAA,CAAS;AAAA,MAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EAAS,QAAQ,OAAA,IAAW,0BAAA;AAAA,MAC5B,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AAAA,EAEA,YAAY,OAAA,EAA0B;AACpC,IAAA,KAAA,CAAM,wBAAmB,OAAA,CAAQ,OAAO,CAAA,EAAA,EAAK,OAAA,CAAQ,OAAO,CAAA,CAAE,CAAA;AAAA,EAChE;AACF,CAAA;;;AC/IO,SAAS,aAUd,KAAA,EAWA;AACA,EAAA,MAAM,UAAU,KAAA,CAAM,IAAA;AACtB,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IAEA,SAAS,MAAM;AACb,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAA,EAAQ,CACN,MAAA,KAcG;AACH,MAAA,OAAO,YAAA,CAAa;AAAA,QAClB,GAAG,KAAA;AAAA,QACH;AAAA,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,WAAA,EAAa,CACX,WAAA,KAMG;AACH,MAAA,OAAO,YAAA,CAAa;AAAA,QAClB,GAAG,KAAA;AAAA,QACH;AAAA,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,gBAAA,EAAkB,CAIhB,KAAA,KACG;AACH,MAAA,IACE,MAAM,QAAA,IACN,KAAA,CAAM,cAAA,CAAe,IAAA,CAAK,CAAC,CAAA,KAAM;AAC/B,QAAA,OAAO,CAAC,CAAA,CAAE,QAAA;AAAA,MACZ,CAAC,CAAA,EACD;AACA,QAAA,MAAM,SAAS,0BAAA,CAA2B;AAAA,UACxC,OAAA;AAAA,UACA,mBAAmB,KAAA,CAAM,IAAA;AAAA,UACzB,OAAA,EACE;AAAA,SACH,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,YAAA,CAAa;AAAA,QAClB,GAAG,KAAA;AAAA,QACH,cAAA,EAAgB;AAAA,UACd,GAAG,KAAA,CAAM,cAAA;AAAA,UACT,EAAE,GAAG,KAAA,EAAO,QAAA,EAAU,KAAA,CAAM,YAAY,IAAA;AAAK;AAC/C,OAMD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,eAAA,EAAiB,CAA2B,KAAA,KAAa;AACvD,MAAA,MAAM,UAAA,GAAA,CAAc,KAAA,CAAM,OAAA,IAAW,EAAC,EAAG,MAAA;AAAA,QACvC,CAAC,KAAK,KAAA,KAAU;AACd,UAAA,GAAA,CAAI,KAAK,IAAI,KAAA,CAAM,IAAA;AACnB,UAAA,OAAO,GAAA;AAAA,QACT,CAAA;AAAA,QACA;AAAC,OACH;AACA,MAAA,OAAO,YAAA,CAKL;AAAA,QACA,GAAG,KAAA;AAAA,QACH,SAAS,EAAE,GAAG,KAAA,CAAM,OAAA,EAAS,GAAG,UAAA,EAAW;AAAA,QAC3C,gBAAA,EAAkB;AAAA,UAChB,GAAG,KAAA,CAAM,gBAAA;AAAA,UACT,CAAC,KAAA,CAAM,IAAI,GAAG;AAAA;AAChB,OAMD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,SAAA,EAAW,CAA2B,KAAA,KAAa;AACjD,MAAA,MAAM,UAAA,GAAA,CAAc,KAAA,CAAM,OAAA,IAAW,EAAC,EAAG,MAAA;AAAA,QACvC,CAAC,KAAK,KAAA,KAAU;AACd,UAAA,GAAA,CAAI,KAAK,IAAI,KAAA,CAAM,IAAA;AACnB,UAAA,OAAO,GAAA;AAAA,QACT,CAAA;AAAA,QACA;AAAC,OACH;AACA,MAAA,OAAO,YAAA,CAKL;AAAA,QACA,GAAG,KAAA;AAAA,QACH,SAAS,EAAE,GAAG,KAAA,CAAM,OAAA,EAAS,GAAG,UAAA,EAAW;AAAA,QAC3C,UAAA,EAAY,EAAE,GAAG,KAAA,CAAM,YAAY,CAAC,KAAA,CAAM,IAAI,GAAG,KAAA;AAAM,OAMxD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,UAAA,EAAY,CACV,WAAA,EACA,GAAA,KAMG;AACH,MAAA,OAAO,YAAA,CAAa;AAAA,QAClB,GAAG,KAAA;AAAA,QACH,QAAA,EAAU;AAAA,UACR,GAAG,KAAA,CAAM,QAAA;AAAA,UACT,CAAC,WAAW,GAAG;AAAA;AACjB,OAMD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,aAAA,EAAe,CACb,WAAA,KACqD;AACrD,MAAA,MAAM,GAAA,GAAM,KAAA,CAAM,QAAA,CAAS,WAAW,CAAA;AACtC,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,SAAS,cAAA,CAAe;AAAA,UAC5B,OAAA;AAAA,UACA,WAAA;AAAA,UACA,OAAA,EAAS,YAAY,WAAW,CAAA,WAAA;AAAA,SACjC,CAAA;AAAA,MACH;AACA,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,GACF;AACF;;;ACzMO,IAAM,eAAA,GAGT;AAAA,EACF,SAAS,EAAC;AAAA,EACV,WAAA,EAAa,MAAA;AAAA,EACb,UAAU,EAAC;AAAA,EACX,gBAAgB,EAAC;AAAA,EACjB,YAAY,EAAC;AAAA,EACb,kBAAkB,EAAC;AAAA,EACnB,MAAA,EAAQ;AACV,CAAA;;;ACHO,SAAS,UACd,IAAA,EACmE;AACnE,EAAA,OAAO,YAAA,CAAa,EAAE,GAAG,eAAA,EAAiB,MAAM,CAAA;AAClD;;;ACfA,IAAM,WAAA,GAAsC;AAAA,EAC1C,KAAA,EAAO,SAAA;AAAA,EACP,KAAA,EAAO,UAAA;AAAA,EACP,GAAA,EAAK,UAAA;AAAA,EACL,KAAA,EAAO,UAAA;AAAA,EACP,MAAA,EAAQ,UAAA;AAAA,EACR,IAAA,EAAM,UAAA;AAAA,EACN,OAAA,EAAS,UAAA;AAAA,EACT,IAAA,EAAM,UAAA;AAAA,EACN,KAAA,EAAO,UAAA;AAAA,EACP,YAAA,EAAc,UAAA;AAAA,EACd,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,UAAA;AAAA,EACN,UAAA,EAAY,UAAA;AAAA,EACZ,YAAA,EAAc,UAAA;AAAA,EACd,aAAA,EAAe,UAAA;AAAA,EACf,WAAA,EAAa,UAAA;AAAA,EACb,cAAA,EAAgB,UAAA;AAAA,EAChB,WAAA,EAAa,UAAA;AAAA,EACb,YAAA,EAAc;AAChB,CAAA;AAEA,IAAM,iBAAA,GAAoB,sBAAA;AAC1B,IAAM,iBAAA,GAAoB,mBAAA;AAM1B,SAAS,iBAAA,CACP,SACA,MAAA,EACA;AACA,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,iBAAA,EAAmB,CAACA,QAAO,GAAA,KAAgB;AAEhE,IAAA,MAAM,KAAA,GAAQ,OAAO,GAAG,CAAA;AACxB,IAAA,IAAI,UAAU,MAAA,EAAW;AACvB,MAAA,OAAO,EAAA;AAAA,IACT;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAC,CAAA;AACH;AAEA,SAAS,YAAY,OAAA,EAAiB;AACpC,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,iBAAA,EAAmB,CAACA,QAAO,SAAA,KAAsB;AACtE,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,SAAA,CAAU,WAAA,EAAa,CAAA;AAChD,IAAA,OAAO,IAAA,IAAQA,MAAAA;AAAA,EACjB,CAAC,CAAA;AACH;AAuCO,SAAS,uBAAA,CACd,OAAA,EACA,MAAA,GAA6C,EAAC,EACtC;AACR,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,OAAA,CAAQ,KAAA,CAAM,iBAAiB,CAAC,CAAA;AAC9D,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,OAAA,EAAQ,CAAE,SAAS,SAAS,CAAA;AAC1D,EAAA,MAAM,YACJ,aAAA,IAAiB,CAAC,aAAA,GAAgB,CAAA,EAAG,OAAO,CAAA,OAAA,CAAA,GAAY,OAAA;AAC1D,EAAA,MAAM,YAAA,GAAe,iBAAA,CAAkB,SAAA,EAAW,MAAM,CAAA;AACxD,EAAA,OAAO,YAAY,YAAY,CAAA;AACjC;;;ACtEA,SAAS,mBAAmB,KAAA,EAA6B;AACvD,EAAA,OAAO,kBAAkB,KAAK,CAAA,OAAA,CAAA;AAChC;AAEA,SAAS,cAAA,GAAyB;AAChC,EAAA,OAAO,qBAAA;AACT;AAEA,SAAS,mBACP,KAAA,EACQ;AACR,EAAA,OAAO,CAAA,gBAAA,EAAmB,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA,QAAA,CAAA;AACjD;AAEA,SAAS,gBAAgB,KAAA,EAAqC;AAC5D,EAAA,MAAM,WAAA,GAAc,MAAM,WAAA,IAAe,gBAAA;AACzC,EAAA,MAAM,aAAA,GACJ,KAAA,CAAM,QAAA,GAAW,sBAAA,GAAyB,uBAAA;AAC5C,EAAA,MAAM,eACJ,KAAA,CAAM,YAAA,KAAiB,SACrB,kBAAA,CAAmB,KAAA,CAAM,YAAY,CAAA,GACrC,MAAA;AACJ,EAAA,MAAM,SAAA,GACJ,KAAA,CAAM,OAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,MAAA,GAAS,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,GAAI,EAAA;AACzE,EAAA,MAAM,WAAA,GAAc,YAAY,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,SAAS,KAAK,KAAA,CAAM,IAAA;AAEtE,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,mBAAmB,WAAW,CAAA,OAAA,CAAA;AAAA,IAC9B,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,CAAA,SAAA,EAAY,aAAa,CAAA,CAAA;AAAA,IACvC,WAAW,WAAW,CAAA,OAAA,CAAA;AAAA,IACtB;AAAA,GACF,CAAE,OAAO,OAAO,CAAA;AAEhB,EAAA,OAAO,QAAA,CAAS,KAAK,GAAG,CAAA;AAC1B;AAEA,SAAS,aAAA,CACP,OACA,MAAA,EACU;AACV,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,OAAO,CAAC,kBAAA,CAAmB,KAAK,CAAA,EAAG,gBAAgB,CAAA;AAAA,EACrD;AAEA,EAAA,OAAO,CAAC,mBAAmB,KAAK,CAAA,EAAG,GAAG,MAAA,CAAO,GAAA,CAAI,eAAe,CAAC,CAAA;AACnE;AAEA,SAAS,kBAAkB,OAAA,EAGhB;AACT,EAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAY,GAAI,OAAA;AAC9B,EAAA,MAAM,QAAQ,WAAA,IAAe,gBAAA;AAC7B,EAAA,OAAO,CAAA,gBAAA,EAAmB,IAAI,CAAA,gBAAA,EAAmB,KAAK,CAAA,OAAA,CAAA;AACxD;AAEA,SAAS,4BAA4B,QAAA,EAA4B;AAC/D,EAAA,MAAM,KAAA,GACJ,SAAS,MAAA,KAAW,CAAA,GAClB,SACA,QAAA,CACG,GAAA,CAAI,CAAC,GAAA,KAAQ;AACZ,IAAA,OAAO,GAAA;AAAA,EACT,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAChB,EAAA,OAAO,mDAAmD,KAAK,CAAA,OAAA,CAAA;AACjE;AAEA,SAAS,uBAAA,CAUP,KAMA,OAAA,EACQ;AACR,EAAA,MAAM,IAAA,GAAO,IAAI,OAAA,EAAQ;AACzB,EAAA,MAAM,WAAA,GAAc,IAAI,KAAA,CAAM,WAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA;AAElC,EAAA,MAAM,gBAAA,GAAmB,IAAI,KAAA,CAC1B,cAAA;AACH,EAAA,MAAM,eAAe,MAAA,CAAO,MAAA;AAAA,IAC1B,IAAI,KAAA,CAAM;AAAA,GACZ;AACA,EAAA,MAAM,qBAAqB,MAAA,CAAO,MAAA;AAAA,IAChC,IAAI,KAAA,CAAM;AAAA,GACZ;AACA,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,MAAM,QAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA,KAAM;AAC3E,IAAA,OAAO,CAAA,CAAE,cAAc,CAAC,CAAA;AAAA,EAC1B,CAAC,CAAA;AACD,EAAA,MAAM,eAAe,cAAA,CAAe,GAAA,CAAI,CAAC,CAAC,WAAW,CAAA,KAAM;AACzD,IAAA,OAAO,WAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,aAAA,EAAgB,IAAI,CAAA,OAAA,CAAS,CAAA;AAClD,EAAA,IAAI,gBAAgB,MAAA,EAAW;AAC7B,IAAA,WAAA,CAAY,IAAA,CAAK,CAAA,QAAA,EAAW,WAAW,CAAA,OAAA,CAAS,CAAA;AAAA,EAClD;AAEA,EAAA,IAAI,cAAA;AACJ,EAAA,IAAI,UAAU,CAAA,EAAG;AACf,IAAA,cAAA,GAAiB;AAAA,MACf,mBAAmB,UAAU,CAAA;AAAA,MAC7B,CAAA,EAAA,EAAK,2BAAA,CAA4B,YAAY,CAAC,CAAA;AAAA,KAChD;AAAA,EACF,CAAA,MAAA,IAAW,cAAA,CAAe,MAAA,KAAW,CAAA,EAAG;AACtC,IAAA,cAAA,GAAiB,CAAC,kBAAA,CAAmB,UAAU,CAAA,EAAG,gBAAgB,CAAA;AAAA,EACpE,CAAA,MAAO;AACL,IAAA,cAAA,GAAiB;AAAA,MACf,mBAAmB,UAAU,CAAA;AAAA,MAC7B,GAAG,cAAA,CAAe,GAAA,CAAI,CAAC,CAAC,WAAA,EAAa,UAAU,CAAA,KAAM;AACnD,QAAA,OAAO,iBAAA,CAAkB;AAAA,UACvB,IAAA,EAAM,WAAA;AAAA,UACN,WAAA,EAAa,WAAW,KAAA,CAAM;AAAA,SAC/B,CAAA;AAAA,MACH,CAAC;AAAA,KACH;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,aAAA,CAAc,wBAAwB,gBAAgB,CAAA;AAAA,IACtD,aAAA,CAAc,WAAW,YAAY,CAAA;AAAA,IACrC,aAAA,CAAc,kBAAkB,kBAAkB,CAAA;AAAA,IAClD;AAAA,GACF;AAEA,EAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,WAAA,EAAa,EAAE,CAAA;AACjC,EAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,EAAS,GAAA,KAAQ;AACjC,IAAA,KAAA,CAAM,IAAA,CAAK,GAAG,OAAO,CAAA;AACrB,IAAA,IAAI,GAAA,GAAM,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAC7B,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,IACf;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAI,UAAU,CAAA,EAAG;AACf,IAAA,MAAM,qBAAqB,cAAA,CAAe,GAAA,CAAI,CAAC,GAAG,UAAU,CAAA,KAAM;AAChE,MAAA,OAAO,uBAAA,CAAwB,UAAA,EAAY,EAAE,KAAA,EAAO,GAAG,CAAA;AAAA,IACzD,CAAC,CAAA;AACD,IAAA,IAAI,kBAAA,CAAmB,SAAS,CAAA,EAAG;AACjC,MAAA,kBAAA,CAAmB,OAAA,CAAQ,CAAC,IAAA,KAAS;AACnC,QAAA,KAAA,CAAM,KAAK,EAAA,EAAI,GAAG,IAAA,CAAK,KAAA,CAAM,IAAI,CAAC,CAAA;AAAA,MACpC,CAAC,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,OAAO,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG,KAAA,GAAQ,CAAC,CAAC,CAAA;AACnD,EAAA,OAAO,KAAA,CACJ,GAAA,CAAI,CAAC,IAAA,KAAS;AACb,IAAA,OAAO,SAAS,EAAA,GAAK,EAAA,GAAK,CAAA,EAAG,MAAM,GAAG,IAAI,CAAA,CAAA;AAAA,EAC5C,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AACd;AAEO,SAAS,iBAUd,GAAA,EAMQ;AACR,EAAA,OAAO,wBAAwB,uBAAA,CAAwB,GAAA,EAAK,EAAE,KAAA,EAAO,CAAA,EAAG,CAAC,CAAA;AAC3E;AC7MA,IAAMC,kBAAAA,GAAoB,iBAAA;AAW1B,SAAS,sBAAsB,OAAA,EAA0B;AACvD,EAAA,MAAM,WAAW,OAAA,CAAQ,OAAA,CAAQA,kBAAAA,EAAmB,EAAE,EAAE,OAAA,EAAQ;AAChE,EAAA,OAAO,SAAS,QAAA,CAAS,GAAG,CAAA,IAAK,QAAA,CAAS,SAAS,GAAG,CAAA;AACxD;AAKA,eAAsB,qBACpB,OAAA,EAC6B;AAC7B,EAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,OAAA,EAAS,eAAc,GAAI,OAAA;AACpD,EAAA,MAAM,MAAA,GACJ,aAAA,CAAc,QAAA,GAAW,EAAA,GAAK,4CAAA;AAChC,EAAA,MAAM,aAAA,GAAgB,aAAA,CAAc,IAAA,KAAS,SAAA,GAAY,eAAA,GAAkB,EAAA;AAC3E,EAAA,MAAM,gBAAgB,CAAA,EAAG,OAAO,CAAA,EAAG,aAAa,GAAG,MAAM,CAAA,CAAA;AACzD,EAAA,MAAM,UAAA,GACJ,sBAAsB,OAAO,CAAA,GAAI,GAAG,aAAa,CAAA,CAAA,CAAA,GAAM,GAAG,aAAa,CAAA,EAAA,CAAA;AACzE,EAAA,MAAM,MAAA,GAAS,uBAAA,CAAwB,UAAA,EAAY,MAAM,CAAA;AAEzD,EAAA,MAAM,KAAK,eAAA,CAAgB,EAAE,OAAO,KAAA,EAAO,MAAA,EAAQ,QAAQ,CAAA;AAC3D,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,EAAM;AACX,MAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,QAAA,CAAS,MAAM,CAAA;AACvC,MAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAC5B,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,QAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,UAAA,MAAA,CAAO,KAAA;AAAA,YACL,uBAAA;AAAA,cACE;AAAA;AACF,WACF;AACA,UAAA;AAAA,QACF;AACA,QAAA,OAAO,KAAA,CAAA;AAAA,MACT;AACA,MAAA,IAAI,aAAA,CAAc,SAAS,SAAA,EAAW;AACpC,QAAA,MAAM,UAAA,GAAa,QAAQ,WAAA,EAAY;AACvC,QAAA,IAAI,UAAA,KAAe,GAAA,IAAO,UAAA,KAAe,KAAA,EAAO;AAC9C,UAAA,OAAO,MAAA;AAAA,QACT;AACA,QAAA,IAAI,UAAA,KAAe,GAAA,IAAO,UAAA,KAAe,IAAA,EAAM;AAC7C,UAAA,OAAO,OAAA;AAAA,QACT;AACA,QAAA,MAAA,CAAO,KAAA;AAAA,UACL,uBAAA;AAAA,YACE;AAAA;AACF,SACF;AACA,QAAA;AAAA,MACF;AACA,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA,SAAE;AACA,IAAA,EAAA,CAAG,KAAA,EAAM;AAAA,EACX;AACF;;;ACjDA,SAAS,uBAAuB,IAAA,EAAyC;AACvE,EAAA,OAAO,IAAA,CAAK,WAAW,IAAI,CAAA;AAC7B;AAEA,SAAS,oBAAoB,IAAA,EAAsC;AACjE,EAAA,OAAO,IAAA,CAAK,WAAW,GAAG,CAAA;AAC5B;AAEA,SAAS,cAAc,GAAA,EAAiC;AACtD,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,MAAA,KAAW,CAAA;AACrC;AAEA,SAAS,qBAGP,OAAA,EAA2E;AAC3E,EAAA,MAAM,EAAE,WAAA,EAAa,WAAA,EAAa,OAAA,EAAQ,GAAI,OAAA;AAC9C,EAAA,IAAI,YAAY,SAAA,EAAW;AACzB,IAAA,MAAM,YAAY,WAAA,CAAY,SAAA;AAG9B,IAAA,MAAM,gBAAA,GAAmB,UAAU,WAAW,CAAA;AAC9C,IAAA,IAAI,qBAAqB,IAAA,EAAM;AAC7B,MAAA,OAAO,WAAA;AAAA,IACT;AACA,IAAA,MAAM,SAAS,oBAAA,CAAqB;AAAA,MAClC,OAAA;AAAA,MACA,WAAW,WAAA,CAAY,IAAA;AAAA,MACvB,UAAA,EAAY,WAAA;AAAA,MACZ,OAAA,EACE,OAAO,gBAAA,KAAqB,QAAA,GAAW,gBAAA,GAAmB;AAAA,KAC7D,CAAA;AAAA,EACH;AACA,EAAA,OAAO,WAAA;AACT;AAEA,SAAS,uBAGP,OAAA,EAKqB;AACrB,EAAA,MAAM,EAAE,OAAA,EAAS,UAAA,EAAY,YAAA,EAAc,aAAY,GAAI,OAAA;AAC3D,EAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,IAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,OAAO,oBAAA,CAAqB;AAAA,MAC1B,OAAA;AAAA,MACA,WAAA,EAAa,YAAA;AAAA,MACb;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,WAAA,GACJ,WAAA,CAAY,MAAA,GACT,WAAA,CAAY,MAAA,CAAO,UAAU,CAAA,GAE7B,KAAA,CAAM,WAAA,CAAY,IAAI,CAAA,CACpB,IAAA,CAAK,WAAW,MAAM;AACrB,IAAA,OAAO,UAAA,KAAe,UAAU,KAAA,GAAQ,IAAA;AAAA,EAC1C,CAAC,CAAA,CACA,IAAA,CAAK,QAAA,EAAU,MAAM;AACpB,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,UAAA,EAAY,EAAE,CAAA;AAAA,EACvC,CAAC,CAAA,CACA,IAAA,CAAK,QAAA,EAAU,MAAM;AACpB,IAAA,OAAO,UAAA;AAAA,EACT,CAAC,CAAA,CACA,UAAA,CAAW,MAAM;AAChB,IAAA,OAAO,UAAA;AAAA,EACT,CAAC,CAAA;AACP,EAAA,OAAO,oBAAA,CAAqB;AAAA,IAC1B,OAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH;AAEA,SAAS,eAAA,CASP;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA,EAQmC;AACjC,EAAA,MAAM,QAAA,GAAW,IAAI,KAAA,CAAM,OAAA;AAC3B,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,iBAAiB,CAAA,CAAE,MAAA;AAAA,IACvC,CAAC,GAAA,EAAK,CAAC,QAAA,EAAU,KAAK,CAAA,KAAM;AAC1B,MAAA,MAAM,KAAA,GAAQ,QAAA;AACd,MAAA,MAAM,UAAA,GAAa,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA;AACtC,MAAA,GAAA,CAAI,UAAU,CAAA,GAAI,KAAA;AAClB,MAAA,OAAO,GAAA;AAAA,IACT,CAAA;AAAA,IACA;AAAC,GACH;AACF;AAMA,eAAe,YAAY,OAAA,EAEK;AAC9B,EAAA,MAAM,EAAE,WAAU,GAAI,OAAA;AACtB,EAAA,MAAM,aAAa,SAAA,CAAU,UAAA;AAC7B,EAAA,MAAM,cACJ,SAAA,CAAU,WAAA,GAAc,CAAA,EAAA,EAAK,SAAA,CAAU,WAAW,CAAA,CAAA,CAAA,GAAM,EAAA;AAC1D,EAAA,MAAM,WAAA,GACJ,OAAO,UAAA,KAAe,QAAA,GACpB,UAAA,CAAW,UACX,CAAA,yBAAA,EAA4B,SAAA,CAAU,IAAI,CAAA,EAAG,WAAW,CAAA,CAAA;AAC5D,EAAA,MAAM,cAAA,GAAiB,gBAAgB,WAAW,CAAA,OAAA,CAAA;AAClD,EAAA,OAAO,oBAAA,CAAqB;AAAA,IAC1B,OAAA,EAAS,cAAA;AAAA,IACT,QAAQ,EAAC;AAAA,IACT,SAAS,EAAE,QAAA,EAAU,UAAU,QAAA,EAAU,IAAA,EAAM,UAAU,IAAA;AAAK,GAC/D,CAAA;AACH;AAEA,eAAe,cASb,OAAA,EAUgB;AAChB,EAAA,MAAM,EAAE,mBAAA,EAAqB,aAAA,EAAe,iBAAA,EAAmB,KAAI,GAAI;AAAA,IACrE,GAAG,OAAA;AAAA,IACH,qBAAqB,eAAA,CAAgB;AAAA,MACnC,mBAAmB,OAAA,CAAQ,mBAAA;AAAA,MAC3B,KAAK,OAAA,CAAQ;AAAA,KACd,CAAA;AAAA,IACD,eAAe,eAAA,CAAgB;AAAA,MAC7B,mBAAmB,OAAA,CAAQ,aAAA;AAAA;AAAA,MAG3B,KAAK,OAAA,CAAQ;AAAA,KACd;AAAA,GACH;AAGA,EAAA,MAAM,QAAA,GAAW,kBAAkB,CAAC,CAAA;AACpC,EAAA,IACE,QAAA,IACA,CAAC,aAAA,CAAc,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA,IACjC,GAAA,CAAI,KAAA,CAAM,QAAA,CAAS,QAAQ,CAAA,EAC3B;AAEA,IAAA,MAAM,aAAa,MAAA,CAAO,MAAA;AAAA,MACxB,IAAI,KAAA,CAAM;AAAA,KACZ,CAAE,MAAA;AAAA,MACA,CAAC,QAAQ,SAAA,KAAc;AACrB,QAAA,OAAO,MAAA,CAAO,gBAAgB,SAAS,CAAA;AAAA,MACzC,CAAA;AAAA,MACA,GAAA,CAAI,cAAc,QAA4C;AAAA,KAChE;AAGA,IAAA,OAAO,aAAA,CAAc;AAAA,MACnB,iBAAA,EAAmB,iBAAA,CAAkB,KAAA,CAAM,CAAC,CAAA;AAAA,MAC5C,aAAA;AAAA,MACA,mBAAA;AAAA,MACA,GAAA,EAAK;AAAA,KACN,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAI5B,EAAA,IAAI,iBAAA,CAAkB,MAAA,GAAS,GAAA,CAAI,KAAA,CAAM,eAAe,MAAA,EAAQ;AAC9D,IAAA,MAAM,SAAS,qBAAA,CAAsB;AAAA,MACnC,OAAA;AAAA,MACA,OAAO,iBAAA,CAAkB;AAAA,KAC1B,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,uBAAyD,EAAC;AAChE,EAAA,KAAA,MAAW,CAAC,KAAK,SAAS,CAAA,IAAK,IAAI,KAAA,CAAM,cAAA,CAAe,SAAQ,EAAG;AACjE,IAAA,IAAI,MAAA,GAAS,kBAAkB,GAAG,CAAA;AAClC,IAAA,IAAI,SAAA,CAAU,UAAA,IAAc,MAAA,KAAW,MAAA,EAAW;AAChD,MAAA,MAAA,GAAS,MAAM,WAAA,CAAY,EAAE,SAAA,EAAW,CAAA;AAAA,IAC1C;AAEA,IAAA,IAAI,SAAA,CAAU,QAAA,IAAY,MAAA,KAAW,MAAA,EAAW;AAC9C,MAAA,MAAM,SAAS,4BAAA,CAA6B;AAAA,QAC1C,OAAA;AAAA,QACA,mBAAmB,SAAA,CAAU;AAAA,OAC9B,CAAA;AAAA,IACH;AAEA,IAAA,oBAAA,CAAqB,SAAA,CAAU,IAAI,CAAA,GAAI,sBAAA,CAAuB;AAAA,MAC5D,OAAA;AAAA,MACA,UAAA,EAAY,MAAA;AAAA,MACZ,cAAc,SAAA,CAAU,YAAA;AAAA,MACxB,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,mBAAqD,EAAC;AAC5D,EAAA,KAAA,MAAW,aAAa,MAAA,CAAO,MAAA;AAAA,IAC7B,IAAI,KAAA,CAAM;AAAA,GACZ,EAAG;AACD,IAAA,IAAI,MAAA,GAAS,aAAA,CAAc,SAAA,CAAU,IAAI,CAAA;AACzC,IAAA,IAAI,SAAA,CAAU,UAAA,IAAc,MAAA,KAAW,MAAA,EAAW;AAChD,MAAA,MAAA,GAAS,MAAM,WAAA,CAAY,EAAE,SAAA,EAAW,CAAA;AAAA,IAC1C;AAEA,IAAA,IAAI,SAAA,CAAU,QAAA,IAAY,MAAA,KAAW,MAAA,EAAW;AAC9C,MAAA,MAAM,SAAS,qBAAA,CAAsB;AAAA,QACnC,OAAA;AAAA,QACA,YAAY,SAAA,CAAU;AAAA,OACvB,CAAA;AAAA,IACH;AAEA,IAAA,gBAAA,CAAiB,SAAA,CAAU,SAAA,CAAU,IAAI,CAAC,IAAI,sBAAA,CAAuB;AAAA,MACnE,OAAA;AAAA,MACA,UAAA,EAAY,MAAA;AAAA,MACZ,cAAc,SAAA,CAAU,YAAA;AAAA,MACxB,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,yBAA2D,EAAC;AAClE,EAAA,KAAA,MAAW,aAAa,MAAA,CAAO,MAAA;AAAA,IAC7B,IAAI,KAAA,CAAM;AAAA,GACZ,EAAG;AACD,IAAA,IAAI,MAAA,GAAS,mBAAA,CAAoB,SAAA,CAAU,IAAI,CAAA;AAC/C,IAAA,IAAI,SAAA,CAAU,UAAA,IAAc,MAAA,KAAW,MAAA,EAAW;AAChD,MAAA,MAAA,GAAS,MAAM,WAAA,CAAY,EAAE,SAAA,EAAW,CAAA;AAAA,IAC1C;AAEA,IAAA,IAAI,SAAA,CAAU,QAAA,IAAY,MAAA,KAAW,MAAA,EAAW;AAC9C,MAAA,MAAM,SAAS,qBAAA,CAAsB;AAAA,QACnC,OAAA;AAAA,QACA,YAAY,SAAA,CAAU;AAAA,OACvB,CAAA;AAAA,IACH;AACA,IAAA,sBAAA,CAAuB,SAAA,CAAU,SAAA,CAAU,IAAI,CAAC,IAAI,sBAAA,CAAuB;AAAA,MACzE,OAAA;AAAA,MACA,UAAA,EAAY,MAAA;AAAA,MACZ,cAAc,SAAA,CAAU,YAAA;AAAA,MACxB,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,MAAA,GAAS,IAAI,KAAA,CAAM,MAAA;AACzB,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAA,CAAO;AAAA,MACL,GAAG,oBAAA;AAAA,MACH,GAAG,gBAAA;AAAA,MACH,GAAG;AAAA,KAKJ,CAAA;AACD,IAAA;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,GAAA,CAAI,gBAAA,CAAiB,GAAG,CAAC,CAAA;AACnC;AAOA,eAAsB,OAAO,OAAA,EAGX;AAChB,EAAA,MAAM,EAAE,KAAA,EAAO,GAAA,EAAI,GAAI,OAAA;AACvB,EAAA,MAAM,cAAA,GAAiB,KAAA,CAAM,SAAA,CAAU,CAAC,KAAA,KAAU;AAChD,IAAA,OAAO,KAAA,CAAM,WAAW,GAAG,CAAA;AAAA,EAC7B,CAAC,CAAA;AAED,EAAA,MAAM,CAAC,mBAAmB,IAAI,CAAA,GAC5B,mBAAmB,EAAA,GACjB,CAAC,OAAO,EAAE,IACV,CAAC,KAAA,CAAM,MAAM,CAAA,EAAG,cAAc,GAAG,KAAA,CAAM,KAAA,CAAM,cAAc,CAAC,CAAA;AAEhE,EAAA,MAAM,gBAAgD,EAAC;AACvD,EAAA,MAAM,sBAAyD,EAAC;AAChE,EAAA,IAAI,YAAA;AACJ,EAAA,IAAI,cAAwB,EAAC;AAE7B,EAAA,MAAM,EAAE,OAAA,EAAS,gBAAA,EAAiB,GAAI,GAAA,CAAI,KAAA;AAO1C,EAAA,KAAA,MAAW,MAAA,IAAU,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA,EAAG;AACrC,IAAA,IAAI,mBAAA,CAAoB,MAAM,CAAA,EAAG;AAC/B,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,MAAM,QAAA,GAAW,WAAA,CAAY,IAAA,CAAK,GAAG,CAAA;AACrC,QAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,YAAY,CAAA,IAAK,YAAA;AAC5C,QAAA,IACE,sBAAA,CAAuB,UAAU,CAAA,IACjC,CAAC,cAAc,gBAAgB,CAAA,IAC/B,gBAAA,CAAiB,UAAU,CAAA,EAC3B;AACA,UAAA,mBAAA,CAAoB,UAAU,CAAA,GAAI,QAAA;AAAA,QACpC,CAAA,MAAO;AACL,UAAA,aAAA,CAAc,UAAU,CAAA,GAAI,QAAA;AAAA,QAC9B;AAAA,MACF;AACA,MAAA,YAAA,GAAe,MAAA;AACf,MAAA,WAAA,GAAc,EAAC;AAAA,IACjB,CAAA,MAAO;AACL,MAAA,WAAA,CAAY,KAAK,MAAM,CAAA;AAAA,IACzB;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,CAAc;AAAA,IAClB,iBAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH;;;AC/SO,IAAM,SAAA,GAAuB;AAAA,EAClC,SAAA;AAAA,EACA,GAAA,EAAK,CAAC,GAAA,KAAgB;AACpB,IAAA,KAAK,MAAA,CAAO,EAAE,GAAA,EAAK,KAAA,EAAO,QAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA;AAAA,EACnD,CAAA;AAAA,EACA,GAAA,EAAK,CAAC,OAAA,EAAiB,MAAA,GAA6C,EAAC,KAAM;AACzE,IAAA,OAAA,CAAQ,GAAA,CAAI,uBAAA,CAAwB,OAAA,EAAS,MAAM,CAAC,CAAA;AAAA,EACtD,CAAA;AAAA,EACA,YAAA,EAAc,CAAC,OAAA,KAAY;AACzB,IAAA,OAAO,qBAAqB,OAAO,CAAA;AAAA,EACrC;AACF","file":"index.js","sourcesContent":["import type { CLIParamDataType } from \"./AcclimateCLI/AcclimateCLI.types\";\n\ntype CLIErrorInfo =\n | {\n code: \"already_run\";\n details: undefined;\n }\n | {\n code: \"unknown_command\";\n details: { commandName: string };\n }\n | {\n code: \"invalid_positional_arg_config\";\n details: { positionalArgName: string };\n }\n | {\n code: \"too_many_positional_args\";\n details: { count: number };\n }\n | {\n code: \"missing_required_positional_arg\";\n details: { positionalArgName: string };\n }\n | {\n code: \"missing_required_option\";\n details: { optionName: string };\n }\n | {\n code: \"unknown_option\";\n details: {\n optionName: string;\n };\n }\n | {\n code: \"invalid_cli_param_value\";\n details: {\n paramName: string;\n paramValue: CLIParamDataType;\n };\n }\n | { code: \"unknown_error\"; details: undefined };\n\ntype CLIErrorOptions = { cliName: string; message: string } & CLIErrorInfo;\n\nexport class CLIError extends Error {\n static invalidCLIParamValue(options: {\n cliName: string;\n paramName: string;\n paramValue: CLIParamDataType;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ?? `Invalid value for CLI param \"${options.paramName}\"`,\n code: \"invalid_cli_param_value\",\n details: { paramName: options.paramName, paramValue: options.paramValue },\n });\n }\n static missingRequiredOption(options: {\n cliName: string;\n optionName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ?? `Required option \"${options.optionName}\" is missing`,\n code: \"missing_required_option\",\n details: { optionName: options.optionName },\n });\n }\n\n static missingRequiredPositionalArg(options: {\n cliName: string;\n positionalArgName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ??\n `Required positional argument \"${options.positionalArgName}\" is missing`,\n code: \"missing_required_positional_arg\",\n details: { positionalArgName: options.positionalArgName },\n });\n }\n\n static unknownOption(options: {\n cliName: string;\n optionName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? `Option \"${options.optionName}\" not found`,\n code: \"unknown_option\",\n details: { optionName: options.optionName },\n });\n }\n\n static tooManyPositionalArgs(options: {\n cliName: string;\n count: number;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? \"Too many positional arguments provided.\",\n code: \"too_many_positional_args\",\n details: { count: options.count },\n });\n }\n\n static invalidPositionalArgConfig(options: {\n cliName: string;\n positionalArgName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ??\n `Positional argument configuration for \"${options.positionalArgName}\" is invalid`,\n code: \"invalid_positional_arg_config\",\n details: { positionalArgName: options.positionalArgName },\n });\n }\n\n static unknownCommand(options: {\n cliName: string;\n commandName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? `Command \"${options.commandName}\" not found`,\n code: \"unknown_command\",\n details: { commandName: options.commandName },\n });\n }\n\n static alreadyRun(options: {\n cliName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? \"CLI has already been run\",\n code: \"already_run\",\n details: undefined,\n });\n }\n\n constructor(options: CLIErrorOptions) {\n super(`❌ Error running ${options.cliName}: ${options.message}`);\n }\n}\n","import { CLIError } from \"@/CLIError\";\nimport type {\n AddEntry,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionParam,\n CLIPositionalParam,\n CLIPositionalParamName,\n CLIState,\n FullCLIArgValues,\n IAcclimateCLI,\n} from \"./AcclimateCLI.types\";\nimport type { EmptyObject, Simplify } from \"type-fest\";\n\nexport function AcclimateCLI<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, IAcclimateCLI> | EmptyObject,\n>(\n state: CLIState<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n> {\n const cliName = state.name;\n return {\n state,\n\n getName: () => {\n return cliName;\n },\n\n action: (\n action: (\n args: Simplify<\n FullCLIArgValues<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams\n >\n >,\n ) => void,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n > => {\n return AcclimateCLI({\n ...state,\n action,\n });\n },\n\n description: (\n description: string,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n > => {\n return AcclimateCLI({\n ...state,\n description,\n });\n },\n\n addPositionalArg: <\n PName extends CLIPositionalParamName,\n P extends CLIPositionalParam<PName>,\n >(\n param: P,\n ) => {\n if (\n param.required &&\n state.positionalArgs.some((p) => {\n return !p.required;\n })\n ) {\n throw CLIError.invalidPositionalArgConfig({\n cliName,\n positionalArgName: param.name,\n message:\n \"Required positional arguments must be before optional positional arguments\",\n });\n }\n\n return AcclimateCLI({\n ...state,\n positionalArgs: [\n ...state.positionalArgs,\n { ...param, required: param.required ?? true },\n ],\n } as unknown as CLIState<\n AddEntry<TPositionalParams, P[\"name\"], P>,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >);\n },\n\n addGlobalOption: <P extends CLIOptionParam>(param: P) => {\n const newAliases = (param.aliases ?? []).reduce(\n (acc, alias) => {\n acc[alias] = param.name;\n return acc;\n },\n {} as Record<`-${string}` | `--${string}`, `--${string}`>,\n );\n return AcclimateCLI<\n TPositionalParams,\n TOptionParams,\n AddEntry<TGlobalOptionParams, P[\"name\"], P>,\n TCommands\n >({\n ...state,\n aliases: { ...state.aliases, ...newAliases },\n globalOptionArgs: {\n ...state.globalOptionArgs,\n [param.name]: param,\n },\n } as unknown as CLIState<\n TPositionalParams,\n TOptionParams,\n AddEntry<TGlobalOptionParams, P[\"name\"], P>,\n TCommands\n >);\n },\n\n addOption: <P extends CLIOptionParam>(param: P) => {\n const newAliases = (param.aliases ?? []).reduce(\n (acc, alias) => {\n acc[alias] = param.name;\n return acc;\n },\n {} as Record<`-${string}` | `--${string}`, `--${string}`>,\n );\n return AcclimateCLI<\n TPositionalParams,\n AddEntry<TOptionParams, P[\"name\"], P>,\n TGlobalOptionParams,\n TCommands\n >({\n ...state,\n aliases: { ...state.aliases, ...newAliases },\n optionArgs: { ...state.optionArgs, [param.name]: param },\n } as unknown as CLIState<\n TPositionalParams,\n AddEntry<TOptionParams, P[\"name\"], P>,\n TGlobalOptionParams,\n TCommands\n >);\n },\n\n addCommand: <C extends CLICommandName, CommandCLI extends IAcclimateCLI>(\n commandName: C,\n cli: CommandCLI,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n AddEntry<TCommands, C, CommandCLI>\n > => {\n return AcclimateCLI({\n ...state,\n commands: {\n ...state.commands,\n [commandName]: cli,\n },\n } as unknown as CLIState<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n AddEntry<TCommands, C, CommandCLI>\n >);\n },\n\n getCommandCLI: <C extends Extract<keyof TCommands, CLICommandName>>(\n commandName: C,\n ): C extends keyof TCommands ? TCommands[C] : never => {\n const cmd = state.commands[commandName];\n if (!cmd) {\n throw CLIError.unknownCommand({\n cliName,\n commandName,\n message: `Command \"${commandName}\" not found`,\n });\n }\n return cmd as C extends keyof TCommands ? TCommands[C] : never;\n },\n };\n}\n","import type { CLIState } from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nexport const defaultCLIState: Omit<\n CLIState<EmptyObject, EmptyObject, EmptyObject, EmptyObject>,\n \"name\"\n> = {\n aliases: {},\n description: undefined,\n commands: {},\n positionalArgs: [],\n optionArgs: {},\n globalOptionArgs: {},\n action: undefined,\n};\n","import { AcclimateCLI } from \"../AcclimateCLI\";\nimport { defaultCLIState } from \"./defaultCLIState\";\nimport type { IAcclimateCLI } from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\n/**\n * Builder function to create a new CLI instance with a given name.\n *\n * @param name - The name of the CLI.\n * @returns A new CLI instance.\n */\nexport function createCLI(\n name: string,\n): IAcclimateCLI<EmptyObject, EmptyObject, EmptyObject, EmptyObject> {\n return AcclimateCLI({ ...defaultCLIState, name });\n}\n","const COLOR_CODES: Record<string, string> = {\n reset: \"\\x1b[0m\",\n black: \"\\x1b[30m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n bright_black: \"\\x1b[90m\",\n gray: \"\\x1b[90m\",\n grey: \"\\x1b[90m\",\n bright_red: \"\\x1b[91m\",\n bright_green: \"\\x1b[92m\",\n bright_yellow: \"\\x1b[93m\",\n bright_blue: \"\\x1b[94m\",\n bright_magenta: \"\\x1b[95m\",\n bright_cyan: \"\\x1b[96m\",\n bright_white: \"\\x1b[97m\",\n};\n\nconst PARAM_TOKEN_REGEX = /\\$([a-zA-Z0-9_]+)\\$/g;\nconst COLOR_TOKEN_REGEX = /\\|([a-zA-Z_]+)\\|/g;\n\n/**\n * Replaces `$token$` placeholders with values from `params`.\n * If a token does not exist in `params`, the placeholder is left unchanged.\n */\nfunction interpolateParams(\n message: string,\n params: Record<string, string | undefined>,\n) {\n return message.replace(PARAM_TOKEN_REGEX, (match, key: string) => {\n void match;\n const value = params[key];\n if (value === undefined) {\n return \"\";\n }\n return value;\n });\n}\n\nfunction applyColors(message: string) {\n return message.replace(COLOR_TOKEN_REGEX, (match, colorName: string) => {\n const code = COLOR_CODES[colorName.toLowerCase()];\n return code ?? match;\n });\n}\n\n/**\n * Outputs a message intended to be passed directly to `console.log`\n *\n * Supports interpolation using `$varName$` as tokens.\n *\n * Colors can be changed within a message `|<COLOR_NAME>|` tokens.\n * Supported colors are:\n * - black\n * - red\n * - green\n * - yellow\n * - blue\n * - magenta\n * - cyan\n * - white\n * - bright_black|gray|grey\n * - bright_red\n * - bright_green\n * - bright_yellow\n * - bright_blue\n * - bright_magenta\n * - bright_cyan\n * - bright_white\n *\n * The color remains active until another color token is found,\n * or if |reset| is found (which resets the terminal color to the default).\n *\n * @example\n *\n * Acclimate.log(\"Hello $name$\", { name: \"Pablo\" });\n * // \"Hello Pablo\"\n *\n * Acclimate.log(\"|red|Error:|reset| There was an error.\")\n * // \"Error: There was an error.\"\n * // ^ the \"Error:\" portion will be red\n *\n */\nexport function generateTerminalMessage(\n message: string,\n params: Record<string, string | undefined> = {},\n): string {\n const hasColorToken = Boolean(message.match(COLOR_TOKEN_REGEX));\n const endsWithReset = message.trimEnd().endsWith(\"|reset|\");\n const withReset =\n hasColorToken && !endsWithReset ? `${message}|reset|` : message;\n const interpolated = interpolateParams(withReset, params);\n return applyColors(interpolated);\n}\n","import { generateTerminalMessage } from \"@/generateTerminalMessage\";\nimport type {\n AnyCLI,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionParam,\n CLIParam,\n CLIPositionalParam,\n CLIPositionalParamName,\n IAcclimateCLI,\n} from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nconst _SECTION_TITLES = [\n \"Positional Arguments\",\n \"Options\",\n \"Global Options\",\n \"Commands\",\n] as const;\n\ntype SectionTitle = (typeof _SECTION_TITLES)[number];\n\ntype CLIParamWithRequired = CLIParam<string> & {\n required: boolean;\n aliases?: readonly string[];\n};\n\nfunction formatSectionTitle(title: SectionTitle): string {\n return `|bright_yellow|${title}|reset|`;\n}\n\nfunction formatNoneLine(): string {\n return \" |gray|None|reset|\";\n}\n\nfunction formatDefaultValue(\n value: CLIParamWithRequired[\"defaultValue\"],\n): string {\n return `|gray|[default: ${JSON.stringify(value)}]|reset|`;\n}\n\nfunction formatParamLine(param: CLIParamWithRequired): string {\n const description = param.description ?? \"No description\";\n const requiredLabel =\n param.required ? \"|red|required|reset|\" : \"|gray|optional|reset|\";\n const defaultLabel =\n param.defaultValue !== undefined ?\n formatDefaultValue(param.defaultValue)\n : undefined;\n const aliasList =\n param.aliases && param.aliases.length > 0 ? param.aliases.join(\", \") : \"\";\n const displayName = aliasList ? `${param.name}, ${aliasList}` : param.name;\n\n const segments = [\n ` |bright_white|${displayName}|reset|`,\n `(${param.type})|reset| ${requiredLabel}`,\n `- |gray|${description}|reset|`,\n defaultLabel,\n ].filter(Boolean);\n\n return segments.join(\" \");\n}\n\nfunction formatSection(\n title: SectionTitle,\n params: readonly CLIParamWithRequired[],\n): string[] {\n if (params.length === 0) {\n return [formatSectionTitle(title), formatNoneLine()];\n }\n\n return [formatSectionTitle(title), ...params.map(formatParamLine)];\n}\n\nfunction formatCommandLine(options: {\n name: string;\n description?: string;\n}): string {\n const { name, description } = options;\n const label = description ?? \"No description\";\n return ` |bright_white|${name}|reset| - |gray|${label}|reset|`;\n}\n\nfunction formatAvailableCommandsLine(commands: string[]): string {\n const label =\n commands.length === 0 ?\n \"None\"\n : commands\n .map((cmd) => {\n return cmd;\n })\n .join(\", \");\n return `|bright_yellow|Available Commands:|reset| |gray|${label}|reset|`;\n}\n\nfunction _generateHelpTextHelper<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n options: { level: 1 | 2 },\n): string {\n const name = cli.getName();\n const description = cli.state.description;\n const level = Number(options.level);\n\n const positionalParams = cli.state\n .positionalArgs as readonly CLIParamWithRequired[];\n const optionParams = Object.values(\n cli.state.optionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ) as readonly CLIParamWithRequired[];\n const globalOptionParams = Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ) as readonly CLIParamWithRequired[];\n const sortedCommands = Object.entries(cli.state.commands).sort(([a], [b]) => {\n return a.localeCompare(b);\n });\n const commandNames = sortedCommands.map(([commandName]) => {\n return commandName;\n });\n\n const headerLines = [`|bright_cyan|${name}|reset|`];\n if (description !== undefined) {\n headerLines.push(` |gray|${description}|reset|`);\n }\n\n let commandSection: string[];\n if (level === 2) {\n commandSection = [\n formatSectionTitle(\"Commands\"),\n ` ${formatAvailableCommandsLine(commandNames)}`,\n ];\n } else if (sortedCommands.length === 0) {\n commandSection = [formatSectionTitle(\"Commands\"), formatNoneLine()];\n } else {\n commandSection = [\n formatSectionTitle(\"Commands\"),\n ...sortedCommands.map(([commandName, commandCLI]) => {\n return formatCommandLine({\n name: commandName,\n description: commandCLI.state.description,\n });\n }),\n ];\n }\n\n const sections = [\n formatSection(\"Positional Arguments\", positionalParams),\n formatSection(\"Options\", optionParams),\n formatSection(\"Global Options\", globalOptionParams),\n commandSection,\n ];\n\n const lines = [...headerLines, \"\"];\n sections.forEach((section, idx) => {\n lines.push(...section);\n if (idx < sections.length - 1) {\n lines.push(\"\");\n }\n });\n\n if (level === 1) {\n const subCommandHelpText = sortedCommands.map(([, commandCLI]) => {\n return _generateHelpTextHelper(commandCLI, { level: 2 });\n });\n if (subCommandHelpText.length > 0) {\n subCommandHelpText.forEach((text) => {\n lines.push(\"\", ...text.split(\"\\n\"));\n });\n }\n }\n\n const indent = \" \".repeat(Math.max(0, level - 1));\n return lines\n .map((line) => {\n return line === \"\" ? \"\" : `${indent}${line}`;\n })\n .join(\"\\n\");\n}\n\nexport function generateHelpText<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n): string {\n return generateTerminalMessage(_generateHelpTextHelper(cli, { level: 1 }));\n}\n","import { stdin, stdout } from \"node:process\";\nimport { createInterface } from \"node:readline/promises\";\nimport { generateTerminalMessage } from \"@/generateTerminalMessage\";\n\nconst COLOR_TOKEN_REGEX = /\\|[a-zA-Z_]+\\|/g;\n\ntype RequestTerminalInputOptions = {\n message: string;\n params: Record<string, string>;\n options: {\n required: boolean;\n type?: \"string\" | \"number\" | \"boolean\";\n };\n};\n\nfunction messageHasPunctuation(message: string): boolean {\n const stripped = message.replace(COLOR_TOKEN_REGEX, \"\").trimEnd();\n return stripped.endsWith(\":\") || stripped.endsWith(\"?\");\n}\n\n/**\n * Prompt the user for terminal input, optionally enforcing a non-empty value.\n */\nexport async function requestTerminalInput(\n options: RequestTerminalInputOptions,\n): Promise<string | undefined> {\n const { message, params, options: promptOptions } = options;\n const notice =\n promptOptions.required ? \"\" : \" |gray|(press Enter to leave empty)|reset|\";\n const booleanNotice = promptOptions.type === \"boolean\" ? \" |reset|(y/n)\" : \"\";\n const promptMessage = `${message}${booleanNotice}${notice}`;\n const promptText =\n messageHasPunctuation(message) ? `${promptMessage} ` : `${promptMessage}: `;\n const prompt = generateTerminalMessage(promptText, params);\n\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n while (true) {\n const answer = await rl.question(prompt);\n const trimmed = answer.trim();\n if (trimmed.length === 0) {\n if (promptOptions.required) {\n stdout.write(\n generateTerminalMessage(\n \"|red|This value is required.|reset| Please enter a value.\\n\",\n ),\n );\n continue;\n }\n return undefined;\n }\n if (promptOptions.type === \"boolean\") {\n const normalized = trimmed.toLowerCase();\n if (normalized === \"y\" || normalized === \"yes\") {\n return \"true\";\n }\n if (normalized === \"n\" || normalized === \"no\") {\n return \"false\";\n }\n stdout.write(\n generateTerminalMessage(\n \"|red|That was not a valid response.|reset| Please enter y or n.\\n\",\n ),\n );\n continue;\n }\n return answer;\n }\n } finally {\n rl.close();\n }\n}\n","import { camelCase } from \"change-case\";\nimport { match } from \"ts-pattern\";\nimport { generateHelpText } from \"@/AcclimateCLI/generateHelpText/generateHelpText\";\nimport { CLIError } from \"@/CLIError\";\nimport { requestTerminalInput } from \"@/requestTerminalInput\";\nimport type {\n AnyCLI,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionAlias,\n CLIOptionParam,\n CLIParam,\n CLIParamDataType,\n CLIPositionalParam,\n CLIPositionalParamName,\n CLIState,\n FullCLIArgValues,\n IAcclimateCLI,\n ValueOfParam,\n} from \"@/AcclimateCLI/AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nfunction _isValidFullOptionName(name: string): name is CLIFullOptionName {\n return name.startsWith(\"--\");\n}\n\nfunction _isValidOptionAlias(name: string): name is CLIOptionAlias {\n return name.startsWith(\"-\");\n}\n\nfunction isEmptyObject(obj: object): obj is EmptyObject {\n return Object.keys(obj).length === 0;\n}\n\nfunction _validateParsedValue<\n P extends CLIParam<string>,\n PValue extends ValueOfParam<P>,\n>(options: { parsedValue: PValue; paramConfig: P; cliName: string }): PValue {\n const { parsedValue, paramConfig, cliName } = options;\n if (paramConfig.validator) {\n const validator = paramConfig.validator as (\n value: PValue,\n ) => boolean | string;\n const validationResult = validator(parsedValue);\n if (validationResult === true) {\n return parsedValue;\n }\n throw CLIError.invalidCLIParamValue({\n cliName,\n paramName: paramConfig.name,\n paramValue: parsedValue,\n message:\n typeof validationResult === \"string\" ? validationResult : undefined,\n });\n }\n return parsedValue;\n}\n\nfunction _parseAndValidateValue<\n P extends CLIParam<string>,\n PValue extends ValueOfParam<P>,\n>(options: {\n cliName: string;\n inputValue: string | undefined;\n defaultValue: PValue | undefined;\n paramConfig: P;\n}): PValue | undefined {\n const { cliName, inputValue, defaultValue, paramConfig } = options;\n if (inputValue === undefined) {\n if (defaultValue === undefined) {\n return undefined;\n }\n return _validateParsedValue({\n cliName,\n parsedValue: defaultValue,\n paramConfig,\n });\n }\n\n const parsedValue =\n paramConfig.parser ?\n (paramConfig.parser(inputValue) as PValue)\n // if no parser was set, we use the default parser\n : (match(paramConfig.type)\n .with(\"boolean\", () => {\n return inputValue === \"false\" ? false : true;\n })\n .with(\"number\", () => {\n return Number.parseInt(inputValue, 10);\n })\n .with(\"string\", () => {\n return inputValue;\n })\n .exhaustive(() => {\n return inputValue;\n }) as PValue);\n return _validateParsedValue({\n cliName,\n parsedValue,\n paramConfig,\n });\n}\n\nfunction _replaceAliases<\n TGlobalOptionArgs extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TOptionArgs extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TPositionalArgs extends\n | Record<CLIPositionalParamName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>({\n aliasedOptionArgs,\n cli,\n}: {\n aliasedOptionArgs: Record<CLIOptionAlias, string>;\n cli: IAcclimateCLI<\n TGlobalOptionArgs,\n TOptionArgs,\n TPositionalArgs,\n TCommands\n >;\n}): Record<CLIOptionAlias, string> {\n const aliasMap = cli.state.aliases;\n return Object.entries(aliasedOptionArgs).reduce(\n (acc, [aliasKey, value]) => {\n const alias = aliasKey as CLIOptionAlias;\n const optionName = aliasMap[alias] ?? alias;\n acc[optionName] = value;\n return acc;\n },\n {} as Record<CLIOptionAlias, string>,\n );\n}\n\ntype CLIParamWithRequired = CLIParam<string> & {\n required: boolean;\n};\n\nasync function askForValue(options: {\n argConfig: CLIParamWithRequired;\n}): Promise<string | undefined> {\n const { argConfig } = options;\n const askIfEmpty = argConfig.askIfEmpty;\n const description =\n argConfig.description ? ` (${argConfig.description})` : \"\";\n const baseMessage =\n typeof askIfEmpty === \"object\" ?\n askIfEmpty.message\n : `Please enter a value for ${argConfig.name}${description}`;\n const coloredMessage = `|bright_cyan|${baseMessage}|reset|`;\n return requestTerminalInput({\n message: coloredMessage,\n params: {},\n options: { required: argConfig.required, type: argConfig.type },\n });\n}\n\nasync function _runCLIHelper<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(options: {\n rawPositionalArgs: string[];\n rawOptionArgs: Record<CLIOptionAlias, string>;\n rawGlobalOptionArgs: Record<CLIFullOptionName, string>;\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >;\n}): Promise<void> {\n const { rawGlobalOptionArgs, rawOptionArgs, rawPositionalArgs, cli } = {\n ...options,\n rawGlobalOptionArgs: _replaceAliases({\n aliasedOptionArgs: options.rawGlobalOptionArgs,\n cli: options.cli,\n }),\n rawOptionArgs: _replaceAliases({\n aliasedOptionArgs: options.rawOptionArgs,\n\n // TODO(jpsyx): fix that this does not have the CLI may not have all\n cli: options.cli,\n }),\n };\n\n // is the first argument a command?\n const firstArg = rawPositionalArgs[0];\n if (\n firstArg &&\n !isEmptyObject(cli.state.commands) &&\n cli.state.commands[firstArg]\n ) {\n // add the parent's global options to the sub-command\n const commandCLI = Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ).reduce(\n (newCmd, argConfig) => {\n return newCmd.addGlobalOption(argConfig);\n },\n cli.getCommandCLI(firstArg as Extract<keyof TCommands, string>) as AnyCLI,\n );\n\n // run the sub-command\n return _runCLIHelper({\n rawPositionalArgs: rawPositionalArgs.slice(1),\n rawOptionArgs,\n rawGlobalOptionArgs,\n cli: commandCLI,\n });\n }\n\n const cliName = cli.getName();\n\n // build the positional arguments dictionary\n // first check that we haven't supplied too many positional arguments\n if (rawPositionalArgs.length > cli.state.positionalArgs.length) {\n throw CLIError.tooManyPositionalArgs({\n cliName,\n count: rawPositionalArgs.length,\n });\n }\n\n // parse positional arguments\n const parsedPositionalArgs: Record<string, CLIParamDataType> = {};\n for (const [idx, argConfig] of cli.state.positionalArgs.entries()) {\n let rawVal = rawPositionalArgs[idx];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredPositionalArg({\n cliName,\n positionalArgName: argConfig.name,\n });\n }\n\n parsedPositionalArgs[argConfig.name] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // parse the options\n const parsedOptionArgs: Record<string, CLIParamDataType> = {};\n for (const argConfig of Object.values(\n cli.state.optionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n )) {\n let rawVal = rawOptionArgs[argConfig.name];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredOption({\n cliName,\n optionName: argConfig.name,\n });\n }\n\n parsedOptionArgs[camelCase(argConfig.name)] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // parse the global options\n const parsedGlobalOptionArgs: Record<string, CLIParamDataType> = {};\n for (const argConfig of Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n )) {\n let rawVal = rawGlobalOptionArgs[argConfig.name];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredOption({\n cliName,\n optionName: argConfig.name,\n });\n }\n parsedGlobalOptionArgs[camelCase(argConfig.name)] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // run the action\n const action = cli.state.action;\n if (action) {\n action({\n ...parsedPositionalArgs,\n ...parsedOptionArgs,\n ...parsedGlobalOptionArgs,\n } as FullCLIArgValues<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams\n >);\n return;\n }\n\n console.log(generateHelpText(cli));\n}\n\n/**\n * Run a CLI instance given an array of inputs.\n *\n * @param options - The options for running the CLI.\n */\nexport async function runCLI(options: {\n input: string[];\n cli: AnyCLI;\n}): Promise<void> {\n const { input, cli } = options;\n const firstOptionIdx = input.findIndex((token) => {\n return token.startsWith(\"-\");\n });\n\n const [rawPositionalArgs, rest] =\n firstOptionIdx === -1 ?\n [input, []]\n : [input.slice(0, firstOptionIdx), input.slice(firstOptionIdx)];\n\n const rawOptionArgs: Record<CLIOptionAlias, string> = {};\n const rawGlobalOptionArgs: Record<CLIFullOptionName, string> = {};\n let currentAlias: CLIOptionAlias | undefined;\n let currentVals: string[] = [];\n\n const { aliases, globalOptionArgs } = cli.state as CLIState<\n Record<CLIFullOptionName, CLIOptionParam>,\n Record<CLIFullOptionName, CLIOptionParam>,\n Record<CLIPositionalParamName, CLIOptionParam>,\n Record<CLICommandName, AnyCLI>\n >;\n\n for (const argVal of rest.concat(\"-\")) {\n if (_isValidOptionAlias(argVal)) {\n if (currentAlias) {\n const rawValue = currentVals.join(\" \");\n const optionName = aliases[currentAlias] ?? currentAlias;\n if (\n _isValidFullOptionName(optionName) &&\n !isEmptyObject(globalOptionArgs) &&\n globalOptionArgs[optionName]\n ) {\n rawGlobalOptionArgs[optionName] = rawValue;\n } else {\n rawOptionArgs[optionName] = rawValue;\n }\n }\n currentAlias = argVal;\n currentVals = [];\n } else {\n currentVals.push(argVal);\n }\n }\n\n await _runCLIHelper({\n rawPositionalArgs,\n rawOptionArgs,\n rawGlobalOptionArgs,\n cli,\n });\n}\n","import { createCLI } from \"./AcclimateCLI\";\nimport { runCLI } from \"./AcclimateCLI/runCLI/runCLI\";\nimport { generateTerminalMessage } from \"./generateTerminalMessage\";\nimport { requestTerminalInput } from \"./requestTerminalInput\";\nimport type { AnyCLI, IAcclimateCLI } from \"./AcclimateCLI/AcclimateCLI.types\";\n\ntype Acclimate = {\n /**\n * Create a new Acclimate CLI instance.\n *\n * @param name - The name of the CLI.\n * @returns A new CLI instance.\n */\n createCLI: (name: string) => IAcclimateCLI;\n\n /**\n * Run a CLI instance.\n *\n * It can only be run once. Calling any other methods after `.run()` will\n * throw an error.\n *\n * @param cli - The CLI instance to run.\n */\n run: (cli: AnyCLI) => void;\n\n /**\n * Outputs a message with `console.log`.\n * Supports interpolation using `$varName$` as tokens.\n *\n * Colors can be changed within a message `|<COLOR_NAME>|` tokens.\n * Supported colors are:\n * - black\n * - red\n * - green\n * - yellow\n * - blue\n * - magenta\n * - cyan\n * - white\n * - bright_black|gray|grey\n * - bright_red\n * - bright_green\n * - bright_yellow\n * - bright_blue\n * - bright_magenta\n * - bright_cyan\n * - bright_white\n *\n * The color remains active until another color token is found,\n * or if |reset| is found (which resets the terminal color to the default).\n *\n * @example\n *\n * Acclimate.log(\"Hello $name$\", { name: \"Pablo\" });\n * // \"Hello Pablo\"\n *\n * Acclimate.log(\"|red|Error:|reset| There was an error.\")\n * // \"Error: There was an error.\"\n * // ^ the \"Error:\" portion will be red\n *\n */\n log: (message: string, params?: Record<string, string | undefined>) => void;\n\n /**\n * Prompt the user for interactive input in the terminal.\n *\n * @param options - Prompt configuration.\n * @returns The user's response, or undefined when left empty and optional.\n */\n requestInput: (options: {\n message: string;\n params: Record<string, string>;\n options: { required: boolean; type?: \"string\" | \"number\" | \"boolean\" };\n }) => Promise<string | undefined>;\n};\n\nexport const Acclimate: Acclimate = {\n createCLI,\n run: (cli: AnyCLI) => {\n void runCLI({ cli, input: process.argv.slice(2) });\n },\n log: (message: string, params: Record<string, string | undefined> = {}) => {\n console.log(generateTerminalMessage(message, params));\n },\n requestInput: (options) => {\n return requestTerminalInput(options);\n },\n};\n"]}
1
+ {"version":3,"sources":["../src/CLIError.ts","../src/AcclimateCLI/AcclimateCLI.ts","../src/AcclimateCLI/createCLI/defaultCLIState.ts","../src/AcclimateCLI/createCLI/createCLI.ts","../src/generateTerminalMessage/generateTerminalMessage.ts","../src/AcclimateCLI/generateHelpText/generateHelpText.ts","../src/requestTerminalInput/requestTerminalInput.ts","../src/AcclimateCLI/runCLI/runCLI.ts","../src/Acclimate.ts"],"names":["match"],"mappings":"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","file":"index.js","sourcesContent":["import type { CLIParamDataType } from \"./AcclimateCLI/AcclimateCLI.types\";\n\ntype CLIErrorInfo =\n | {\n code: \"already_run\";\n details: undefined;\n }\n | {\n code: \"unknown_command\";\n details: { commandName: string };\n }\n | {\n code: \"invalid_positional_arg_config\";\n details: { positionalArgName: string };\n }\n | {\n code: \"too_many_positional_args\";\n details: { count: number };\n }\n | {\n code: \"missing_required_positional_arg\";\n details: { positionalArgName: string };\n }\n | {\n code: \"missing_required_option\";\n details: { optionName: string };\n }\n | {\n code: \"unknown_option\";\n details: {\n optionName: string;\n };\n }\n | {\n code: \"invalid_cli_param_value\";\n details: {\n paramName: string;\n paramValue: CLIParamDataType;\n };\n }\n | { code: \"unknown_error\"; details: undefined };\n\ntype CLIErrorOptions = { cliName: string; message: string } & CLIErrorInfo;\n\nexport class CLIError extends Error {\n static invalidCLIParamValue(options: {\n cliName: string;\n paramName: string;\n paramValue: CLIParamDataType;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ?? `Invalid value for CLI param \"${options.paramName}\"`,\n code: \"invalid_cli_param_value\",\n details: { paramName: options.paramName, paramValue: options.paramValue },\n });\n }\n static missingRequiredOption(options: {\n cliName: string;\n optionName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ?? `Required option \"${options.optionName}\" is missing`,\n code: \"missing_required_option\",\n details: { optionName: options.optionName },\n });\n }\n\n static missingRequiredPositionalArg(options: {\n cliName: string;\n positionalArgName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ??\n `Required positional argument \"${options.positionalArgName}\" is missing`,\n code: \"missing_required_positional_arg\",\n details: { positionalArgName: options.positionalArgName },\n });\n }\n\n static unknownOption(options: {\n cliName: string;\n optionName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? `Option \"${options.optionName}\" not found`,\n code: \"unknown_option\",\n details: { optionName: options.optionName },\n });\n }\n\n static tooManyPositionalArgs(options: {\n cliName: string;\n count: number;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? \"Too many positional arguments provided.\",\n code: \"too_many_positional_args\",\n details: { count: options.count },\n });\n }\n\n static invalidPositionalArgConfig(options: {\n cliName: string;\n positionalArgName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message:\n options.message ??\n `Positional argument configuration for \"${options.positionalArgName}\" is invalid`,\n code: \"invalid_positional_arg_config\",\n details: { positionalArgName: options.positionalArgName },\n });\n }\n\n static unknownCommand(options: {\n cliName: string;\n commandName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? `Command \"${options.commandName}\" not found`,\n code: \"unknown_command\",\n details: { commandName: options.commandName },\n });\n }\n\n static alreadyRun(options: {\n cliName: string;\n message?: string;\n }): CLIError {\n return new CLIError({\n cliName: options.cliName,\n message: options.message ?? \"CLI has already been run\",\n code: \"already_run\",\n details: undefined,\n });\n }\n\n constructor(options: CLIErrorOptions) {\n super(`❌ Error running ${options.cliName}: ${options.message}`);\n }\n}\n","import { CLIError } from \"@/CLIError\";\nimport type {\n AddEntry,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionParam,\n CLIPositionalParam,\n CLIPositionalParamName,\n CLIState,\n FullCLIArgValues,\n IAcclimateCLI,\n} from \"./AcclimateCLI.types\";\nimport type { EmptyObject, Simplify } from \"type-fest\";\n\nexport function AcclimateCLI<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, IAcclimateCLI> | EmptyObject,\n>(\n state: CLIState<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n> {\n const cliName = state.name;\n return {\n state,\n\n getName: () => {\n return cliName;\n },\n\n action: (\n action: (\n args: Simplify<\n FullCLIArgValues<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams\n >\n >,\n ) => void,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n > => {\n return AcclimateCLI({\n ...state,\n action,\n });\n },\n\n description: (\n description: string,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n > => {\n return AcclimateCLI({\n ...state,\n description,\n });\n },\n\n addPositionalArg: <\n PName extends CLIPositionalParamName,\n P extends CLIPositionalParam<PName>,\n >(\n param: P,\n ) => {\n if (\n param.required &&\n state.positionalArgs.some((p) => {\n return !p.required;\n })\n ) {\n throw CLIError.invalidPositionalArgConfig({\n cliName,\n positionalArgName: param.name,\n message:\n \"Required positional arguments must be before optional positional arguments\",\n });\n }\n\n return AcclimateCLI({\n ...state,\n positionalArgs: [\n ...state.positionalArgs,\n { ...param, required: param.required ?? true },\n ],\n } as unknown as CLIState<\n AddEntry<TPositionalParams, P[\"name\"], P>,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >);\n },\n\n addGlobalOption: <P extends CLIOptionParam>(param: P) => {\n const newAliases = (param.aliases ?? []).reduce(\n (acc, alias) => {\n acc[alias] = param.name;\n return acc;\n },\n {} as Record<`-${string}` | `--${string}`, `--${string}`>,\n );\n return AcclimateCLI<\n TPositionalParams,\n TOptionParams,\n AddEntry<TGlobalOptionParams, P[\"name\"], P>,\n TCommands\n >({\n ...state,\n aliases: { ...state.aliases, ...newAliases },\n globalOptionArgs: {\n ...state.globalOptionArgs,\n [param.name]: param,\n },\n } as unknown as CLIState<\n TPositionalParams,\n TOptionParams,\n AddEntry<TGlobalOptionParams, P[\"name\"], P>,\n TCommands\n >);\n },\n\n addOption: <P extends CLIOptionParam>(param: P) => {\n const newAliases = (param.aliases ?? []).reduce(\n (acc, alias) => {\n acc[alias] = param.name;\n return acc;\n },\n {} as Record<`-${string}` | `--${string}`, `--${string}`>,\n );\n return AcclimateCLI<\n TPositionalParams,\n AddEntry<TOptionParams, P[\"name\"], P>,\n TGlobalOptionParams,\n TCommands\n >({\n ...state,\n aliases: { ...state.aliases, ...newAliases },\n optionArgs: { ...state.optionArgs, [param.name]: param },\n } as unknown as CLIState<\n TPositionalParams,\n AddEntry<TOptionParams, P[\"name\"], P>,\n TGlobalOptionParams,\n TCommands\n >);\n },\n\n addCommand: <C extends CLICommandName, CommandCLI extends IAcclimateCLI>(\n commandName: C,\n cli: CommandCLI,\n ): IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n AddEntry<TCommands, C, CommandCLI>\n > => {\n return AcclimateCLI({\n ...state,\n commands: {\n ...state.commands,\n [commandName]: cli,\n },\n } as unknown as CLIState<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n AddEntry<TCommands, C, CommandCLI>\n >);\n },\n\n getCommandCLI: <C extends Extract<keyof TCommands, CLICommandName>>(\n commandName: C,\n ): C extends keyof TCommands ? TCommands[C] : never => {\n const cmd = state.commands[commandName];\n if (!cmd) {\n throw CLIError.unknownCommand({\n cliName,\n commandName,\n message: `Command \"${commandName}\" not found`,\n });\n }\n return cmd as C extends keyof TCommands ? TCommands[C] : never;\n },\n };\n}\n","import type { CLIState } from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nexport const defaultCLIState: Omit<\n CLIState<EmptyObject, EmptyObject, EmptyObject, EmptyObject>,\n \"name\"\n> = {\n aliases: {},\n description: undefined,\n commands: {},\n positionalArgs: [],\n optionArgs: {},\n globalOptionArgs: {},\n action: undefined,\n};\n","import { AcclimateCLI } from \"../AcclimateCLI\";\nimport { defaultCLIState } from \"./defaultCLIState\";\nimport type { IAcclimateCLI } from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\n/**\n * Builder function to create a new CLI instance with a given name.\n *\n * @param name - The name of the CLI.\n * @returns A new CLI instance.\n */\nexport function createCLI(\n name: string,\n): IAcclimateCLI<EmptyObject, EmptyObject, EmptyObject, EmptyObject> {\n return AcclimateCLI({ ...defaultCLIState, name });\n}\n","const COLOR_CODES: Record<string, string> = {\n reset: \"\\x1b[0m\",\n black: \"\\x1b[30m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n bright_black: \"\\x1b[90m\",\n gray: \"\\x1b[90m\",\n grey: \"\\x1b[90m\",\n bright_red: \"\\x1b[91m\",\n bright_green: \"\\x1b[92m\",\n bright_yellow: \"\\x1b[93m\",\n bright_blue: \"\\x1b[94m\",\n bright_magenta: \"\\x1b[95m\",\n bright_cyan: \"\\x1b[96m\",\n bright_white: \"\\x1b[97m\",\n};\n\nconst PARAM_TOKEN_REGEX = /\\$([a-zA-Z0-9_]+)\\$/g;\nconst COLOR_TOKEN_REGEX = /\\|([a-zA-Z_]+)\\|/g;\n\n/**\n * Replaces `$token$` placeholders with values from `params`.\n * If a token does not exist in `params`, the placeholder is left unchanged.\n */\nfunction interpolateParams(\n message: string,\n params: Record<string, string | undefined>,\n) {\n return message.replace(PARAM_TOKEN_REGEX, (match, key: string) => {\n void match;\n const value = params[key];\n if (value === undefined) {\n return \"\";\n }\n return value;\n });\n}\n\nfunction applyColors(message: string) {\n return message.replace(COLOR_TOKEN_REGEX, (match, colorName: string) => {\n const code = COLOR_CODES[colorName.toLowerCase()];\n return code ?? match;\n });\n}\n\n/**\n * Outputs a message intended to be passed directly to `console.log`\n *\n * Supports interpolation using `$varName$` as tokens.\n *\n * Colors can be changed within a message `|<COLOR_NAME>|` tokens.\n * Supported colors are:\n * - black\n * - red\n * - green\n * - yellow\n * - blue\n * - magenta\n * - cyan\n * - white\n * - bright_black|gray|grey\n * - bright_red\n * - bright_green\n * - bright_yellow\n * - bright_blue\n * - bright_magenta\n * - bright_cyan\n * - bright_white\n *\n * The color remains active until another color token is found,\n * or if |reset| is found (which resets the terminal color to the default).\n *\n * @example\n *\n * Acclimate.log(\"Hello $name$\", { name: \"Pablo\" });\n * // \"Hello Pablo\"\n *\n * Acclimate.log(\"|red|Error:|reset| There was an error.\")\n * // \"Error: There was an error.\"\n * // ^ the \"Error:\" portion will be red\n *\n */\nexport function generateTerminalMessage(\n message: string,\n params: Record<string, string | undefined> = {},\n): string {\n const hasColorToken = Boolean(message.match(COLOR_TOKEN_REGEX));\n const endsWithReset = message.trimEnd().endsWith(\"|reset|\");\n const withReset =\n hasColorToken && !endsWithReset ? `${message}|reset|` : message;\n const interpolated = interpolateParams(withReset, params);\n return applyColors(interpolated);\n}\n","import { generateTerminalMessage } from \"@/generateTerminalMessage\";\nimport type {\n AnyCLI,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionParam,\n CLIParam,\n CLIPositionalParam,\n CLIPositionalParamName,\n IAcclimateCLI,\n} from \"../AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nconst _SECTION_TITLES = [\n \"Positional Arguments\",\n \"Options\",\n \"Global Options\",\n \"Commands\",\n] as const;\n\ntype SectionTitle = (typeof _SECTION_TITLES)[number];\n\ntype CLIParamWithRequired = CLIParam<string> & {\n required: boolean;\n aliases?: readonly string[];\n};\n\nfunction formatSectionTitle(title: SectionTitle): string {\n return `|bright_yellow|${title}|reset|`;\n}\n\nfunction formatNoneLine(): string {\n return \" |gray|None|reset|\";\n}\n\nfunction formatDefaultValue(\n value: CLIParamWithRequired[\"defaultValue\"],\n): string {\n return `|gray|[default: ${JSON.stringify(value)}]|reset|`;\n}\n\nfunction formatParamLine(param: CLIParamWithRequired): string {\n const description = param.description ?? \"No description\";\n const requiredLabel =\n param.required ? \"|red|required|reset|\" : \"|gray|optional|reset|\";\n const defaultLabel =\n param.defaultValue !== undefined ?\n formatDefaultValue(param.defaultValue)\n : undefined;\n const aliasList =\n param.aliases && param.aliases.length > 0 ? param.aliases.join(\", \") : \"\";\n const displayName = aliasList ? `${param.name}, ${aliasList}` : param.name;\n\n const segments = [\n ` |bright_white|${displayName}|reset|`,\n `(${param.type})|reset| ${requiredLabel}`,\n `- |gray|${description}|reset|`,\n defaultLabel,\n ].filter(Boolean);\n\n return segments.join(\" \");\n}\n\nfunction formatSection(\n title: SectionTitle,\n params: readonly CLIParamWithRequired[],\n): string[] {\n if (params.length === 0) {\n return [formatSectionTitle(title), formatNoneLine()];\n }\n\n return [formatSectionTitle(title), ...params.map(formatParamLine)];\n}\n\nfunction formatCommandLine(options: {\n name: string;\n description?: string;\n}): string {\n const { name, description } = options;\n const label = description ?? \"No description\";\n return ` |bright_white|${name}|reset| - |gray|${label}|reset|`;\n}\n\nfunction formatAvailableCommandsLine(commands: string[]): string {\n const label =\n commands.length === 0 ?\n \"None\"\n : commands\n .map((cmd) => {\n return cmd;\n })\n .join(\", \");\n return `|bright_yellow|Available Commands:|reset| |gray|${label}|reset|`;\n}\n\nfunction _generateHelpTextHelper<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n options: { level: 1 | 2 },\n): string {\n const name = cli.getName();\n const description = cli.state.description;\n const level = Number(options.level);\n\n const positionalParams = cli.state\n .positionalArgs as readonly CLIParamWithRequired[];\n const optionParams = Object.values(\n cli.state.optionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ) as readonly CLIParamWithRequired[];\n const globalOptionParams = Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ) as readonly CLIParamWithRequired[];\n const sortedCommands = Object.entries(cli.state.commands).sort(([a], [b]) => {\n return a.localeCompare(b);\n });\n const commandNames = sortedCommands.map(([commandName]) => {\n return commandName;\n });\n\n const headerLines = [`|bright_cyan|${name}|reset|`];\n if (description !== undefined) {\n headerLines.push(` |gray|${description}|reset|`);\n }\n\n let commandSection: string[];\n if (level === 2) {\n commandSection = [\n formatSectionTitle(\"Commands\"),\n ` ${formatAvailableCommandsLine(commandNames)}`,\n ];\n } else if (sortedCommands.length === 0) {\n commandSection = [formatSectionTitle(\"Commands\"), formatNoneLine()];\n } else {\n commandSection = [\n formatSectionTitle(\"Commands\"),\n ...sortedCommands.map(([commandName, commandCLI]) => {\n return formatCommandLine({\n name: commandName,\n description: commandCLI.state.description,\n });\n }),\n ];\n }\n\n const sections = [\n formatSection(\"Positional Arguments\", positionalParams),\n formatSection(\"Options\", optionParams),\n formatSection(\"Global Options\", globalOptionParams),\n commandSection,\n ];\n\n const lines = [...headerLines, \"\"];\n sections.forEach((section, idx) => {\n lines.push(...section);\n if (idx < sections.length - 1) {\n lines.push(\"\");\n }\n });\n\n if (level === 1) {\n const subCommandHelpText = sortedCommands.map(([, commandCLI]) => {\n return _generateHelpTextHelper(commandCLI, { level: 2 });\n });\n if (subCommandHelpText.length > 0) {\n subCommandHelpText.forEach((text) => {\n lines.push(\"\", ...text.split(\"\\n\"));\n });\n }\n }\n\n const indent = \" \".repeat(Math.max(0, level - 1));\n return lines\n .map((line) => {\n return line === \"\" ? \"\" : `${indent}${line}`;\n })\n .join(\"\\n\");\n}\n\nexport function generateHelpText<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >,\n): string {\n return generateTerminalMessage(_generateHelpTextHelper(cli, { level: 1 }));\n}\n","import { stdin, stdout } from \"node:process\";\nimport { createInterface } from \"node:readline/promises\";\nimport { generateTerminalMessage } from \"@/generateTerminalMessage\";\n\n/**\n * Prompt the user for terminal input, optionally enforcing a non-empty value.\n */\nexport async function requestTerminalInput(options: {\n message: string;\n params: Record<string, string>;\n responseOptions: {\n required: boolean;\n type?: \"string\" | \"number\" | \"boolean\";\n\n /*\n * Default value to use if the user enters an empty response.\n *\n * If the option is `required` and the user doesn't supply a value, we will\n * not show an error if there is a `defaultValue` we can use.\n */\n defaultValue?: string | number | boolean;\n };\n}): Promise<string | undefined> {\n const {\n message,\n params,\n responseOptions: { required, type, defaultValue },\n } = options;\n const notice =\n defaultValue !== undefined ? \" |gray|(press Enter to use default)|reset|\"\n : required ? \"\"\n : \" |gray|(press Enter to leave empty)|reset|\";\n const defaultNotice =\n defaultValue !== undefined ? ` [default: ${defaultValue}]` : \"\";\n const booleanNotice = type === \"boolean\" ? \" |reset|(y/n)\" : \"\";\n const promptMessage = `${message}${defaultNotice}${booleanNotice}${notice} `;\n const prompt = generateTerminalMessage(promptMessage, params);\n\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n while (true) {\n const answer = await rl.question(prompt);\n const trimmed = answer.trim();\n if (trimmed.length === 0) {\n if (defaultValue !== undefined) {\n // use the default value, parsed to a string\n return (\n typeof defaultValue === \"string\" ? defaultValue\n : typeof defaultValue === \"number\" ? String(defaultValue)\n : defaultValue ? \"true\"\n : \"false\"\n );\n }\n\n if (required) {\n stdout.write(\n generateTerminalMessage(\n \"|red|This value is required.|reset| Please enter a value.\\n\",\n ),\n );\n continue;\n }\n return undefined;\n }\n if (type === \"boolean\") {\n const normalized = trimmed.toLowerCase();\n if (normalized === \"y\" || normalized === \"yes\") {\n return \"true\";\n }\n if (normalized === \"n\" || normalized === \"no\") {\n return \"false\";\n }\n stdout.write(\n generateTerminalMessage(\n \"|red|That was not a valid response.|reset| Please enter y or n.\\n\",\n ),\n );\n continue;\n }\n return answer;\n }\n } finally {\n rl.close();\n }\n}\n","import { camelCase } from \"change-case\";\nimport { match } from \"ts-pattern\";\nimport { generateHelpText } from \"@/AcclimateCLI/generateHelpText/generateHelpText\";\nimport { CLIError } from \"@/CLIError\";\nimport { requestTerminalInput } from \"@/requestTerminalInput\";\nimport type {\n AnyCLI,\n CLICommandName,\n CLIFullOptionName,\n CLIOptionAlias,\n CLIOptionParam,\n CLIParam,\n CLIParamDataType,\n CLIPositionalParam,\n CLIPositionalParamName,\n CLIState,\n FullCLIArgValues,\n IAcclimateCLI,\n ValueOfParam,\n} from \"@/AcclimateCLI/AcclimateCLI.types\";\nimport type { EmptyObject } from \"type-fest\";\n\nfunction _isValidFullOptionName(name: string): name is CLIFullOptionName {\n return name.startsWith(\"--\");\n}\n\nfunction _isValidOptionAlias(name: string): name is CLIOptionAlias {\n return name.startsWith(\"-\");\n}\n\nfunction isEmptyObject(obj: object): obj is EmptyObject {\n return Object.keys(obj).length === 0;\n}\n\nfunction _validateParsedValue<\n P extends CLIParam<string>,\n PValue extends ValueOfParam<P>,\n>(options: { parsedValue: PValue; paramConfig: P; cliName: string }): PValue {\n const { parsedValue, paramConfig, cliName } = options;\n if (paramConfig.validator) {\n const validator = paramConfig.validator as (\n value: PValue,\n ) => boolean | string;\n const validationResult = validator(parsedValue);\n if (validationResult === true) {\n return parsedValue;\n }\n throw CLIError.invalidCLIParamValue({\n cliName,\n paramName: paramConfig.name,\n paramValue: parsedValue,\n message:\n typeof validationResult === \"string\" ? validationResult : undefined,\n });\n }\n return parsedValue;\n}\n\nfunction _parseAndValidateValue<\n P extends CLIParam<string>,\n PValue extends ValueOfParam<P>,\n>(options: {\n cliName: string;\n inputValue: string | undefined;\n defaultValue: PValue | undefined;\n paramConfig: P;\n}): PValue | undefined {\n const { cliName, inputValue, defaultValue, paramConfig } = options;\n if (inputValue === undefined) {\n if (defaultValue === undefined) {\n return undefined;\n }\n return _validateParsedValue({\n cliName,\n parsedValue: defaultValue,\n paramConfig,\n });\n }\n\n const parsedValue =\n paramConfig.parser ?\n (paramConfig.parser(inputValue) as PValue)\n // if no parser was set, we use the default parser\n : (match(paramConfig.type)\n .with(\"boolean\", () => {\n return inputValue === \"false\" ? false : true;\n })\n .with(\"number\", () => {\n return Number.parseInt(inputValue, 10);\n })\n .with(\"string\", () => {\n return inputValue;\n })\n .exhaustive(() => {\n return inputValue;\n }) as PValue);\n return _validateParsedValue({\n cliName,\n parsedValue,\n paramConfig,\n });\n}\n\nfunction _replaceAliases<\n TGlobalOptionArgs extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TOptionArgs extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TPositionalArgs extends\n | Record<CLIPositionalParamName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>({\n aliasedOptionArgs,\n cli,\n}: {\n aliasedOptionArgs: Record<CLIOptionAlias, string>;\n cli: IAcclimateCLI<\n TGlobalOptionArgs,\n TOptionArgs,\n TPositionalArgs,\n TCommands\n >;\n}): Record<CLIOptionAlias, string> {\n const aliasMap = cli.state.aliases;\n return Object.entries(aliasedOptionArgs).reduce(\n (acc, [aliasKey, value]) => {\n const alias = aliasKey as CLIOptionAlias;\n const optionName = aliasMap[alias] ?? alias;\n acc[optionName] = value;\n return acc;\n },\n {} as Record<CLIOptionAlias, string>,\n );\n}\n\ntype CLIParamWithRequired = CLIParam<string> & {\n required: boolean;\n};\n\nasync function askForValue(options: {\n argConfig: CLIParamWithRequired;\n}): Promise<string | undefined> {\n const { argConfig } = options;\n const askIfEmpty = argConfig.askIfEmpty;\n const description =\n argConfig.description ? ` (${argConfig.description})` : \"\";\n const baseMessage =\n typeof askIfEmpty === \"object\" ?\n askIfEmpty.message\n : `Please enter a value for ${argConfig.name}${description}`;\n const coloredMessage = `|bright_cyan|${baseMessage}|reset|`;\n return requestTerminalInput({\n message: coloredMessage,\n params: {},\n responseOptions: {\n required: argConfig.required,\n type: argConfig.type,\n defaultValue: argConfig.defaultValue,\n },\n });\n}\n\nasync function _runCLIHelper<\n TPositionalParams extends\n | Record<CLIPositionalParamName, CLIPositionalParam>\n | EmptyObject,\n TOptionParams extends Record<CLIFullOptionName, CLIOptionParam> | EmptyObject,\n TGlobalOptionParams extends\n | Record<CLIFullOptionName, CLIOptionParam>\n | EmptyObject,\n TCommands extends Record<CLICommandName, AnyCLI> | EmptyObject,\n>(options: {\n rawPositionalArgs: string[];\n rawOptionArgs: Record<CLIOptionAlias, string>;\n rawGlobalOptionArgs: Record<CLIFullOptionName, string>;\n cli: IAcclimateCLI<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams,\n TCommands\n >;\n}): Promise<void> {\n const { rawGlobalOptionArgs, rawOptionArgs, rawPositionalArgs, cli } = {\n ...options,\n rawGlobalOptionArgs: _replaceAliases({\n aliasedOptionArgs: options.rawGlobalOptionArgs,\n cli: options.cli,\n }),\n rawOptionArgs: _replaceAliases({\n aliasedOptionArgs: options.rawOptionArgs,\n\n // TODO(jpsyx): fix that this does not have the CLI may not have all\n cli: options.cli,\n }),\n };\n\n // is the first argument a command?\n const firstArg = rawPositionalArgs[0];\n if (\n firstArg &&\n !isEmptyObject(cli.state.commands) &&\n cli.state.commands[firstArg]\n ) {\n // add the parent's global options to the sub-command\n const commandCLI = Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n ).reduce(\n (newCmd, argConfig) => {\n return newCmd.addGlobalOption(argConfig);\n },\n cli.getCommandCLI(firstArg as Extract<keyof TCommands, string>) as AnyCLI,\n );\n\n // run the sub-command\n return _runCLIHelper({\n rawPositionalArgs: rawPositionalArgs.slice(1),\n rawOptionArgs,\n rawGlobalOptionArgs,\n cli: commandCLI,\n });\n }\n\n const cliName = cli.getName();\n\n // build the positional arguments dictionary\n // first check that we haven't supplied too many positional arguments\n if (rawPositionalArgs.length > cli.state.positionalArgs.length) {\n throw CLIError.tooManyPositionalArgs({\n cliName,\n count: rawPositionalArgs.length,\n });\n }\n\n // parse positional arguments\n const parsedPositionalArgs: Record<string, CLIParamDataType> = {};\n for (const [idx, argConfig] of cli.state.positionalArgs.entries()) {\n let rawVal = rawPositionalArgs[idx];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredPositionalArg({\n cliName,\n positionalArgName: argConfig.name,\n });\n }\n\n parsedPositionalArgs[argConfig.name] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // parse the options\n const parsedOptionArgs: Record<string, CLIParamDataType> = {};\n for (const argConfig of Object.values(\n cli.state.optionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n )) {\n let rawVal = rawOptionArgs[argConfig.name];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredOption({\n cliName,\n optionName: argConfig.name,\n });\n }\n\n parsedOptionArgs[camelCase(argConfig.name)] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // parse the global options\n const parsedGlobalOptionArgs: Record<string, CLIParamDataType> = {};\n for (const argConfig of Object.values(\n cli.state.globalOptionArgs as Record<CLIFullOptionName, CLIOptionParam>,\n )) {\n let rawVal = rawGlobalOptionArgs[argConfig.name];\n if (argConfig.askIfEmpty && rawVal === undefined) {\n rawVal = await askForValue({ argConfig });\n }\n\n if (argConfig.required && rawVal === undefined) {\n throw CLIError.missingRequiredOption({\n cliName,\n optionName: argConfig.name,\n });\n }\n parsedGlobalOptionArgs[camelCase(argConfig.name)] = _parseAndValidateValue({\n cliName,\n inputValue: rawVal,\n defaultValue: argConfig.defaultValue,\n paramConfig: argConfig,\n });\n }\n\n // run the action\n const action = cli.state.action;\n if (action) {\n action({\n ...parsedPositionalArgs,\n ...parsedOptionArgs,\n ...parsedGlobalOptionArgs,\n } as FullCLIArgValues<\n TPositionalParams,\n TOptionParams,\n TGlobalOptionParams\n >);\n return;\n }\n\n console.log(generateHelpText(cli));\n}\n\n/**\n * Run a CLI instance given an array of inputs.\n *\n * @param options - The options for running the CLI.\n */\nexport async function runCLI(options: {\n input: string[];\n cli: AnyCLI;\n}): Promise<void> {\n const { input, cli } = options;\n const firstOptionIdx = input.findIndex((token) => {\n return token.startsWith(\"-\");\n });\n\n const [rawPositionalArgs, rest] =\n firstOptionIdx === -1 ?\n [input, []]\n : [input.slice(0, firstOptionIdx), input.slice(firstOptionIdx)];\n\n const rawOptionArgs: Record<CLIOptionAlias, string> = {};\n const rawGlobalOptionArgs: Record<CLIFullOptionName, string> = {};\n let currentAlias: CLIOptionAlias | undefined;\n let currentVals: string[] = [];\n\n const { aliases, globalOptionArgs } = cli.state as CLIState<\n Record<CLIFullOptionName, CLIOptionParam>,\n Record<CLIFullOptionName, CLIOptionParam>,\n Record<CLIPositionalParamName, CLIOptionParam>,\n Record<CLICommandName, AnyCLI>\n >;\n\n for (const argVal of rest.concat(\"-\")) {\n if (_isValidOptionAlias(argVal)) {\n if (currentAlias) {\n const rawValue = currentVals.join(\" \");\n const optionName = aliases[currentAlias] ?? currentAlias;\n if (\n _isValidFullOptionName(optionName) &&\n !isEmptyObject(globalOptionArgs) &&\n globalOptionArgs[optionName]\n ) {\n rawGlobalOptionArgs[optionName] = rawValue;\n } else {\n rawOptionArgs[optionName] = rawValue;\n }\n }\n currentAlias = argVal;\n currentVals = [];\n } else {\n currentVals.push(argVal);\n }\n }\n\n await _runCLIHelper({\n rawPositionalArgs,\n rawOptionArgs,\n rawGlobalOptionArgs,\n cli,\n });\n}\n","import { createCLI } from \"./AcclimateCLI\";\nimport { runCLI } from \"./AcclimateCLI/runCLI/runCLI\";\nimport { generateTerminalMessage } from \"./generateTerminalMessage\";\nimport { requestTerminalInput } from \"./requestTerminalInput\";\nimport type { AnyCLI, IAcclimateCLI } from \"./AcclimateCLI/AcclimateCLI.types\";\n\ntype Acclimate = {\n /**\n * Create a new Acclimate CLI instance.\n *\n * @param name - The name of the CLI.\n * @returns A new CLI instance.\n */\n createCLI: (name: string) => IAcclimateCLI;\n\n /**\n * Run a CLI instance.\n *\n * It can only be run once. Calling any other methods after `.run()` will\n * throw an error.\n *\n * @param cli - The CLI instance to run.\n */\n run: (cli: AnyCLI) => void;\n\n /**\n * Outputs a message with `console.log`.\n * Supports interpolation using `$varName$` as tokens.\n *\n * Colors can be changed within a message `|<COLOR_NAME>|` tokens.\n * Supported colors are:\n * - black\n * - red\n * - green\n * - yellow\n * - blue\n * - magenta\n * - cyan\n * - white\n * - bright_black|gray|grey\n * - bright_red\n * - bright_green\n * - bright_yellow\n * - bright_blue\n * - bright_magenta\n * - bright_cyan\n * - bright_white\n *\n * The color remains active until another color token is found,\n * or if |reset| is found (which resets the terminal color to the default).\n *\n * @example\n *\n * Acclimate.log(\"Hello $name$\", { name: \"Pablo\" });\n * // \"Hello Pablo\"\n *\n * Acclimate.log(\"|red|Error:|reset| There was an error.\")\n * // \"Error: There was an error.\"\n * // ^ the \"Error:\" portion will be red\n *\n */\n log: (message: string, params?: Record<string, string | undefined>) => void;\n\n /**\n * Prompt the user for interactive input in the terminal.\n *\n * @param options - Prompt configuration.\n * @returns The user's response, or undefined when left empty and optional.\n */\n requestInput: (options: {\n message: string;\n params: Record<string, string>;\n responseOptions: {\n required: boolean;\n type?: \"string\" | \"number\" | \"boolean\";\n\n /*\n * Default value to use if the user enters an empty response.\n *\n * If the option is `required` and the user doesn't supply a value, we will\n * not show an error if there is a `defaultValue` we can use.\n */\n defaultValue?: string | number | boolean;\n };\n }) => Promise<string | undefined>;\n};\n\nexport const Acclimate: Acclimate = {\n createCLI,\n run: (cli: AnyCLI) => {\n void runCLI({ cli, input: process.argv.slice(2) });\n },\n log: (message: string, params: Record<string, string | undefined> = {}) => {\n console.log(generateTerminalMessage(message, params));\n },\n requestInput: (options) => {\n return requestTerminalInput(options);\n },\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avandar/acclimate",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "A lightweight TypeScript framework for building CLI tools.",
5
5
  "license": "MIT",
6
6
  "type": "module",