@noresources/command 0.0.0-stage → 0.1.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.
- package/README.md +76 -2
- package/package.json +44 -4
- package/src/Builders.mjs +368 -0
- package/src/Command.mjs +159 -0
- package/src/CommandHandler.mjs +14 -0
- package/src/Documentation.mjs +63 -0
- package/src/Input.mjs +42 -0
- package/src/Options.mjs +515 -0
- package/src/Parameters.mjs +350 -0
- package/src/Positionals.mjs +493 -0
- package/src/commander/adapters.mjs +343 -0
- package/src/commander/index.mjs +26 -0
- package/src/commander/package.json +1 -0
- package/src/lib/options/Verbosity.mjs +55 -0
- package/src/lib/options/index.mjs +15 -0
- package/src/utilities.mjs +40 -0
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Defines core structures and logic for managing positional arguments
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
transformParameterProperty
|
|
9
|
+
} from './utilities.mjs';
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
Parameter
|
|
13
|
+
} from './Parameters.mjs';
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
assertType,
|
|
17
|
+
assertTypes,
|
|
18
|
+
merge
|
|
19
|
+
} from '@noresources/core';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @constant {object} POSITIONAL_TYPE
|
|
23
|
+
* @description A static map containing string constants used globally to identify
|
|
24
|
+
* the semantic type of a positional argument definition, namely whether it
|
|
25
|
+
* represents a single fixed value or a sequence of values.
|
|
26
|
+
* @property {('VALUE'|'VARIADIC')} VALUE - Identifier used for defining a single, fixed-value positional argument.
|
|
27
|
+
* @property {('VALUE'|'VARIADIC')} VARIADIC - Identifier used for defining a variadic positional argument, which accepts zero or more inputs.
|
|
28
|
+
*/
|
|
29
|
+
export const POSITIONAL_TYPE = {
|
|
30
|
+
'VALUE': 'value',
|
|
31
|
+
'VARIADIC': 'variadic'
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @abstract
|
|
36
|
+
* @class Positional
|
|
37
|
+
* @description Base class providing the fundamental structure for any positional
|
|
38
|
+
* argument within the parsing system. It holds the metadata necessary to map
|
|
39
|
+
* the argument slot to a specific property in the resulting data object.
|
|
40
|
+
*
|
|
41
|
+
* @property {boolean} property - The string identifier corresponding to the property name in the output structure where the value will be stored.
|
|
42
|
+
* @property {number} [min=0] - The minimum number of values that must satisfy this argument's constraints.
|
|
43
|
+
* @property {number} [max=1] - The maximum number of values allowed for this argument (varies by concrete implementation).
|
|
44
|
+
* @param {object} options - Configuration object passed during instantiation.
|
|
45
|
+
*/
|
|
46
|
+
export class Positional {
|
|
47
|
+
constructor (options) {
|
|
48
|
+
if (!(typeof options === 'object' && options)) {
|
|
49
|
+
options = {};
|
|
50
|
+
}
|
|
51
|
+
this.property = options.property;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Coerce and validate a raw input value intended for a positional argument slot.
|
|
56
|
+
* This method delegates the actual transformation to the associated `Parameter` object.
|
|
57
|
+
* @param {mixed} value - The raw input value provided by the caller.
|
|
58
|
+
* @returns {mixed} A value that has been successfully coerced and validated against the parameter constraints.
|
|
59
|
+
*/
|
|
60
|
+
parse (value) {
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @class PositionalValue
|
|
67
|
+
* @extends Positional
|
|
68
|
+
* @description Represents a single, fixed-slot positional argument. This structure
|
|
69
|
+
* is used when the parsing system is explicitly expected to consume exactly one
|
|
70
|
+
* input value from the command line arguments.
|
|
71
|
+
*
|
|
72
|
+
* @property {Parameter} argument - The underlying type definition (e.g., string, number) that dictates the constraints of the expected single value.
|
|
73
|
+
* @property {*} [default] - The fallback default value assigned to this parameter if no value is provided by the caller and the argument is not required.
|
|
74
|
+
*/
|
|
75
|
+
export class PositionalValue extends Positional {
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Initializes a new PositionalValue instance, configuring its type constraints and default values.
|
|
79
|
+
* @param {object} options - The configuration object for the positional argument.
|
|
80
|
+
* @param {* | undefined} [options.default=undefined] - The default value to assign if the argument is omitted during a function call.
|
|
81
|
+
* @param {Parameter | undefined} [options.argument=undefined] - The required type definition for the argument, adhering to the `Parameter` class structure.
|
|
82
|
+
* @throws {Error} If options.argument is not a valid Parameter object.
|
|
83
|
+
*/
|
|
84
|
+
constructor(options) {
|
|
85
|
+
options = merge ({
|
|
86
|
+
//'default': undefined,
|
|
87
|
+
//'required': undefined,
|
|
88
|
+
//'parameter': undefined
|
|
89
|
+
}, options);
|
|
90
|
+
|
|
91
|
+
assertTypes (options.parameter, ['undefined', Parameter], 'options.parameter');
|
|
92
|
+
|
|
93
|
+
super (options);
|
|
94
|
+
this.default = options.default;
|
|
95
|
+
this.parameter = options.parameter;
|
|
96
|
+
this._required = options.required;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Gets the predefined type constant for a single, fixed-value positional argument.
|
|
101
|
+
* @returns {('VALUE'|'VARIADIC')} The constant identifier 'value'.
|
|
102
|
+
*/
|
|
103
|
+
get type () {
|
|
104
|
+
return POSITIONAL_TYPE.VALUE;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Determines if the positional value must be explicitly provided by the caller.
|
|
108
|
+
* It considers the argument required if the `_required` flag is set to true, or if no default value has been assigned.
|
|
109
|
+
* @returns {boolean} True if the value is mandatory (required).
|
|
110
|
+
*/
|
|
111
|
+
get required () {
|
|
112
|
+
if (typeof this._required !== 'undefined') {
|
|
113
|
+
return this._required ? true : false;
|
|
114
|
+
}
|
|
115
|
+
return (typeof this.default === 'undefined');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Sets the explicit required status of the positional value.
|
|
120
|
+
* @param {boolean} value - The new required state.
|
|
121
|
+
*/
|
|
122
|
+
set required (value) {
|
|
123
|
+
this._required = value;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Gets the minimum expected count. For PositionalValue, this is always 1 if required, 0 otherwise.
|
|
128
|
+
* @returns {number} The minimum number of expected values (1 or 0).
|
|
129
|
+
*/
|
|
130
|
+
get min () {
|
|
131
|
+
return this.required ? 1 : 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Gets the maximum allowed count. For PositionalValue, this is always 1.
|
|
136
|
+
* @returns {number} The maximum number of allowed values (always 1).
|
|
137
|
+
*/
|
|
138
|
+
get max () {
|
|
139
|
+
return 1;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Parses and validates the input value against the defined parameter constraints.
|
|
144
|
+
* @param {mixed} value - The raw value from the input source.
|
|
145
|
+
* @returns {mixed} The processed and validated value.
|
|
146
|
+
*/
|
|
147
|
+
parse (value) {
|
|
148
|
+
if (!(this.parameter instanceof Parameter)) {
|
|
149
|
+
return value;
|
|
150
|
+
}
|
|
151
|
+
value = this.parameter.coerce(value);
|
|
152
|
+
this.parameter.validate(value);
|
|
153
|
+
return value;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @class PositionalVariadic
|
|
159
|
+
* @extends Positional
|
|
160
|
+
* @description Represents a variadic positional argument, which allows the parsing
|
|
161
|
+
* system to consume zero or more arguments into a list or array. This structure
|
|
162
|
+
* is essential for handling variable numbers of inputs, such as lists of file paths or names.
|
|
163
|
+
*
|
|
164
|
+
* @property {Parameter} parameters - The underlying type definition that dictates the constraints of the elements within the received arguments array.
|
|
165
|
+
* @property {number} min - The minimum required count of arguments that must be passed (this property is derived from the required state).
|
|
166
|
+
* @property {number} [max] - The maximum number of arguments that are allowed to be consumed.
|
|
167
|
+
*/
|
|
168
|
+
export class PositionalVariadic extends Positional {
|
|
169
|
+
/**
|
|
170
|
+
* Initializes a new PositionalVariadic instance.
|
|
171
|
+
* @param {object} options - Configuration options for the variadic argument.
|
|
172
|
+
* @param {number} [options.min=0] - The absolute minimum number of values that must be passed for this slot. Must be >= 0.
|
|
173
|
+
* @param {number} [options.max=undefined] - The maximum number of values that this argument is allowed to accept.
|
|
174
|
+
* @param {Parameter | undefined} [options.parameters=undefined] - The base type definition used to validate every value collected in this array.
|
|
175
|
+
* @throws {Error} If options.min is not a number or options.max is not a number.
|
|
176
|
+
*/
|
|
177
|
+
constructor(options) {
|
|
178
|
+
options = merge ({
|
|
179
|
+
'min': 0,
|
|
180
|
+
//'max': undefined,
|
|
181
|
+
//'arguments': undefined
|
|
182
|
+
}, options);
|
|
183
|
+
|
|
184
|
+
assertType (options.min, 'number', 'options.min');
|
|
185
|
+
assertTypes(options.max, ['undefined', 'number'], 'options.max');
|
|
186
|
+
assertTypes (options.parameters, ['undefined', Parameter], 'options.parameters');
|
|
187
|
+
|
|
188
|
+
super (options);
|
|
189
|
+
this.min = options.min;
|
|
190
|
+
this.max = options.max;
|
|
191
|
+
this.parameters = options.parameters;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Gets the predefined type constant for a variadic positional argument.
|
|
196
|
+
* @returns {('VALUE'|'VARIADIC')} The constant identifier 'variadic'.
|
|
197
|
+
*/
|
|
198
|
+
get type () {
|
|
199
|
+
return POSITIONAL_TYPE.VARIADIC;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Checks if the variadic argument is mandatory.
|
|
204
|
+
* This is determined by whether the `min` count is greater than zero.
|
|
205
|
+
* @returns {boolean} True if at least one value is mandatory (min > 0).
|
|
206
|
+
*/
|
|
207
|
+
get required () {
|
|
208
|
+
return this.min > 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Updates the minimum required count for this variadic argument.
|
|
213
|
+
* @param {boolean} value - If true, sets the minimum to at least 1; if false, sets it to 0.
|
|
214
|
+
*/
|
|
215
|
+
set required (value) {
|
|
216
|
+
if (value) {
|
|
217
|
+
this.min = Math.max(1, this.min);
|
|
218
|
+
} else {
|
|
219
|
+
this.min = 0;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Parses and validates a raw input value within the context of a variadic argument.
|
|
225
|
+
* Note: This function typically runs during consumption, not the initial parsing phase.
|
|
226
|
+
* @param {any} value - A single raw value item.
|
|
227
|
+
* @returns {any} The single value, having been coerced and validated.
|
|
228
|
+
*/
|
|
229
|
+
parse (value) {
|
|
230
|
+
if (!(this.parameters instanceof Parameter)) {
|
|
231
|
+
return value;
|
|
232
|
+
}
|
|
233
|
+
value = this.parameters.coerce (value);
|
|
234
|
+
this.parameters.validate(value);
|
|
235
|
+
return value;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Internal utility function to automatically infer the positional argument type
|
|
241
|
+
* (Value or Variadic) when the type is not explicitly defined in the options object.
|
|
242
|
+
* This function is strictly internal and should not be called externally.
|
|
243
|
+
* @private
|
|
244
|
+
* @param {object} [options] - The configuration options object to inspect for type clues.
|
|
245
|
+
* @returns {('VALUE'|'VARIADIC')} The detected type of the positional argument.
|
|
246
|
+
*/
|
|
247
|
+
function autodetectType (options) {
|
|
248
|
+
if ('type' in options) {
|
|
249
|
+
return options.type;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
for (const property of ['parameter', 'default']) {
|
|
253
|
+
if (property in options) {
|
|
254
|
+
return POSITIONAL_TYPE.VALUE;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
for (const property of ['parameters', 'min', 'max']) {
|
|
259
|
+
if (property in options) {
|
|
260
|
+
return POSITIONAL_TYPE.VARIADIC;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return POSITIONAL_TYPE.VALUE;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Creates and initializes a specific positional argument object, either PositionalValue or PositionalVariadic,
|
|
269
|
+
* based on the provided type descriptor and configuration options.
|
|
270
|
+
*
|
|
271
|
+
* @param {object | string} type - The explicit type identifier. This can be a string ('value', 'variadic') or a configuration object which must contain a 'type' property.
|
|
272
|
+
* @param {object} [options] - The options object containing detailed configuration parameters for the positional argument (e.g., default values, min/max constraints).
|
|
273
|
+
* @returns {PositionalValue | PositionalVariadic} A fully initialized instance of the correct positional argument class.
|
|
274
|
+
* @throws {Error} If the provided type identifier cannot be resolved or handled by this function.
|
|
275
|
+
*/
|
|
276
|
+
export function createPositional(type, options) {
|
|
277
|
+
if (typeof type === 'object') {
|
|
278
|
+
options = type;
|
|
279
|
+
type = type.type;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (typeof type === 'undefined') {
|
|
283
|
+
type = autodetectType(options || {});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
switch (type) {
|
|
288
|
+
case POSITIONAL_TYPE.VALUE: {
|
|
289
|
+
transformParameterProperty.apply (this, [options, 'parameter']);
|
|
290
|
+
return new PositionalValue(options);
|
|
291
|
+
}
|
|
292
|
+
case POSITIONAL_TYPE.VARIADIC: {
|
|
293
|
+
transformParameterProperty.apply (this, [options, 'parameters']);
|
|
294
|
+
return new PositionalVariadic(options);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
throw new Error ('Invalid positional argument type ' + type);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* @param {Array<Positional>} positionals - An array of Positional objects defining the expected argument slots.
|
|
302
|
+
* @param {Array<any>} values - The raw array of values received from the caller.
|
|
303
|
+
* @param {object} [options] - Optional settings to control the dispatch process.
|
|
304
|
+
* @param {boolean} [options.dispatched=false] - The {values} argument is already dispatched
|
|
305
|
+
* @param {boolean} [options.dispatchOnly=false] - If true, the function will only match values to positional slots and return the intermediate dispatch state, without creating the final result object. Useful for debugging.
|
|
306
|
+
* @param {boolean} [options.skipValidation=false] - If true, the system will bypass all internal validation checks (e.g., type coercion checks) during the argument processing phase.
|
|
307
|
+
* @returns {Proxy} A Proxy object that mimics an array-like structure for the collection of all received values.
|
|
308
|
+
* @throws {Error} If the number of values provided does not match the minimum required count, or if too many values are provided for the current structure.
|
|
309
|
+
*/
|
|
310
|
+
export function createPositionalArgumentResult(positionals, values, options) {
|
|
311
|
+
options = merge ({}, options);
|
|
312
|
+
const dispatched = options.dispatched
|
|
313
|
+
? Array.from (values)
|
|
314
|
+
: dispatchPositionalValues(positionals, values, options);
|
|
315
|
+
|
|
316
|
+
if (options.dispatchOnly) {
|
|
317
|
+
return dispatched;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
const object = {};
|
|
322
|
+
const array = [];
|
|
323
|
+
dispatched.forEach((e, i) => {
|
|
324
|
+
const p = positionals[i];
|
|
325
|
+
if (e.values.length == 0) {
|
|
326
|
+
if ('default' in p) {
|
|
327
|
+
e.values.push (p.default);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
if (e.property) {
|
|
331
|
+
object[e.property] = (p.type == POSITIONAL_TYPE.VALUE)
|
|
332
|
+
? e.values[0]
|
|
333
|
+
: e.values;
|
|
334
|
+
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
e.values.forEach (v => array.push (v));
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
return new Proxy ({
|
|
343
|
+
object,
|
|
344
|
+
array
|
|
345
|
+
}, {
|
|
346
|
+
has (o, k) {
|
|
347
|
+
return (k == 'length')
|
|
348
|
+
|| [Symbol.iterator,
|
|
349
|
+
'keys', 'entries', 'values',
|
|
350
|
+
'length'].includes (k);
|
|
351
|
+
},
|
|
352
|
+
get (o, k) {
|
|
353
|
+
if (k in o.object) {
|
|
354
|
+
return o.object[k];
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (typeof k === 'symbol') {
|
|
358
|
+
switch (k) {
|
|
359
|
+
case Symbol.iterator: return o.array[k];
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (!isNaN(k)) {
|
|
364
|
+
if (k < 0 || k >= o.array.length) {
|
|
365
|
+
throw new RangeError (k + ' is not a valid offset. Expected [0, ' + o.array.length + ']');
|
|
366
|
+
}
|
|
367
|
+
return o.array[k];
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
switch (k) {
|
|
372
|
+
case 'length':
|
|
373
|
+
case 'values': {
|
|
374
|
+
return o.array[k];
|
|
375
|
+
}
|
|
376
|
+
case 'entries':
|
|
377
|
+
case 'keys': {
|
|
378
|
+
return Object[k](o.object);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Dispatches raw values into the positional argument slots based on minimum requirements and maximum capacities.
|
|
387
|
+
* This function handles the core logic of matching inputs to defined slots.
|
|
388
|
+
* @param {Array<Positional>} positionals - The array of positional definitions.
|
|
389
|
+
* @param {Array<any>} values - The input array of raw values.
|
|
390
|
+
* @param {object} [options] - Optional parameters, including `skipValidation`.
|
|
391
|
+
* @returns {Array<{property: string, values: Array<any>}>} A list of intermediate dispatch objects, each containing the target property name and the collected values.
|
|
392
|
+
* @throws {Error} If the number of input values is insufficient (less than required minimum) or excessive.
|
|
393
|
+
*/
|
|
394
|
+
function dispatchPositionalValues (positionals, values, options) {
|
|
395
|
+
let min = 0;
|
|
396
|
+
const dispatched = [];
|
|
397
|
+
positionals.forEach (p => {
|
|
398
|
+
min += p.min;
|
|
399
|
+
dispatched.push ({
|
|
400
|
+
'property': p.property,
|
|
401
|
+
'values': []
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
if (values.length < min) {
|
|
406
|
+
const c = min - values.length;
|
|
407
|
+
throw new Error ('Missing ' + (min - values.length)
|
|
408
|
+
+ ' required positional argument' + ((c != 1) ? 's' : '') );
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (positionals.length == 0) {
|
|
412
|
+
if (values.length) {
|
|
413
|
+
throw new Error ('Too many positional argument values');
|
|
414
|
+
}
|
|
415
|
+
return dispatched;
|
|
416
|
+
}
|
|
417
|
+
if (values.length == 0) {
|
|
418
|
+
return dispatched;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
let sp = 0;
|
|
422
|
+
let ep = positionals.length - 1;
|
|
423
|
+
const P = Array.from (positionals);
|
|
424
|
+
const V = Array.from (values);
|
|
425
|
+
let p;
|
|
426
|
+
let v;
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
while (P.length
|
|
430
|
+
&& V.length
|
|
431
|
+
&& (p = P[0])
|
|
432
|
+
&& (dispatched[sp].values.length < p.min)
|
|
433
|
+
) {
|
|
434
|
+
v = V.shift();
|
|
435
|
+
if (!options.skipValidation) {
|
|
436
|
+
v = p.parse (v);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
dispatched[sp].values.push (v);
|
|
440
|
+
if (dispatched[sp].values.length >= p.min) {
|
|
441
|
+
P.shift();
|
|
442
|
+
++sp;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
while (P.length
|
|
448
|
+
&& V.length
|
|
449
|
+
&& (ep > sp)
|
|
450
|
+
&& (p = P[P.length - 1])
|
|
451
|
+
&& (dispatched[ep].values.length < p.min)
|
|
452
|
+
) {
|
|
453
|
+
v = V.pop();
|
|
454
|
+
dispatched[ep].values.push (v);
|
|
455
|
+
if (dispatched[ep].values.length >= p.min) {
|
|
456
|
+
P.pop();
|
|
457
|
+
--ep;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
while (P.length && V.length) {
|
|
463
|
+
if (dispatched[sp].values.length >= P[0].max) {
|
|
464
|
+
P.shift();
|
|
465
|
+
++sp;
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
dispatched[sp].values.push (V.shift());
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (V.length) {
|
|
472
|
+
throw new Error ('Too many positional argument values');
|
|
473
|
+
}
|
|
474
|
+
if (P.length) {
|
|
475
|
+
let remainingRequired = 0;
|
|
476
|
+
P.forEach(p => {
|
|
477
|
+
remainingRequired += p.min;
|
|
478
|
+
});
|
|
479
|
+
if (remainingRequired) {
|
|
480
|
+
throw new Error ('Too few positional argument values');
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return dispatched;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
export default {
|
|
488
|
+
Positional,
|
|
489
|
+
PositionalValue,
|
|
490
|
+
PositionalVariadic,
|
|
491
|
+
createPositional,
|
|
492
|
+
createPositionalArgumentResult,
|
|
493
|
+
};
|