@optique/core 1.0.0-dev.1536 → 1.0.0-dev.1553
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/dist/constructs.cjs +113 -5
- package/dist/constructs.js +113 -5
- package/dist/dependency.cjs +34 -0
- package/dist/dependency.js +34 -0
- package/dist/facade.cjs +5 -3
- package/dist/facade.js +6 -4
- package/dist/index.cjs +0 -3
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/modifiers.cjs +81 -9
- package/dist/modifiers.js +81 -9
- package/dist/parser.d.cts +58 -0
- package/dist/parser.d.ts +58 -0
- package/dist/primitives.cjs +52 -0
- package/dist/primitives.js +52 -0
- package/dist/usage.cjs +0 -194
- package/dist/usage.d.cts +1 -75
- package/dist/usage.d.ts +1 -75
- package/dist/usage.js +1 -192
- package/dist/validate.cjs +24 -13
- package/dist/validate.js +24 -13
- package/dist/valueparser.cjs +246 -30
- package/dist/valueparser.d.cts +27 -0
- package/dist/valueparser.d.ts +27 -0
- package/dist/valueparser.js +246 -30
- package/package.json +1 -1
package/dist/constructs.cjs
CHANGED
|
@@ -9,6 +9,43 @@ const require_suggestion = require('./suggestion.cjs');
|
|
|
9
9
|
const require_usage_internals = require('./usage-internals.cjs');
|
|
10
10
|
|
|
11
11
|
//#region src/constructs.ts
|
|
12
|
+
/**
|
|
13
|
+
* A shared empty set used as the `leadingNames` value for parsers that
|
|
14
|
+
* do not match any specific name at the first buffer position.
|
|
15
|
+
*/
|
|
16
|
+
const EMPTY_LEADING_NAMES = /* @__PURE__ */ new Set();
|
|
17
|
+
/**
|
|
18
|
+
* Computes the union of `leadingNames` from all given parsers.
|
|
19
|
+
* Used for alternative combinators (`or()`, `longestMatch()`) where all
|
|
20
|
+
* branches compete independently.
|
|
21
|
+
*/
|
|
22
|
+
function unionLeadingNames(parsers) {
|
|
23
|
+
const names = /* @__PURE__ */ new Set();
|
|
24
|
+
for (const p of parsers) for (const name of p.leadingNames) names.add(name);
|
|
25
|
+
return names.size === 0 ? EMPTY_LEADING_NAMES : names;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Computes `leadingNames` for shared-buffer compositions (`tuple()`,
|
|
29
|
+
* `object()`, `merge()`, `concat()`).
|
|
30
|
+
*
|
|
31
|
+
* Children are processed in descending priority order (matching the
|
|
32
|
+
* round-robin parse loop). Once a child with `acceptingAnyToken` is
|
|
33
|
+
* encountered, no lower-priority children can match at position 0, so
|
|
34
|
+
* their names are excluded.
|
|
35
|
+
*/
|
|
36
|
+
function sharedBufferLeadingNames(parsers) {
|
|
37
|
+
const sorted = parsers.toSorted((a, b) => b.priority - a.priority);
|
|
38
|
+
const names = /* @__PURE__ */ new Set();
|
|
39
|
+
let positionalBlocked = false;
|
|
40
|
+
for (const p of sorted) {
|
|
41
|
+
if (p.leadingNames) for (const name of p.leadingNames) {
|
|
42
|
+
if (positionalBlocked && !name.startsWith("-")) continue;
|
|
43
|
+
names.add(name);
|
|
44
|
+
}
|
|
45
|
+
if (p.acceptingAnyToken) positionalBlocked = true;
|
|
46
|
+
}
|
|
47
|
+
return names.size === 0 ? EMPTY_LEADING_NAMES : names;
|
|
48
|
+
}
|
|
12
49
|
const inheritParentAnnotationsKey = Symbol.for("@optique/core/inheritParentAnnotations");
|
|
13
50
|
/**
|
|
14
51
|
* Internal symbol for exposing field-level parser pairs from `object()`
|
|
@@ -454,7 +491,7 @@ function or(...args) {
|
|
|
454
491
|
success: false
|
|
455
492
|
};
|
|
456
493
|
};
|
|
457
|
-
|
|
494
|
+
const singleResult = {
|
|
458
495
|
$mode: combinedMode,
|
|
459
496
|
$valueType: [],
|
|
460
497
|
$stateType: [],
|
|
@@ -463,6 +500,8 @@ function or(...args) {
|
|
|
463
500
|
type: "exclusive",
|
|
464
501
|
terms: parsers.map((p) => p.usage)
|
|
465
502
|
}],
|
|
503
|
+
leadingNames: unionLeadingNames(parsers),
|
|
504
|
+
acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
|
|
466
505
|
initialState: void 0,
|
|
467
506
|
complete: createExclusiveComplete(parsers, options, noMatchContext, combinedMode),
|
|
468
507
|
parse(context) {
|
|
@@ -496,6 +535,7 @@ function or(...args) {
|
|
|
496
535
|
};
|
|
497
536
|
}
|
|
498
537
|
};
|
|
538
|
+
return singleResult;
|
|
499
539
|
}
|
|
500
540
|
/**
|
|
501
541
|
* @since 0.5.0
|
|
@@ -591,7 +631,7 @@ function longestMatch(...args) {
|
|
|
591
631
|
success: false
|
|
592
632
|
};
|
|
593
633
|
};
|
|
594
|
-
|
|
634
|
+
const multiResult = {
|
|
595
635
|
$mode: combinedMode,
|
|
596
636
|
$valueType: [],
|
|
597
637
|
$stateType: [],
|
|
@@ -600,6 +640,8 @@ function longestMatch(...args) {
|
|
|
600
640
|
type: "exclusive",
|
|
601
641
|
terms: parsers.map((p) => p.usage)
|
|
602
642
|
}],
|
|
643
|
+
leadingNames: unionLeadingNames(parsers),
|
|
644
|
+
acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
|
|
603
645
|
initialState: void 0,
|
|
604
646
|
complete: createExclusiveComplete(parsers, options, noMatchContext, combinedMode),
|
|
605
647
|
parse(context) {
|
|
@@ -640,6 +682,7 @@ function longestMatch(...args) {
|
|
|
640
682
|
};
|
|
641
683
|
}
|
|
642
684
|
};
|
|
685
|
+
return multiResult;
|
|
643
686
|
}
|
|
644
687
|
/**
|
|
645
688
|
* Internal sync helper for object suggest functionality.
|
|
@@ -1178,13 +1221,15 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1178
1221
|
success: false
|
|
1179
1222
|
};
|
|
1180
1223
|
};
|
|
1181
|
-
|
|
1224
|
+
const objectParser = {
|
|
1182
1225
|
$mode: combinedMode,
|
|
1183
1226
|
$valueType: [],
|
|
1184
1227
|
$stateType: [],
|
|
1185
1228
|
[fieldParsersKey]: parserPairs,
|
|
1186
1229
|
priority: Math.max(...parserKeys.map((k) => parsers[k].priority)),
|
|
1187
1230
|
usage: applyHiddenToUsage(parserPairs.flatMap(([_, p]) => p.usage), options.hidden),
|
|
1231
|
+
leadingNames: sharedBufferLeadingNames(parserPairs.map(([_, p]) => p)),
|
|
1232
|
+
acceptingAnyToken: parserPairs.some(([_, p]) => p.acceptingAnyToken),
|
|
1188
1233
|
get initialState() {
|
|
1189
1234
|
return createInitialState();
|
|
1190
1235
|
},
|
|
@@ -1380,6 +1425,28 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1380
1425
|
})) };
|
|
1381
1426
|
}
|
|
1382
1427
|
};
|
|
1428
|
+
const fieldNormalizers = [];
|
|
1429
|
+
for (const [key, fieldParser] of parserPairs) if (typeof fieldParser.normalizeValue === "function") fieldNormalizers.push([key, fieldParser.normalizeValue.bind(fieldParser)]);
|
|
1430
|
+
if (fieldNormalizers.length > 0) Object.defineProperty(objectParser, "normalizeValue", {
|
|
1431
|
+
value(obj) {
|
|
1432
|
+
if (typeof obj !== "object" || obj == null) return obj;
|
|
1433
|
+
let changed = false;
|
|
1434
|
+
let result;
|
|
1435
|
+
for (const [key, normalize] of fieldNormalizers) if (Object.hasOwn(obj, key)) try {
|
|
1436
|
+
const original = obj[key];
|
|
1437
|
+
const normalized = normalize(original);
|
|
1438
|
+
if (normalized !== original) {
|
|
1439
|
+
if (!result) result = { ...obj };
|
|
1440
|
+
result[key] = normalized;
|
|
1441
|
+
changed = true;
|
|
1442
|
+
}
|
|
1443
|
+
} catch {}
|
|
1444
|
+
return changed ? result : obj;
|
|
1445
|
+
},
|
|
1446
|
+
configurable: true,
|
|
1447
|
+
enumerable: false
|
|
1448
|
+
});
|
|
1449
|
+
return objectParser;
|
|
1383
1450
|
}
|
|
1384
1451
|
function suggestTupleSync(context, prefix, parsers) {
|
|
1385
1452
|
const suggestions = [];
|
|
@@ -1551,11 +1618,13 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1551
1618
|
consumed: allConsumed
|
|
1552
1619
|
};
|
|
1553
1620
|
};
|
|
1554
|
-
|
|
1621
|
+
const tupleParser = {
|
|
1555
1622
|
$mode: combinedMode,
|
|
1556
1623
|
$valueType: [],
|
|
1557
1624
|
$stateType: [],
|
|
1558
1625
|
usage: parsers.toSorted((a, b) => b.priority - a.priority).flatMap((p) => p.usage),
|
|
1626
|
+
leadingNames: sharedBufferLeadingNames(parsers),
|
|
1627
|
+
acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
|
|
1559
1628
|
priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
|
|
1560
1629
|
initialState: parsers.map((parser) => parser.initialState),
|
|
1561
1630
|
parse(context) {
|
|
@@ -1723,6 +1792,31 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1723
1792
|
return label ? `tuple(${JSON.stringify(label)}, ${parsersStr})` : `tuple(${parsersStr})`;
|
|
1724
1793
|
}
|
|
1725
1794
|
};
|
|
1795
|
+
const tupleNormalizers = [];
|
|
1796
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1797
|
+
const p = parsers[i];
|
|
1798
|
+
if (typeof p.normalizeValue === "function") tupleNormalizers.push([i, p.normalizeValue.bind(p)]);
|
|
1799
|
+
}
|
|
1800
|
+
if (tupleNormalizers.length > 0) Object.defineProperty(tupleParser, "normalizeValue", {
|
|
1801
|
+
value(arr) {
|
|
1802
|
+
if (!Array.isArray(arr)) return arr;
|
|
1803
|
+
let changed = false;
|
|
1804
|
+
let result;
|
|
1805
|
+
for (const [idx, normalize] of tupleNormalizers) if (idx < arr.length && Object.hasOwn(arr, idx)) try {
|
|
1806
|
+
const original = arr[idx];
|
|
1807
|
+
const normalized = normalize(original);
|
|
1808
|
+
if (normalized !== original) {
|
|
1809
|
+
if (!result) result = [...arr];
|
|
1810
|
+
result[idx] = normalized;
|
|
1811
|
+
changed = true;
|
|
1812
|
+
}
|
|
1813
|
+
} catch {}
|
|
1814
|
+
return changed ? result : arr;
|
|
1815
|
+
},
|
|
1816
|
+
configurable: true,
|
|
1817
|
+
enumerable: false
|
|
1818
|
+
});
|
|
1819
|
+
return tupleParser;
|
|
1726
1820
|
}
|
|
1727
1821
|
function merge(...args) {
|
|
1728
1822
|
const label = typeof args[0] === "string" ? args[0] : void 0;
|
|
@@ -1870,13 +1964,15 @@ function merge(...args) {
|
|
|
1870
1964
|
};
|
|
1871
1965
|
};
|
|
1872
1966
|
const mergedFieldParsers = collectChildFieldParsers(parsers);
|
|
1873
|
-
|
|
1967
|
+
const mergeParser = {
|
|
1874
1968
|
$mode: combinedMode,
|
|
1875
1969
|
$valueType: [],
|
|
1876
1970
|
$stateType: [],
|
|
1877
1971
|
[fieldParsersKey]: mergedFieldParsers,
|
|
1878
1972
|
priority: Math.max(...parsers.map((p) => p.priority)),
|
|
1879
1973
|
usage: applyHiddenToUsage(parsers.flatMap((p) => p.usage), options.hidden),
|
|
1974
|
+
leadingNames: sharedBufferLeadingNames(parsers),
|
|
1975
|
+
acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
|
|
1880
1976
|
initialState,
|
|
1881
1977
|
parse(context) {
|
|
1882
1978
|
if (isAsync) return parseAsync(context);
|
|
@@ -2087,6 +2183,7 @@ function merge(...args) {
|
|
|
2087
2183
|
};
|
|
2088
2184
|
}
|
|
2089
2185
|
};
|
|
2186
|
+
return mergeParser;
|
|
2090
2187
|
}
|
|
2091
2188
|
/**
|
|
2092
2189
|
* Builds a dependency registry from the pre-parsed context state and returns
|
|
@@ -2415,6 +2512,8 @@ function concat(...parsers) {
|
|
|
2415
2512
|
$stateType: [],
|
|
2416
2513
|
priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
|
|
2417
2514
|
usage: parsers.flatMap((p) => p.usage),
|
|
2515
|
+
leadingNames: sharedBufferLeadingNames(parsers),
|
|
2516
|
+
acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
|
|
2418
2517
|
initialState,
|
|
2419
2518
|
parse(context) {
|
|
2420
2519
|
if (isAsync) return parseAsync(context);
|
|
@@ -2492,6 +2591,8 @@ function group(label, parser, options = {}) {
|
|
|
2492
2591
|
$stateType: parser.$stateType,
|
|
2493
2592
|
priority: parser.priority,
|
|
2494
2593
|
usage: applyHiddenToUsage(parser.usage, options.hidden),
|
|
2594
|
+
leadingNames: parser.leadingNames,
|
|
2595
|
+
acceptingAnyToken: parser.acceptingAnyToken,
|
|
2495
2596
|
initialState: parser.initialState,
|
|
2496
2597
|
...fieldParsersKey in parser ? { [fieldParsersKey]: parser[fieldParsersKey] } : {},
|
|
2497
2598
|
...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: parser.shouldDeferCompletion.bind(parser) } : {},
|
|
@@ -2546,6 +2647,11 @@ function group(label, parser, options = {}) {
|
|
|
2546
2647
|
configurable: true,
|
|
2547
2648
|
enumerable: false
|
|
2548
2649
|
});
|
|
2650
|
+
if (typeof parser.normalizeValue === "function") Object.defineProperty(groupParser, "normalizeValue", {
|
|
2651
|
+
value: parser.normalizeValue.bind(parser),
|
|
2652
|
+
configurable: true,
|
|
2653
|
+
enumerable: false
|
|
2654
|
+
});
|
|
2549
2655
|
return groupParser;
|
|
2550
2656
|
}
|
|
2551
2657
|
/**
|
|
@@ -2976,6 +3082,8 @@ function conditional(discriminator, branches, defaultBranch, options) {
|
|
|
2976
3082
|
$stateType: [],
|
|
2977
3083
|
priority: maxPriority,
|
|
2978
3084
|
usage,
|
|
3085
|
+
leadingNames: defaultBranch ? unionLeadingNames([discriminator, defaultBranch]) : discriminator.leadingNames,
|
|
3086
|
+
acceptingAnyToken: defaultBranch?.acceptingAnyToken ?? false,
|
|
2979
3087
|
initialState,
|
|
2980
3088
|
parse(context) {
|
|
2981
3089
|
if (isAsync) return parseAsync(context);
|
package/dist/constructs.js
CHANGED
|
@@ -9,6 +9,43 @@ import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggest
|
|
|
9
9
|
import { collectLeadingCandidates } from "./usage-internals.js";
|
|
10
10
|
|
|
11
11
|
//#region src/constructs.ts
|
|
12
|
+
/**
|
|
13
|
+
* A shared empty set used as the `leadingNames` value for parsers that
|
|
14
|
+
* do not match any specific name at the first buffer position.
|
|
15
|
+
*/
|
|
16
|
+
const EMPTY_LEADING_NAMES = /* @__PURE__ */ new Set();
|
|
17
|
+
/**
|
|
18
|
+
* Computes the union of `leadingNames` from all given parsers.
|
|
19
|
+
* Used for alternative combinators (`or()`, `longestMatch()`) where all
|
|
20
|
+
* branches compete independently.
|
|
21
|
+
*/
|
|
22
|
+
function unionLeadingNames(parsers) {
|
|
23
|
+
const names = /* @__PURE__ */ new Set();
|
|
24
|
+
for (const p of parsers) for (const name of p.leadingNames) names.add(name);
|
|
25
|
+
return names.size === 0 ? EMPTY_LEADING_NAMES : names;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Computes `leadingNames` for shared-buffer compositions (`tuple()`,
|
|
29
|
+
* `object()`, `merge()`, `concat()`).
|
|
30
|
+
*
|
|
31
|
+
* Children are processed in descending priority order (matching the
|
|
32
|
+
* round-robin parse loop). Once a child with `acceptingAnyToken` is
|
|
33
|
+
* encountered, no lower-priority children can match at position 0, so
|
|
34
|
+
* their names are excluded.
|
|
35
|
+
*/
|
|
36
|
+
function sharedBufferLeadingNames(parsers) {
|
|
37
|
+
const sorted = parsers.toSorted((a, b) => b.priority - a.priority);
|
|
38
|
+
const names = /* @__PURE__ */ new Set();
|
|
39
|
+
let positionalBlocked = false;
|
|
40
|
+
for (const p of sorted) {
|
|
41
|
+
if (p.leadingNames) for (const name of p.leadingNames) {
|
|
42
|
+
if (positionalBlocked && !name.startsWith("-")) continue;
|
|
43
|
+
names.add(name);
|
|
44
|
+
}
|
|
45
|
+
if (p.acceptingAnyToken) positionalBlocked = true;
|
|
46
|
+
}
|
|
47
|
+
return names.size === 0 ? EMPTY_LEADING_NAMES : names;
|
|
48
|
+
}
|
|
12
49
|
const inheritParentAnnotationsKey = Symbol.for("@optique/core/inheritParentAnnotations");
|
|
13
50
|
/**
|
|
14
51
|
* Internal symbol for exposing field-level parser pairs from `object()`
|
|
@@ -454,7 +491,7 @@ function or(...args) {
|
|
|
454
491
|
success: false
|
|
455
492
|
};
|
|
456
493
|
};
|
|
457
|
-
|
|
494
|
+
const singleResult = {
|
|
458
495
|
$mode: combinedMode,
|
|
459
496
|
$valueType: [],
|
|
460
497
|
$stateType: [],
|
|
@@ -463,6 +500,8 @@ function or(...args) {
|
|
|
463
500
|
type: "exclusive",
|
|
464
501
|
terms: parsers.map((p) => p.usage)
|
|
465
502
|
}],
|
|
503
|
+
leadingNames: unionLeadingNames(parsers),
|
|
504
|
+
acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
|
|
466
505
|
initialState: void 0,
|
|
467
506
|
complete: createExclusiveComplete(parsers, options, noMatchContext, combinedMode),
|
|
468
507
|
parse(context) {
|
|
@@ -496,6 +535,7 @@ function or(...args) {
|
|
|
496
535
|
};
|
|
497
536
|
}
|
|
498
537
|
};
|
|
538
|
+
return singleResult;
|
|
499
539
|
}
|
|
500
540
|
/**
|
|
501
541
|
* @since 0.5.0
|
|
@@ -591,7 +631,7 @@ function longestMatch(...args) {
|
|
|
591
631
|
success: false
|
|
592
632
|
};
|
|
593
633
|
};
|
|
594
|
-
|
|
634
|
+
const multiResult = {
|
|
595
635
|
$mode: combinedMode,
|
|
596
636
|
$valueType: [],
|
|
597
637
|
$stateType: [],
|
|
@@ -600,6 +640,8 @@ function longestMatch(...args) {
|
|
|
600
640
|
type: "exclusive",
|
|
601
641
|
terms: parsers.map((p) => p.usage)
|
|
602
642
|
}],
|
|
643
|
+
leadingNames: unionLeadingNames(parsers),
|
|
644
|
+
acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
|
|
603
645
|
initialState: void 0,
|
|
604
646
|
complete: createExclusiveComplete(parsers, options, noMatchContext, combinedMode),
|
|
605
647
|
parse(context) {
|
|
@@ -640,6 +682,7 @@ function longestMatch(...args) {
|
|
|
640
682
|
};
|
|
641
683
|
}
|
|
642
684
|
};
|
|
685
|
+
return multiResult;
|
|
643
686
|
}
|
|
644
687
|
/**
|
|
645
688
|
* Internal sync helper for object suggest functionality.
|
|
@@ -1178,13 +1221,15 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1178
1221
|
success: false
|
|
1179
1222
|
};
|
|
1180
1223
|
};
|
|
1181
|
-
|
|
1224
|
+
const objectParser = {
|
|
1182
1225
|
$mode: combinedMode,
|
|
1183
1226
|
$valueType: [],
|
|
1184
1227
|
$stateType: [],
|
|
1185
1228
|
[fieldParsersKey]: parserPairs,
|
|
1186
1229
|
priority: Math.max(...parserKeys.map((k) => parsers[k].priority)),
|
|
1187
1230
|
usage: applyHiddenToUsage(parserPairs.flatMap(([_, p]) => p.usage), options.hidden),
|
|
1231
|
+
leadingNames: sharedBufferLeadingNames(parserPairs.map(([_, p]) => p)),
|
|
1232
|
+
acceptingAnyToken: parserPairs.some(([_, p]) => p.acceptingAnyToken),
|
|
1188
1233
|
get initialState() {
|
|
1189
1234
|
return createInitialState();
|
|
1190
1235
|
},
|
|
@@ -1380,6 +1425,28 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1380
1425
|
})) };
|
|
1381
1426
|
}
|
|
1382
1427
|
};
|
|
1428
|
+
const fieldNormalizers = [];
|
|
1429
|
+
for (const [key, fieldParser] of parserPairs) if (typeof fieldParser.normalizeValue === "function") fieldNormalizers.push([key, fieldParser.normalizeValue.bind(fieldParser)]);
|
|
1430
|
+
if (fieldNormalizers.length > 0) Object.defineProperty(objectParser, "normalizeValue", {
|
|
1431
|
+
value(obj) {
|
|
1432
|
+
if (typeof obj !== "object" || obj == null) return obj;
|
|
1433
|
+
let changed = false;
|
|
1434
|
+
let result;
|
|
1435
|
+
for (const [key, normalize] of fieldNormalizers) if (Object.hasOwn(obj, key)) try {
|
|
1436
|
+
const original = obj[key];
|
|
1437
|
+
const normalized = normalize(original);
|
|
1438
|
+
if (normalized !== original) {
|
|
1439
|
+
if (!result) result = { ...obj };
|
|
1440
|
+
result[key] = normalized;
|
|
1441
|
+
changed = true;
|
|
1442
|
+
}
|
|
1443
|
+
} catch {}
|
|
1444
|
+
return changed ? result : obj;
|
|
1445
|
+
},
|
|
1446
|
+
configurable: true,
|
|
1447
|
+
enumerable: false
|
|
1448
|
+
});
|
|
1449
|
+
return objectParser;
|
|
1383
1450
|
}
|
|
1384
1451
|
function suggestTupleSync(context, prefix, parsers) {
|
|
1385
1452
|
const suggestions = [];
|
|
@@ -1551,11 +1618,13 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1551
1618
|
consumed: allConsumed
|
|
1552
1619
|
};
|
|
1553
1620
|
};
|
|
1554
|
-
|
|
1621
|
+
const tupleParser = {
|
|
1555
1622
|
$mode: combinedMode,
|
|
1556
1623
|
$valueType: [],
|
|
1557
1624
|
$stateType: [],
|
|
1558
1625
|
usage: parsers.toSorted((a, b) => b.priority - a.priority).flatMap((p) => p.usage),
|
|
1626
|
+
leadingNames: sharedBufferLeadingNames(parsers),
|
|
1627
|
+
acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
|
|
1559
1628
|
priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
|
|
1560
1629
|
initialState: parsers.map((parser) => parser.initialState),
|
|
1561
1630
|
parse(context) {
|
|
@@ -1723,6 +1792,31 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1723
1792
|
return label ? `tuple(${JSON.stringify(label)}, ${parsersStr})` : `tuple(${parsersStr})`;
|
|
1724
1793
|
}
|
|
1725
1794
|
};
|
|
1795
|
+
const tupleNormalizers = [];
|
|
1796
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1797
|
+
const p = parsers[i];
|
|
1798
|
+
if (typeof p.normalizeValue === "function") tupleNormalizers.push([i, p.normalizeValue.bind(p)]);
|
|
1799
|
+
}
|
|
1800
|
+
if (tupleNormalizers.length > 0) Object.defineProperty(tupleParser, "normalizeValue", {
|
|
1801
|
+
value(arr) {
|
|
1802
|
+
if (!Array.isArray(arr)) return arr;
|
|
1803
|
+
let changed = false;
|
|
1804
|
+
let result;
|
|
1805
|
+
for (const [idx, normalize] of tupleNormalizers) if (idx < arr.length && Object.hasOwn(arr, idx)) try {
|
|
1806
|
+
const original = arr[idx];
|
|
1807
|
+
const normalized = normalize(original);
|
|
1808
|
+
if (normalized !== original) {
|
|
1809
|
+
if (!result) result = [...arr];
|
|
1810
|
+
result[idx] = normalized;
|
|
1811
|
+
changed = true;
|
|
1812
|
+
}
|
|
1813
|
+
} catch {}
|
|
1814
|
+
return changed ? result : arr;
|
|
1815
|
+
},
|
|
1816
|
+
configurable: true,
|
|
1817
|
+
enumerable: false
|
|
1818
|
+
});
|
|
1819
|
+
return tupleParser;
|
|
1726
1820
|
}
|
|
1727
1821
|
function merge(...args) {
|
|
1728
1822
|
const label = typeof args[0] === "string" ? args[0] : void 0;
|
|
@@ -1870,13 +1964,15 @@ function merge(...args) {
|
|
|
1870
1964
|
};
|
|
1871
1965
|
};
|
|
1872
1966
|
const mergedFieldParsers = collectChildFieldParsers(parsers);
|
|
1873
|
-
|
|
1967
|
+
const mergeParser = {
|
|
1874
1968
|
$mode: combinedMode,
|
|
1875
1969
|
$valueType: [],
|
|
1876
1970
|
$stateType: [],
|
|
1877
1971
|
[fieldParsersKey]: mergedFieldParsers,
|
|
1878
1972
|
priority: Math.max(...parsers.map((p) => p.priority)),
|
|
1879
1973
|
usage: applyHiddenToUsage(parsers.flatMap((p) => p.usage), options.hidden),
|
|
1974
|
+
leadingNames: sharedBufferLeadingNames(parsers),
|
|
1975
|
+
acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
|
|
1880
1976
|
initialState,
|
|
1881
1977
|
parse(context) {
|
|
1882
1978
|
if (isAsync) return parseAsync(context);
|
|
@@ -2087,6 +2183,7 @@ function merge(...args) {
|
|
|
2087
2183
|
};
|
|
2088
2184
|
}
|
|
2089
2185
|
};
|
|
2186
|
+
return mergeParser;
|
|
2090
2187
|
}
|
|
2091
2188
|
/**
|
|
2092
2189
|
* Builds a dependency registry from the pre-parsed context state and returns
|
|
@@ -2415,6 +2512,8 @@ function concat(...parsers) {
|
|
|
2415
2512
|
$stateType: [],
|
|
2416
2513
|
priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
|
|
2417
2514
|
usage: parsers.flatMap((p) => p.usage),
|
|
2515
|
+
leadingNames: sharedBufferLeadingNames(parsers),
|
|
2516
|
+
acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
|
|
2418
2517
|
initialState,
|
|
2419
2518
|
parse(context) {
|
|
2420
2519
|
if (isAsync) return parseAsync(context);
|
|
@@ -2492,6 +2591,8 @@ function group(label, parser, options = {}) {
|
|
|
2492
2591
|
$stateType: parser.$stateType,
|
|
2493
2592
|
priority: parser.priority,
|
|
2494
2593
|
usage: applyHiddenToUsage(parser.usage, options.hidden),
|
|
2594
|
+
leadingNames: parser.leadingNames,
|
|
2595
|
+
acceptingAnyToken: parser.acceptingAnyToken,
|
|
2495
2596
|
initialState: parser.initialState,
|
|
2496
2597
|
...fieldParsersKey in parser ? { [fieldParsersKey]: parser[fieldParsersKey] } : {},
|
|
2497
2598
|
...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: parser.shouldDeferCompletion.bind(parser) } : {},
|
|
@@ -2546,6 +2647,11 @@ function group(label, parser, options = {}) {
|
|
|
2546
2647
|
configurable: true,
|
|
2547
2648
|
enumerable: false
|
|
2548
2649
|
});
|
|
2650
|
+
if (typeof parser.normalizeValue === "function") Object.defineProperty(groupParser, "normalizeValue", {
|
|
2651
|
+
value: parser.normalizeValue.bind(parser),
|
|
2652
|
+
configurable: true,
|
|
2653
|
+
enumerable: false
|
|
2654
|
+
});
|
|
2549
2655
|
return groupParser;
|
|
2550
2656
|
}
|
|
2551
2657
|
/**
|
|
@@ -2976,6 +3082,8 @@ function conditional(discriminator, branches, defaultBranch, options) {
|
|
|
2976
3082
|
$stateType: [],
|
|
2977
3083
|
priority: maxPriority,
|
|
2978
3084
|
usage,
|
|
3085
|
+
leadingNames: defaultBranch ? unionLeadingNames([discriminator, defaultBranch]) : discriminator.leadingNames,
|
|
3086
|
+
acceptingAnyToken: defaultBranch?.acceptingAnyToken ?? false,
|
|
2979
3087
|
initialState,
|
|
2980
3088
|
parse(context) {
|
|
2981
3089
|
if (isAsync) return parseAsync(context);
|
package/dist/dependency.cjs
CHANGED
|
@@ -199,6 +199,25 @@ function deriveFromAsync(options) {
|
|
|
199
199
|
function isAsyncModeParser(parser) {
|
|
200
200
|
return parser.$mode === "async";
|
|
201
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Shared helper for derived value parser `normalize()` implementations.
|
|
204
|
+
* Builds the inner parser from the factory and delegates to its
|
|
205
|
+
* `normalize()` if available, falling back to the original value on error.
|
|
206
|
+
*/
|
|
207
|
+
function normalizeWithDerivedParser(value, getParser) {
|
|
208
|
+
let derivedParser;
|
|
209
|
+
try {
|
|
210
|
+
derivedParser = getParser();
|
|
211
|
+
} catch {
|
|
212
|
+
return value;
|
|
213
|
+
}
|
|
214
|
+
if (derivedParser && typeof derivedParser.normalize === "function") try {
|
|
215
|
+
return derivedParser.normalize(value);
|
|
216
|
+
} catch {
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
219
|
+
return value;
|
|
220
|
+
}
|
|
202
221
|
function createSyncDerivedFromParser(sourceId, options) {
|
|
203
222
|
const alldependencyIds = options.dependencies.map((dep) => dep[dependencyId]);
|
|
204
223
|
return {
|
|
@@ -271,6 +290,9 @@ function createSyncDerivedFromParser(sourceId, options) {
|
|
|
271
290
|
if (isAsyncModeParser(derivedParser) || !derivedParser.suggest) return;
|
|
272
291
|
yield* derivedParser.suggest(prefix);
|
|
273
292
|
},
|
|
293
|
+
normalize(value) {
|
|
294
|
+
return normalizeWithDerivedParser(value, () => options.factory(...options.defaultValues()));
|
|
295
|
+
},
|
|
274
296
|
*[suggestWithDependency](prefix, dependencyValue) {
|
|
275
297
|
let derivedParser;
|
|
276
298
|
try {
|
|
@@ -345,6 +367,9 @@ function createAsyncDerivedFromParserFromAsyncFactory(sourceId, options) {
|
|
|
345
367
|
}
|
|
346
368
|
return derivedParser.format(value);
|
|
347
369
|
},
|
|
370
|
+
normalize(value) {
|
|
371
|
+
return normalizeWithDerivedParser(value, () => options.factory(...options.defaultValues()));
|
|
372
|
+
},
|
|
348
373
|
async *suggest(prefix) {
|
|
349
374
|
let derivedParser;
|
|
350
375
|
try {
|
|
@@ -428,6 +453,9 @@ function createAsyncDerivedFromParserFromSyncFactory(sourceId, options) {
|
|
|
428
453
|
}
|
|
429
454
|
return derivedParser.format(value);
|
|
430
455
|
},
|
|
456
|
+
normalize(value) {
|
|
457
|
+
return normalizeWithDerivedParser(value, () => options.factory(...options.defaultValues()));
|
|
458
|
+
},
|
|
431
459
|
async *suggest(prefix) {
|
|
432
460
|
let derivedParser;
|
|
433
461
|
try {
|
|
@@ -521,6 +549,9 @@ function createSyncDerivedParser(sourceId, options) {
|
|
|
521
549
|
}
|
|
522
550
|
return derivedParser.format(value);
|
|
523
551
|
},
|
|
552
|
+
normalize(value) {
|
|
553
|
+
return normalizeWithDerivedParser(value, () => options.factory(options.defaultValue()));
|
|
554
|
+
},
|
|
524
555
|
*suggest(prefix) {
|
|
525
556
|
let derivedParser;
|
|
526
557
|
try {
|
|
@@ -681,6 +712,9 @@ function createAsyncDerivedParserFromSyncFactory(sourceId, options) {
|
|
|
681
712
|
}
|
|
682
713
|
return derivedParser.format(value);
|
|
683
714
|
},
|
|
715
|
+
normalize(value) {
|
|
716
|
+
return normalizeWithDerivedParser(value, () => options.factory(options.defaultValue()));
|
|
717
|
+
},
|
|
684
718
|
async *suggest(prefix) {
|
|
685
719
|
let derivedParser;
|
|
686
720
|
try {
|
package/dist/dependency.js
CHANGED
|
@@ -199,6 +199,25 @@ function deriveFromAsync(options) {
|
|
|
199
199
|
function isAsyncModeParser(parser) {
|
|
200
200
|
return parser.$mode === "async";
|
|
201
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Shared helper for derived value parser `normalize()` implementations.
|
|
204
|
+
* Builds the inner parser from the factory and delegates to its
|
|
205
|
+
* `normalize()` if available, falling back to the original value on error.
|
|
206
|
+
*/
|
|
207
|
+
function normalizeWithDerivedParser(value, getParser) {
|
|
208
|
+
let derivedParser;
|
|
209
|
+
try {
|
|
210
|
+
derivedParser = getParser();
|
|
211
|
+
} catch {
|
|
212
|
+
return value;
|
|
213
|
+
}
|
|
214
|
+
if (derivedParser && typeof derivedParser.normalize === "function") try {
|
|
215
|
+
return derivedParser.normalize(value);
|
|
216
|
+
} catch {
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
219
|
+
return value;
|
|
220
|
+
}
|
|
202
221
|
function createSyncDerivedFromParser(sourceId, options) {
|
|
203
222
|
const alldependencyIds = options.dependencies.map((dep) => dep[dependencyId]);
|
|
204
223
|
return {
|
|
@@ -271,6 +290,9 @@ function createSyncDerivedFromParser(sourceId, options) {
|
|
|
271
290
|
if (isAsyncModeParser(derivedParser) || !derivedParser.suggest) return;
|
|
272
291
|
yield* derivedParser.suggest(prefix);
|
|
273
292
|
},
|
|
293
|
+
normalize(value) {
|
|
294
|
+
return normalizeWithDerivedParser(value, () => options.factory(...options.defaultValues()));
|
|
295
|
+
},
|
|
274
296
|
*[suggestWithDependency](prefix, dependencyValue) {
|
|
275
297
|
let derivedParser;
|
|
276
298
|
try {
|
|
@@ -345,6 +367,9 @@ function createAsyncDerivedFromParserFromAsyncFactory(sourceId, options) {
|
|
|
345
367
|
}
|
|
346
368
|
return derivedParser.format(value);
|
|
347
369
|
},
|
|
370
|
+
normalize(value) {
|
|
371
|
+
return normalizeWithDerivedParser(value, () => options.factory(...options.defaultValues()));
|
|
372
|
+
},
|
|
348
373
|
async *suggest(prefix) {
|
|
349
374
|
let derivedParser;
|
|
350
375
|
try {
|
|
@@ -428,6 +453,9 @@ function createAsyncDerivedFromParserFromSyncFactory(sourceId, options) {
|
|
|
428
453
|
}
|
|
429
454
|
return derivedParser.format(value);
|
|
430
455
|
},
|
|
456
|
+
normalize(value) {
|
|
457
|
+
return normalizeWithDerivedParser(value, () => options.factory(...options.defaultValues()));
|
|
458
|
+
},
|
|
431
459
|
async *suggest(prefix) {
|
|
432
460
|
let derivedParser;
|
|
433
461
|
try {
|
|
@@ -521,6 +549,9 @@ function createSyncDerivedParser(sourceId, options) {
|
|
|
521
549
|
}
|
|
522
550
|
return derivedParser.format(value);
|
|
523
551
|
},
|
|
552
|
+
normalize(value) {
|
|
553
|
+
return normalizeWithDerivedParser(value, () => options.factory(options.defaultValue()));
|
|
554
|
+
},
|
|
524
555
|
*suggest(prefix) {
|
|
525
556
|
let derivedParser;
|
|
526
557
|
try {
|
|
@@ -681,6 +712,9 @@ function createAsyncDerivedParserFromSyncFactory(sourceId, options) {
|
|
|
681
712
|
}
|
|
682
713
|
return derivedParser.format(value);
|
|
683
714
|
},
|
|
715
|
+
normalize(value) {
|
|
716
|
+
return normalizeWithDerivedParser(value, () => options.factory(options.defaultValue()));
|
|
717
|
+
},
|
|
684
718
|
async *suggest(prefix) {
|
|
685
719
|
let derivedParser;
|
|
686
720
|
try {
|
package/dist/facade.cjs
CHANGED
|
@@ -196,6 +196,8 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
196
196
|
$stateType: [],
|
|
197
197
|
priority: 200,
|
|
198
198
|
usage: helpParsers.helpOption.usage,
|
|
199
|
+
leadingNames: helpParsers.helpOption.leadingNames,
|
|
200
|
+
acceptingAnyToken: false,
|
|
199
201
|
initialState: null,
|
|
200
202
|
parse(context) {
|
|
201
203
|
const { buffer, optionsTerminated } = context;
|
|
@@ -275,6 +277,8 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
275
277
|
$stateType: [],
|
|
276
278
|
priority: 200,
|
|
277
279
|
usage: versionParsers.versionOption.usage,
|
|
280
|
+
leadingNames: versionParsers.versionOption.leadingNames,
|
|
281
|
+
acceptingAnyToken: false,
|
|
278
282
|
initialState: null,
|
|
279
283
|
parse(context) {
|
|
280
284
|
const { buffer, optionsTerminated } = context;
|
|
@@ -620,9 +624,7 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
620
624
|
completionCommandNames
|
|
621
625
|
]);
|
|
622
626
|
require_validate.validateMetaNameCollisions({
|
|
623
|
-
|
|
624
|
-
leadingCommands: require_usage.extractLeadingCommandNames(parser.usage, true),
|
|
625
|
-
leadingLiterals: require_usage.extractLeadingLiteralValues(parser.usage),
|
|
627
|
+
leadingNames: parser.leadingNames,
|
|
626
628
|
allOptions: require_usage.extractOptionNames(parser.usage, true),
|
|
627
629
|
allCommands: require_usage.extractCommandNames(parser.usage, true),
|
|
628
630
|
allLiterals: require_usage.extractLiteralValues(parser.usage)
|