@optique/core 0.7.1 → 0.8.0-dev.161
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 +264 -0
- package/dist/constructs.d.cts +89 -1
- package/dist/constructs.d.ts +89 -1
- package/dist/constructs.js +264 -1
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/parser.cjs +1 -0
- package/dist/parser.d.cts +2 -2
- package/dist/parser.d.ts +2 -2
- package/dist/parser.js +2 -2
- package/dist/usage.cjs +5 -1
- package/dist/usage.d.cts +15 -0
- package/dist/usage.d.ts +15 -0
- package/dist/usage.js +5 -1
- package/package.json +1 -1
package/dist/constructs.cjs
CHANGED
|
@@ -1030,9 +1030,273 @@ function group(label, parser) {
|
|
|
1030
1030
|
}
|
|
1031
1031
|
};
|
|
1032
1032
|
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Creates a conditional parser that selects different branch parsers based on
|
|
1035
|
+
* a discriminator option value. This enables discriminated union patterns where
|
|
1036
|
+
* certain options are only required or available when a specific discriminator
|
|
1037
|
+
* value is selected.
|
|
1038
|
+
*
|
|
1039
|
+
* The result type is a tuple: `[discriminatorValue, branchResult]`
|
|
1040
|
+
*
|
|
1041
|
+
* @example
|
|
1042
|
+
* ```typescript
|
|
1043
|
+
* // Basic conditional parsing
|
|
1044
|
+
* const parser = conditional(
|
|
1045
|
+
* option("--reporter", choice(["console", "junit"])),
|
|
1046
|
+
* {
|
|
1047
|
+
* console: object({}),
|
|
1048
|
+
* junit: object({ outputFile: option("--output-file", string()) }),
|
|
1049
|
+
* },
|
|
1050
|
+
* object({}) // default when --reporter is not provided
|
|
1051
|
+
* );
|
|
1052
|
+
*
|
|
1053
|
+
* const result = parse(parser, ["--reporter", "junit", "--output-file", "out.xml"]);
|
|
1054
|
+
* // result.value = ["junit", { outputFile: "out.xml" }]
|
|
1055
|
+
*
|
|
1056
|
+
* // Without --reporter, uses default branch:
|
|
1057
|
+
* const defaultResult = parse(parser, []);
|
|
1058
|
+
* // defaultResult.value = [undefined, {}]
|
|
1059
|
+
* ```
|
|
1060
|
+
*
|
|
1061
|
+
* @since 0.8.0
|
|
1062
|
+
*/
|
|
1063
|
+
function conditional(discriminator, branches, defaultBranch, options) {
|
|
1064
|
+
const branchParsers = Object.entries(branches);
|
|
1065
|
+
const allBranchParsers = defaultBranch ? [...branchParsers.map(([_, p]) => p), defaultBranch] : branchParsers.map(([_, p]) => p);
|
|
1066
|
+
const maxPriority = Math.max(discriminator.priority, ...allBranchParsers.map((p) => p.priority));
|
|
1067
|
+
function appendLiteralToUsage(usage$1, literalValue) {
|
|
1068
|
+
const result = [];
|
|
1069
|
+
for (const term of usage$1) if (term.type === "option" && term.metavar !== void 0) {
|
|
1070
|
+
const { metavar: _,...optionWithoutMetavar } = term;
|
|
1071
|
+
result.push(optionWithoutMetavar);
|
|
1072
|
+
result.push({
|
|
1073
|
+
type: "literal",
|
|
1074
|
+
value: literalValue
|
|
1075
|
+
});
|
|
1076
|
+
} else if (term.type === "optional") result.push({
|
|
1077
|
+
...term,
|
|
1078
|
+
terms: appendLiteralToUsage(term.terms, literalValue)
|
|
1079
|
+
});
|
|
1080
|
+
else if (term.type === "multiple") result.push({
|
|
1081
|
+
...term,
|
|
1082
|
+
terms: appendLiteralToUsage(term.terms, literalValue)
|
|
1083
|
+
});
|
|
1084
|
+
else if (term.type === "exclusive") result.push({
|
|
1085
|
+
...term,
|
|
1086
|
+
terms: term.terms.map((t) => appendLiteralToUsage(t, literalValue))
|
|
1087
|
+
});
|
|
1088
|
+
else result.push(term);
|
|
1089
|
+
return result;
|
|
1090
|
+
}
|
|
1091
|
+
const branchUsages = branchParsers.map(([key, p]) => [...appendLiteralToUsage(discriminator.usage, key), ...p.usage]);
|
|
1092
|
+
if (defaultBranch) branchUsages.push(defaultBranch.usage);
|
|
1093
|
+
const usage = branchUsages.length > 1 ? [{
|
|
1094
|
+
type: "exclusive",
|
|
1095
|
+
terms: branchUsages
|
|
1096
|
+
}] : branchUsages[0] ?? [];
|
|
1097
|
+
const initialState = {
|
|
1098
|
+
discriminatorState: discriminator.initialState,
|
|
1099
|
+
discriminatorValue: void 0,
|
|
1100
|
+
selectedBranch: void 0,
|
|
1101
|
+
branchState: void 0
|
|
1102
|
+
};
|
|
1103
|
+
return {
|
|
1104
|
+
$valueType: [],
|
|
1105
|
+
$stateType: [],
|
|
1106
|
+
priority: maxPriority,
|
|
1107
|
+
usage,
|
|
1108
|
+
initialState,
|
|
1109
|
+
parse(context) {
|
|
1110
|
+
const state = context.state ?? initialState;
|
|
1111
|
+
if (state.selectedBranch !== void 0) {
|
|
1112
|
+
const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
|
|
1113
|
+
const branchResult = branchParser.parse({
|
|
1114
|
+
...context,
|
|
1115
|
+
state: state.branchState,
|
|
1116
|
+
usage: branchParser.usage
|
|
1117
|
+
});
|
|
1118
|
+
if (branchResult.success) return {
|
|
1119
|
+
success: true,
|
|
1120
|
+
next: {
|
|
1121
|
+
...branchResult.next,
|
|
1122
|
+
state: {
|
|
1123
|
+
...state,
|
|
1124
|
+
branchState: branchResult.next.state
|
|
1125
|
+
}
|
|
1126
|
+
},
|
|
1127
|
+
consumed: branchResult.consumed
|
|
1128
|
+
};
|
|
1129
|
+
return branchResult;
|
|
1130
|
+
}
|
|
1131
|
+
const discriminatorResult = discriminator.parse({
|
|
1132
|
+
...context,
|
|
1133
|
+
state: state.discriminatorState
|
|
1134
|
+
});
|
|
1135
|
+
if (discriminatorResult.success && discriminatorResult.consumed.length > 0) {
|
|
1136
|
+
const completionResult = discriminator.complete(discriminatorResult.next.state);
|
|
1137
|
+
if (completionResult.success) {
|
|
1138
|
+
const value = completionResult.value;
|
|
1139
|
+
const branchParser = branches[value];
|
|
1140
|
+
if (branchParser) {
|
|
1141
|
+
const branchParseResult = branchParser.parse({
|
|
1142
|
+
...context,
|
|
1143
|
+
buffer: discriminatorResult.next.buffer,
|
|
1144
|
+
optionsTerminated: discriminatorResult.next.optionsTerminated,
|
|
1145
|
+
state: branchParser.initialState,
|
|
1146
|
+
usage: branchParser.usage
|
|
1147
|
+
});
|
|
1148
|
+
if (branchParseResult.success) return {
|
|
1149
|
+
success: true,
|
|
1150
|
+
next: {
|
|
1151
|
+
...branchParseResult.next,
|
|
1152
|
+
state: {
|
|
1153
|
+
discriminatorState: discriminatorResult.next.state,
|
|
1154
|
+
discriminatorValue: value,
|
|
1155
|
+
selectedBranch: {
|
|
1156
|
+
kind: "branch",
|
|
1157
|
+
key: value
|
|
1158
|
+
},
|
|
1159
|
+
branchState: branchParseResult.next.state
|
|
1160
|
+
}
|
|
1161
|
+
},
|
|
1162
|
+
consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
|
|
1163
|
+
};
|
|
1164
|
+
return {
|
|
1165
|
+
success: true,
|
|
1166
|
+
next: {
|
|
1167
|
+
...discriminatorResult.next,
|
|
1168
|
+
state: {
|
|
1169
|
+
discriminatorState: discriminatorResult.next.state,
|
|
1170
|
+
discriminatorValue: value,
|
|
1171
|
+
selectedBranch: {
|
|
1172
|
+
kind: "branch",
|
|
1173
|
+
key: value
|
|
1174
|
+
},
|
|
1175
|
+
branchState: branchParser.initialState
|
|
1176
|
+
}
|
|
1177
|
+
},
|
|
1178
|
+
consumed: discriminatorResult.consumed
|
|
1179
|
+
};
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
if (defaultBranch !== void 0) {
|
|
1184
|
+
const defaultResult = defaultBranch.parse({
|
|
1185
|
+
...context,
|
|
1186
|
+
state: state.branchState ?? defaultBranch.initialState,
|
|
1187
|
+
usage: defaultBranch.usage
|
|
1188
|
+
});
|
|
1189
|
+
if (defaultResult.success && defaultResult.consumed.length > 0) return {
|
|
1190
|
+
success: true,
|
|
1191
|
+
next: {
|
|
1192
|
+
...defaultResult.next,
|
|
1193
|
+
state: {
|
|
1194
|
+
...state,
|
|
1195
|
+
selectedBranch: { kind: "default" },
|
|
1196
|
+
branchState: defaultResult.next.state
|
|
1197
|
+
}
|
|
1198
|
+
},
|
|
1199
|
+
consumed: defaultResult.consumed
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
const noMatchContext = analyzeNoMatchContext([discriminator, ...allBranchParsers]);
|
|
1203
|
+
const errorMessage = options?.errors?.noMatch ? typeof options.errors.noMatch === "function" ? options.errors.noMatch(noMatchContext) : options.errors.noMatch : generateNoMatchError(noMatchContext);
|
|
1204
|
+
return {
|
|
1205
|
+
success: false,
|
|
1206
|
+
consumed: 0,
|
|
1207
|
+
error: errorMessage
|
|
1208
|
+
};
|
|
1209
|
+
},
|
|
1210
|
+
complete(state) {
|
|
1211
|
+
if (state.selectedBranch === void 0) {
|
|
1212
|
+
if (defaultBranch !== void 0) {
|
|
1213
|
+
const branchState = state.branchState ?? defaultBranch.initialState;
|
|
1214
|
+
const defaultResult = defaultBranch.complete(branchState);
|
|
1215
|
+
if (!defaultResult.success) return defaultResult;
|
|
1216
|
+
return {
|
|
1217
|
+
success: true,
|
|
1218
|
+
value: [void 0, defaultResult.value]
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
return {
|
|
1222
|
+
success: false,
|
|
1223
|
+
error: require_message.message`Missing required discriminator option.`
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
|
|
1227
|
+
const branchResult = branchParser.complete(state.branchState);
|
|
1228
|
+
if (!branchResult.success) {
|
|
1229
|
+
if (state.discriminatorValue !== void 0 && options?.errors?.branchError) return {
|
|
1230
|
+
success: false,
|
|
1231
|
+
error: options.errors.branchError(state.discriminatorValue, branchResult.error)
|
|
1232
|
+
};
|
|
1233
|
+
return branchResult;
|
|
1234
|
+
}
|
|
1235
|
+
const discriminatorValue = state.selectedBranch.kind === "default" ? void 0 : state.selectedBranch.key;
|
|
1236
|
+
return {
|
|
1237
|
+
success: true,
|
|
1238
|
+
value: [discriminatorValue, branchResult.value]
|
|
1239
|
+
};
|
|
1240
|
+
},
|
|
1241
|
+
suggest(context, prefix) {
|
|
1242
|
+
const state = context.state ?? initialState;
|
|
1243
|
+
const suggestions = [];
|
|
1244
|
+
if (state.selectedBranch === void 0) {
|
|
1245
|
+
suggestions.push(...discriminator.suggest({
|
|
1246
|
+
...context,
|
|
1247
|
+
state: state.discriminatorState
|
|
1248
|
+
}, prefix));
|
|
1249
|
+
if (defaultBranch !== void 0) suggestions.push(...defaultBranch.suggest({
|
|
1250
|
+
...context,
|
|
1251
|
+
state: state.branchState ?? defaultBranch.initialState
|
|
1252
|
+
}, prefix));
|
|
1253
|
+
} else {
|
|
1254
|
+
const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
|
|
1255
|
+
suggestions.push(...branchParser.suggest({
|
|
1256
|
+
...context,
|
|
1257
|
+
state: state.branchState
|
|
1258
|
+
}, prefix));
|
|
1259
|
+
}
|
|
1260
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1261
|
+
return suggestions.filter((suggestion) => {
|
|
1262
|
+
const key = suggestion.kind === "literal" ? suggestion.text : `__FILE__:${suggestion.type}:${suggestion.extensions?.join(",")}`;
|
|
1263
|
+
if (seen.has(key)) return false;
|
|
1264
|
+
seen.add(key);
|
|
1265
|
+
return true;
|
|
1266
|
+
});
|
|
1267
|
+
},
|
|
1268
|
+
getDocFragments(_state, _defaultValue) {
|
|
1269
|
+
const fragments = [];
|
|
1270
|
+
const discriminatorFragments = discriminator.getDocFragments({ kind: "unavailable" }, void 0);
|
|
1271
|
+
fragments.push(...discriminatorFragments.fragments);
|
|
1272
|
+
for (const [key, branchParser] of branchParsers) {
|
|
1273
|
+
const branchFragments = branchParser.getDocFragments({ kind: "unavailable" }, void 0);
|
|
1274
|
+
const entries = branchFragments.fragments.filter((f) => f.type === "entry");
|
|
1275
|
+
for (const fragment of branchFragments.fragments) if (fragment.type === "section") entries.push(...fragment.entries);
|
|
1276
|
+
if (entries.length > 0) fragments.push({
|
|
1277
|
+
type: "section",
|
|
1278
|
+
title: `Options when ${key}`,
|
|
1279
|
+
entries
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
if (defaultBranch !== void 0) {
|
|
1283
|
+
const defaultFragments = defaultBranch.getDocFragments({ kind: "unavailable" }, void 0);
|
|
1284
|
+
const entries = defaultFragments.fragments.filter((f) => f.type === "entry");
|
|
1285
|
+
for (const fragment of defaultFragments.fragments) if (fragment.type === "section") entries.push(...fragment.entries);
|
|
1286
|
+
if (entries.length > 0) fragments.push({
|
|
1287
|
+
type: "section",
|
|
1288
|
+
title: "Default options",
|
|
1289
|
+
entries
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
return { fragments };
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1033
1296
|
|
|
1034
1297
|
//#endregion
|
|
1035
1298
|
exports.concat = concat;
|
|
1299
|
+
exports.conditional = conditional;
|
|
1036
1300
|
exports.group = group;
|
|
1037
1301
|
exports.longestMatch = longestMatch;
|
|
1038
1302
|
exports.merge = merge;
|
package/dist/constructs.d.cts
CHANGED
|
@@ -1258,5 +1258,93 @@ declare function concat<TA extends readonly unknown[], TB extends readonly unkno
|
|
|
1258
1258
|
* @since 0.4.0
|
|
1259
1259
|
*/
|
|
1260
1260
|
declare function group<TValue, TState>(label: string, parser: Parser<TValue, TState>): Parser<TValue, TState>;
|
|
1261
|
+
/**
|
|
1262
|
+
* Tagged union type representing which branch is selected.
|
|
1263
|
+
* Uses tagged union to avoid collision with discriminator values.
|
|
1264
|
+
* @internal
|
|
1265
|
+
*/
|
|
1266
|
+
type SelectedBranch<TDiscriminator extends string> = {
|
|
1267
|
+
readonly kind: "branch";
|
|
1268
|
+
readonly key: TDiscriminator;
|
|
1269
|
+
} | {
|
|
1270
|
+
readonly kind: "default";
|
|
1271
|
+
};
|
|
1272
|
+
/**
|
|
1273
|
+
* State type for the conditional parser.
|
|
1274
|
+
* @internal
|
|
1275
|
+
*/
|
|
1276
|
+
interface ConditionalState<TDiscriminator extends string> {
|
|
1277
|
+
readonly discriminatorState: unknown;
|
|
1278
|
+
readonly discriminatorValue: TDiscriminator | undefined;
|
|
1279
|
+
readonly selectedBranch: SelectedBranch<TDiscriminator> | undefined;
|
|
1280
|
+
readonly branchState: unknown;
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Options for customizing error messages in the {@link conditional} combinator.
|
|
1284
|
+
* @since 0.8.0
|
|
1285
|
+
*/
|
|
1286
|
+
interface ConditionalErrorOptions {
|
|
1287
|
+
/**
|
|
1288
|
+
* Custom error message when branch parser fails.
|
|
1289
|
+
* Receives the discriminator value for context.
|
|
1290
|
+
*/
|
|
1291
|
+
branchError?: (discriminatorValue: string | undefined, error: Message) => Message;
|
|
1292
|
+
/**
|
|
1293
|
+
* Custom error message for no matching input.
|
|
1294
|
+
*/
|
|
1295
|
+
noMatch?: Message | ((context: NoMatchContext) => Message);
|
|
1296
|
+
}
|
|
1297
|
+
/**
|
|
1298
|
+
* Options for customizing the {@link conditional} combinator behavior.
|
|
1299
|
+
* @since 0.8.0
|
|
1300
|
+
*/
|
|
1301
|
+
interface ConditionalOptions {
|
|
1302
|
+
/**
|
|
1303
|
+
* Custom error messages.
|
|
1304
|
+
*/
|
|
1305
|
+
errors?: ConditionalErrorOptions;
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Helper type to infer result type without default branch.
|
|
1309
|
+
* @internal
|
|
1310
|
+
*/
|
|
1311
|
+
type ConditionalResultWithoutDefault<TDiscriminator extends string, TBranches extends Record<string, Parser<unknown, unknown>>> = { [K in keyof TBranches & string]: readonly [K, InferValue<TBranches[K]>] }[keyof TBranches & string];
|
|
1312
|
+
/**
|
|
1313
|
+
* Helper type to infer result type with default branch.
|
|
1314
|
+
* @internal
|
|
1315
|
+
*/
|
|
1316
|
+
type ConditionalResultWithDefault<TDiscriminator extends string, TBranches extends Record<string, Parser<unknown, unknown>>, TDefault extends Parser<unknown, unknown>> = ConditionalResultWithoutDefault<TDiscriminator, TBranches> | readonly [undefined, InferValue<TDefault>];
|
|
1317
|
+
/**
|
|
1318
|
+
* Helper type to infer value type from a parser.
|
|
1319
|
+
* @internal
|
|
1320
|
+
*/
|
|
1321
|
+
type InferValue<T> = T extends Parser<infer V, unknown> ? V : never;
|
|
1322
|
+
/**
|
|
1323
|
+
* Creates a conditional parser without a default branch.
|
|
1324
|
+
* The discriminator option is required; parsing fails if not provided.
|
|
1325
|
+
*
|
|
1326
|
+
* @template TDiscriminator The string literal union type of discriminator values.
|
|
1327
|
+
* @template TBranches Record mapping discriminator values to branch parsers.
|
|
1328
|
+
* @param discriminator Parser for the discriminator option (typically using choice()).
|
|
1329
|
+
* @param branches Object mapping each discriminator value to its branch parser.
|
|
1330
|
+
* @returns A parser that produces a tuple `[discriminatorValue, branchResult]`.
|
|
1331
|
+
* @since 0.8.0
|
|
1332
|
+
*/
|
|
1333
|
+
declare function conditional<TDiscriminator extends string, TBranches extends { [K in TDiscriminator]: Parser<unknown, unknown> }>(discriminator: Parser<TDiscriminator, unknown>, branches: TBranches): Parser<ConditionalResultWithoutDefault<TDiscriminator, TBranches>, ConditionalState<TDiscriminator>>;
|
|
1334
|
+
/**
|
|
1335
|
+
* Creates a conditional parser with a default branch.
|
|
1336
|
+
* The default branch is used when the discriminator option is not provided.
|
|
1337
|
+
*
|
|
1338
|
+
* @template TDiscriminator The string literal union type of discriminator values.
|
|
1339
|
+
* @template TBranches Record mapping discriminator values to branch parsers.
|
|
1340
|
+
* @template TDefault The default branch parser type.
|
|
1341
|
+
* @param discriminator Parser for the discriminator option (typically using choice()).
|
|
1342
|
+
* @param branches Object mapping each discriminator value to its branch parser.
|
|
1343
|
+
* @param defaultBranch Parser to use when discriminator is not provided.
|
|
1344
|
+
* @param options Optional configuration for error messages.
|
|
1345
|
+
* @returns A parser that produces a tuple `[discriminatorValue | undefined, branchResult]`.
|
|
1346
|
+
* @since 0.8.0
|
|
1347
|
+
*/
|
|
1348
|
+
declare function conditional<TDiscriminator extends string, TBranches extends { [K in TDiscriminator]: Parser<unknown, unknown> }, TDefault extends Parser<unknown, unknown>>(discriminator: Parser<TDiscriminator, unknown>, branches: TBranches, defaultBranch: TDefault, options?: ConditionalOptions): Parser<ConditionalResultWithDefault<TDiscriminator, TBranches, TDefault>, ConditionalState<TDiscriminator>>;
|
|
1261
1349
|
//#endregion
|
|
1262
|
-
export { LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, group, longestMatch, merge, object, or, tuple };
|
|
1350
|
+
export { ConditionalErrorOptions, ConditionalOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple };
|
package/dist/constructs.d.ts
CHANGED
|
@@ -1258,5 +1258,93 @@ declare function concat<TA extends readonly unknown[], TB extends readonly unkno
|
|
|
1258
1258
|
* @since 0.4.0
|
|
1259
1259
|
*/
|
|
1260
1260
|
declare function group<TValue, TState>(label: string, parser: Parser<TValue, TState>): Parser<TValue, TState>;
|
|
1261
|
+
/**
|
|
1262
|
+
* Tagged union type representing which branch is selected.
|
|
1263
|
+
* Uses tagged union to avoid collision with discriminator values.
|
|
1264
|
+
* @internal
|
|
1265
|
+
*/
|
|
1266
|
+
type SelectedBranch<TDiscriminator extends string> = {
|
|
1267
|
+
readonly kind: "branch";
|
|
1268
|
+
readonly key: TDiscriminator;
|
|
1269
|
+
} | {
|
|
1270
|
+
readonly kind: "default";
|
|
1271
|
+
};
|
|
1272
|
+
/**
|
|
1273
|
+
* State type for the conditional parser.
|
|
1274
|
+
* @internal
|
|
1275
|
+
*/
|
|
1276
|
+
interface ConditionalState<TDiscriminator extends string> {
|
|
1277
|
+
readonly discriminatorState: unknown;
|
|
1278
|
+
readonly discriminatorValue: TDiscriminator | undefined;
|
|
1279
|
+
readonly selectedBranch: SelectedBranch<TDiscriminator> | undefined;
|
|
1280
|
+
readonly branchState: unknown;
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Options for customizing error messages in the {@link conditional} combinator.
|
|
1284
|
+
* @since 0.8.0
|
|
1285
|
+
*/
|
|
1286
|
+
interface ConditionalErrorOptions {
|
|
1287
|
+
/**
|
|
1288
|
+
* Custom error message when branch parser fails.
|
|
1289
|
+
* Receives the discriminator value for context.
|
|
1290
|
+
*/
|
|
1291
|
+
branchError?: (discriminatorValue: string | undefined, error: Message) => Message;
|
|
1292
|
+
/**
|
|
1293
|
+
* Custom error message for no matching input.
|
|
1294
|
+
*/
|
|
1295
|
+
noMatch?: Message | ((context: NoMatchContext) => Message);
|
|
1296
|
+
}
|
|
1297
|
+
/**
|
|
1298
|
+
* Options for customizing the {@link conditional} combinator behavior.
|
|
1299
|
+
* @since 0.8.0
|
|
1300
|
+
*/
|
|
1301
|
+
interface ConditionalOptions {
|
|
1302
|
+
/**
|
|
1303
|
+
* Custom error messages.
|
|
1304
|
+
*/
|
|
1305
|
+
errors?: ConditionalErrorOptions;
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Helper type to infer result type without default branch.
|
|
1309
|
+
* @internal
|
|
1310
|
+
*/
|
|
1311
|
+
type ConditionalResultWithoutDefault<TDiscriminator extends string, TBranches extends Record<string, Parser<unknown, unknown>>> = { [K in keyof TBranches & string]: readonly [K, InferValue<TBranches[K]>] }[keyof TBranches & string];
|
|
1312
|
+
/**
|
|
1313
|
+
* Helper type to infer result type with default branch.
|
|
1314
|
+
* @internal
|
|
1315
|
+
*/
|
|
1316
|
+
type ConditionalResultWithDefault<TDiscriminator extends string, TBranches extends Record<string, Parser<unknown, unknown>>, TDefault extends Parser<unknown, unknown>> = ConditionalResultWithoutDefault<TDiscriminator, TBranches> | readonly [undefined, InferValue<TDefault>];
|
|
1317
|
+
/**
|
|
1318
|
+
* Helper type to infer value type from a parser.
|
|
1319
|
+
* @internal
|
|
1320
|
+
*/
|
|
1321
|
+
type InferValue<T> = T extends Parser<infer V, unknown> ? V : never;
|
|
1322
|
+
/**
|
|
1323
|
+
* Creates a conditional parser without a default branch.
|
|
1324
|
+
* The discriminator option is required; parsing fails if not provided.
|
|
1325
|
+
*
|
|
1326
|
+
* @template TDiscriminator The string literal union type of discriminator values.
|
|
1327
|
+
* @template TBranches Record mapping discriminator values to branch parsers.
|
|
1328
|
+
* @param discriminator Parser for the discriminator option (typically using choice()).
|
|
1329
|
+
* @param branches Object mapping each discriminator value to its branch parser.
|
|
1330
|
+
* @returns A parser that produces a tuple `[discriminatorValue, branchResult]`.
|
|
1331
|
+
* @since 0.8.0
|
|
1332
|
+
*/
|
|
1333
|
+
declare function conditional<TDiscriminator extends string, TBranches extends { [K in TDiscriminator]: Parser<unknown, unknown> }>(discriminator: Parser<TDiscriminator, unknown>, branches: TBranches): Parser<ConditionalResultWithoutDefault<TDiscriminator, TBranches>, ConditionalState<TDiscriminator>>;
|
|
1334
|
+
/**
|
|
1335
|
+
* Creates a conditional parser with a default branch.
|
|
1336
|
+
* The default branch is used when the discriminator option is not provided.
|
|
1337
|
+
*
|
|
1338
|
+
* @template TDiscriminator The string literal union type of discriminator values.
|
|
1339
|
+
* @template TBranches Record mapping discriminator values to branch parsers.
|
|
1340
|
+
* @template TDefault The default branch parser type.
|
|
1341
|
+
* @param discriminator Parser for the discriminator option (typically using choice()).
|
|
1342
|
+
* @param branches Object mapping each discriminator value to its branch parser.
|
|
1343
|
+
* @param defaultBranch Parser to use when discriminator is not provided.
|
|
1344
|
+
* @param options Optional configuration for error messages.
|
|
1345
|
+
* @returns A parser that produces a tuple `[discriminatorValue | undefined, branchResult]`.
|
|
1346
|
+
* @since 0.8.0
|
|
1347
|
+
*/
|
|
1348
|
+
declare function conditional<TDiscriminator extends string, TBranches extends { [K in TDiscriminator]: Parser<unknown, unknown> }, TDefault extends Parser<unknown, unknown>>(discriminator: Parser<TDiscriminator, unknown>, branches: TBranches, defaultBranch: TDefault, options?: ConditionalOptions): Parser<ConditionalResultWithDefault<TDiscriminator, TBranches, TDefault>, ConditionalState<TDiscriminator>>;
|
|
1261
1349
|
//#endregion
|
|
1262
|
-
export { LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, group, longestMatch, merge, object, or, tuple };
|
|
1350
|
+
export { ConditionalErrorOptions, ConditionalOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple };
|
package/dist/constructs.js
CHANGED
|
@@ -1030,6 +1030,269 @@ function group(label, parser) {
|
|
|
1030
1030
|
}
|
|
1031
1031
|
};
|
|
1032
1032
|
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Creates a conditional parser that selects different branch parsers based on
|
|
1035
|
+
* a discriminator option value. This enables discriminated union patterns where
|
|
1036
|
+
* certain options are only required or available when a specific discriminator
|
|
1037
|
+
* value is selected.
|
|
1038
|
+
*
|
|
1039
|
+
* The result type is a tuple: `[discriminatorValue, branchResult]`
|
|
1040
|
+
*
|
|
1041
|
+
* @example
|
|
1042
|
+
* ```typescript
|
|
1043
|
+
* // Basic conditional parsing
|
|
1044
|
+
* const parser = conditional(
|
|
1045
|
+
* option("--reporter", choice(["console", "junit"])),
|
|
1046
|
+
* {
|
|
1047
|
+
* console: object({}),
|
|
1048
|
+
* junit: object({ outputFile: option("--output-file", string()) }),
|
|
1049
|
+
* },
|
|
1050
|
+
* object({}) // default when --reporter is not provided
|
|
1051
|
+
* );
|
|
1052
|
+
*
|
|
1053
|
+
* const result = parse(parser, ["--reporter", "junit", "--output-file", "out.xml"]);
|
|
1054
|
+
* // result.value = ["junit", { outputFile: "out.xml" }]
|
|
1055
|
+
*
|
|
1056
|
+
* // Without --reporter, uses default branch:
|
|
1057
|
+
* const defaultResult = parse(parser, []);
|
|
1058
|
+
* // defaultResult.value = [undefined, {}]
|
|
1059
|
+
* ```
|
|
1060
|
+
*
|
|
1061
|
+
* @since 0.8.0
|
|
1062
|
+
*/
|
|
1063
|
+
function conditional(discriminator, branches, defaultBranch, options) {
|
|
1064
|
+
const branchParsers = Object.entries(branches);
|
|
1065
|
+
const allBranchParsers = defaultBranch ? [...branchParsers.map(([_, p]) => p), defaultBranch] : branchParsers.map(([_, p]) => p);
|
|
1066
|
+
const maxPriority = Math.max(discriminator.priority, ...allBranchParsers.map((p) => p.priority));
|
|
1067
|
+
function appendLiteralToUsage(usage$1, literalValue) {
|
|
1068
|
+
const result = [];
|
|
1069
|
+
for (const term of usage$1) if (term.type === "option" && term.metavar !== void 0) {
|
|
1070
|
+
const { metavar: _,...optionWithoutMetavar } = term;
|
|
1071
|
+
result.push(optionWithoutMetavar);
|
|
1072
|
+
result.push({
|
|
1073
|
+
type: "literal",
|
|
1074
|
+
value: literalValue
|
|
1075
|
+
});
|
|
1076
|
+
} else if (term.type === "optional") result.push({
|
|
1077
|
+
...term,
|
|
1078
|
+
terms: appendLiteralToUsage(term.terms, literalValue)
|
|
1079
|
+
});
|
|
1080
|
+
else if (term.type === "multiple") result.push({
|
|
1081
|
+
...term,
|
|
1082
|
+
terms: appendLiteralToUsage(term.terms, literalValue)
|
|
1083
|
+
});
|
|
1084
|
+
else if (term.type === "exclusive") result.push({
|
|
1085
|
+
...term,
|
|
1086
|
+
terms: term.terms.map((t) => appendLiteralToUsage(t, literalValue))
|
|
1087
|
+
});
|
|
1088
|
+
else result.push(term);
|
|
1089
|
+
return result;
|
|
1090
|
+
}
|
|
1091
|
+
const branchUsages = branchParsers.map(([key, p]) => [...appendLiteralToUsage(discriminator.usage, key), ...p.usage]);
|
|
1092
|
+
if (defaultBranch) branchUsages.push(defaultBranch.usage);
|
|
1093
|
+
const usage = branchUsages.length > 1 ? [{
|
|
1094
|
+
type: "exclusive",
|
|
1095
|
+
terms: branchUsages
|
|
1096
|
+
}] : branchUsages[0] ?? [];
|
|
1097
|
+
const initialState = {
|
|
1098
|
+
discriminatorState: discriminator.initialState,
|
|
1099
|
+
discriminatorValue: void 0,
|
|
1100
|
+
selectedBranch: void 0,
|
|
1101
|
+
branchState: void 0
|
|
1102
|
+
};
|
|
1103
|
+
return {
|
|
1104
|
+
$valueType: [],
|
|
1105
|
+
$stateType: [],
|
|
1106
|
+
priority: maxPriority,
|
|
1107
|
+
usage,
|
|
1108
|
+
initialState,
|
|
1109
|
+
parse(context) {
|
|
1110
|
+
const state = context.state ?? initialState;
|
|
1111
|
+
if (state.selectedBranch !== void 0) {
|
|
1112
|
+
const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
|
|
1113
|
+
const branchResult = branchParser.parse({
|
|
1114
|
+
...context,
|
|
1115
|
+
state: state.branchState,
|
|
1116
|
+
usage: branchParser.usage
|
|
1117
|
+
});
|
|
1118
|
+
if (branchResult.success) return {
|
|
1119
|
+
success: true,
|
|
1120
|
+
next: {
|
|
1121
|
+
...branchResult.next,
|
|
1122
|
+
state: {
|
|
1123
|
+
...state,
|
|
1124
|
+
branchState: branchResult.next.state
|
|
1125
|
+
}
|
|
1126
|
+
},
|
|
1127
|
+
consumed: branchResult.consumed
|
|
1128
|
+
};
|
|
1129
|
+
return branchResult;
|
|
1130
|
+
}
|
|
1131
|
+
const discriminatorResult = discriminator.parse({
|
|
1132
|
+
...context,
|
|
1133
|
+
state: state.discriminatorState
|
|
1134
|
+
});
|
|
1135
|
+
if (discriminatorResult.success && discriminatorResult.consumed.length > 0) {
|
|
1136
|
+
const completionResult = discriminator.complete(discriminatorResult.next.state);
|
|
1137
|
+
if (completionResult.success) {
|
|
1138
|
+
const value = completionResult.value;
|
|
1139
|
+
const branchParser = branches[value];
|
|
1140
|
+
if (branchParser) {
|
|
1141
|
+
const branchParseResult = branchParser.parse({
|
|
1142
|
+
...context,
|
|
1143
|
+
buffer: discriminatorResult.next.buffer,
|
|
1144
|
+
optionsTerminated: discriminatorResult.next.optionsTerminated,
|
|
1145
|
+
state: branchParser.initialState,
|
|
1146
|
+
usage: branchParser.usage
|
|
1147
|
+
});
|
|
1148
|
+
if (branchParseResult.success) return {
|
|
1149
|
+
success: true,
|
|
1150
|
+
next: {
|
|
1151
|
+
...branchParseResult.next,
|
|
1152
|
+
state: {
|
|
1153
|
+
discriminatorState: discriminatorResult.next.state,
|
|
1154
|
+
discriminatorValue: value,
|
|
1155
|
+
selectedBranch: {
|
|
1156
|
+
kind: "branch",
|
|
1157
|
+
key: value
|
|
1158
|
+
},
|
|
1159
|
+
branchState: branchParseResult.next.state
|
|
1160
|
+
}
|
|
1161
|
+
},
|
|
1162
|
+
consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
|
|
1163
|
+
};
|
|
1164
|
+
return {
|
|
1165
|
+
success: true,
|
|
1166
|
+
next: {
|
|
1167
|
+
...discriminatorResult.next,
|
|
1168
|
+
state: {
|
|
1169
|
+
discriminatorState: discriminatorResult.next.state,
|
|
1170
|
+
discriminatorValue: value,
|
|
1171
|
+
selectedBranch: {
|
|
1172
|
+
kind: "branch",
|
|
1173
|
+
key: value
|
|
1174
|
+
},
|
|
1175
|
+
branchState: branchParser.initialState
|
|
1176
|
+
}
|
|
1177
|
+
},
|
|
1178
|
+
consumed: discriminatorResult.consumed
|
|
1179
|
+
};
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
if (defaultBranch !== void 0) {
|
|
1184
|
+
const defaultResult = defaultBranch.parse({
|
|
1185
|
+
...context,
|
|
1186
|
+
state: state.branchState ?? defaultBranch.initialState,
|
|
1187
|
+
usage: defaultBranch.usage
|
|
1188
|
+
});
|
|
1189
|
+
if (defaultResult.success && defaultResult.consumed.length > 0) return {
|
|
1190
|
+
success: true,
|
|
1191
|
+
next: {
|
|
1192
|
+
...defaultResult.next,
|
|
1193
|
+
state: {
|
|
1194
|
+
...state,
|
|
1195
|
+
selectedBranch: { kind: "default" },
|
|
1196
|
+
branchState: defaultResult.next.state
|
|
1197
|
+
}
|
|
1198
|
+
},
|
|
1199
|
+
consumed: defaultResult.consumed
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
const noMatchContext = analyzeNoMatchContext([discriminator, ...allBranchParsers]);
|
|
1203
|
+
const errorMessage = options?.errors?.noMatch ? typeof options.errors.noMatch === "function" ? options.errors.noMatch(noMatchContext) : options.errors.noMatch : generateNoMatchError(noMatchContext);
|
|
1204
|
+
return {
|
|
1205
|
+
success: false,
|
|
1206
|
+
consumed: 0,
|
|
1207
|
+
error: errorMessage
|
|
1208
|
+
};
|
|
1209
|
+
},
|
|
1210
|
+
complete(state) {
|
|
1211
|
+
if (state.selectedBranch === void 0) {
|
|
1212
|
+
if (defaultBranch !== void 0) {
|
|
1213
|
+
const branchState = state.branchState ?? defaultBranch.initialState;
|
|
1214
|
+
const defaultResult = defaultBranch.complete(branchState);
|
|
1215
|
+
if (!defaultResult.success) return defaultResult;
|
|
1216
|
+
return {
|
|
1217
|
+
success: true,
|
|
1218
|
+
value: [void 0, defaultResult.value]
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
return {
|
|
1222
|
+
success: false,
|
|
1223
|
+
error: message`Missing required discriminator option.`
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
|
|
1227
|
+
const branchResult = branchParser.complete(state.branchState);
|
|
1228
|
+
if (!branchResult.success) {
|
|
1229
|
+
if (state.discriminatorValue !== void 0 && options?.errors?.branchError) return {
|
|
1230
|
+
success: false,
|
|
1231
|
+
error: options.errors.branchError(state.discriminatorValue, branchResult.error)
|
|
1232
|
+
};
|
|
1233
|
+
return branchResult;
|
|
1234
|
+
}
|
|
1235
|
+
const discriminatorValue = state.selectedBranch.kind === "default" ? void 0 : state.selectedBranch.key;
|
|
1236
|
+
return {
|
|
1237
|
+
success: true,
|
|
1238
|
+
value: [discriminatorValue, branchResult.value]
|
|
1239
|
+
};
|
|
1240
|
+
},
|
|
1241
|
+
suggest(context, prefix) {
|
|
1242
|
+
const state = context.state ?? initialState;
|
|
1243
|
+
const suggestions = [];
|
|
1244
|
+
if (state.selectedBranch === void 0) {
|
|
1245
|
+
suggestions.push(...discriminator.suggest({
|
|
1246
|
+
...context,
|
|
1247
|
+
state: state.discriminatorState
|
|
1248
|
+
}, prefix));
|
|
1249
|
+
if (defaultBranch !== void 0) suggestions.push(...defaultBranch.suggest({
|
|
1250
|
+
...context,
|
|
1251
|
+
state: state.branchState ?? defaultBranch.initialState
|
|
1252
|
+
}, prefix));
|
|
1253
|
+
} else {
|
|
1254
|
+
const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
|
|
1255
|
+
suggestions.push(...branchParser.suggest({
|
|
1256
|
+
...context,
|
|
1257
|
+
state: state.branchState
|
|
1258
|
+
}, prefix));
|
|
1259
|
+
}
|
|
1260
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1261
|
+
return suggestions.filter((suggestion) => {
|
|
1262
|
+
const key = suggestion.kind === "literal" ? suggestion.text : `__FILE__:${suggestion.type}:${suggestion.extensions?.join(",")}`;
|
|
1263
|
+
if (seen.has(key)) return false;
|
|
1264
|
+
seen.add(key);
|
|
1265
|
+
return true;
|
|
1266
|
+
});
|
|
1267
|
+
},
|
|
1268
|
+
getDocFragments(_state, _defaultValue) {
|
|
1269
|
+
const fragments = [];
|
|
1270
|
+
const discriminatorFragments = discriminator.getDocFragments({ kind: "unavailable" }, void 0);
|
|
1271
|
+
fragments.push(...discriminatorFragments.fragments);
|
|
1272
|
+
for (const [key, branchParser] of branchParsers) {
|
|
1273
|
+
const branchFragments = branchParser.getDocFragments({ kind: "unavailable" }, void 0);
|
|
1274
|
+
const entries = branchFragments.fragments.filter((f) => f.type === "entry");
|
|
1275
|
+
for (const fragment of branchFragments.fragments) if (fragment.type === "section") entries.push(...fragment.entries);
|
|
1276
|
+
if (entries.length > 0) fragments.push({
|
|
1277
|
+
type: "section",
|
|
1278
|
+
title: `Options when ${key}`,
|
|
1279
|
+
entries
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
if (defaultBranch !== void 0) {
|
|
1283
|
+
const defaultFragments = defaultBranch.getDocFragments({ kind: "unavailable" }, void 0);
|
|
1284
|
+
const entries = defaultFragments.fragments.filter((f) => f.type === "entry");
|
|
1285
|
+
for (const fragment of defaultFragments.fragments) if (fragment.type === "section") entries.push(...fragment.entries);
|
|
1286
|
+
if (entries.length > 0) fragments.push({
|
|
1287
|
+
type: "section",
|
|
1288
|
+
title: "Default options",
|
|
1289
|
+
entries
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
return { fragments };
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1033
1296
|
|
|
1034
1297
|
//#endregion
|
|
1035
|
-
export { concat, group, longestMatch, merge, object, or, tuple };
|
|
1298
|
+
export { concat, conditional, group, longestMatch, merge, object, or, tuple };
|
package/dist/index.cjs
CHANGED
|
@@ -17,6 +17,7 @@ exports.choice = require_valueparser.choice;
|
|
|
17
17
|
exports.command = require_primitives.command;
|
|
18
18
|
exports.commandLine = require_message.commandLine;
|
|
19
19
|
exports.concat = require_constructs.concat;
|
|
20
|
+
exports.conditional = require_constructs.conditional;
|
|
20
21
|
exports.constant = require_primitives.constant;
|
|
21
22
|
exports.envVar = require_message.envVar;
|
|
22
23
|
exports.extractArgumentMetavars = require_usage.extractArgumentMetavars;
|
package/dist/index.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ import { ChoiceOptions, FloatOptions, IntegerOptionsBigInt, IntegerOptionsNumber
|
|
|
5
5
|
import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, optional, withDefault } from "./modifiers.cjs";
|
|
6
6
|
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, argument, command, constant, flag, option } from "./primitives.cjs";
|
|
7
7
|
import { DocState, InferValue, Parser, ParserContext, ParserResult, Result, Suggestion, getDocPage, parse, suggest } from "./parser.cjs";
|
|
8
|
-
import { LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, group, longestMatch, merge, object, or, tuple } from "./constructs.cjs";
|
|
8
|
+
import { ConditionalErrorOptions, ConditionalOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.cjs";
|
|
9
9
|
import { ShellCompletion, bash, fish, nu, pwsh, zsh } from "./completion.cjs";
|
|
10
10
|
import { RunError, RunOptions, run } from "./facade.cjs";
|
|
11
|
-
export { ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, CommandErrorOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagErrorOptions, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Message, MessageFormatOptions, MessageTerm, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShellCompletion, ShowDefaultOptions, StringOptions, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, WithDefaultOptions, argument, bash, choice, command, commandLine, concat, constant, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
|
11
|
+
export { ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagErrorOptions, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Message, MessageFormatOptions, MessageTerm, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShellCompletion, ShowDefaultOptions, StringOptions, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, WithDefaultOptions, argument, bash, choice, command, commandLine, concat, conditional, constant, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { ChoiceOptions, FloatOptions, IntegerOptionsBigInt, IntegerOptionsNumber
|
|
|
5
5
|
import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, optional, withDefault } from "./modifiers.js";
|
|
6
6
|
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, argument, command, constant, flag, option } from "./primitives.js";
|
|
7
7
|
import { DocState, InferValue, Parser, ParserContext, ParserResult, Result, Suggestion, getDocPage, parse, suggest } from "./parser.js";
|
|
8
|
-
import { LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
8
|
+
import { ConditionalErrorOptions, ConditionalOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
9
9
|
import { ShellCompletion, bash, fish, nu, pwsh, zsh } from "./completion.js";
|
|
10
10
|
import { RunError, RunOptions, run } from "./facade.js";
|
|
11
|
-
export { ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, CommandErrorOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagErrorOptions, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Message, MessageFormatOptions, MessageTerm, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShellCompletion, ShowDefaultOptions, StringOptions, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, WithDefaultOptions, argument, bash, choice, command, commandLine, concat, constant, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
|
11
|
+
export { ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagErrorOptions, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Message, MessageFormatOptions, MessageTerm, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShellCompletion, ShowDefaultOptions, StringOptions, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, WithDefaultOptions, argument, bash, choice, command, commandLine, concat, conditional, constant, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { commandLine, envVar, formatMessage, message, metavar, optionName, optionNames, text, value, values } from "./message.js";
|
|
2
2
|
import { extractArgumentMetavars, extractCommandNames, extractOptionNames, formatUsage, formatUsageTerm, normalizeUsage } from "./usage.js";
|
|
3
|
-
import { concat, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
3
|
+
import { concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
4
4
|
import { formatDocPage } from "./doc.js";
|
|
5
5
|
import { bash, fish, nu, pwsh, zsh } from "./completion.js";
|
|
6
6
|
import { WithDefaultError, map, multiple, optional, withDefault } from "./modifiers.js";
|
|
@@ -9,4 +9,4 @@ import { argument, command, constant, flag, option } from "./primitives.js";
|
|
|
9
9
|
import { getDocPage, parse, suggest } from "./parser.js";
|
|
10
10
|
import { RunError, run } from "./facade.js";
|
|
11
11
|
|
|
12
|
-
export { RunError, WithDefaultError, argument, bash, choice, command, commandLine, concat, constant, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
|
12
|
+
export { RunError, WithDefaultError, argument, bash, choice, command, commandLine, concat, conditional, constant, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
package/dist/parser.cjs
CHANGED
|
@@ -176,6 +176,7 @@ exports.WithDefaultError = require_modifiers.WithDefaultError;
|
|
|
176
176
|
exports.argument = require_primitives.argument;
|
|
177
177
|
exports.command = require_primitives.command;
|
|
178
178
|
exports.concat = require_constructs.concat;
|
|
179
|
+
exports.conditional = require_constructs.conditional;
|
|
179
180
|
exports.constant = require_primitives.constant;
|
|
180
181
|
exports.flag = require_primitives.flag;
|
|
181
182
|
exports.getDocPage = getDocPage;
|
package/dist/parser.d.cts
CHANGED
|
@@ -4,7 +4,7 @@ import { DocFragments, DocPage } from "./doc.cjs";
|
|
|
4
4
|
import { ValueParserResult } from "./valueparser.cjs";
|
|
5
5
|
import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, optional, withDefault } from "./modifiers.cjs";
|
|
6
6
|
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, argument, command, constant, flag, option } from "./primitives.cjs";
|
|
7
|
-
import { LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, group, longestMatch, merge, object, or, tuple } from "./constructs.cjs";
|
|
7
|
+
import { ConditionalErrorOptions, ConditionalOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.cjs";
|
|
8
8
|
|
|
9
9
|
//#region src/parser.d.ts
|
|
10
10
|
|
|
@@ -323,4 +323,4 @@ declare function suggest<T>(parser: Parser<T, unknown>, args: readonly [string,
|
|
|
323
323
|
*/
|
|
324
324
|
declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
|
|
325
325
|
//#endregion
|
|
326
|
-
export { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, DocState, FlagErrorOptions, FlagOptions, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, suggest, tuple, withDefault };
|
|
326
|
+
export { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, FlagErrorOptions, FlagOptions, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, suggest, tuple, withDefault };
|
package/dist/parser.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { DocFragments, DocPage } from "./doc.js";
|
|
|
4
4
|
import { ValueParserResult } from "./valueparser.js";
|
|
5
5
|
import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, optional, withDefault } from "./modifiers.js";
|
|
6
6
|
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, argument, command, constant, flag, option } from "./primitives.js";
|
|
7
|
-
import { LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
7
|
+
import { ConditionalErrorOptions, ConditionalOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
8
8
|
|
|
9
9
|
//#region src/parser.d.ts
|
|
10
10
|
|
|
@@ -323,4 +323,4 @@ declare function suggest<T>(parser: Parser<T, unknown>, args: readonly [string,
|
|
|
323
323
|
*/
|
|
324
324
|
declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
|
|
325
325
|
//#endregion
|
|
326
|
-
export { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, DocState, FlagErrorOptions, FlagOptions, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, suggest, tuple, withDefault };
|
|
326
|
+
export { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, FlagErrorOptions, FlagOptions, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, suggest, tuple, withDefault };
|
package/dist/parser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { message } from "./message.js";
|
|
2
2
|
import { normalizeUsage } from "./usage.js";
|
|
3
|
-
import { concat, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
3
|
+
import { concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
4
4
|
import { WithDefaultError, map, multiple, optional, withDefault } from "./modifiers.js";
|
|
5
5
|
import { argument, command, constant, flag, option } from "./primitives.js";
|
|
6
6
|
|
|
@@ -172,4 +172,4 @@ function getDocPage(parser, args = []) {
|
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
//#endregion
|
|
175
|
-
export { WithDefaultError, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, suggest, tuple, withDefault };
|
|
175
|
+
export { WithDefaultError, argument, command, concat, conditional, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, suggest, tuple, withDefault };
|
package/dist/usage.cjs
CHANGED
|
@@ -327,7 +327,11 @@ function* formatUsageTermInternal(term, options) {
|
|
|
327
327
|
text: options?.colors ? `\x1b[2m]\x1b[0m` : "]",
|
|
328
328
|
width: 1
|
|
329
329
|
};
|
|
330
|
-
} else
|
|
330
|
+
} else if (term.type === "literal") yield {
|
|
331
|
+
text: term.value,
|
|
332
|
+
width: term.value.length
|
|
333
|
+
};
|
|
334
|
+
else throw new TypeError(`Unknown usage term type: ${term["type"]}.`);
|
|
331
335
|
}
|
|
332
336
|
|
|
333
337
|
//#endregion
|
package/dist/usage.d.cts
CHANGED
|
@@ -108,6 +108,21 @@ type UsageTerm =
|
|
|
108
108
|
* arguments, options, commands, or other usage terms.
|
|
109
109
|
*/
|
|
110
110
|
readonly terms: readonly Usage[];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* A literal term, which represents a fixed string value in the command-line
|
|
114
|
+
* usage. Unlike metavars which are placeholders for user-provided values,
|
|
115
|
+
* literals represent exact strings that must be typed as-is.
|
|
116
|
+
* @since 0.8.0
|
|
117
|
+
*/ | {
|
|
118
|
+
/**
|
|
119
|
+
* The type of the term, which is always `"literal"` for this term.
|
|
120
|
+
*/
|
|
121
|
+
readonly type: "literal";
|
|
122
|
+
/**
|
|
123
|
+
* The literal value that must be provided exactly as written.
|
|
124
|
+
*/
|
|
125
|
+
readonly value: string;
|
|
111
126
|
};
|
|
112
127
|
/**
|
|
113
128
|
* Represents a command-line usage description, which is a sequence of
|
package/dist/usage.d.ts
CHANGED
|
@@ -108,6 +108,21 @@ type UsageTerm =
|
|
|
108
108
|
* arguments, options, commands, or other usage terms.
|
|
109
109
|
*/
|
|
110
110
|
readonly terms: readonly Usage[];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* A literal term, which represents a fixed string value in the command-line
|
|
114
|
+
* usage. Unlike metavars which are placeholders for user-provided values,
|
|
115
|
+
* literals represent exact strings that must be typed as-is.
|
|
116
|
+
* @since 0.8.0
|
|
117
|
+
*/ | {
|
|
118
|
+
/**
|
|
119
|
+
* The type of the term, which is always `"literal"` for this term.
|
|
120
|
+
*/
|
|
121
|
+
readonly type: "literal";
|
|
122
|
+
/**
|
|
123
|
+
* The literal value that must be provided exactly as written.
|
|
124
|
+
*/
|
|
125
|
+
readonly value: string;
|
|
111
126
|
};
|
|
112
127
|
/**
|
|
113
128
|
* Represents a command-line usage description, which is a sequence of
|
package/dist/usage.js
CHANGED
|
@@ -326,7 +326,11 @@ function* formatUsageTermInternal(term, options) {
|
|
|
326
326
|
text: options?.colors ? `\x1b[2m]\x1b[0m` : "]",
|
|
327
327
|
width: 1
|
|
328
328
|
};
|
|
329
|
-
} else
|
|
329
|
+
} else if (term.type === "literal") yield {
|
|
330
|
+
text: term.value,
|
|
331
|
+
width: term.value.length
|
|
332
|
+
};
|
|
333
|
+
else throw new TypeError(`Unknown usage term type: ${term["type"]}.`);
|
|
330
334
|
}
|
|
331
335
|
|
|
332
336
|
//#endregion
|