/// export type ConfigType = 'number' | 'string' | 'boolean'; /** * Given a Jack object, get the typeof its ConfigSet */ export type Unwrap = J extends Jack ? C : never; import { inspect, InspectOptions } from 'node:util'; /** * Defines the type of value that is valid, given a config definition's * {@link ConfigType} and boolean multiple setting */ export type ValidValue = [ T, M ] extends ['number', true] ? number[] : [T, M] extends ['string', true] ? string[] : [T, M] extends ['boolean', true] ? boolean[] : [T, M] extends ['number', false] ? number : [T, M] extends ['string', false] ? string : [T, M] extends ['boolean', false] ? boolean : [T, M] extends ['string', boolean] ? string | string[] : [T, M] extends ['boolean', boolean] ? boolean | boolean[] : [T, M] extends ['number', boolean] ? number | number[] : [T, M] extends [ConfigType, false] ? string | number | boolean : [T, M] extends [ConfigType, true] ? string[] | number[] | boolean[] : string | number | boolean | string[] | number[] | boolean[]; /** * The meta information for a config option definition, when the * type and multiple values can be inferred by the method being used */ export type ConfigOptionMeta = { default?: undefined | (ValidValue & (O extends number[] | string[] ? M extends false ? O[number] : O[number][] : unknown)); validOptions?: O; description?: string; validate?: ((v: unknown) => v is ValidValue) | ((v: unknown) => boolean); short?: string | undefined; type?: T; hint?: T extends 'boolean' ? never : string; delim?: M extends true ? string : never; } & (M extends false ? { multiple?: false | undefined; } : M extends true ? { multiple: true; } : { multiple?: boolean; }); /** * A set of {@link ConfigOptionMeta} fields, referenced by their longOption * string values. */ export type ConfigMetaSet = { [longOption: string]: ConfigOptionMeta; }; /** * Infer {@link ConfigSet} fields from a given {@link ConfigMetaSet} */ export type ConfigSetFromMetaSet> = { [longOption in keyof S]: ConfigOptionBase; }; /** * Fields that can be set on a {@link ConfigOptionBase} or * {@link ConfigOptionMeta} based on whether or not the field is known to be * multiple. */ export type MultiType = M extends true ? { multiple: true; delim?: string | undefined; } : M extends false ? { multiple?: false | undefined; delim?: undefined; } : { multiple?: boolean | undefined; delim?: string | undefined; }; /** * A config field definition, in its full representation. */ export type ConfigOptionBase = { type: T; short?: string | undefined; default?: ValidValue | undefined; description?: string; hint?: T extends 'boolean' ? undefined : string | undefined; validate?: (v: unknown) => v is ValidValue; validOptions?: T extends 'boolean' ? undefined : T extends 'string' ? readonly string[] : T extends 'number' ? readonly number[] : readonly number[] | readonly string[]; } & MultiType; export declare const isConfigType: (t: string) => t is ConfigType; export declare const isConfigOption: (o: any, type: T, multi: M) => o is ConfigOptionBase; /** * A set of {@link ConfigOptionBase} objects, referenced by their longOption * string values. */ export type ConfigSet = { [longOption: string]: ConfigOptionBase; }; /** * The 'values' field returned by {@link Jack#parse} */ export type OptionsResults = { [k in keyof T]?: T[k]['validOptions'] extends (readonly string[] | readonly number[]) ? T[k] extends ConfigOptionBase<'string' | 'number', false> ? T[k]['validOptions'][number] : T[k] extends ConfigOptionBase<'string' | 'number', true> ? T[k]['validOptions'][number][] : never : T[k] extends ConfigOptionBase<'string', false> ? string : T[k] extends ConfigOptionBase<'string', true> ? string[] : T[k] extends ConfigOptionBase<'number', false> ? number : T[k] extends ConfigOptionBase<'number', true> ? number[] : T[k] extends ConfigOptionBase<'boolean', false> ? boolean : T[k] extends ConfigOptionBase<'boolean', true> ? boolean[] : never; }; /** * The object retured by {@link Jack#parse} */ export type Parsed = { values: OptionsResults; positionals: string[]; }; /** * A row used when generating the {@link Jack#usage} string */ export interface Row { left?: string; text: string; skipLine?: boolean; type?: string; } /** * A heading for a section in the usage, created by the jack.heading() * method. * * First heading is always level 1, subsequent headings default to 2. * * The level of the nearest heading level sets the indentation of the * description that follows. */ export interface Heading extends Row { type: 'heading'; text: string; left?: ''; skipLine?: boolean; level: number; pre?: boolean; } /** * An arbitrary blob of text describing some stuff, set by the * jack.description() method. * * Indentation determined by level of the nearest header. */ export interface Description extends Row { type: 'description'; text: string; left?: ''; skipLine?: boolean; pre?: boolean; } /** * A heading or description row used when generating the {@link Jack#usage} * string */ export type TextRow = Heading | Description; /** * Either a {@link TextRow} or a reference to a {@link ConfigOptionBase} */ export type UsageField = TextRow | { type: 'config'; name: string; value: ConfigOptionBase; }; /** * Options provided to the {@link Jack} constructor */ export interface JackOptions { /** * Whether to allow positional arguments * * @default true */ allowPositionals?: boolean; /** * Prefix to use when reading/writing the environment variables * * If not specified, environment behavior will not be available. */ envPrefix?: string; /** * Environment object to read/write. Defaults `process.env`. * No effect if `envPrefix` is not set. */ env?: { [k: string]: string | undefined; }; /** * A short usage string. If not provided, will be generated from the * options provided, but that can of course be rather verbose if * there are a lot of options. */ usage?: string; /** * Stop parsing flags and opts at the first positional argument. * This is to support cases like `cmd [flags] [options]`, where * each subcommand may have different options. This effectively treats * any positional as a `--` argument. Only relevant if `allowPositionals` * is true. * * To do subcommands, set this option, look at the first positional, and * parse the remaining positionals as appropriate. * * @default false */ stopAtPositional?: boolean; } /** * Class returned by the {@link jack} function and all configuration * definition methods. This is what gets chained together. */ export declare class Jack { #private; constructor(options?: JackOptions); /** * Set the default value (which will still be overridden by env or cli) * as if from a parsed config file. The optional `source` param, if * provided, will be included in error messages if a value is invalid or * unknown. */ setConfigValues(values: OptionsResults, source?: string): this; /** * Parse a string of arguments, and return the resulting * `{ values, positionals }` object. * * If an {@link JackOptions#envPrefix} is set, then it will read default * values from the environment, and write the resulting values back * to the environment as well. * * Environment values always take precedence over any other value, except * an explicit CLI setting. */ parse(args?: string[]): Parsed; /** * Validate that any arbitrary object is a valid configuration `values` * object. Useful when loading config files or other sources. */ validate(o: unknown): asserts o is Parsed['values']; /** * Add a heading to the usage output banner */ heading(text: string, level?: 1 | 2 | 3 | 4 | 5 | 6, { pre }?: { pre?: boolean; }): Jack; /** * Add a long-form description to the usage output at this position. */ description(text: string, { pre }?: { pre?: boolean; }): Jack; /** * Add one or more number fields. */ num>(fields: F): Jack>; /** * Add one or more multiple number fields. */ numList>(fields: F): Jack>; /** * Add one or more string option fields. */ opt>(fields: F): Jack>; /** * Add one or more multiple string option fields. */ optList>(fields: F): Jack>; /** * Add one or more flag fields. */ flag>(fields: F): Jack>; /** * Add one or more multiple flag fields. */ flagList>(fields: F): Jack>; /** * Generic field definition method. Similar to flag/flagList/number/etc, * but you must specify the `type` (and optionally `multiple` and `delim`) * fields on each one, or Jack won't know how to define them. */ addFields(fields: F): Jack; /** * Return the usage banner for the given configuration */ usage(): string; /** * Return the usage banner markdown for the given configuration */ usageMarkdown(): string; /** * Return the configuration options as a plain object */ toJSON(): { [k: string]: { default?: string | number | boolean | string[] | number[] | boolean[] | undefined; validOptions?: readonly number[] | readonly string[] | undefined; validate?: ((v: unknown) => v is string | number | boolean | string[] | number[] | boolean[]) | undefined; description?: string | undefined; short?: string | undefined; delim?: string | undefined; multiple?: boolean | undefined; type: ConfigType; }; }; /** * Custom printer for `util.inspect` */ [inspect.custom](_: number, options: InspectOptions): string; } /** * Main entry point. Create and return a {@link Jack} object. */ export declare const jack: (options?: JackOptions) => Jack<{}>; //# sourceMappingURL=index.d.ts.map