@boneskull/bargs 2.0.0 → 3.0.0

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.
Files changed (58) hide show
  1. package/README.md +305 -299
  2. package/dist/bargs.cjs +465 -135
  3. package/dist/bargs.cjs.map +1 -1
  4. package/dist/bargs.d.cts +35 -17
  5. package/dist/bargs.d.cts.map +1 -1
  6. package/dist/bargs.d.ts +35 -17
  7. package/dist/bargs.d.ts.map +1 -1
  8. package/dist/bargs.js +463 -135
  9. package/dist/bargs.js.map +1 -1
  10. package/dist/help.cjs +1 -2
  11. package/dist/help.cjs.map +1 -1
  12. package/dist/help.d.cts +20 -3
  13. package/dist/help.d.cts.map +1 -1
  14. package/dist/help.d.ts +20 -3
  15. package/dist/help.d.ts.map +1 -1
  16. package/dist/help.js +1 -2
  17. package/dist/help.js.map +1 -1
  18. package/dist/index.cjs +27 -31
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +15 -79
  21. package/dist/index.d.cts.map +1 -1
  22. package/dist/index.d.ts +15 -79
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +20 -30
  25. package/dist/index.js.map +1 -1
  26. package/dist/opt.cjs +148 -122
  27. package/dist/opt.cjs.map +1 -1
  28. package/dist/opt.d.cts +87 -113
  29. package/dist/opt.d.cts.map +1 -1
  30. package/dist/opt.d.ts +87 -113
  31. package/dist/opt.d.ts.map +1 -1
  32. package/dist/opt.js +147 -121
  33. package/dist/opt.js.map +1 -1
  34. package/dist/parser.cjs +3 -230
  35. package/dist/parser.cjs.map +1 -1
  36. package/dist/parser.d.cts +3 -51
  37. package/dist/parser.d.cts.map +1 -1
  38. package/dist/parser.d.ts +3 -51
  39. package/dist/parser.d.ts.map +1 -1
  40. package/dist/parser.js +2 -223
  41. package/dist/parser.js.map +1 -1
  42. package/dist/types.cjs +1 -3
  43. package/dist/types.cjs.map +1 -1
  44. package/dist/types.d.cts +111 -233
  45. package/dist/types.d.cts.map +1 -1
  46. package/dist/types.d.ts +111 -233
  47. package/dist/types.d.ts.map +1 -1
  48. package/dist/types.js +1 -3
  49. package/dist/types.js.map +1 -1
  50. package/package.json +2 -2
  51. package/dist/validate.cjs +0 -463
  52. package/dist/validate.cjs.map +0 -1
  53. package/dist/validate.d.cts +0 -28
  54. package/dist/validate.d.cts.map +0 -1
  55. package/dist/validate.d.ts +0 -28
  56. package/dist/validate.d.ts.map +0 -1
  57. package/dist/validate.js +0 -459
  58. package/dist/validate.js.map +0 -1
package/dist/opt.js CHANGED
@@ -1,31 +1,16 @@
1
1
  /**
2
- * Builder functions for defining CLI options, positionals, and commands.
2
+ * Builder functions for defining CLI options and positionals.
3
3
  *
4
4
  * Provides ergonomic helpers with full TypeScript type inference for
5
5
  * constructing option schemas (`opt.string()`, `opt.boolean()`, `opt.enum()`,
6
- * etc.), positional schemas (`opt.stringPos()`, `opt.numberPos()`,
7
- * `opt.variadic()`), and command definitions (`opt.command()`). Includes
8
- * composition utilities for merging schemas (`opt.options()`,
9
- * `opt.positionals()`).
6
+ * etc.) and positional schemas (`opt.stringPos()`, `opt.numberPos()`,
7
+ * `opt.variadic()`).
10
8
  *
11
9
  * @packageDocumentation
12
10
  */
13
11
  import { BargsError } from "./errors.js";
14
12
  /**
15
- * Implementation of command builder that detects whether it's called with
16
- * config (direct) or without args (curried for global options).
17
- */
18
- const commandBuilder = (configOrNothing) => {
19
- if (configOrNothing === undefined) {
20
- // Curried usage: return function that accepts config
21
- return (config) => config;
22
- }
23
- // Direct usage: return config as-is
24
- return configOrNothing;
25
- };
26
- /**
27
- * Validate that no alias conflicts exist in a merged options schema. Throws
28
- * BargsError if the same alias is used by multiple options.
13
+ * Validate that no alias conflicts exist in a merged options schema.
29
14
  */
30
15
  const validateAliasConflicts = (schema) => {
31
16
  const aliasToOption = new Map();
@@ -43,32 +28,56 @@ const validateAliasConflicts = (schema) => {
43
28
  }
44
29
  };
45
30
  /**
46
- * Compose multiple option schemas into one.
31
+ * Create a Parser from an options schema that can also merge with existing
32
+ * parsers.
33
+ *
34
+ * Supports two usage patterns:
35
+ *
36
+ * 1. Standalone: `opt.options({ ... })` - returns a Parser
37
+ * 2. Merging: `pos.positionals(...)(opt.options(...))` - merges positionals into
38
+ * options
47
39
  */
48
- const optionsImpl = (...schemas) => {
49
- const merged = Object.assign({}, ...schemas);
50
- validateAliasConflicts(merged);
51
- return merged;
40
+ const optionsImpl = (schema) => {
41
+ validateAliasConflicts(schema);
42
+ // Create the merge function
43
+ const merger = (parser) => {
44
+ const mergedSchema = { ...parser.__optionsSchema, ...schema };
45
+ validateAliasConflicts(mergedSchema);
46
+ // Preserve transforms from the incoming parser
47
+ const transformed = parser;
48
+ const result = {
49
+ ...parser,
50
+ __brand: 'Parser',
51
+ __optionsSchema: mergedSchema,
52
+ __values: {},
53
+ };
54
+ if (transformed.__transform) {
55
+ result.__transform = transformed.__transform;
56
+ }
57
+ return result;
58
+ };
59
+ // Add Parser properties to the function
60
+ const parserProps = {
61
+ __brand: 'Parser',
62
+ __optionsSchema: schema,
63
+ __positionals: [],
64
+ __positionalsSchema: [],
65
+ __values: {},
66
+ };
67
+ return Object.assign(merger, parserProps);
52
68
  };
53
- /**
54
- * Create a positionals schema from positional definitions.
55
- */
56
- const positionalsImpl = (...positionals) => positionals;
57
69
  /**
58
70
  * Namespaced option builders.
59
71
  *
60
- * Provides ergonomic helpers for defining CLI options, positionals, and
61
- * commands with full TypeScript type inference.
62
- *
63
72
  * @example
64
73
  *
65
74
  * ```typescript
66
75
  * import { opt } from 'bargs';
67
76
  *
68
- * const options = opt.options({
77
+ * const parser = opt.options({
69
78
  * verbose: opt.boolean({ aliases: ['v'] }),
70
79
  * name: opt.string({ default: 'world' }),
71
- * level: opt.enum(['low', 'medium', 'high'] as const),
80
+ * level: opt.enum(['low', 'medium', 'high']),
72
81
  * });
73
82
  * ```
74
83
  */
@@ -83,61 +92,12 @@ export const opt = {
83
92
  ...props,
84
93
  }),
85
94
  /**
86
- * Define a boolean option. Props type is preserved to enable default
87
- * inference.
95
+ * Define a boolean option.
88
96
  */
89
97
  boolean: (props = {}) => ({
90
98
  type: 'boolean',
91
99
  ...props,
92
100
  }),
93
- /**
94
- * Define a command with proper type inference.
95
- *
96
- * Three usage patterns:
97
- *
98
- * 1. Simple usage (no global options): `bargs.command({ ... })`
99
- * 2. With global options: `bargs.command<typeof globalOptions>()({ ... })`
100
- * 3. With global options AND transforms: `bargs.command<typeof globalOptions,
101
- * typeof globalTransforms>()({ ... })`
102
- *
103
- * @example
104
- *
105
- * ```typescript
106
- * // Simple usage - no global options typed
107
- * const simpleCmd = bargs.command({
108
- * description: 'Simple command',
109
- * handler: ({ values }) => { ... },
110
- * });
111
- *
112
- * // With global options typed
113
- * const globalOptions = {
114
- * verbose: bargs.boolean({ aliases: ['v'] }),
115
- * } as const;
116
- *
117
- * const greetCmd = bargs.command<typeof globalOptions>()({
118
- * description: 'Greet someone',
119
- * options: { name: bargs.string({ default: 'world' }) },
120
- * handler: ({ values }) => {
121
- * // values.verbose is properly typed as boolean | undefined
122
- * console.log(`Hello, ${values.name}!`);
123
- * },
124
- * });
125
- *
126
- * // With global options AND global transforms typed
127
- * const globalTransforms = {
128
- * values: (v) => ({ ...v, timestamp: Date.now() }),
129
- * } as const;
130
- *
131
- * const timedCmd = bargs.command<typeof globalOptions, typeof globalTransforms>()({
132
- * description: 'Time-aware command',
133
- * handler: ({ values }) => {
134
- * // values.timestamp is properly typed from global transforms
135
- * console.log(`Ran at ${values.timestamp}`);
136
- * },
137
- * });
138
- * ```
139
- */
140
- command: commandBuilder,
141
101
  /**
142
102
  * Define a count option (--verbose --verbose = 2).
143
103
  */
@@ -146,9 +106,7 @@ export const opt = {
146
106
  ...props,
147
107
  }),
148
108
  /**
149
- * Define an enum option with string choices. The choices array is inferred as
150
- * a tuple of literal types automatically. Props type is preserved to enable
151
- * default inference.
109
+ * Define an enum option with string choices.
152
110
  */
153
111
  enum: (choices, props = {}) => ({
154
112
  choices,
@@ -156,8 +114,7 @@ export const opt = {
156
114
  ...props,
157
115
  }),
158
116
  /**
159
- * Define an enum positional argument with string choices. The choices array
160
- * is inferred as a tuple of literal types automatically.
117
+ * Define an enum positional argument with string choices.
161
118
  */
162
119
  enumPos: (choices, props = {}) => ({
163
120
  choices,
@@ -165,75 +122,144 @@ export const opt = {
165
122
  ...props,
166
123
  }),
167
124
  /**
168
- * Define a number option. Props type is preserved to enable default
169
- * inference.
125
+ * Define a number option.
170
126
  */
171
127
  number: (props = {}) => ({
172
128
  type: 'number',
173
129
  ...props,
174
130
  }),
175
- // ─── Positional Builders ───────────────────────────────────────────
176
131
  /**
177
- * Define a number positional argument. Props type is preserved to enable
178
- * required inference.
132
+ * Define a number positional argument.
179
133
  */
180
134
  numberPos: (props = {}) => ({
181
135
  type: 'number',
182
136
  ...props,
183
137
  }),
184
138
  /**
185
- * Compose multiple option schemas into one. Later schemas override earlier
186
- * ones for duplicate option names. Validates that no alias conflicts exist.
139
+ * Create a Parser from an options schema.
187
140
  *
188
141
  * @example
189
142
  *
190
143
  * ```typescript
191
- * // Single schema (identity, enables reuse)
192
- * const loggingOpts = opt.options({
144
+ * const parser = opt.options({
193
145
  * verbose: opt.boolean({ aliases: ['v'] }),
194
- * quiet: opt.boolean({ aliases: ['q'] }),
195
- * });
196
- *
197
- * // Merge multiple schemas
198
- * const allOpts = opt.options(loggingOpts, ioOpts, {
199
- * format: opt.enum(['json', 'yaml'] as const),
146
+ * name: opt.string({ default: 'world' }),
200
147
  * });
148
+ * // Type: Parser<{ verbose: boolean | undefined, name: string }, []>
201
149
  * ```
202
- *
203
- * @throws BargsError if multiple options use the same alias
204
150
  */
205
151
  options: optionsImpl,
206
152
  /**
207
- * Create a positionals schema with proper tuple type inference.
153
+ * Define a string option.
154
+ */
155
+ string: (props = {}) => ({
156
+ type: 'string',
157
+ ...props,
158
+ }),
159
+ /**
160
+ * Define a string positional argument.
161
+ */
162
+ stringPos: (props = {}) => ({
163
+ type: 'string',
164
+ ...props,
165
+ }),
166
+ /**
167
+ * Define a variadic positional (rest args).
168
+ */
169
+ variadic: (items, props = {}) => ({
170
+ items,
171
+ type: 'variadic',
172
+ ...props,
173
+ }),
174
+ };
175
+ /**
176
+ * Create a Parser from positional definitions that can also merge with existing
177
+ * parsers.
178
+ *
179
+ * Supports two usage patterns:
180
+ *
181
+ * 1. Standalone: `pos.positionals(...)` - returns a Parser
182
+ * 2. Merging: `pos.positionals(...)(opt.options(...))` - merges positionals into
183
+ * options
184
+ */
185
+ const positionalsImpl = (...positionals) => {
186
+ // Create the merge function - just passes through V2, no intersection needed
187
+ const merger = (parser) => {
188
+ // Preserve transforms from the incoming parser
189
+ const transformed = parser;
190
+ const result = {
191
+ ...parser,
192
+ __brand: 'Parser',
193
+ __positionals: [],
194
+ __positionalsSchema: [...parser.__positionalsSchema, ...positionals],
195
+ };
196
+ if (transformed.__transform) {
197
+ result.__transform = transformed.__transform;
198
+ }
199
+ return result;
200
+ };
201
+ // Add Parser properties to the function
202
+ // Use empty object {} instead of Record<string, never> for better intersection behavior
203
+ const parserProps = {
204
+ __brand: 'Parser',
205
+ __optionsSchema: {},
206
+ __positionals: [],
207
+ __positionalsSchema: positionals,
208
+ __values: {},
209
+ };
210
+ return Object.assign(merger, parserProps);
211
+ };
212
+ /**
213
+ * Namespaced positional builders.
214
+ *
215
+ * @example
216
+ *
217
+ * ```typescript
218
+ * import { pos } from 'bargs';
219
+ *
220
+ * const parser = pos.positionals(
221
+ * pos.string({ name: 'input', required: true }),
222
+ * pos.string({ name: 'output' }),
223
+ * );
224
+ * ```
225
+ */
226
+ export const pos = {
227
+ /**
228
+ * Define an enum positional argument with string choices.
229
+ */
230
+ enum: (choices, props = {}) => ({
231
+ choices,
232
+ type: 'enum',
233
+ ...props,
234
+ }),
235
+ /**
236
+ * Define a number positional argument.
237
+ */
238
+ number: (props = {}) => ({
239
+ type: 'number',
240
+ ...props,
241
+ }),
242
+ /**
243
+ * Create a Parser from positional definitions.
208
244
  *
209
245
  * @example
210
246
  *
211
247
  * ```typescript
212
- * const positionals = opt.positionals(
213
- * opt.stringPos({ description: 'Input file', required: true }),
214
- * opt.stringPos({ description: 'Output file' }),
248
+ * const parser = pos.positionals(
249
+ * pos.string({ name: 'input', required: true }),
250
+ * pos.string({ name: 'output' }),
215
251
  * );
252
+ * // Type: Parser<{}, readonly [string, string | undefined]>
216
253
  * ```
217
254
  */
218
255
  positionals: positionalsImpl,
219
256
  /**
220
- * Define a string option. Props type is preserved to enable default
221
- * inference.
257
+ * Define a string positional argument.
222
258
  */
223
259
  string: (props = {}) => ({
224
260
  type: 'string',
225
261
  ...props,
226
262
  }),
227
- // ─── Composition ───────────────────────────────────────────────────
228
- /**
229
- * Define a string positional argument. Props type is preserved to enable
230
- * required inference.
231
- */
232
- stringPos: (props = {}) => ({
233
- type: 'string',
234
- ...props,
235
- }),
236
- // ─── Command Builder ───────────────────────────────────────────────
237
263
  /**
238
264
  * Define a variadic positional (rest args).
239
265
  */
package/dist/opt.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"opt.js","sourceRoot":"","sources":["../src/opt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"opt.js","sourceRoot":"","sources":["../src/opt.ts"],"names":[],"mappings":"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"}
package/dist/parser.cjs CHANGED
@@ -7,93 +7,12 @@
7
7
  * - Building `parseArgs` configuration from bargs option schemas
8
8
  * - Coercing parsed string values to their declared types (number, enum, etc.)
9
9
  * - Processing positional arguments including variadic rest args
10
- * - Running handler functions (sync or async) after successful parsing
11
- * - Supporting both simple CLIs and command-based CLIs with subcommand dispatch
12
10
  *
13
11
  * @packageDocumentation
14
12
  */
15
13
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.parseCommandsAsync = exports.parseCommandsSync = exports.parseSimple = exports.runHandler = exports.runSyncHandler = void 0;
17
- exports.runSyncTransforms = runSyncTransforms;
18
- exports.runTransforms = runTransforms;
14
+ exports.parseSimple = void 0;
19
15
  const node_util_1 = require("node:util");
20
- const errors_js_1 = require("./errors.cjs");
21
- /**
22
- * Check if a value is a thenable (Promise-like). Uses duck-typing for
23
- * cross-realm compatibility.
24
- */
25
- const isThenable = (value) => value !== null &&
26
- typeof value === 'object' &&
27
- typeof value.then === 'function';
28
- /**
29
- * Run a handler synchronously. Throws if handler returns a thenable.
30
- */
31
- const runSyncHandler = (handler, result) => {
32
- const maybePromise = handler(result);
33
- if (isThenable(maybePromise)) {
34
- throw new errors_js_1.BargsError('Handler returned a thenable. Use bargsAsync() for async handlers.');
35
- }
36
- };
37
- exports.runSyncHandler = runSyncHandler;
38
- /**
39
- * Run a handler (async).
40
- */
41
- const runHandler = async (handler, result) => {
42
- await handler(result);
43
- };
44
- exports.runHandler = runHandler;
45
- /**
46
- * Run transforms synchronously. Throws if any transform returns a thenable.
47
- */
48
- function runSyncTransforms(transforms, values, positionals) {
49
- if (!transforms) {
50
- return { positionals, values };
51
- }
52
- // Apply values transform
53
- const transformedValues = transforms.values
54
- ? (() => {
55
- const result = transforms.values(values);
56
- if (isThenable(result)) {
57
- throw new errors_js_1.BargsError('Transform returned a thenable. Use bargsAsync() for async transforms.');
58
- }
59
- return result;
60
- })()
61
- : values;
62
- // Apply positionals transform
63
- const transformedPositionals = transforms.positionals
64
- ? (() => {
65
- const result = transforms.positionals(positionals);
66
- if (isThenable(result)) {
67
- throw new errors_js_1.BargsError('Transform returned a thenable. Use bargsAsync() for async transforms.');
68
- }
69
- return result;
70
- })()
71
- : positionals;
72
- return {
73
- positionals: transformedPositionals,
74
- values: transformedValues,
75
- };
76
- }
77
- /**
78
- * Run transforms asynchronously.
79
- */
80
- async function runTransforms(transforms, values, positionals) {
81
- if (!transforms) {
82
- return { positionals, values };
83
- }
84
- // Apply values transform (await if needed)
85
- const transformedValues = transforms.values
86
- ? await transforms.values(values)
87
- : values;
88
- // Apply positionals transform (await if needed)
89
- const transformedPositionals = transforms.positionals
90
- ? await transforms.positionals(positionals)
91
- : positionals;
92
- return {
93
- positionals: transformedPositionals,
94
- values: transformedValues,
95
- };
96
- }
97
16
  /**
98
17
  * Build parseArgs options config from our options schema.
99
18
  */
@@ -165,9 +84,6 @@ const coerceValues = (values, schema) => {
165
84
  };
166
85
  /**
167
86
  * Coerce positional values.
168
- *
169
- * Note: Schema validation (variadic last, required order) is done upfront by
170
- * validateConfig in bargs.ts.
171
87
  */
172
88
  const coercePositionals = (positionals, schema) => {
173
89
  const result = [];
@@ -175,7 +91,7 @@ const coercePositionals = (positionals, schema) => {
175
91
  const def = schema[i];
176
92
  const value = positionals[i];
177
93
  if (def.type === 'variadic') {
178
- // Rest of positionals - def is narrowed to VariadicPositional here
94
+ // Rest of positionals
179
95
  const variadicDef = def;
180
96
  const rest = positionals.slice(i);
181
97
  if (variadicDef.items === 'number') {
@@ -214,8 +130,7 @@ const coercePositionals = (positionals, schema) => {
214
130
  return result;
215
131
  };
216
132
  /**
217
- * Parse arguments for a simple CLI (no commands). This is synchronous - it only
218
- * parses, does not run handlers.
133
+ * Parse arguments for a simple CLI (no commands).
219
134
  */
220
135
  const parseSimple = (config) => {
221
136
  const { args = process.argv.slice(2), options: optionsSchema = {}, positionals: positionalsSchema = [], } = config;
@@ -232,151 +147,9 @@ const parseSimple = (config) => {
232
147
  const coercedValues = coerceValues(values, optionsSchema);
233
148
  const coercedPositionals = coercePositionals(positionals, positionalsSchema);
234
149
  return {
235
- command: undefined,
236
150
  positionals: coercedPositionals,
237
151
  values: coercedValues,
238
152
  };
239
153
  };
240
154
  exports.parseSimple = parseSimple;
241
- /**
242
- * Core command parsing logic (sync, no handler execution). Returns the parsed
243
- * result and the handler to run.
244
- */
245
- const parseCommandsCore = (config) => {
246
- const { args = process.argv.slice(2), commands, defaultHandler, options: globalOptions = {}, } = config;
247
- const commandsRecord = commands;
248
- // Find command name (first non-flag argument)
249
- const commandIndex = args.findIndex((arg) => !arg.startsWith('-'));
250
- const commandName = commandIndex >= 0 ? args[commandIndex] : undefined;
251
- const remainingArgs = commandName
252
- ? [...args.slice(0, commandIndex), ...args.slice(commandIndex + 1)]
253
- : args;
254
- // No command specified
255
- if (!commandName) {
256
- if (typeof defaultHandler === 'string') {
257
- // Use named default command (recursive)
258
- return parseCommandsCore({
259
- ...config,
260
- args: [defaultHandler, ...args],
261
- defaultHandler: undefined,
262
- });
263
- }
264
- else if (typeof defaultHandler === 'function') {
265
- // Parse global options only
266
- const parseArgsOptions = buildParseArgsConfig(globalOptions);
267
- const { values } = (0, node_util_1.parseArgs)({
268
- allowPositionals: false,
269
- args: remainingArgs,
270
- options: parseArgsOptions,
271
- strict: true,
272
- });
273
- const coercedValues = coerceValues(values, globalOptions);
274
- const result = {
275
- command: undefined,
276
- positionals: [],
277
- values: coercedValues,
278
- };
279
- return {
280
- commandTransforms: undefined,
281
- handler: defaultHandler,
282
- result,
283
- topLevelTransforms: config.transforms,
284
- };
285
- }
286
- else {
287
- throw new errors_js_1.HelpError('No command specified.');
288
- }
289
- }
290
- // Find command config
291
- const command = commandsRecord[commandName];
292
- if (!command) {
293
- throw new errors_js_1.HelpError(`Unknown command: ${commandName}`);
294
- }
295
- // Merge global and command options
296
- const commandOptions = command.options ?? {};
297
- const mergedOptionsSchema = { ...globalOptions, ...commandOptions };
298
- const commandPositionals = command.positionals ?? [];
299
- // Build parseArgs config
300
- const parseArgsOptions = buildParseArgsConfig(mergedOptionsSchema);
301
- // Parse
302
- const { positionals, values } = (0, node_util_1.parseArgs)({
303
- allowPositionals: commandPositionals.length > 0,
304
- args: remainingArgs,
305
- options: parseArgsOptions,
306
- strict: true,
307
- });
308
- // Coerce
309
- const coercedValues = coerceValues(values, mergedOptionsSchema);
310
- const coercedPositionals = coercePositionals(positionals, commandPositionals);
311
- const result = {
312
- command: commandName,
313
- positionals: coercedPositionals,
314
- values: coercedValues,
315
- };
316
- return {
317
- commandTransforms: command.transforms,
318
- handler: command.handler,
319
- result,
320
- topLevelTransforms: config.transforms,
321
- };
322
- };
323
- /**
324
- * Parse arguments for a command-based CLI (sync). Throws if any handler or
325
- * transform returns a thenable.
326
- */
327
- const parseCommandsSync = (config) => {
328
- const { commandTransforms, handler, result, topLevelTransforms } = parseCommandsCore(config);
329
- // Apply transforms: top-level first, then command-level
330
- let currentValues = result.values;
331
- let currentPositionals = result.positionals;
332
- if (topLevelTransforms) {
333
- const transformed = runSyncTransforms(topLevelTransforms, currentValues, currentPositionals);
334
- currentValues = transformed.values;
335
- currentPositionals = transformed.positionals;
336
- }
337
- if (commandTransforms) {
338
- const transformed = runSyncTransforms(commandTransforms, currentValues, currentPositionals);
339
- currentValues = transformed.values;
340
- currentPositionals = transformed.positionals;
341
- }
342
- const finalResult = {
343
- command: result.command,
344
- positionals: currentPositionals,
345
- values: currentValues,
346
- };
347
- if (handler) {
348
- (0, exports.runSyncHandler)(handler, finalResult);
349
- }
350
- return finalResult;
351
- };
352
- exports.parseCommandsSync = parseCommandsSync;
353
- /**
354
- * Parse arguments for a command-based CLI (async).
355
- */
356
- const parseCommandsAsync = async (config) => {
357
- const { commandTransforms, handler, result, topLevelTransforms } = parseCommandsCore(config);
358
- // Apply transforms: top-level first, then command-level
359
- let currentValues = result.values;
360
- let currentPositionals = result.positionals;
361
- if (topLevelTransforms) {
362
- const transformed = await runTransforms(topLevelTransforms, currentValues, currentPositionals);
363
- currentValues = transformed.values;
364
- currentPositionals = transformed.positionals;
365
- }
366
- if (commandTransforms) {
367
- const transformed = await runTransforms(commandTransforms, currentValues, currentPositionals);
368
- currentValues = transformed.values;
369
- currentPositionals = transformed.positionals;
370
- }
371
- const finalResult = {
372
- command: result.command,
373
- positionals: currentPositionals,
374
- values: currentValues,
375
- };
376
- if (handler) {
377
- await (0, exports.runHandler)(handler, finalResult);
378
- }
379
- return finalResult;
380
- };
381
- exports.parseCommandsAsync = parseCommandsAsync;
382
155
  //# sourceMappingURL=parser.js.map