args-tokens 0.23.0 → 0.23.1

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.
@@ -1,561 +0,0 @@
1
- import { ArgToken } from "./parser-C6MbpZjd.js";
2
-
3
- //#region src/resolver.d.ts
4
-
5
- /**
6
- * An argument schema definition for command-line argument parsing.
7
- *
8
- * This schema is similar to the schema of Node.js `util.parseArgs` but with extended features:
9
- * - Additional `required` and `description` properties
10
- * - Extended `type` support: 'string', 'boolean', 'number', 'enum', 'positional', 'custom'
11
- * - Simplified `default` property (single type, not union types)
12
- *
13
- * @example
14
- * Basic string argument:
15
- * ```ts
16
- * const schema: ArgSchema = {
17
- * type: 'string',
18
- * description: 'Server hostname',
19
- * default: 'localhost'
20
- * }
21
- * ```
22
- *
23
- * @example
24
- * Required number argument with alias:
25
- * ```ts
26
- * const schema: ArgSchema = {
27
- * type: 'number',
28
- * short: 'p',
29
- * description: 'Port number to listen on',
30
- * required: true
31
- * }
32
- * ```
33
- *
34
- * @example
35
- * Enum argument with choices:
36
- * ```ts
37
- * const schema: ArgSchema = {
38
- * type: 'enum',
39
- * choices: ['info', 'warn', 'error'],
40
- * description: 'Logging level',
41
- * default: 'info'
42
- * }
43
- * ```
44
- */
45
- interface ArgSchema {
46
- /**
47
- * Type of the argument value.
48
- *
49
- * - `'string'`: Text value (default if not specified)
50
- * - `'boolean'`: `true`/`false` flag (can be negatable with `--no-` prefix)
51
- * - `'number'`: Numeric value (parsed as integer or float)
52
- * - `'enum'`: One of predefined string values (requires `choices` property)
53
- * - `'positional'`: Non-option argument by position
54
- * - `'custom'`: Custom parsing with user-defined `parse` function
55
- *
56
- * @example
57
- * Different argument types:
58
- * ```ts
59
- * {
60
- * name: { type: 'string' }, // --name value
61
- * verbose: { type: 'boolean' }, // --verbose or --no-verbose
62
- * port: { type: 'number' }, // --port 3000
63
- * level: { type: 'enum', choices: ['debug', 'info'] },
64
- * file: { type: 'positional' }, // first positional arg
65
- * config: { type: 'custom', parse: JSON.parse }
66
- * }
67
- * ```
68
- */
69
- type: 'string' | 'boolean' | 'number' | 'enum' | 'positional' | 'custom';
70
- /**
71
- * Single character alias for the long option name.
72
- *
73
- * As example, allows users to use `-x` instead of `--extended-option`.
74
- * Only valid for non-positional argument types.
75
- *
76
- * @example
77
- * Short alias usage:
78
- * ```ts
79
- * {
80
- * verbose: {
81
- * type: 'boolean',
82
- * short: 'v' // Enables both --verbose and -v
83
- * },
84
- * port: {
85
- * type: 'number',
86
- * short: 'p' // Enables both --port 3000 and -p 3000
87
- * }
88
- * }
89
- * ```
90
- */
91
- short?: string;
92
- /**
93
- * Human-readable description of the argument's purpose.
94
- *
95
- * Used for help text generation and documentation.
96
- * Should be concise but descriptive enough to understand the argument's role.
97
- *
98
- * @example
99
- * Descriptive help text:
100
- * ```ts
101
- * {
102
- * config: {
103
- * type: 'string',
104
- * description: 'Path to configuration file'
105
- * },
106
- * timeout: {
107
- * type: 'number',
108
- * description: 'Request timeout in milliseconds'
109
- * }
110
- * }
111
- * ```
112
- */
113
- description?: string;
114
- /**
115
- * Marks the argument as required.
116
- *
117
- * When `true`, the argument must be provided by the user.
118
- * If missing, an `ArgResolveError` with type 'required' will be thrown.
119
- *
120
- * Note: Only `true` is allowed (not `false`) to make intent explicit.
121
- *
122
- * @example
123
- * Required arguments:
124
- * ```ts
125
- * {
126
- * input: {
127
- * type: 'string',
128
- * required: true, // Must be provided: --input file.txt
129
- * description: 'Input file path'
130
- * },
131
- * source: {
132
- * type: 'positional',
133
- * required: true // First positional argument must exist
134
- * }
135
- * }
136
- * ```
137
- */
138
- required?: true;
139
- /**
140
- * Allows the argument to accept multiple values.
141
- *
142
- * When `true`, the resolved value becomes an array.
143
- * For options: can be specified multiple times (--tag foo --tag bar)
144
- * For positional: collects remaining positional arguments
145
- *
146
- * Note: Only `true` is allowed (not `false`) to make intent explicit.
147
- *
148
- * @example
149
- * Multiple values:
150
- * ```ts
151
- * {
152
- * tags: {
153
- * type: 'string',
154
- * multiple: true, // --tags foo --tags bar → ['foo', 'bar']
155
- * description: 'Tags to apply'
156
- * },
157
- * files: {
158
- * type: 'positional',
159
- * multiple: true // Collects all remaining positional args
160
- * }
161
- * }
162
- * ```
163
- */
164
- multiple?: true;
165
- /**
166
- * Enables negation for boolean arguments using `--no-` prefix.
167
- *
168
- * When `true`, allows users to explicitly set the boolean to `false`
169
- * using `--no-option-name`. When `false` or omitted, only positive
170
- * form is available.
171
- *
172
- * Only applicable to `type: 'boolean'` arguments.
173
- *
174
- * @example
175
- * Negatable boolean:
176
- * ```ts
177
- * {
178
- * color: {
179
- * type: 'boolean',
180
- * negatable: true,
181
- * default: true,
182
- * description: 'Enable colorized output'
183
- * }
184
- * // Usage: --color (true), --no-color (false)
185
- * }
186
- * ```
187
- */
188
- negatable?: boolean;
189
- /**
190
- * Array of allowed string values for enum-type arguments.
191
- *
192
- * Required when `type: 'enum'`. The argument value must be one of these choices,
193
- * otherwise an `ArgResolveError` with type 'type' will be thrown.
194
- *
195
- * Supports both mutable arrays and readonly arrays for type safety.
196
- *
197
- * @example
198
- * Enum choices:
199
- * ```ts
200
- * {
201
- * logLevel: {
202
- * type: 'enum',
203
- * choices: ['debug', 'info', 'warn', 'error'] as const,
204
- * default: 'info',
205
- * description: 'Logging verbosity level'
206
- * },
207
- * format: {
208
- * type: 'enum',
209
- * choices: ['json', 'yaml', 'toml'],
210
- * description: 'Output format'
211
- * }
212
- * }
213
- * ```
214
- */
215
- choices?: string[] | readonly string[];
216
- /**
217
- * Default value used when the argument is not provided.
218
- *
219
- * The type must match the argument's `type` property:
220
- * - `string` type: string default
221
- * - `boolean` type: boolean default
222
- * - `number` type: number default
223
- * - `enum` type: must be one of the `choices` values
224
- * - `positional`/`custom` type: any appropriate default
225
- *
226
- * @example
227
- * Default values by type:
228
- * ```ts
229
- * {
230
- * host: {
231
- * type: 'string',
232
- * default: 'localhost' // string default
233
- * },
234
- * verbose: {
235
- * type: 'boolean',
236
- * default: false // boolean default
237
- * },
238
- * port: {
239
- * type: 'number',
240
- * default: 8080 // number default
241
- * },
242
- * level: {
243
- * type: 'enum',
244
- * choices: ['low', 'high'],
245
- * default: 'low' // must be in choices
246
- * }
247
- * }
248
- * ```
249
- */
250
- default?: string | boolean | number;
251
- /**
252
- * Converts the argument name from camelCase to kebab-case for CLI usage.
253
- *
254
- * When `true`, a property like `maxCount` becomes available as `--max-count`.
255
- * This allows [CAC](https://github.com/cacjs/cac) user-friendly property names while maintaining CLI conventions.
256
- *
257
- * Can be overridden globally with `resolveArgs({ toKebab: true })`.
258
- *
259
- * Note: Only `true` is allowed (not `false`) to make intent explicit.
260
- *
261
- * @example
262
- * Kebab-case conversion:
263
- * ```ts
264
- * {
265
- * maxRetries: {
266
- * type: 'number',
267
- * toKebab: true, // Accessible as --max-retries
268
- * description: 'Maximum retry attempts'
269
- * },
270
- * enableLogging: {
271
- * type: 'boolean',
272
- * toKebab: true // Accessible as --enable-logging
273
- * }
274
- * }
275
- * ```
276
- */
277
- toKebab?: true;
278
- /**
279
- * Names of other options that conflict with this option.
280
- *
281
- * When this option is used together with any of the conflicting options,
282
- * an `ArgResolveError` with type 'conflict' will be thrown.
283
- *
284
- * Conflicts only need to be defined on one side - if option A defines a conflict
285
- * with option B, the conflict is automatically detected when both are used,
286
- * regardless of whether B also defines a conflict with A.
287
- *
288
- * Supports both single option name or array of option names.
289
- * Option names must match the property keys in the schema object exactly
290
- * (no automatic conversion between camelCase and kebab-case).
291
- *
292
- * @example
293
- * Single conflict (bidirectional definition):
294
- * ```ts
295
- * {
296
- * summer: {
297
- * type: 'boolean',
298
- * conflicts: 'autumn' // Cannot use --summer with --autumn
299
- * },
300
- * autumn: {
301
- * type: 'boolean',
302
- * conflicts: 'summer' // Can define on both sides for clarity
303
- * }
304
- * }
305
- * ```
306
- *
307
- * @example
308
- * Single conflict (one-way definition):
309
- * ```ts
310
- * {
311
- * summer: {
312
- * type: 'boolean',
313
- * conflicts: 'autumn' // Only defined on summer side
314
- * },
315
- * autumn: {
316
- * type: 'boolean'
317
- * // No conflicts defined, but still cannot use with --summer
318
- * }
319
- * }
320
- * // Usage: --summer --autumn will throw error
321
- * // Error: "Optional argument '--summer' conflicts with '--autumn'"
322
- * ```
323
- *
324
- * @example
325
- * Multiple conflicts:
326
- * ```ts
327
- * {
328
- * port: {
329
- * type: 'number',
330
- * conflicts: ['socket', 'pipe'], // Cannot use with --socket or --pipe
331
- * description: 'TCP port number'
332
- * },
333
- * socket: {
334
- * type: 'string',
335
- * conflicts: ['port', 'pipe'], // Cannot use with --port or --pipe
336
- * description: 'Unix socket path'
337
- * },
338
- * pipe: {
339
- * type: 'string',
340
- * conflicts: ['port', 'socket'], // Cannot use with --port or --socket
341
- * description: 'Named pipe path'
342
- * }
343
- * }
344
- * // These three options are mutually exclusive
345
- * ```
346
- *
347
- * @example
348
- * With kebab-case conversion:
349
- * ```ts
350
- * {
351
- * summerSeason: {
352
- * type: 'boolean',
353
- * toKebab: true, // Accessible as --summer-season
354
- * conflicts: 'autumnSeason' // Must use property key, not CLI name
355
- * },
356
- * autumnSeason: {
357
- * type: 'boolean',
358
- * toKebab: true // Accessible as --autumn-season
359
- * }
360
- * }
361
- * // Error: "Optional argument '--summer-season' conflicts with '--autumn-season'"
362
- * ```
363
- */
364
- conflicts?: string | string[];
365
- /**
366
- * Custom parsing function for `type: 'custom'` arguments.
367
- *
368
- * Required when `type: 'custom'`. Receives the raw string value and must
369
- * return the parsed result. Should throw an Error (or subclass) if parsing fails.
370
- *
371
- * The function's return type becomes the resolved argument type.
372
- *
373
- * @param value - Raw string value from command line
374
- * @returns Parsed value of any type
375
- * @throws Error or subclass when value is invalid
376
- *
377
- * @example
378
- * Custom parsing functions:
379
- * ```ts
380
- * {
381
- * config: {
382
- * type: 'custom',
383
- * parse: (value: string) => {
384
- * try {
385
- * return JSON.parse(value) // Parse JSON config
386
- * } catch {
387
- * throw new Error('Invalid JSON configuration')
388
- * }
389
- * },
390
- * description: 'JSON configuration object'
391
- * },
392
- * date: {
393
- * type: 'custom',
394
- * parse: (value: string) => {
395
- * const date = new Date(value)
396
- * if (isNaN(date.getTime())) {
397
- * throw new Error('Invalid date format')
398
- * }
399
- * return date
400
- * }
401
- * }
402
- * }
403
- * ```
404
- */
405
- parse?: (value: string) => any;
406
- }
407
- /**
408
- * An object that contains {@link ArgSchema | argument schema}.
409
- *
410
- * This type is used to define the structure and validation rules for command line arguments.
411
- */
412
- interface Args {
413
- [option: string]: ArgSchema;
414
- }
415
- /**
416
- * An object that contains the values of the arguments.
417
- *
418
- * @typeParam T - {@link Args | Arguments} which is an object that defines the command line arguments.
419
- */
420
- type ArgValues<T> = T extends Args ? ResolveArgValues<T, { [Arg in keyof T]: ExtractOptionValue<T[Arg]> }> : {
421
- [option: string]: string | boolean | number | (string | boolean | number)[] | undefined;
422
- };
423
- type IsFunction<T> = T extends ((...args: any[]) => any) ? true : false;
424
- /**
425
- * Extracts the value type from the argument schema.
426
- *
427
- * @typeParam A - {@link ArgSchema | Argument schema} which is an object that defines command line arguments.
428
- *
429
- * @internal
430
- */
431
- type ExtractOptionValue<A extends ArgSchema> = A['type'] extends 'string' ? ResolveOptionValue<A, string> : A['type'] extends 'boolean' ? ResolveOptionValue<A, boolean> : A['type'] extends 'number' ? ResolveOptionValue<A, number> : A['type'] extends 'positional' ? ResolveOptionValue<A, string> : A['type'] extends 'enum' ? A['choices'] extends string[] | readonly string[] ? ResolveOptionValue<A, A['choices'][number]> : never : A['type'] extends 'custom' ? IsFunction<A['parse']> extends true ? ResolveOptionValue<A, ReturnType<NonNullable<A['parse']>>> : never : ResolveOptionValue<A, string | boolean | number>;
432
- type ResolveOptionValue<A extends ArgSchema, T> = A['multiple'] extends true ? T[] : T;
433
- /**
434
- * Resolved argument values.
435
- *
436
- * @typeParam A - {@link Arguments | Args} which is an object that defines the command line arguments.
437
- * @typeParam V - Resolvable argument values.
438
- *
439
- * @internal
440
- */
441
- type ResolveArgValues<A extends Args, V extends Record<keyof A, unknown>> = { -readonly [Arg in keyof A]?: V[Arg] } & FilterArgs<A, V, 'default'> & FilterArgs<A, V, 'required'> & FilterPositionalArgs<A, V> extends infer P ? { [K in keyof P]: P[K] } : never;
442
- /**
443
- * Filters the arguments based on their default values.
444
- *
445
- * @typeParam A - {@link Args | Arguments}, which is an object that defines the command line arguments.
446
- * @typeParam V - Resolvable argument values.
447
- * @typeParam K - Key of the {@link ArgSchema | argument schema} to filter by.
448
- *
449
- * @internal
450
- */
451
- type FilterArgs<A extends Args, V extends Record<keyof A, unknown>, K extends keyof ArgSchema> = { [Arg in keyof A as A[Arg][K] extends {} ? Arg : never]: V[Arg] };
452
- /**
453
- * Filters positional arguments from the argument schema.
454
- *
455
- * @typeParam A - {@link Args | Arguments}, which is an object that defines the command line arguments.
456
- * @typeParam V - Resolvable argument values.
457
- *
458
- * @internal
459
- */
460
- type FilterPositionalArgs<A extends Args, V extends Record<keyof A, unknown>> = { [Arg in keyof A as A[Arg]['type'] extends 'positional' ? Arg : never]: V[Arg] };
461
- /**
462
- * An arguments for {@link resolveArgs | resolve arguments}.
463
- */
464
- interface ResolveArgs {
465
- /**
466
- * Whether to group short arguments.
467
- *
468
- * @see guideline 5 in https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap12.html
469
- *
470
- * @default false
471
- */
472
- shortGrouping?: boolean;
473
- /**
474
- * Skip positional arguments index.
475
- *
476
- * @default -1
477
- */
478
- skipPositional?: number;
479
- /**
480
- * Whether to convert the argument name to kebab-case. This option is applied to all arguments as `toKebab: true`, if set to `true`.
481
- *
482
- * @default false
483
- */
484
- toKebab?: boolean;
485
- }
486
- /**
487
- * Tracks which arguments were explicitly provided by the user.
488
- *
489
- * Each property indicates whether the corresponding argument was explicitly
490
- * provided (true) or is using a default value or not provided (false).
491
- *
492
- * @typeParam A - {@link Args | Arguments}, which is an object that defines the command line arguments.
493
- */
494
- type ArgExplicitlyProvided<A extends Args> = { [K in keyof A]: boolean };
495
- /**
496
- * Resolve command line arguments.
497
- *
498
- * @typeParam A - {@link Args | Arguments}, which is an object that defines the command line arguments.
499
- *
500
- * @param args - An arguments that contains {@link ArgSchema | arguments schema}.
501
- * @param tokens - An array of {@link ArgToken | tokens}.
502
- * @param resolveArgs - An arguments that contains {@link ResolveArgs | resolve arguments}.
503
- * @returns An object that contains the values of the arguments, positional arguments, rest arguments, {@link AggregateError | validation errors}, and explicit provision status.
504
- *
505
- * @example
506
- * ```typescript
507
- * // passed tokens: --port 3000
508
- *
509
- * const { values, explicit } = resolveArgs({
510
- * port: {
511
- * type: 'number',
512
- * default: 8080
513
- * },
514
- * host: {
515
- * type: 'string',
516
- * default: 'localhost'
517
- * }
518
- * }, parsedTokens)
519
- *
520
- * values.port // 3000
521
- * values.host // 'localhost'
522
- *
523
- * explicit.port // true (explicitly provided)
524
- * explicit.host // false (not provided, fallback to default)
525
- * ```
526
- */
527
- declare function resolveArgs<A extends Args>(args: A, tokens: ArgToken[], {
528
- shortGrouping,
529
- skipPositional,
530
- toKebab
531
- }?: ResolveArgs): {
532
- values: ArgValues<A>;
533
- positionals: string[];
534
- rest: string[];
535
- error: AggregateError | undefined;
536
- explicit: ArgExplicitlyProvided<A>;
537
- };
538
- /**
539
- * An error type for {@link ArgResolveError}.
540
- */
541
- type ArgResolveErrorType = 'type' | 'required' | 'conflict';
542
- /**
543
- * An error that occurs when resolving arguments.
544
- * This error is thrown when the argument is not valid.
545
- */
546
- declare class ArgResolveError extends Error {
547
- name: string;
548
- schema: ArgSchema;
549
- type: ArgResolveErrorType;
550
- /**
551
- * Create an `ArgResolveError` instance.
552
- *
553
- * @param message - the error message
554
- * @param name - the name of the argument
555
- * @param type - the type of the error, either 'type' or 'required'
556
- * @param schema - the argument schema that caused the error
557
- */
558
- constructor(message: string, name: string, type: ArgResolveErrorType, schema: ArgSchema);
559
- }
560
- //#endregion
561
- export { ArgExplicitlyProvided, ArgResolveError, ArgResolveErrorType, ArgSchema, ArgValues, Args, ExtractOptionValue, FilterArgs, FilterPositionalArgs, ResolveArgValues, ResolveArgs, resolveArgs };