@optique/core 1.0.0-dev.1758 → 1.0.0-dev.1772
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/annotations.cjs +19 -0
- package/dist/annotations.d.cts +16 -1
- package/dist/annotations.d.ts +16 -1
- package/dist/annotations.js +19 -1
- package/dist/constructs.cjs +5 -0
- package/dist/constructs.js +5 -0
- package/dist/modifiers.cjs +96 -0
- package/dist/modifiers.js +97 -1
- package/dist/parser.cjs +3 -3
- package/dist/parser.d.cts +44 -0
- package/dist/parser.d.ts +44 -0
- package/dist/parser.js +4 -4
- package/dist/primitives.cjs +79 -2
- package/dist/primitives.js +80 -3
- package/package.json +1 -1
package/dist/annotations.cjs
CHANGED
|
@@ -131,6 +131,21 @@ function inheritAnnotations(source, target) {
|
|
|
131
131
|
return cloned;
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
134
|
+
* Returns whether an annotations record carries at least one own symbol key.
|
|
135
|
+
*
|
|
136
|
+
* An annotations object with no own symbol keys is treated as a no-op by the
|
|
137
|
+
* injection pipeline: it should behave identically to omitting the
|
|
138
|
+
* `annotations` option entirely. `null` and `undefined` are accepted for
|
|
139
|
+
* call-site convenience and always return `false`.
|
|
140
|
+
*
|
|
141
|
+
* @param annotations The annotations record to check.
|
|
142
|
+
* @returns `true` when the record has at least one own symbol key.
|
|
143
|
+
* @internal
|
|
144
|
+
*/
|
|
145
|
+
function hasMeaningfulAnnotations(annotations) {
|
|
146
|
+
return annotations != null && Object.getOwnPropertySymbols(annotations).length > 0;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
134
149
|
* Injects annotations into parser state while preserving state shape.
|
|
135
150
|
*
|
|
136
151
|
* - Primitive, null, and undefined states are wrapped with internal metadata.
|
|
@@ -138,6 +153,8 @@ function inheritAnnotations(source, target) {
|
|
|
138
153
|
* - Plain object states are shallow-cloned with annotations attached.
|
|
139
154
|
* - Built-in object states (Date/Map/Set/RegExp) are cloned by constructor.
|
|
140
155
|
* - Other non-plain object states are cloned via prototype/descriptors.
|
|
156
|
+
* - If the `annotations` record has no own symbol keys, the state is
|
|
157
|
+
* returned unchanged; an empty annotations object is a no-op.
|
|
141
158
|
*
|
|
142
159
|
* @param state The parser state to annotate.
|
|
143
160
|
* @param annotations The annotations to inject.
|
|
@@ -145,6 +162,7 @@ function inheritAnnotations(source, target) {
|
|
|
145
162
|
* @internal
|
|
146
163
|
*/
|
|
147
164
|
function injectAnnotations(state, annotations) {
|
|
165
|
+
if (!hasMeaningfulAnnotations(annotations)) return state;
|
|
148
166
|
if (state == null || typeof state !== "object") {
|
|
149
167
|
const wrapper = {};
|
|
150
168
|
Object.defineProperties(wrapper, {
|
|
@@ -243,6 +261,7 @@ exports.annotationStateValueKey = annotationStateValueKey;
|
|
|
243
261
|
exports.annotationWrapperKey = annotationWrapperKey;
|
|
244
262
|
exports.firstPassAnnotationKey = firstPassAnnotationKey;
|
|
245
263
|
exports.getAnnotations = getAnnotations;
|
|
264
|
+
exports.hasMeaningfulAnnotations = hasMeaningfulAnnotations;
|
|
246
265
|
exports.inheritAnnotations = inheritAnnotations;
|
|
247
266
|
exports.injectAnnotations = injectAnnotations;
|
|
248
267
|
exports.isInjectedAnnotationWrapper = isInjectedAnnotationWrapper;
|
package/dist/annotations.d.cts
CHANGED
|
@@ -100,6 +100,19 @@ declare function annotateFreshArray<T>(source: unknown, target: readonly T[]): r
|
|
|
100
100
|
* @internal
|
|
101
101
|
*/
|
|
102
102
|
declare function inheritAnnotations<T>(source: unknown, target: T): T;
|
|
103
|
+
/**
|
|
104
|
+
* Returns whether an annotations record carries at least one own symbol key.
|
|
105
|
+
*
|
|
106
|
+
* An annotations object with no own symbol keys is treated as a no-op by the
|
|
107
|
+
* injection pipeline: it should behave identically to omitting the
|
|
108
|
+
* `annotations` option entirely. `null` and `undefined` are accepted for
|
|
109
|
+
* call-site convenience and always return `false`.
|
|
110
|
+
*
|
|
111
|
+
* @param annotations The annotations record to check.
|
|
112
|
+
* @returns `true` when the record has at least one own symbol key.
|
|
113
|
+
* @internal
|
|
114
|
+
*/
|
|
115
|
+
declare function hasMeaningfulAnnotations(annotations: Annotations | null | undefined): annotations is Annotations;
|
|
103
116
|
/**
|
|
104
117
|
* Injects annotations into parser state while preserving state shape.
|
|
105
118
|
*
|
|
@@ -108,6 +121,8 @@ declare function inheritAnnotations<T>(source: unknown, target: T): T;
|
|
|
108
121
|
* - Plain object states are shallow-cloned with annotations attached.
|
|
109
122
|
* - Built-in object states (Date/Map/Set/RegExp) are cloned by constructor.
|
|
110
123
|
* - Other non-plain object states are cloned via prototype/descriptors.
|
|
124
|
+
* - If the `annotations` record has no own symbol keys, the state is
|
|
125
|
+
* returned unchanged; an empty annotations object is a no-op.
|
|
111
126
|
*
|
|
112
127
|
* @param state The parser state to annotate.
|
|
113
128
|
* @param annotations The annotations to inject.
|
|
@@ -134,4 +149,4 @@ declare function unwrapInjectedAnnotationWrapper<T>(value: T): T;
|
|
|
134
149
|
*/
|
|
135
150
|
declare function isInjectedAnnotationWrapper(value: unknown): boolean;
|
|
136
151
|
//#endregion
|
|
137
|
-
export { Annotations, ParseOptions, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
|
152
|
+
export { Annotations, ParseOptions, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, hasMeaningfulAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
package/dist/annotations.d.ts
CHANGED
|
@@ -100,6 +100,19 @@ declare function annotateFreshArray<T>(source: unknown, target: readonly T[]): r
|
|
|
100
100
|
* @internal
|
|
101
101
|
*/
|
|
102
102
|
declare function inheritAnnotations<T>(source: unknown, target: T): T;
|
|
103
|
+
/**
|
|
104
|
+
* Returns whether an annotations record carries at least one own symbol key.
|
|
105
|
+
*
|
|
106
|
+
* An annotations object with no own symbol keys is treated as a no-op by the
|
|
107
|
+
* injection pipeline: it should behave identically to omitting the
|
|
108
|
+
* `annotations` option entirely. `null` and `undefined` are accepted for
|
|
109
|
+
* call-site convenience and always return `false`.
|
|
110
|
+
*
|
|
111
|
+
* @param annotations The annotations record to check.
|
|
112
|
+
* @returns `true` when the record has at least one own symbol key.
|
|
113
|
+
* @internal
|
|
114
|
+
*/
|
|
115
|
+
declare function hasMeaningfulAnnotations(annotations: Annotations | null | undefined): annotations is Annotations;
|
|
103
116
|
/**
|
|
104
117
|
* Injects annotations into parser state while preserving state shape.
|
|
105
118
|
*
|
|
@@ -108,6 +121,8 @@ declare function inheritAnnotations<T>(source: unknown, target: T): T;
|
|
|
108
121
|
* - Plain object states are shallow-cloned with annotations attached.
|
|
109
122
|
* - Built-in object states (Date/Map/Set/RegExp) are cloned by constructor.
|
|
110
123
|
* - Other non-plain object states are cloned via prototype/descriptors.
|
|
124
|
+
* - If the `annotations` record has no own symbol keys, the state is
|
|
125
|
+
* returned unchanged; an empty annotations object is a no-op.
|
|
111
126
|
*
|
|
112
127
|
* @param state The parser state to annotate.
|
|
113
128
|
* @param annotations The annotations to inject.
|
|
@@ -134,4 +149,4 @@ declare function unwrapInjectedAnnotationWrapper<T>(value: T): T;
|
|
|
134
149
|
*/
|
|
135
150
|
declare function isInjectedAnnotationWrapper(value: unknown): boolean;
|
|
136
151
|
//#endregion
|
|
137
|
-
export { Annotations, ParseOptions, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
|
152
|
+
export { Annotations, ParseOptions, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, hasMeaningfulAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
package/dist/annotations.js
CHANGED
|
@@ -130,6 +130,21 @@ function inheritAnnotations(source, target) {
|
|
|
130
130
|
return cloned;
|
|
131
131
|
}
|
|
132
132
|
/**
|
|
133
|
+
* Returns whether an annotations record carries at least one own symbol key.
|
|
134
|
+
*
|
|
135
|
+
* An annotations object with no own symbol keys is treated as a no-op by the
|
|
136
|
+
* injection pipeline: it should behave identically to omitting the
|
|
137
|
+
* `annotations` option entirely. `null` and `undefined` are accepted for
|
|
138
|
+
* call-site convenience and always return `false`.
|
|
139
|
+
*
|
|
140
|
+
* @param annotations The annotations record to check.
|
|
141
|
+
* @returns `true` when the record has at least one own symbol key.
|
|
142
|
+
* @internal
|
|
143
|
+
*/
|
|
144
|
+
function hasMeaningfulAnnotations(annotations) {
|
|
145
|
+
return annotations != null && Object.getOwnPropertySymbols(annotations).length > 0;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
133
148
|
* Injects annotations into parser state while preserving state shape.
|
|
134
149
|
*
|
|
135
150
|
* - Primitive, null, and undefined states are wrapped with internal metadata.
|
|
@@ -137,6 +152,8 @@ function inheritAnnotations(source, target) {
|
|
|
137
152
|
* - Plain object states are shallow-cloned with annotations attached.
|
|
138
153
|
* - Built-in object states (Date/Map/Set/RegExp) are cloned by constructor.
|
|
139
154
|
* - Other non-plain object states are cloned via prototype/descriptors.
|
|
155
|
+
* - If the `annotations` record has no own symbol keys, the state is
|
|
156
|
+
* returned unchanged; an empty annotations object is a no-op.
|
|
140
157
|
*
|
|
141
158
|
* @param state The parser state to annotate.
|
|
142
159
|
* @param annotations The annotations to inject.
|
|
@@ -144,6 +161,7 @@ function inheritAnnotations(source, target) {
|
|
|
144
161
|
* @internal
|
|
145
162
|
*/
|
|
146
163
|
function injectAnnotations(state, annotations) {
|
|
164
|
+
if (!hasMeaningfulAnnotations(annotations)) return state;
|
|
147
165
|
if (state == null || typeof state !== "object") {
|
|
148
166
|
const wrapper = {};
|
|
149
167
|
Object.defineProperties(wrapper, {
|
|
@@ -236,4 +254,4 @@ function isInjectedAnnotationWrapper(value) {
|
|
|
236
254
|
}
|
|
237
255
|
|
|
238
256
|
//#endregion
|
|
239
|
-
export { annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
|
257
|
+
export { annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, hasMeaningfulAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
|
package/dist/constructs.cjs
CHANGED
|
@@ -3795,6 +3795,11 @@ function group(label, parser, options = {}) {
|
|
|
3795
3795
|
configurable: true,
|
|
3796
3796
|
enumerable: false
|
|
3797
3797
|
});
|
|
3798
|
+
if (typeof parser.validateValue === "function") Object.defineProperty(groupParser, "validateValue", {
|
|
3799
|
+
value: parser.validateValue.bind(parser),
|
|
3800
|
+
configurable: true,
|
|
3801
|
+
enumerable: false
|
|
3802
|
+
});
|
|
3798
3803
|
return groupParser;
|
|
3799
3804
|
}
|
|
3800
3805
|
/**
|
package/dist/constructs.js
CHANGED
|
@@ -3795,6 +3795,11 @@ function group(label, parser, options = {}) {
|
|
|
3795
3795
|
configurable: true,
|
|
3796
3796
|
enumerable: false
|
|
3797
3797
|
});
|
|
3798
|
+
if (typeof parser.validateValue === "function") Object.defineProperty(groupParser, "validateValue", {
|
|
3799
|
+
value: parser.validateValue.bind(parser),
|
|
3800
|
+
configurable: true,
|
|
3801
|
+
enumerable: false
|
|
3802
|
+
});
|
|
3798
3803
|
return groupParser;
|
|
3799
3804
|
}
|
|
3800
3805
|
/**
|
package/dist/modifiers.cjs
CHANGED
|
@@ -306,6 +306,20 @@ function optional(parser) {
|
|
|
306
306
|
enumerable: false
|
|
307
307
|
});
|
|
308
308
|
}
|
|
309
|
+
if (typeof parser.validateValue === "function") {
|
|
310
|
+
const innerValidate = parser.validateValue.bind(parser);
|
|
311
|
+
Object.defineProperty(optionalParser, "validateValue", {
|
|
312
|
+
value(v) {
|
|
313
|
+
if (v === void 0) return require_mode_dispatch.wrapForMode(parser.$mode, {
|
|
314
|
+
success: true,
|
|
315
|
+
value: v
|
|
316
|
+
});
|
|
317
|
+
return innerValidate(v);
|
|
318
|
+
},
|
|
319
|
+
configurable: true,
|
|
320
|
+
enumerable: false
|
|
321
|
+
});
|
|
322
|
+
}
|
|
309
323
|
if (parser.dependencyMetadata != null) {
|
|
310
324
|
const composed = require_dependency_metadata.composeDependencyMetadata(parser.dependencyMetadata, "optional");
|
|
311
325
|
if (composed != null) optionalParser.dependencyMetadata = composed;
|
|
@@ -504,6 +518,16 @@ function withDefault(parser, defaultValue, options) {
|
|
|
504
518
|
enumerable: false
|
|
505
519
|
});
|
|
506
520
|
}
|
|
521
|
+
if (typeof parser.validateValue === "function") {
|
|
522
|
+
const innerValidate = parser.validateValue.bind(parser);
|
|
523
|
+
Object.defineProperty(withDefaultParser, "validateValue", {
|
|
524
|
+
value(v) {
|
|
525
|
+
return innerValidate(v);
|
|
526
|
+
},
|
|
527
|
+
configurable: true,
|
|
528
|
+
enumerable: false
|
|
529
|
+
});
|
|
530
|
+
}
|
|
507
531
|
if (parser.dependencyMetadata != null) {
|
|
508
532
|
const composed = require_dependency_metadata.composeDependencyMetadata(parser.dependencyMetadata, "withDefault", { defaultValue: () => {
|
|
509
533
|
let v;
|
|
@@ -649,6 +673,7 @@ function map(parser, transform) {
|
|
|
649
673
|
}
|
|
650
674
|
};
|
|
651
675
|
delete mappedParser.normalizeValue;
|
|
676
|
+
delete mappedParser.validateValue;
|
|
652
677
|
if ("placeholder" in parser) Object.defineProperty(mappedParser, "placeholder", {
|
|
653
678
|
get() {
|
|
654
679
|
try {
|
|
@@ -1152,6 +1177,72 @@ function multiple(parser, options = {}) {
|
|
|
1152
1177
|
enumerable: false
|
|
1153
1178
|
});
|
|
1154
1179
|
}
|
|
1180
|
+
{
|
|
1181
|
+
const innerValidate = typeof parser.validateValue === "function" ? parser.validateValue.bind(parser) : void 0;
|
|
1182
|
+
const validateArity = (values) => {
|
|
1183
|
+
if (values.length < min) {
|
|
1184
|
+
const customMessage = options.errors?.tooFew;
|
|
1185
|
+
return {
|
|
1186
|
+
success: false,
|
|
1187
|
+
error: customMessage ? typeof customMessage === "function" ? customMessage(min, values.length) : customMessage : require_message.message`Expected at least ${require_message.text(min.toLocaleString("en"))} values, but got only ${require_message.text(values.length.toLocaleString("en"))}.`
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1190
|
+
if (values.length > max) {
|
|
1191
|
+
const customMessage = options.errors?.tooMany;
|
|
1192
|
+
return {
|
|
1193
|
+
success: false,
|
|
1194
|
+
error: customMessage ? typeof customMessage === "function" ? customMessage(max, values.length) : customMessage : require_message.message`Expected at most ${require_message.text(max.toLocaleString("en"))} values, but got ${require_message.text(values.length.toLocaleString("en"))}.`
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
return {
|
|
1198
|
+
success: true,
|
|
1199
|
+
value: values
|
|
1200
|
+
};
|
|
1201
|
+
};
|
|
1202
|
+
Object.defineProperty(resultParser, "validateValue", {
|
|
1203
|
+
value(values) {
|
|
1204
|
+
if (!Array.isArray(values)) {
|
|
1205
|
+
const actualType = values === null ? "null" : typeof values;
|
|
1206
|
+
return require_mode_dispatch.wrapForMode(parser.$mode, {
|
|
1207
|
+
success: false,
|
|
1208
|
+
error: require_message.message`Expected an array of values, but received ${actualType}.`
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
const arity = validateArity(values);
|
|
1212
|
+
if (!arity.success) return require_mode_dispatch.wrapForMode(parser.$mode, arity);
|
|
1213
|
+
if (innerValidate == null) return require_mode_dispatch.wrapForMode(parser.$mode, arity);
|
|
1214
|
+
return require_mode_dispatch.dispatchByMode(parser.$mode, () => {
|
|
1215
|
+
let changed = false;
|
|
1216
|
+
const normalized = [];
|
|
1217
|
+
for (const v of values) {
|
|
1218
|
+
const r = innerValidate(v);
|
|
1219
|
+
if (!r.success) return r;
|
|
1220
|
+
normalized.push(r.value);
|
|
1221
|
+
if (r.value !== v) changed = true;
|
|
1222
|
+
}
|
|
1223
|
+
return {
|
|
1224
|
+
success: true,
|
|
1225
|
+
value: changed ? normalized : values
|
|
1226
|
+
};
|
|
1227
|
+
}, async () => {
|
|
1228
|
+
let changed = false;
|
|
1229
|
+
const normalized = [];
|
|
1230
|
+
for (const v of values) {
|
|
1231
|
+
const r = await innerValidate(v);
|
|
1232
|
+
if (!r.success) return r;
|
|
1233
|
+
normalized.push(r.value);
|
|
1234
|
+
if (r.value !== v) changed = true;
|
|
1235
|
+
}
|
|
1236
|
+
return {
|
|
1237
|
+
success: true,
|
|
1238
|
+
value: changed ? normalized : values
|
|
1239
|
+
};
|
|
1240
|
+
});
|
|
1241
|
+
},
|
|
1242
|
+
configurable: true,
|
|
1243
|
+
enumerable: false
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1155
1246
|
if (parser.dependencyMetadata?.source != null) {
|
|
1156
1247
|
const innerSource = parser.dependencyMetadata.source;
|
|
1157
1248
|
Object.defineProperty(resultParser, "dependencyMetadata", {
|
|
@@ -1279,6 +1370,11 @@ function nonEmpty(parser) {
|
|
|
1279
1370
|
configurable: true,
|
|
1280
1371
|
enumerable: false
|
|
1281
1372
|
});
|
|
1373
|
+
if (typeof parser.validateValue === "function") Object.defineProperty(nonEmptyParser, "validateValue", {
|
|
1374
|
+
value: parser.validateValue.bind(parser),
|
|
1375
|
+
configurable: true,
|
|
1376
|
+
enumerable: false
|
|
1377
|
+
});
|
|
1282
1378
|
return nonEmptyParser;
|
|
1283
1379
|
}
|
|
1284
1380
|
|
package/dist/modifiers.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { annotateFreshArray, annotationKey, getAnnotations, inheritAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./annotations.js";
|
|
2
2
|
import { formatMessage, message, text } from "./message.js";
|
|
3
|
-
import { dispatchByMode, dispatchIterableByMode, mapModeValue } from "./mode-dispatch.js";
|
|
3
|
+
import { dispatchByMode, dispatchIterableByMode, mapModeValue, wrapForMode } from "./mode-dispatch.js";
|
|
4
4
|
import { composeDependencyMetadata } from "./dependency-metadata.js";
|
|
5
5
|
import { defineInheritedAnnotationParser, defineSourceBindingOnlyAnnotationCompletionParser, unmatchedNonCliDependencySourceStateMarker } from "./parser.js";
|
|
6
6
|
|
|
@@ -306,6 +306,20 @@ function optional(parser) {
|
|
|
306
306
|
enumerable: false
|
|
307
307
|
});
|
|
308
308
|
}
|
|
309
|
+
if (typeof parser.validateValue === "function") {
|
|
310
|
+
const innerValidate = parser.validateValue.bind(parser);
|
|
311
|
+
Object.defineProperty(optionalParser, "validateValue", {
|
|
312
|
+
value(v) {
|
|
313
|
+
if (v === void 0) return wrapForMode(parser.$mode, {
|
|
314
|
+
success: true,
|
|
315
|
+
value: v
|
|
316
|
+
});
|
|
317
|
+
return innerValidate(v);
|
|
318
|
+
},
|
|
319
|
+
configurable: true,
|
|
320
|
+
enumerable: false
|
|
321
|
+
});
|
|
322
|
+
}
|
|
309
323
|
if (parser.dependencyMetadata != null) {
|
|
310
324
|
const composed = composeDependencyMetadata(parser.dependencyMetadata, "optional");
|
|
311
325
|
if (composed != null) optionalParser.dependencyMetadata = composed;
|
|
@@ -504,6 +518,16 @@ function withDefault(parser, defaultValue, options) {
|
|
|
504
518
|
enumerable: false
|
|
505
519
|
});
|
|
506
520
|
}
|
|
521
|
+
if (typeof parser.validateValue === "function") {
|
|
522
|
+
const innerValidate = parser.validateValue.bind(parser);
|
|
523
|
+
Object.defineProperty(withDefaultParser, "validateValue", {
|
|
524
|
+
value(v) {
|
|
525
|
+
return innerValidate(v);
|
|
526
|
+
},
|
|
527
|
+
configurable: true,
|
|
528
|
+
enumerable: false
|
|
529
|
+
});
|
|
530
|
+
}
|
|
507
531
|
if (parser.dependencyMetadata != null) {
|
|
508
532
|
const composed = composeDependencyMetadata(parser.dependencyMetadata, "withDefault", { defaultValue: () => {
|
|
509
533
|
let v;
|
|
@@ -649,6 +673,7 @@ function map(parser, transform) {
|
|
|
649
673
|
}
|
|
650
674
|
};
|
|
651
675
|
delete mappedParser.normalizeValue;
|
|
676
|
+
delete mappedParser.validateValue;
|
|
652
677
|
if ("placeholder" in parser) Object.defineProperty(mappedParser, "placeholder", {
|
|
653
678
|
get() {
|
|
654
679
|
try {
|
|
@@ -1152,6 +1177,72 @@ function multiple(parser, options = {}) {
|
|
|
1152
1177
|
enumerable: false
|
|
1153
1178
|
});
|
|
1154
1179
|
}
|
|
1180
|
+
{
|
|
1181
|
+
const innerValidate = typeof parser.validateValue === "function" ? parser.validateValue.bind(parser) : void 0;
|
|
1182
|
+
const validateArity = (values) => {
|
|
1183
|
+
if (values.length < min) {
|
|
1184
|
+
const customMessage = options.errors?.tooFew;
|
|
1185
|
+
return {
|
|
1186
|
+
success: false,
|
|
1187
|
+
error: customMessage ? typeof customMessage === "function" ? customMessage(min, values.length) : customMessage : message`Expected at least ${text(min.toLocaleString("en"))} values, but got only ${text(values.length.toLocaleString("en"))}.`
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1190
|
+
if (values.length > max) {
|
|
1191
|
+
const customMessage = options.errors?.tooMany;
|
|
1192
|
+
return {
|
|
1193
|
+
success: false,
|
|
1194
|
+
error: customMessage ? typeof customMessage === "function" ? customMessage(max, values.length) : customMessage : message`Expected at most ${text(max.toLocaleString("en"))} values, but got ${text(values.length.toLocaleString("en"))}.`
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
return {
|
|
1198
|
+
success: true,
|
|
1199
|
+
value: values
|
|
1200
|
+
};
|
|
1201
|
+
};
|
|
1202
|
+
Object.defineProperty(resultParser, "validateValue", {
|
|
1203
|
+
value(values) {
|
|
1204
|
+
if (!Array.isArray(values)) {
|
|
1205
|
+
const actualType = values === null ? "null" : typeof values;
|
|
1206
|
+
return wrapForMode(parser.$mode, {
|
|
1207
|
+
success: false,
|
|
1208
|
+
error: message`Expected an array of values, but received ${actualType}.`
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
const arity = validateArity(values);
|
|
1212
|
+
if (!arity.success) return wrapForMode(parser.$mode, arity);
|
|
1213
|
+
if (innerValidate == null) return wrapForMode(parser.$mode, arity);
|
|
1214
|
+
return dispatchByMode(parser.$mode, () => {
|
|
1215
|
+
let changed = false;
|
|
1216
|
+
const normalized = [];
|
|
1217
|
+
for (const v of values) {
|
|
1218
|
+
const r = innerValidate(v);
|
|
1219
|
+
if (!r.success) return r;
|
|
1220
|
+
normalized.push(r.value);
|
|
1221
|
+
if (r.value !== v) changed = true;
|
|
1222
|
+
}
|
|
1223
|
+
return {
|
|
1224
|
+
success: true,
|
|
1225
|
+
value: changed ? normalized : values
|
|
1226
|
+
};
|
|
1227
|
+
}, async () => {
|
|
1228
|
+
let changed = false;
|
|
1229
|
+
const normalized = [];
|
|
1230
|
+
for (const v of values) {
|
|
1231
|
+
const r = await innerValidate(v);
|
|
1232
|
+
if (!r.success) return r;
|
|
1233
|
+
normalized.push(r.value);
|
|
1234
|
+
if (r.value !== v) changed = true;
|
|
1235
|
+
}
|
|
1236
|
+
return {
|
|
1237
|
+
success: true,
|
|
1238
|
+
value: changed ? normalized : values
|
|
1239
|
+
};
|
|
1240
|
+
});
|
|
1241
|
+
},
|
|
1242
|
+
configurable: true,
|
|
1243
|
+
enumerable: false
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1155
1246
|
if (parser.dependencyMetadata?.source != null) {
|
|
1156
1247
|
const innerSource = parser.dependencyMetadata.source;
|
|
1157
1248
|
Object.defineProperty(resultParser, "dependencyMetadata", {
|
|
@@ -1279,6 +1370,11 @@ function nonEmpty(parser) {
|
|
|
1279
1370
|
configurable: true,
|
|
1280
1371
|
enumerable: false
|
|
1281
1372
|
});
|
|
1373
|
+
if (typeof parser.validateValue === "function") Object.defineProperty(nonEmptyParser, "validateValue", {
|
|
1374
|
+
value: parser.validateValue.bind(parser),
|
|
1375
|
+
configurable: true,
|
|
1376
|
+
enumerable: false
|
|
1377
|
+
});
|
|
1282
1378
|
return nonEmptyParser;
|
|
1283
1379
|
}
|
|
1284
1380
|
|
package/dist/parser.cjs
CHANGED
|
@@ -68,7 +68,7 @@ function createParserContext(frame, exec) {
|
|
|
68
68
|
}
|
|
69
69
|
function injectAnnotationsIntoState(state, options) {
|
|
70
70
|
const annotations = options?.annotations;
|
|
71
|
-
if (annotations
|
|
71
|
+
if (!require_annotations.hasMeaningfulAnnotations(annotations)) return state;
|
|
72
72
|
return require_annotations.injectAnnotations(state, annotations);
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
@@ -97,7 +97,7 @@ function injectAnnotationsIntoState(state, options) {
|
|
|
97
97
|
*/
|
|
98
98
|
function parseSync(parser, args, options) {
|
|
99
99
|
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
100
|
-
const shouldUnwrapAnnotatedValue = options?.annotations
|
|
100
|
+
const shouldUnwrapAnnotatedValue = require_annotations.hasMeaningfulAnnotations(options?.annotations) || require_annotations.isInjectedAnnotationWrapper(parser.initialState);
|
|
101
101
|
const exec = {
|
|
102
102
|
usage: parser.usage,
|
|
103
103
|
phase: "parse",
|
|
@@ -169,7 +169,7 @@ function isBufferUnchanged(previous, current) {
|
|
|
169
169
|
*/
|
|
170
170
|
async function parseAsync(parser, args, options) {
|
|
171
171
|
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
172
|
-
const shouldUnwrapAnnotatedValue = options?.annotations
|
|
172
|
+
const shouldUnwrapAnnotatedValue = require_annotations.hasMeaningfulAnnotations(options?.annotations) || require_annotations.isInjectedAnnotationWrapper(parser.initialState);
|
|
173
173
|
const exec = {
|
|
174
174
|
usage: parser.usage,
|
|
175
175
|
phase: "parse",
|
package/dist/parser.d.cts
CHANGED
|
@@ -262,6 +262,50 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
|
|
|
262
262
|
* @since 1.0.0
|
|
263
263
|
*/
|
|
264
264
|
normalizeValue?(value: TValue): TValue;
|
|
265
|
+
/**
|
|
266
|
+
* Optionally re-validates a value as if it had been parsed from CLI
|
|
267
|
+
* input, surfacing any constraint violations from the underlying value
|
|
268
|
+
* parser (e.g., regex patterns, numeric bounds, `choice()` values).
|
|
269
|
+
*
|
|
270
|
+
* Wrappers like `bindEnv()` and `bindConfig()` call this on fallback
|
|
271
|
+
* values — environment variables parsed by a looser env parser,
|
|
272
|
+
* configured defaults, and values loaded from config files — so that
|
|
273
|
+
* those values obey the same validation semantics as CLI input.
|
|
274
|
+
* Without it, parser constraints can be silently bypassed through
|
|
275
|
+
* fallback paths.
|
|
276
|
+
*
|
|
277
|
+
* Built-in primitive parsers ({@link option}, {@link argument})
|
|
278
|
+
* implement this method by round-tripping the value through the inner
|
|
279
|
+
* {@link ValueParser.format} and {@link ValueParser.parse} calls: the
|
|
280
|
+
* value is serialized back to a string and re-parsed, which re-runs
|
|
281
|
+
* every constraint check. Combinator wrappers ({@link optional},
|
|
282
|
+
* {@link withDefault}) forward this method from their inner parser.
|
|
283
|
+
* {@link map} intentionally does *not* forward it because the mapping
|
|
284
|
+
* function is one-way: the mapped output type no longer corresponds
|
|
285
|
+
* to the inner parser's constraints. Exclusive combinators
|
|
286
|
+
* ({@link or}, `longestMatch()`) and multi-source combinators
|
|
287
|
+
* (`merge()`, `concat()`) intentionally do not implement this method
|
|
288
|
+
* because the active branch or key ownership is unknown at validation
|
|
289
|
+
* time.
|
|
290
|
+
*
|
|
291
|
+
* Implementations must wrap any *exception* thrown by `format()` in
|
|
292
|
+
* `try`/`catch` and return the original value as a successful
|
|
293
|
+
* {@link ValueParserResult}. This specifically protects
|
|
294
|
+
* dependency-derived parsers whose factory cannot run without the
|
|
295
|
+
* current dependency value, and custom value parsers whose `format()`
|
|
296
|
+
* intentionally throws for unsupported inputs. Values that
|
|
297
|
+
* `format()` successfully serializes to a string are always re-parsed,
|
|
298
|
+
* and any resulting parse failure is propagated — they represent the
|
|
299
|
+
* bug class this method exists to surface.
|
|
300
|
+
*
|
|
301
|
+
* @param value The candidate value to validate.
|
|
302
|
+
* @returns A {@link ValueParserResult} indicating success (with the
|
|
303
|
+
* possibly-canonicalized value) or failure (with an error
|
|
304
|
+
* message). In async mode, returns a `Promise` resolving to
|
|
305
|
+
* the result.
|
|
306
|
+
* @since 1.0.0
|
|
307
|
+
*/
|
|
308
|
+
validateValue?(value: TValue): ModeValue<M, ValueParserResult<TValue>>;
|
|
265
309
|
/**
|
|
266
310
|
* Internal dependency metadata describing this parser's dependency
|
|
267
311
|
* capabilities. Used by the dependency runtime to resolve dependencies
|
package/dist/parser.d.ts
CHANGED
|
@@ -262,6 +262,50 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
|
|
|
262
262
|
* @since 1.0.0
|
|
263
263
|
*/
|
|
264
264
|
normalizeValue?(value: TValue): TValue;
|
|
265
|
+
/**
|
|
266
|
+
* Optionally re-validates a value as if it had been parsed from CLI
|
|
267
|
+
* input, surfacing any constraint violations from the underlying value
|
|
268
|
+
* parser (e.g., regex patterns, numeric bounds, `choice()` values).
|
|
269
|
+
*
|
|
270
|
+
* Wrappers like `bindEnv()` and `bindConfig()` call this on fallback
|
|
271
|
+
* values — environment variables parsed by a looser env parser,
|
|
272
|
+
* configured defaults, and values loaded from config files — so that
|
|
273
|
+
* those values obey the same validation semantics as CLI input.
|
|
274
|
+
* Without it, parser constraints can be silently bypassed through
|
|
275
|
+
* fallback paths.
|
|
276
|
+
*
|
|
277
|
+
* Built-in primitive parsers ({@link option}, {@link argument})
|
|
278
|
+
* implement this method by round-tripping the value through the inner
|
|
279
|
+
* {@link ValueParser.format} and {@link ValueParser.parse} calls: the
|
|
280
|
+
* value is serialized back to a string and re-parsed, which re-runs
|
|
281
|
+
* every constraint check. Combinator wrappers ({@link optional},
|
|
282
|
+
* {@link withDefault}) forward this method from their inner parser.
|
|
283
|
+
* {@link map} intentionally does *not* forward it because the mapping
|
|
284
|
+
* function is one-way: the mapped output type no longer corresponds
|
|
285
|
+
* to the inner parser's constraints. Exclusive combinators
|
|
286
|
+
* ({@link or}, `longestMatch()`) and multi-source combinators
|
|
287
|
+
* (`merge()`, `concat()`) intentionally do not implement this method
|
|
288
|
+
* because the active branch or key ownership is unknown at validation
|
|
289
|
+
* time.
|
|
290
|
+
*
|
|
291
|
+
* Implementations must wrap any *exception* thrown by `format()` in
|
|
292
|
+
* `try`/`catch` and return the original value as a successful
|
|
293
|
+
* {@link ValueParserResult}. This specifically protects
|
|
294
|
+
* dependency-derived parsers whose factory cannot run without the
|
|
295
|
+
* current dependency value, and custom value parsers whose `format()`
|
|
296
|
+
* intentionally throws for unsupported inputs. Values that
|
|
297
|
+
* `format()` successfully serializes to a string are always re-parsed,
|
|
298
|
+
* and any resulting parse failure is propagated — they represent the
|
|
299
|
+
* bug class this method exists to surface.
|
|
300
|
+
*
|
|
301
|
+
* @param value The candidate value to validate.
|
|
302
|
+
* @returns A {@link ValueParserResult} indicating success (with the
|
|
303
|
+
* possibly-canonicalized value) or failure (with an error
|
|
304
|
+
* message). In async mode, returns a `Promise` resolving to
|
|
305
|
+
* the result.
|
|
306
|
+
* @since 1.0.0
|
|
307
|
+
*/
|
|
308
|
+
validateValue?(value: TValue): ModeValue<M, ValueParserResult<TValue>>;
|
|
265
309
|
/**
|
|
266
310
|
* Internal dependency metadata describing this parser's dependency
|
|
267
311
|
* capabilities. Used by the dependency runtime to resolve dependencies
|
package/dist/parser.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./annotations.js";
|
|
1
|
+
import { hasMeaningfulAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./annotations.js";
|
|
2
2
|
import { cloneMessage, message } from "./message.js";
|
|
3
3
|
import { cloneUsage, normalizeUsage } from "./usage.js";
|
|
4
4
|
import { cloneDocEntry, isDocEntryHidden } from "./doc.js";
|
|
@@ -68,7 +68,7 @@ function createParserContext(frame, exec) {
|
|
|
68
68
|
}
|
|
69
69
|
function injectAnnotationsIntoState(state, options) {
|
|
70
70
|
const annotations = options?.annotations;
|
|
71
|
-
if (annotations
|
|
71
|
+
if (!hasMeaningfulAnnotations(annotations)) return state;
|
|
72
72
|
return injectAnnotations(state, annotations);
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
@@ -97,7 +97,7 @@ function injectAnnotationsIntoState(state, options) {
|
|
|
97
97
|
*/
|
|
98
98
|
function parseSync(parser, args, options) {
|
|
99
99
|
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
100
|
-
const shouldUnwrapAnnotatedValue = options?.annotations
|
|
100
|
+
const shouldUnwrapAnnotatedValue = hasMeaningfulAnnotations(options?.annotations) || isInjectedAnnotationWrapper(parser.initialState);
|
|
101
101
|
const exec = {
|
|
102
102
|
usage: parser.usage,
|
|
103
103
|
phase: "parse",
|
|
@@ -169,7 +169,7 @@ function isBufferUnchanged(previous, current) {
|
|
|
169
169
|
*/
|
|
170
170
|
async function parseAsync(parser, args, options) {
|
|
171
171
|
const initialState = injectAnnotationsIntoState(parser.initialState, options);
|
|
172
|
-
const shouldUnwrapAnnotatedValue = options?.annotations
|
|
172
|
+
const shouldUnwrapAnnotatedValue = hasMeaningfulAnnotations(options?.annotations) || isInjectedAnnotationWrapper(parser.initialState);
|
|
173
173
|
const exec = {
|
|
174
174
|
usage: parser.usage,
|
|
175
175
|
phase: "parse",
|
package/dist/primitives.cjs
CHANGED
|
@@ -438,6 +438,7 @@ function option(...args) {
|
|
|
438
438
|
const isAsync = mode === "async";
|
|
439
439
|
const syncValueParser = valueParser;
|
|
440
440
|
const dependencyMetadata = valueParser != null ? require_dependency_metadata.extractDependencyMetadata(valueParser) : void 0;
|
|
441
|
+
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : require_message.message`${require_message.optionNames(optionNames$1)}: ${error}`;
|
|
441
442
|
const result = {
|
|
442
443
|
$mode: mode,
|
|
443
444
|
$valueType: [],
|
|
@@ -619,7 +620,6 @@ function option(...args) {
|
|
|
619
620
|
};
|
|
620
621
|
},
|
|
621
622
|
complete(state, exec) {
|
|
622
|
-
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : require_message.message`${require_message.optionNames(optionNames$1)}: ${error}`;
|
|
623
623
|
const missing = valueParser == null ? {
|
|
624
624
|
success: true,
|
|
625
625
|
value: false
|
|
@@ -693,6 +693,50 @@ function option(...args) {
|
|
|
693
693
|
enumerable: false
|
|
694
694
|
});
|
|
695
695
|
}
|
|
696
|
+
if (valueParser == null) Object.defineProperty(result, "validateValue", {
|
|
697
|
+
value(v) {
|
|
698
|
+
if (typeof v !== "boolean") {
|
|
699
|
+
const actualType = v === null ? "null" : typeof v;
|
|
700
|
+
return require_mode_dispatch.wrapForMode(mode, {
|
|
701
|
+
success: false,
|
|
702
|
+
error: formatInvalidValueError(require_message.message`Expected a boolean value, but received ${actualType}.`)
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
return require_mode_dispatch.wrapForMode(mode, {
|
|
706
|
+
success: true,
|
|
707
|
+
value: v
|
|
708
|
+
});
|
|
709
|
+
},
|
|
710
|
+
configurable: true,
|
|
711
|
+
enumerable: false
|
|
712
|
+
});
|
|
713
|
+
else if (!require_dependency.isDerivedValueParser(valueParser)) {
|
|
714
|
+
const vp = valueParser;
|
|
715
|
+
const wrapParseResult = (parsed) => parsed.success ? parsed : {
|
|
716
|
+
success: false,
|
|
717
|
+
error: formatInvalidValueError(parsed.error)
|
|
718
|
+
};
|
|
719
|
+
Object.defineProperty(result, "validateValue", {
|
|
720
|
+
value(v) {
|
|
721
|
+
let stringified;
|
|
722
|
+
try {
|
|
723
|
+
stringified = vp.format(v);
|
|
724
|
+
} catch {
|
|
725
|
+
return require_mode_dispatch.wrapForMode(mode, {
|
|
726
|
+
success: true,
|
|
727
|
+
value: v
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
if (typeof stringified !== "string") return require_mode_dispatch.wrapForMode(mode, {
|
|
731
|
+
success: true,
|
|
732
|
+
value: v
|
|
733
|
+
});
|
|
734
|
+
return require_mode_dispatch.dispatchByMode(mode, () => wrapParseResult(vp.parse(stringified)), async () => wrapParseResult(await vp.parse(stringified)));
|
|
735
|
+
},
|
|
736
|
+
configurable: true,
|
|
737
|
+
enumerable: false
|
|
738
|
+
});
|
|
739
|
+
}
|
|
696
740
|
if (valueParser != null) Object.defineProperty(result, "placeholder", {
|
|
697
741
|
get() {
|
|
698
742
|
try {
|
|
@@ -934,6 +978,7 @@ function argument(valueParser, options = {}) {
|
|
|
934
978
|
const isAsync = valueParser.$mode === "async";
|
|
935
979
|
const syncValueParser = valueParser;
|
|
936
980
|
const dependencyMetadata = require_dependency_metadata.extractDependencyMetadata(valueParser);
|
|
981
|
+
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : require_message.message`${require_message.metavar(valueParser.metavar)}: ${error}`;
|
|
937
982
|
const optionPattern = /^--?[a-z0-9-]+$/i;
|
|
938
983
|
const term = {
|
|
939
984
|
type: "argument",
|
|
@@ -1007,7 +1052,6 @@ function argument(valueParser, options = {}) {
|
|
|
1007
1052
|
});
|
|
1008
1053
|
},
|
|
1009
1054
|
complete(state, exec) {
|
|
1010
|
-
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : require_message.message`${require_message.metavar(valueParser.metavar)}: ${error}`;
|
|
1011
1055
|
const missing = {
|
|
1012
1056
|
success: false,
|
|
1013
1057
|
error: options.errors?.endOfInput ?? require_message.message`Expected a ${require_message.metavar(valueParser.metavar)}, but too few arguments.`
|
|
@@ -1075,6 +1119,34 @@ function argument(valueParser, options = {}) {
|
|
|
1075
1119
|
enumerable: false
|
|
1076
1120
|
});
|
|
1077
1121
|
}
|
|
1122
|
+
if (!require_dependency.isDerivedValueParser(valueParser)) {
|
|
1123
|
+
const vp = valueParser;
|
|
1124
|
+
const vpMode = valueParser.$mode;
|
|
1125
|
+
const wrapParseResult = (parsed) => parsed.success ? parsed : {
|
|
1126
|
+
success: false,
|
|
1127
|
+
error: formatInvalidValueError(parsed.error)
|
|
1128
|
+
};
|
|
1129
|
+
Object.defineProperty(result, "validateValue", {
|
|
1130
|
+
value(v) {
|
|
1131
|
+
let stringified;
|
|
1132
|
+
try {
|
|
1133
|
+
stringified = vp.format(v);
|
|
1134
|
+
} catch {
|
|
1135
|
+
return require_mode_dispatch.wrapForMode(vpMode, {
|
|
1136
|
+
success: true,
|
|
1137
|
+
value: v
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
if (typeof stringified !== "string") return require_mode_dispatch.wrapForMode(vpMode, {
|
|
1141
|
+
success: true,
|
|
1142
|
+
value: v
|
|
1143
|
+
});
|
|
1144
|
+
return require_mode_dispatch.dispatchByMode(vpMode, () => wrapParseResult(syncValueParser.parse(stringified)), async () => wrapParseResult(await vp.parse(stringified)));
|
|
1145
|
+
},
|
|
1146
|
+
configurable: true,
|
|
1147
|
+
enumerable: false
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1078
1150
|
Object.defineProperty(result, "placeholder", {
|
|
1079
1151
|
get() {
|
|
1080
1152
|
try {
|
|
@@ -1316,6 +1388,11 @@ function command(name, parser, options = {}) {
|
|
|
1316
1388
|
configurable: true,
|
|
1317
1389
|
enumerable: false
|
|
1318
1390
|
});
|
|
1391
|
+
if (typeof parser.validateValue === "function") Object.defineProperty(result, "validateValue", {
|
|
1392
|
+
value: parser.validateValue.bind(parser),
|
|
1393
|
+
configurable: true,
|
|
1394
|
+
enumerable: false
|
|
1395
|
+
});
|
|
1319
1396
|
return result;
|
|
1320
1397
|
}
|
|
1321
1398
|
/**
|
package/dist/primitives.js
CHANGED
|
@@ -3,7 +3,7 @@ import { message, metavar, optionName, optionNames, text, valueSet } from "./mes
|
|
|
3
3
|
import { getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDerivedValueParser, suggestWithDependency } from "./dependency.js";
|
|
4
4
|
import { validateCommandNames, validateOptionNames } from "./validate.js";
|
|
5
5
|
import { extractOptionNames, isDocHidden, isSuggestionHidden } from "./usage.js";
|
|
6
|
-
import { dispatchByMode, dispatchIterableByMode } from "./mode-dispatch.js";
|
|
6
|
+
import { dispatchByMode, dispatchIterableByMode, wrapForMode } from "./mode-dispatch.js";
|
|
7
7
|
import { extractDependencyMetadata } from "./dependency-metadata.js";
|
|
8
8
|
import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggestionMessage, findSimilar } from "./suggestion.js";
|
|
9
9
|
import { extractLeadingCommandNames } from "./usage-internals.js";
|
|
@@ -438,6 +438,7 @@ function option(...args) {
|
|
|
438
438
|
const isAsync = mode === "async";
|
|
439
439
|
const syncValueParser = valueParser;
|
|
440
440
|
const dependencyMetadata = valueParser != null ? extractDependencyMetadata(valueParser) : void 0;
|
|
441
|
+
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : message`${optionNames(optionNames$1)}: ${error}`;
|
|
441
442
|
const result = {
|
|
442
443
|
$mode: mode,
|
|
443
444
|
$valueType: [],
|
|
@@ -619,7 +620,6 @@ function option(...args) {
|
|
|
619
620
|
};
|
|
620
621
|
},
|
|
621
622
|
complete(state, exec) {
|
|
622
|
-
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : message`${optionNames(optionNames$1)}: ${error}`;
|
|
623
623
|
const missing = valueParser == null ? {
|
|
624
624
|
success: true,
|
|
625
625
|
value: false
|
|
@@ -693,6 +693,50 @@ function option(...args) {
|
|
|
693
693
|
enumerable: false
|
|
694
694
|
});
|
|
695
695
|
}
|
|
696
|
+
if (valueParser == null) Object.defineProperty(result, "validateValue", {
|
|
697
|
+
value(v) {
|
|
698
|
+
if (typeof v !== "boolean") {
|
|
699
|
+
const actualType = v === null ? "null" : typeof v;
|
|
700
|
+
return wrapForMode(mode, {
|
|
701
|
+
success: false,
|
|
702
|
+
error: formatInvalidValueError(message`Expected a boolean value, but received ${actualType}.`)
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
return wrapForMode(mode, {
|
|
706
|
+
success: true,
|
|
707
|
+
value: v
|
|
708
|
+
});
|
|
709
|
+
},
|
|
710
|
+
configurable: true,
|
|
711
|
+
enumerable: false
|
|
712
|
+
});
|
|
713
|
+
else if (!isDerivedValueParser(valueParser)) {
|
|
714
|
+
const vp = valueParser;
|
|
715
|
+
const wrapParseResult = (parsed) => parsed.success ? parsed : {
|
|
716
|
+
success: false,
|
|
717
|
+
error: formatInvalidValueError(parsed.error)
|
|
718
|
+
};
|
|
719
|
+
Object.defineProperty(result, "validateValue", {
|
|
720
|
+
value(v) {
|
|
721
|
+
let stringified;
|
|
722
|
+
try {
|
|
723
|
+
stringified = vp.format(v);
|
|
724
|
+
} catch {
|
|
725
|
+
return wrapForMode(mode, {
|
|
726
|
+
success: true,
|
|
727
|
+
value: v
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
if (typeof stringified !== "string") return wrapForMode(mode, {
|
|
731
|
+
success: true,
|
|
732
|
+
value: v
|
|
733
|
+
});
|
|
734
|
+
return dispatchByMode(mode, () => wrapParseResult(vp.parse(stringified)), async () => wrapParseResult(await vp.parse(stringified)));
|
|
735
|
+
},
|
|
736
|
+
configurable: true,
|
|
737
|
+
enumerable: false
|
|
738
|
+
});
|
|
739
|
+
}
|
|
696
740
|
if (valueParser != null) Object.defineProperty(result, "placeholder", {
|
|
697
741
|
get() {
|
|
698
742
|
try {
|
|
@@ -934,6 +978,7 @@ function argument(valueParser, options = {}) {
|
|
|
934
978
|
const isAsync = valueParser.$mode === "async";
|
|
935
979
|
const syncValueParser = valueParser;
|
|
936
980
|
const dependencyMetadata = extractDependencyMetadata(valueParser);
|
|
981
|
+
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : message`${metavar(valueParser.metavar)}: ${error}`;
|
|
937
982
|
const optionPattern = /^--?[a-z0-9-]+$/i;
|
|
938
983
|
const term = {
|
|
939
984
|
type: "argument",
|
|
@@ -1007,7 +1052,6 @@ function argument(valueParser, options = {}) {
|
|
|
1007
1052
|
});
|
|
1008
1053
|
},
|
|
1009
1054
|
complete(state, exec) {
|
|
1010
|
-
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : message`${metavar(valueParser.metavar)}: ${error}`;
|
|
1011
1055
|
const missing = {
|
|
1012
1056
|
success: false,
|
|
1013
1057
|
error: options.errors?.endOfInput ?? message`Expected a ${metavar(valueParser.metavar)}, but too few arguments.`
|
|
@@ -1075,6 +1119,34 @@ function argument(valueParser, options = {}) {
|
|
|
1075
1119
|
enumerable: false
|
|
1076
1120
|
});
|
|
1077
1121
|
}
|
|
1122
|
+
if (!isDerivedValueParser(valueParser)) {
|
|
1123
|
+
const vp = valueParser;
|
|
1124
|
+
const vpMode = valueParser.$mode;
|
|
1125
|
+
const wrapParseResult = (parsed) => parsed.success ? parsed : {
|
|
1126
|
+
success: false,
|
|
1127
|
+
error: formatInvalidValueError(parsed.error)
|
|
1128
|
+
};
|
|
1129
|
+
Object.defineProperty(result, "validateValue", {
|
|
1130
|
+
value(v) {
|
|
1131
|
+
let stringified;
|
|
1132
|
+
try {
|
|
1133
|
+
stringified = vp.format(v);
|
|
1134
|
+
} catch {
|
|
1135
|
+
return wrapForMode(vpMode, {
|
|
1136
|
+
success: true,
|
|
1137
|
+
value: v
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
if (typeof stringified !== "string") return wrapForMode(vpMode, {
|
|
1141
|
+
success: true,
|
|
1142
|
+
value: v
|
|
1143
|
+
});
|
|
1144
|
+
return dispatchByMode(vpMode, () => wrapParseResult(syncValueParser.parse(stringified)), async () => wrapParseResult(await vp.parse(stringified)));
|
|
1145
|
+
},
|
|
1146
|
+
configurable: true,
|
|
1147
|
+
enumerable: false
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1078
1150
|
Object.defineProperty(result, "placeholder", {
|
|
1079
1151
|
get() {
|
|
1080
1152
|
try {
|
|
@@ -1316,6 +1388,11 @@ function command(name, parser, options = {}) {
|
|
|
1316
1388
|
configurable: true,
|
|
1317
1389
|
enumerable: false
|
|
1318
1390
|
});
|
|
1391
|
+
if (typeof parser.validateValue === "function") Object.defineProperty(result, "validateValue", {
|
|
1392
|
+
value: parser.validateValue.bind(parser),
|
|
1393
|
+
configurable: true,
|
|
1394
|
+
enumerable: false
|
|
1395
|
+
});
|
|
1319
1396
|
return result;
|
|
1320
1397
|
}
|
|
1321
1398
|
/**
|