zod-args-parser 1.0.5 → 1.0.7
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/lib/commonjs/autocomplete.js +32 -4
- package/lib/commonjs/autocomplete.js.map +1 -1
- package/lib/commonjs/index.js +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/parser.js.map +1 -1
- package/lib/module/autocomplete.js +32 -4
- package/lib/module/autocomplete.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/parser.js.map +1 -1
- package/lib/typescript/autocomplete.d.ts +21 -2
- package/lib/typescript/autocomplete.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +37 -7
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/parser.d.ts +0 -2
- package/lib/typescript/parser.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +6 -4
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/autocomplete.ts +95 -13
- package/src/index.ts +84 -44
- package/src/parser.ts +19 -15
- package/src/types.ts +333 -332
package/src/types.ts
CHANGED
|
@@ -1,332 +1,333 @@
|
|
|
1
|
-
import type { z } from "zod";
|
|
2
|
-
|
|
3
|
-
export type Subcommand = {
|
|
4
|
-
/**
|
|
5
|
-
* - The subcommand name, use `kebab-case`.
|
|
6
|
-
* - Make sure to not duplicate commands and aliases.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* name: "test";
|
|
10
|
-
* name: "run-app";
|
|
11
|
-
*/
|
|
12
|
-
name: string;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* - The description of the subcommand.
|
|
16
|
-
* - Used for generating the help message.
|
|
17
|
-
*/
|
|
18
|
-
description?: string;
|
|
19
|
-
|
|
20
|
-
/** - The usage message in the help message. */
|
|
21
|
-
usage?: string;
|
|
22
|
-
|
|
23
|
-
/** - Used for generating the help message. */
|
|
24
|
-
placeholder?: string;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* - Provide an example to show to the user.
|
|
28
|
-
* - Used for generating the help message.
|
|
29
|
-
*/
|
|
30
|
-
example?: string;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* - The aliases of the subcommand.
|
|
34
|
-
* - Make sure to not duplicate aliases and commands.
|
|
35
|
-
*/
|
|
36
|
-
aliases?: string[];
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* - Allows positional arguments for this subcommand.
|
|
40
|
-
* - Unlike `arguments`, which are strictly typed, positional arguments are untyped and represented as a string array of
|
|
41
|
-
* variable length.
|
|
42
|
-
* - When enabled and `arguments` are provided, `arguments` will be parsed first. Any remaining arguments will be
|
|
43
|
-
* considered positional arguments and added to the `positional` property in the result.
|
|
44
|
-
*/
|
|
45
|
-
allowPositional?: boolean;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* - The options of the command.
|
|
49
|
-
* - Those options are specific to this subcommand.
|
|
50
|
-
*/
|
|
51
|
-
options?: [Option, ...Option[]];
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* - Specifies a list of strictly typed arguments.
|
|
55
|
-
* - The order is important; for example, the first argument will be validated against the first specified type.
|
|
56
|
-
* - It is recommended to not use optional arguments as the parser will fill the arguments by order and can't determine
|
|
57
|
-
* which arguments are optional.
|
|
58
|
-
*/
|
|
59
|
-
arguments?: [Argument, ...Argument[]];
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* - The action is executed with the result of the parsed arguments.
|
|
63
|
-
* - To get typescript types use `setAction` instead of this.
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* const helpCommand = createSubcommand({ name: "help", options: [...] });
|
|
67
|
-
* helpCommand.setAction(res => console.log(res));
|
|
68
|
-
*/
|
|
69
|
-
action?: (results?: any) => void;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
export type Cli = Prettify<
|
|
73
|
-
Omit<Subcommand, "name"> & {
|
|
74
|
-
/** - The name of the CLI program. */
|
|
75
|
-
cliName: string;
|
|
76
|
-
}
|
|
77
|
-
>;
|
|
78
|
-
|
|
79
|
-
export type Option = {
|
|
80
|
-
/**
|
|
81
|
-
* - The name of the option, use `CamelCase`.
|
|
82
|
-
* - For example: the syntax for the option `rootPath` is `--root-path`.
|
|
83
|
-
*/
|
|
84
|
-
name: string;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* - The will be used to validate the user input.
|
|
88
|
-
*
|
|
89
|
-
* @example
|
|
90
|
-
* type: z.boolean().default(false);
|
|
91
|
-
* type: z.coerce.number(); // will be coerced to number by Zod
|
|
92
|
-
* type: z.preprocess(parseStringToArrFn, z.array(z.coerce.number())); // array of numbers
|
|
93
|
-
*
|
|
94
|
-
* @see https://zod.dev/?id=types
|
|
95
|
-
*/
|
|
96
|
-
type: z.ZodTypeAny;
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* - The description of the option.
|
|
100
|
-
* - Used for generating the help message.
|
|
101
|
-
*/
|
|
102
|
-
description?: string;
|
|
103
|
-
|
|
104
|
-
/** - Used for generating the help message. */
|
|
105
|
-
placeholder?: string;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* - The example of using the option.
|
|
109
|
-
* - Used for generating the help message.
|
|
110
|
-
*/
|
|
111
|
-
example?: string;
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* - The aliases of the option, use `CamelCase`.
|
|
115
|
-
* - Here you can specify short names or flags.
|
|
116
|
-
* - Make sure to not duplicate aliases.
|
|
117
|
-
*/
|
|
118
|
-
aliases?: [string, ...string[]];
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
export type Argument = {
|
|
122
|
-
/** - The name of the argument. */
|
|
123
|
-
name: string;
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* - The will be used to validate the user input.
|
|
127
|
-
*
|
|
128
|
-
* @example
|
|
129
|
-
* type: z.boolean();
|
|
130
|
-
* type: z.coerce.number(); // will be coerced to number by Zod
|
|
131
|
-
* type: z.preprocess(ParseStringToArrFn, z.array(z.coerce.number())); // array of numbers
|
|
132
|
-
*
|
|
133
|
-
* @see https://zod.dev/?id=types
|
|
134
|
-
*/
|
|
135
|
-
type: z.ZodTypeAny;
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* - The description of the argument.
|
|
139
|
-
* - Used for generating the help message.
|
|
140
|
-
*/
|
|
141
|
-
description?: string;
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* - The example of using the argument.
|
|
145
|
-
* - Used for generating the help message.
|
|
146
|
-
*/
|
|
147
|
-
example?: string;
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
export type ColorFnType = (...text: unknown[]) => string;
|
|
151
|
-
|
|
152
|
-
export type PrintHelpOpt = {
|
|
153
|
-
/**
|
|
154
|
-
* - **Optional** `boolean`
|
|
155
|
-
* - Whether to print colors or not.
|
|
156
|
-
* - Default: `true`
|
|
157
|
-
*/
|
|
158
|
-
colors?: boolean;
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* - **Optional** `object`
|
|
162
|
-
* - The colors to use for the help message.
|
|
163
|
-
*/
|
|
164
|
-
customColors?: {
|
|
165
|
-
title?: ColorFnType;
|
|
166
|
-
description?: ColorFnType;
|
|
167
|
-
default?: ColorFnType;
|
|
168
|
-
optional?: ColorFnType;
|
|
169
|
-
exampleTitle?: ColorFnType;
|
|
170
|
-
example?: ColorFnType;
|
|
171
|
-
command?: ColorFnType;
|
|
172
|
-
option?: ColorFnType;
|
|
173
|
-
argument?: ColorFnType;
|
|
174
|
-
placeholder?: ColorFnType;
|
|
175
|
-
punctuation?: ColorFnType;
|
|
176
|
-
};
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
export type _Info = {
|
|
180
|
-
/**
|
|
181
|
-
* - The raw argument as it was passed in
|
|
182
|
-
* - For options that have a default value and are not passed in, the raw argument will be `undefined`
|
|
183
|
-
*/
|
|
184
|
-
rawArg?: string;
|
|
185
|
-
/**
|
|
186
|
-
* - The raw value of the argument as it was passed in
|
|
187
|
-
* - It will be empty string for `boolean` options. E.g. `--help` or `-h`
|
|
188
|
-
* - For options that have a default value and are not passed in, the raw value will be `undefined`
|
|
189
|
-
*/
|
|
190
|
-
rawValue?: string;
|
|
191
|
-
/**
|
|
192
|
-
* - The source value of the argument:
|
|
193
|
-
* - `cli`: The argument was passed in by the user
|
|
194
|
-
* - `default`: The argument was not passed in and has a default value
|
|
195
|
-
*/
|
|
196
|
-
source: "cli" | "default";
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* - Infer the options type from a subcommand.
|
|
201
|
-
*
|
|
202
|
-
* @example
|
|
203
|
-
* const subcommand = createSubcommand({ name: "build", options: [...] });
|
|
204
|
-
* type OptionsType = InferOptionsType<typeof subcommand>;
|
|
205
|
-
*/
|
|
206
|
-
export type InferOptionsType<T extends Partial<Subcommand>> = T["options"] extends infer U extends Option[]
|
|
207
|
-
? ToOptional<{ [K in U[number]["name"]]: z.infer<Extract<U[number], { name: K }>["type"]> }>
|
|
208
|
-
: undefined;
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* - Infer the arguments type from a subcommand.
|
|
212
|
-
*
|
|
213
|
-
* @example
|
|
214
|
-
* const subcommand = createSubcommand({ name: "build", arguments: [...] });
|
|
215
|
-
* type ArgumentsType = InferArgumentsType<typeof subcommand>;
|
|
216
|
-
*/
|
|
217
|
-
export type InferArgumentsType<T extends Partial<Subcommand>> = T["arguments"] extends infer U extends Argument[]
|
|
218
|
-
? { [K in keyof U]: U[K] extends { type: z.ZodTypeAny } ? z.infer<U[K]["type"]> : never }
|
|
219
|
-
: undefined;
|
|
220
|
-
|
|
221
|
-
/** `{ some props } & { other props }` => `{ some props, other props }` */
|
|
222
|
-
export type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
223
|
-
|
|
224
|
-
/** Allow string type for literal union and get auto completion */
|
|
225
|
-
export type LiteralUnion<T extends string> = T | (string & {});
|
|
226
|
-
|
|
227
|
-
/** Extract the undefined properties from an object */
|
|
228
|
-
type UndefinedProperties<T> = { [P in keyof T]-?: undefined extends T[P] ? P : never }[keyof T];
|
|
229
|
-
|
|
230
|
-
/** Make undefined properties optional? */
|
|
231
|
-
type ToOptional<T> = Prettify<
|
|
232
|
-
Partial<Pick<T, UndefinedProperties<T>>> & Pick<T, Exclude<keyof T, UndefinedProperties<T>>>
|
|
233
|
-
>;
|
|
234
|
-
|
|
235
|
-
export type OptionsArr2RecordType<T extends Option[] | undefined> = T extends Option[]
|
|
236
|
-
? ToOptional<{ [K in T[number]["name"]]: z.infer<Extract<T[number], { name: K }>["type"]> }>
|
|
237
|
-
: object;
|
|
238
|
-
|
|
239
|
-
export type ArgumentsArr2ArrType<T extends Argument[] | undefined> = T extends Argument[]
|
|
240
|
-
? { arguments: { [K in keyof T]: T[K] extends { type: z.ZodTypeAny } ? z.infer<T[K]["type"]> : never } }
|
|
241
|
-
: object;
|
|
242
|
-
|
|
243
|
-
export type Positional<S extends Partial<Subcommand>> = S["allowPositional"] extends true
|
|
244
|
-
? { positional: string[] }
|
|
245
|
-
: object;
|
|
246
|
-
|
|
247
|
-
export type Info<T extends Option[] | undefined> = T extends Option[]
|
|
248
|
-
? {
|
|
249
|
-
_info: ToOptional<{
|
|
250
|
-
[K in T[number]["name"]]: Extract<T[number], { name: K }> extends infer U extends Option
|
|
251
|
-
? undefined extends z.infer<U["type"]>
|
|
252
|
-
? undefined | Prettify<_Info & U> // if optional add undefined
|
|
253
|
-
: Prettify<_Info & U>
|
|
254
|
-
: never;
|
|
255
|
-
}>;
|
|
256
|
-
}
|
|
257
|
-
: object;
|
|
258
|
-
|
|
259
|
-
export type NoSubcommand = { name: undefined };
|
|
260
|
-
|
|
261
|
-
export type ParseResult<S extends Partial<Subcommand>[]> = {
|
|
262
|
-
[K in keyof S]: Prettify<
|
|
263
|
-
{ subcommand: S[K]["name"] } & Positional<S[K]> &
|
|
264
|
-
Info<S[K]["options"]> &
|
|
265
|
-
OptionsArr2RecordType<S[K]["options"]> &
|
|
266
|
-
ArgumentsArr2ArrType<S[K]["arguments"]>
|
|
267
|
-
>;
|
|
268
|
-
}[number];
|
|
269
|
-
|
|
270
|
-
export type PrintMethods<N extends Subcommand["name"]
|
|
271
|
-
printCliHelp: (options?: PrintHelpOpt) => void;
|
|
272
|
-
printSubcommandHelp: (subcommand: LiteralUnion<NonNullable<N>>, options?: PrintHelpOpt) => void;
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
export type UnSafeParseResult<S extends Partial<Subcommand>[]> =
|
|
276
|
-
CheckDuplicatedSubcommands<S> extends infer E extends string
|
|
277
|
-
? E
|
|
278
|
-
: Prettify<ParseResult<S> & PrintMethods<S[number]["name"]
|
|
279
|
-
|
|
280
|
-
export type SafeParseResult<S extends Partial<Subcommand>[]> =
|
|
281
|
-
CheckDuplicatedSubcommands<S> extends infer E extends string
|
|
282
|
-
? E
|
|
283
|
-
: Prettify<
|
|
284
|
-
({ success: false; error: Error } | { success: true; data: ParseResult<S> }) &
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
* -
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
* -
|
|
316
|
-
* - Return
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
:
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
* -
|
|
327
|
-
* - Return
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
:
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export type Subcommand = {
|
|
4
|
+
/**
|
|
5
|
+
* - The subcommand name, use `kebab-case`.
|
|
6
|
+
* - Make sure to not duplicate commands and aliases.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* name: "test";
|
|
10
|
+
* name: "run-app";
|
|
11
|
+
*/
|
|
12
|
+
name: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* - The description of the subcommand.
|
|
16
|
+
* - Used for generating the help message.
|
|
17
|
+
*/
|
|
18
|
+
description?: string;
|
|
19
|
+
|
|
20
|
+
/** - The usage message in the help message. */
|
|
21
|
+
usage?: string;
|
|
22
|
+
|
|
23
|
+
/** - Used for generating the help message. */
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* - Provide an example to show to the user.
|
|
28
|
+
* - Used for generating the help message.
|
|
29
|
+
*/
|
|
30
|
+
example?: string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* - The aliases of the subcommand.
|
|
34
|
+
* - Make sure to not duplicate aliases and commands.
|
|
35
|
+
*/
|
|
36
|
+
aliases?: string[];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* - Allows positional arguments for this subcommand.
|
|
40
|
+
* - Unlike `arguments`, which are strictly typed, positional arguments are untyped and represented as a string array of
|
|
41
|
+
* variable length.
|
|
42
|
+
* - When enabled and `arguments` are provided, `arguments` will be parsed first. Any remaining arguments will be
|
|
43
|
+
* considered positional arguments and added to the `positional` property in the result.
|
|
44
|
+
*/
|
|
45
|
+
allowPositional?: boolean;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* - The options of the command.
|
|
49
|
+
* - Those options are specific to this subcommand.
|
|
50
|
+
*/
|
|
51
|
+
options?: [Option, ...Option[]];
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* - Specifies a list of strictly typed arguments.
|
|
55
|
+
* - The order is important; for example, the first argument will be validated against the first specified type.
|
|
56
|
+
* - It is recommended to not use optional arguments as the parser will fill the arguments by order and can't determine
|
|
57
|
+
* which arguments are optional.
|
|
58
|
+
*/
|
|
59
|
+
arguments?: [Argument, ...Argument[]];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* - The action is executed with the result of the parsed arguments.
|
|
63
|
+
* - To get typescript types use `setAction` instead of this.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* const helpCommand = createSubcommand({ name: "help", options: [...] });
|
|
67
|
+
* helpCommand.setAction(res => console.log(res));
|
|
68
|
+
*/
|
|
69
|
+
action?: (results?: any) => void;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export type Cli = Prettify<
|
|
73
|
+
Omit<Subcommand, "name"> & {
|
|
74
|
+
/** - The name of the CLI program. */
|
|
75
|
+
cliName: string;
|
|
76
|
+
}
|
|
77
|
+
>;
|
|
78
|
+
|
|
79
|
+
export type Option = {
|
|
80
|
+
/**
|
|
81
|
+
* - The name of the option, use `CamelCase`.
|
|
82
|
+
* - For example: the syntax for the option `rootPath` is `--root-path`.
|
|
83
|
+
*/
|
|
84
|
+
name: string;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* - The will be used to validate the user input.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* type: z.boolean().default(false);
|
|
91
|
+
* type: z.coerce.number(); // will be coerced to number by Zod
|
|
92
|
+
* type: z.preprocess(parseStringToArrFn, z.array(z.coerce.number())); // array of numbers
|
|
93
|
+
*
|
|
94
|
+
* @see https://zod.dev/?id=types
|
|
95
|
+
*/
|
|
96
|
+
type: z.ZodTypeAny;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* - The description of the option.
|
|
100
|
+
* - Used for generating the help message.
|
|
101
|
+
*/
|
|
102
|
+
description?: string;
|
|
103
|
+
|
|
104
|
+
/** - Used for generating the help message. */
|
|
105
|
+
placeholder?: string;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* - The example of using the option.
|
|
109
|
+
* - Used for generating the help message.
|
|
110
|
+
*/
|
|
111
|
+
example?: string;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* - The aliases of the option, use `CamelCase`.
|
|
115
|
+
* - Here you can specify short names or flags.
|
|
116
|
+
* - Make sure to not duplicate aliases.
|
|
117
|
+
*/
|
|
118
|
+
aliases?: [string, ...string[]];
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export type Argument = {
|
|
122
|
+
/** - The name of the argument. */
|
|
123
|
+
name: string;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* - The will be used to validate the user input.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* type: z.boolean();
|
|
130
|
+
* type: z.coerce.number(); // will be coerced to number by Zod
|
|
131
|
+
* type: z.preprocess(ParseStringToArrFn, z.array(z.coerce.number())); // array of numbers
|
|
132
|
+
*
|
|
133
|
+
* @see https://zod.dev/?id=types
|
|
134
|
+
*/
|
|
135
|
+
type: z.ZodTypeAny;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* - The description of the argument.
|
|
139
|
+
* - Used for generating the help message.
|
|
140
|
+
*/
|
|
141
|
+
description?: string;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* - The example of using the argument.
|
|
145
|
+
* - Used for generating the help message.
|
|
146
|
+
*/
|
|
147
|
+
example?: string;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export type ColorFnType = (...text: unknown[]) => string;
|
|
151
|
+
|
|
152
|
+
export type PrintHelpOpt = {
|
|
153
|
+
/**
|
|
154
|
+
* - **Optional** `boolean`
|
|
155
|
+
* - Whether to print colors or not.
|
|
156
|
+
* - Default: `true`
|
|
157
|
+
*/
|
|
158
|
+
colors?: boolean;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* - **Optional** `object`
|
|
162
|
+
* - The colors to use for the help message.
|
|
163
|
+
*/
|
|
164
|
+
customColors?: {
|
|
165
|
+
title?: ColorFnType;
|
|
166
|
+
description?: ColorFnType;
|
|
167
|
+
default?: ColorFnType;
|
|
168
|
+
optional?: ColorFnType;
|
|
169
|
+
exampleTitle?: ColorFnType;
|
|
170
|
+
example?: ColorFnType;
|
|
171
|
+
command?: ColorFnType;
|
|
172
|
+
option?: ColorFnType;
|
|
173
|
+
argument?: ColorFnType;
|
|
174
|
+
placeholder?: ColorFnType;
|
|
175
|
+
punctuation?: ColorFnType;
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export type _Info = {
|
|
180
|
+
/**
|
|
181
|
+
* - The raw argument as it was passed in
|
|
182
|
+
* - For options that have a default value and are not passed in, the raw argument will be `undefined`
|
|
183
|
+
*/
|
|
184
|
+
rawArg?: string;
|
|
185
|
+
/**
|
|
186
|
+
* - The raw value of the argument as it was passed in
|
|
187
|
+
* - It will be empty string for `boolean` options. E.g. `--help` or `-h`
|
|
188
|
+
* - For options that have a default value and are not passed in, the raw value will be `undefined`
|
|
189
|
+
*/
|
|
190
|
+
rawValue?: string;
|
|
191
|
+
/**
|
|
192
|
+
* - The source value of the argument:
|
|
193
|
+
* - `cli`: The argument was passed in by the user
|
|
194
|
+
* - `default`: The argument was not passed in and has a default value
|
|
195
|
+
*/
|
|
196
|
+
source: "cli" | "default";
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* - Infer the options type from a subcommand.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* const subcommand = createSubcommand({ name: "build", options: [...] });
|
|
204
|
+
* type OptionsType = InferOptionsType<typeof subcommand>;
|
|
205
|
+
*/
|
|
206
|
+
export type InferOptionsType<T extends Partial<Subcommand>> = T["options"] extends infer U extends Option[]
|
|
207
|
+
? ToOptional<{ [K in U[number]["name"]]: z.infer<Extract<U[number], { name: K }>["type"]> }>
|
|
208
|
+
: undefined;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* - Infer the arguments type from a subcommand.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* const subcommand = createSubcommand({ name: "build", arguments: [...] });
|
|
215
|
+
* type ArgumentsType = InferArgumentsType<typeof subcommand>;
|
|
216
|
+
*/
|
|
217
|
+
export type InferArgumentsType<T extends Partial<Subcommand>> = T["arguments"] extends infer U extends Argument[]
|
|
218
|
+
? { [K in keyof U]: U[K] extends { type: z.ZodTypeAny } ? z.infer<U[K]["type"]> : never }
|
|
219
|
+
: undefined;
|
|
220
|
+
|
|
221
|
+
/** `{ some props } & { other props }` => `{ some props, other props }` */
|
|
222
|
+
export type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
223
|
+
|
|
224
|
+
/** Allow string type for literal union and get auto completion */
|
|
225
|
+
export type LiteralUnion<T extends string> = T | (string & {});
|
|
226
|
+
|
|
227
|
+
/** Extract the undefined properties from an object */
|
|
228
|
+
type UndefinedProperties<T> = { [P in keyof T]-?: undefined extends T[P] ? P : never }[keyof T];
|
|
229
|
+
|
|
230
|
+
/** Make undefined properties optional? */
|
|
231
|
+
type ToOptional<T> = Prettify<
|
|
232
|
+
Partial<Pick<T, UndefinedProperties<T>>> & Pick<T, Exclude<keyof T, UndefinedProperties<T>>>
|
|
233
|
+
>;
|
|
234
|
+
|
|
235
|
+
export type OptionsArr2RecordType<T extends Option[] | undefined> = T extends Option[]
|
|
236
|
+
? ToOptional<{ [K in T[number]["name"]]: z.infer<Extract<T[number], { name: K }>["type"]> }>
|
|
237
|
+
: object;
|
|
238
|
+
|
|
239
|
+
export type ArgumentsArr2ArrType<T extends Argument[] | undefined> = T extends Argument[]
|
|
240
|
+
? { arguments: { [K in keyof T]: T[K] extends { type: z.ZodTypeAny } ? z.infer<T[K]["type"]> : never } }
|
|
241
|
+
: object;
|
|
242
|
+
|
|
243
|
+
export type Positional<S extends Partial<Subcommand>> = S["allowPositional"] extends true
|
|
244
|
+
? { positional: string[] }
|
|
245
|
+
: object;
|
|
246
|
+
|
|
247
|
+
export type Info<T extends Option[] | undefined> = T extends Option[]
|
|
248
|
+
? {
|
|
249
|
+
_info: ToOptional<{
|
|
250
|
+
[K in T[number]["name"]]: Extract<T[number], { name: K }> extends infer U extends Option
|
|
251
|
+
? undefined extends z.infer<U["type"]>
|
|
252
|
+
? undefined | Prettify<_Info & U> // if optional add undefined
|
|
253
|
+
: Prettify<_Info & U>
|
|
254
|
+
: never;
|
|
255
|
+
}>;
|
|
256
|
+
}
|
|
257
|
+
: object;
|
|
258
|
+
|
|
259
|
+
export type NoSubcommand = { name: undefined };
|
|
260
|
+
|
|
261
|
+
export type ParseResult<S extends Partial<Subcommand>[]> = {
|
|
262
|
+
[K in keyof S]: Prettify<
|
|
263
|
+
{ subcommand: S[K]["name"] } & Positional<S[K]> &
|
|
264
|
+
Info<S[K]["options"]> &
|
|
265
|
+
OptionsArr2RecordType<S[K]["options"]> &
|
|
266
|
+
ArgumentsArr2ArrType<S[K]["arguments"]>
|
|
267
|
+
>;
|
|
268
|
+
}[number];
|
|
269
|
+
|
|
270
|
+
export type PrintMethods<N extends Subcommand["name"]> = {
|
|
271
|
+
printCliHelp: (options?: PrintHelpOpt) => void;
|
|
272
|
+
printSubcommandHelp: (subcommand: LiteralUnion<NonNullable<N>>, options?: PrintHelpOpt) => void;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
export type UnSafeParseResult<S extends Partial<Subcommand>[]> =
|
|
276
|
+
CheckDuplicatedSubcommands<S> extends infer E extends string
|
|
277
|
+
? E
|
|
278
|
+
: Prettify<ParseResult<S> & PrintMethods<NonNullable<S[number]["name"]>>>;
|
|
279
|
+
|
|
280
|
+
export type SafeParseResult<S extends Partial<Subcommand>[]> =
|
|
281
|
+
CheckDuplicatedSubcommands<S> extends infer E extends string
|
|
282
|
+
? E
|
|
283
|
+
: Prettify<
|
|
284
|
+
({ success: false; error: Error } | { success: true; data: ParseResult<S> }) &
|
|
285
|
+
PrintMethods<NonNullable<S[number]["name"]>>
|
|
286
|
+
>;
|
|
287
|
+
|
|
288
|
+
export type ActionFn<T extends Subcommand | Cli> = {
|
|
289
|
+
setAction: (actions: (res: UnSafeParseResult<[T]>) => void) => void;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
/** - Combine `name` and `aliases` to a `string[]` */
|
|
293
|
+
type MapNameAndAliases2StrArr<T extends { name?: string; aliases?: string[] }[]> = T extends [
|
|
294
|
+
infer First extends Subcommand,
|
|
295
|
+
...infer Rest,
|
|
296
|
+
]
|
|
297
|
+
? Rest extends { name?: string; aliases?: string[] }[]
|
|
298
|
+
? [First["name"], ...(First["aliases"] extends string[] ? First["aliases"] : []), ...MapNameAndAliases2StrArr<Rest>]
|
|
299
|
+
: [First["name"], ...(First["aliases"] extends string[] ? First["aliases"] : [])]
|
|
300
|
+
: [];
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* - Find duplicated items in an array and return it
|
|
304
|
+
* - Return `false` if not found
|
|
305
|
+
*/
|
|
306
|
+
type IsDuplicatesInArr<Input extends any[]> = Input extends [infer Item, ...infer Rest]
|
|
307
|
+
? Rest extends any[]
|
|
308
|
+
? Item extends Rest[number]
|
|
309
|
+
? Item
|
|
310
|
+
: IsDuplicatesInArr<Rest>
|
|
311
|
+
: false
|
|
312
|
+
: false;
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* - Check if there are duplicated options including aliases in `subcommand`
|
|
316
|
+
* - Return an error message if duplicated is found
|
|
317
|
+
* - Return `subcommand` if not found
|
|
318
|
+
*/
|
|
319
|
+
export type CheckDuplicatedOptions<T extends { options?: Option[] }> = T["options"] extends infer O extends Option[]
|
|
320
|
+
? IsDuplicatesInArr<MapNameAndAliases2StrArr<O>> extends infer D extends string
|
|
321
|
+
? `>>> Error: Duplicated Options \`${D}\` <<<`
|
|
322
|
+
: T
|
|
323
|
+
: T;
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* - Check for duplicated subcommands including aliases
|
|
327
|
+
* - Return an error message if duplicated is found
|
|
328
|
+
* - Return the `subcommand[]` if no error
|
|
329
|
+
*/
|
|
330
|
+
export type CheckDuplicatedSubcommands<T extends Partial<Subcommand>[]> =
|
|
331
|
+
IsDuplicatesInArr<MapNameAndAliases2StrArr<T>> extends infer D extends string
|
|
332
|
+
? `>>> Error: Duplicated Subcommand \`${D}\` <<<`
|
|
333
|
+
: T;
|