1 |
|
2 |
|
3 | import { Readable, Writable } from 'stream';
|
4 | import { CommandBuilder } from '../core';
|
5 | import { ColorFormat } from '../format';
|
6 | import { CommandClass, Command, Definition } from './Command';
|
7 | import { CommandOption } from './options/utils';
|
8 | type MakeOptional<T, Keys extends keyof T> = Omit<T, Keys> & Partial<Pick<T, Keys>>;
|
9 | type VoidIfEmpty<T> = keyof T extends never ? void : never;
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | export type BaseContext = {
|
16 | |
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | env: Record<string, string | undefined>;
|
23 | |
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | stdin: Readable;
|
30 | |
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | stdout: Writable;
|
37 | |
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | stderr: Writable;
|
44 | |
45 |
|
46 |
|
47 | colorDepth: number;
|
48 | };
|
49 | export type CliContext<Context extends BaseContext> = {
|
50 | commandClass: CommandClass<Context>;
|
51 | };
|
52 | export type UserContextKeys<Context extends BaseContext> = Exclude<keyof Context, keyof BaseContext>;
|
53 | export type UserContext<Context extends BaseContext> = Pick<Context, UserContextKeys<Context>>;
|
54 | export type PartialContext<Context extends BaseContext> = UserContextKeys<Context> extends never ? Partial<Pick<Context, keyof BaseContext>> | undefined | void : Partial<Pick<Context, keyof BaseContext>> & UserContext<Context>;
|
55 | export type RunContext<Context extends BaseContext = BaseContext> = Partial<Pick<Context, keyof BaseContext>> & UserContext<Context>;
|
56 | export type RunCommand<Context extends BaseContext = BaseContext> = Array<CommandClass<Context>> | CommandClass<Context>;
|
57 | export type RunCommandNoContext<Context extends BaseContext = BaseContext> = UserContextKeys<Context> extends never ? RunCommand<Context> : never;
|
58 | export type CliOptions = Readonly<{
|
59 | |
60 |
|
61 |
|
62 |
|
63 |
|
64 | binaryLabel?: string;
|
65 | |
66 |
|
67 |
|
68 |
|
69 |
|
70 | binaryName: string;
|
71 | |
72 |
|
73 |
|
74 |
|
75 |
|
76 | binaryVersion?: string;
|
77 | |
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | enableCapture: boolean;
|
86 | |
87 |
|
88 |
|
89 |
|
90 | enableColors?: boolean;
|
91 | }>;
|
92 | export type MiniCli<Context extends BaseContext> = CliOptions & {
|
93 | |
94 |
|
95 |
|
96 | definitions(): Array<Definition>;
|
97 | |
98 |
|
99 |
|
100 | definition(command: CommandClass<Context>): Definition | null;
|
101 | |
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 | error(error: Error, opts?: {
|
108 | command?: Command<Context> | null;
|
109 | }): string;
|
110 | |
111 |
|
112 |
|
113 |
|
114 |
|
115 | format(colored?: boolean): ColorFormat;
|
116 | |
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 | process(input: Array<string>, context?: Partial<Context>): Command<Context>;
|
124 | |
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 | run(input: Array<string>, context?: Partial<Context>): Promise<number>;
|
133 | |
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 | usage(command?: CommandClass<Context> | Command<Context> | null, opts?: {
|
141 | detailed?: boolean;
|
142 | prefix?: string;
|
143 | }): string;
|
144 | };
|
145 | export type MandatoryContextKeys<Context extends BaseContext> = keyof MandatoryContext<Context>;
|
146 | export type MandatoryContext<Context extends BaseContext> = {
|
147 | [K in Exclude<keyof Context, keyof BaseContext> as undefined extends Context[K] ? never : K]: Context[K];
|
148 | };
|
149 | export type UserProvidedContext<Context extends BaseContext> = MandatoryContext<Context> & Partial<Omit<Context, MandatoryContextKeys<Context>>>;
|
150 | export type MaybeProvidedContext<Context extends BaseContext> = MandatoryContextKeys<Context> extends never ? {
|
151 | context?: UserProvidedContext<Context>;
|
152 | } : {
|
153 | context: UserProvidedContext<Context>;
|
154 | };
|
155 | export type ProcessOptions<Context extends BaseContext> = MaybeProvidedContext<Context> & {
|
156 | input: Array<string>;
|
157 | |
158 |
|
159 |
|
160 | partial?: boolean;
|
161 | };
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 | export declare function runExit<Context extends BaseContext = BaseContext>(commandClasses: RunCommandNoContext<Context>): Promise<void>;
|
172 | export declare function runExit<Context extends BaseContext = BaseContext>(commandClasses: RunCommand<Context>, context: RunContext<Context>): Promise<void>;
|
173 | export declare function runExit<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommandNoContext<Context>): Promise<void>;
|
174 | export declare function runExit<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommand<Context>, context: RunContext<Context>): Promise<void>;
|
175 | export declare function runExit<Context extends BaseContext = BaseContext>(commandClasses: RunCommandNoContext<Context>, argv: Array<string>): Promise<void>;
|
176 | export declare function runExit<Context extends BaseContext = BaseContext>(commandClasses: RunCommand<Context>, argv: Array<string>, context: RunContext<Context>): Promise<void>;
|
177 | export declare function runExit<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommandNoContext<Context>, argv: Array<string>): Promise<void>;
|
178 | export declare function runExit<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommand<Context>, argv: Array<string>, context: RunContext<Context>): Promise<void>;
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 | export declare function run<Context extends BaseContext = BaseContext>(commandClasses: RunCommandNoContext<Context>): Promise<number>;
|
189 | export declare function run<Context extends BaseContext = BaseContext>(commandClasses: RunCommand<Context>, context: RunContext<Context>): Promise<number>;
|
190 | export declare function run<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommandNoContext<Context>): Promise<number>;
|
191 | export declare function run<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommand<Context>, context: RunContext<Context>): Promise<number>;
|
192 | export declare function run<Context extends BaseContext = BaseContext>(commandClasses: RunCommandNoContext<Context>, argv: Array<string>): Promise<number>;
|
193 | export declare function run<Context extends BaseContext = BaseContext>(commandClasses: RunCommand<Context>, argv: Array<string>, context: RunContext<Context>): Promise<number>;
|
194 | export declare function run<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommandNoContext<Context>, argv: Array<string>): Promise<number>;
|
195 | export declare function run<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommand<Context>, argv: Array<string>, context: RunContext<Context>): Promise<number>;
|
196 |
|
197 |
|
198 |
|
199 | export declare class Cli<Context extends BaseContext = BaseContext> implements Omit<MiniCli<Context>, `process` | `run`> {
|
200 | |
201 |
|
202 |
|
203 |
|
204 |
|
205 | static defaultContext: {
|
206 | env: NodeJS.ProcessEnv;
|
207 | stdin: NodeJS.ReadStream & {
|
208 | fd: 0;
|
209 | };
|
210 | stdout: NodeJS.WriteStream & {
|
211 | fd: 1;
|
212 | };
|
213 | stderr: NodeJS.WriteStream & {
|
214 | fd: 2;
|
215 | };
|
216 | colorDepth: number;
|
217 | };
|
218 | private readonly builder;
|
219 | protected readonly registrations: Map<CommandClass<Context>, {
|
220 | index: number;
|
221 | builder: CommandBuilder<CliContext<Context>>;
|
222 | specs: Map<string, CommandOption<unknown>>;
|
223 | }>;
|
224 | readonly binaryLabel?: string;
|
225 | readonly binaryName: string;
|
226 | readonly binaryVersion?: string;
|
227 | readonly enableCapture: boolean;
|
228 | readonly enableColors?: boolean;
|
229 | |
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 | static from<Context extends BaseContext = BaseContext>(commandClasses: RunCommand<Context>, options?: Partial<CliOptions>): Cli<Context>;
|
236 | constructor({ binaryLabel, binaryName: binaryNameOpt, binaryVersion, enableCapture, enableColors }?: Partial<CliOptions>);
|
237 | /**
|
238 | * Registers a command inside the CLI.
|
239 | */
|
240 | register(commandClass: CommandClass<Context>): void;
|
241 | process(opts: ProcessOptions<Context>): Command<Context>;
|
242 | process(input: Array<string>, context: VoidIfEmpty<Omit<Context, keyof BaseContext>>): Command<Context>;
|
243 | process(input: Array<string>, context: MakeOptional<Context, keyof BaseContext>): Command<Context>;
|
244 | run(input: Command<Context> | Array<string>, context: VoidIfEmpty<Omit<Context, keyof BaseContext>>): Promise<number>;
|
245 | run(input: Command<Context> | Array<string>, context: MakeOptional<Context, keyof BaseContext>): Promise<number>;
|
246 | /**
|
247 | * Runs a command and exits the current `process` with the exit code returned by the command.
|
248 | *
|
249 | * @param input An array containing the name of the command and its arguments.
|
250 | *
|
251 | * @example
|
252 | * cli.runExit(process.argv.slice(2))
|
253 | */
|
254 | runExit(input: Command<Context> | Array<string>, context: VoidIfEmpty<Omit<Context, keyof BaseContext>>): Promise<void>;
|
255 | runExit(input: Command<Context> | Array<string>, context: MakeOptional<Context, keyof BaseContext>): Promise<void>;
|
256 | definition(commandClass: CommandClass<Context>, { colored }?: {
|
257 | colored?: boolean;
|
258 | }): Definition | null;
|
259 | definitions({ colored }?: {
|
260 | colored?: boolean;
|
261 | }): Array<Definition>;
|
262 | usage(command?: CommandClass<Context> | Command<Context> | null, { colored, detailed, prefix }?: {
|
263 | colored?: boolean;
|
264 | detailed?: boolean;
|
265 | prefix?: string;
|
266 | }): string;
|
267 | error(error: Error | any, { colored, command }?: {
|
268 | colored?: boolean;
|
269 | command?: Command<Context> | null;
|
270 | }): string;
|
271 | format(colored?: boolean): ColorFormat;
|
272 | protected getUsageByRegistration(klass: CommandClass<Context>, opts?: {
|
273 | detailed?: boolean;
|
274 | inlineOptions?: boolean;
|
275 | }): {
|
276 | usage: string;
|
277 | options: {
|
278 | preferredName: string;
|
279 | nameSet: string[];
|
280 | definition: string;
|
281 | description: string;
|
282 | required: boolean;
|
283 | }[];
|
284 | };
|
285 | protected getUsageByIndex(n: number, opts?: {
|
286 | detailed?: boolean;
|
287 | inlineOptions?: boolean;
|
288 | }): {
|
289 | usage: string;
|
290 | options: {
|
291 | preferredName: string;
|
292 | nameSet: string[];
|
293 | definition: string;
|
294 | description: string;
|
295 | required: boolean;
|
296 | }[];
|
297 | };
|
298 | }
|
299 | export {};
|