@optique/core 0.9.0-dev.211 → 0.9.0-dev.212
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 +1332 -602
- package/dist/constructs.d.cts +182 -62
- package/dist/constructs.d.ts +182 -62
- package/dist/constructs.js +1332 -602
- package/dist/facade.cjs +188 -144
- package/dist/facade.d.cts +41 -3
- package/dist/facade.d.ts +41 -3
- package/dist/facade.js +187 -145
- package/dist/index.cjs +8 -0
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/modifiers.cjs +228 -79
- package/dist/modifiers.d.cts +11 -6
- package/dist/modifiers.d.ts +11 -6
- package/dist/modifiers.js +228 -79
- package/dist/parser.cjs +217 -33
- package/dist/parser.d.cts +202 -18
- package/dist/parser.d.ts +202 -18
- package/dist/parser.js +212 -34
- package/dist/primitives.cjs +242 -97
- package/dist/primitives.d.cts +14 -10
- package/dist/primitives.d.ts +14 -10
- package/dist/primitives.js +242 -97
- package/dist/valueparser.cjs +10 -1
- package/dist/valueparser.d.cts +29 -16
- package/dist/valueparser.d.ts +29 -16
- package/dist/valueparser.js +10 -1
- package/package.json +1 -1
package/dist/modifiers.js
CHANGED
|
@@ -9,12 +9,31 @@ import { formatMessage, message, text } from "./message.js";
|
|
|
9
9
|
* - Returning success with undefined state when inner parser fails without consuming
|
|
10
10
|
* @internal
|
|
11
11
|
*/
|
|
12
|
-
function
|
|
12
|
+
function parseOptionalStyleSync(context, parser) {
|
|
13
13
|
const innerState = typeof context.state === "undefined" ? parser.initialState : context.state[0];
|
|
14
14
|
const result = parser.parse({
|
|
15
15
|
...context,
|
|
16
16
|
state: innerState
|
|
17
17
|
});
|
|
18
|
+
return processOptionalStyleResult(result, innerState, context);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Internal async helper for optional-style parsing logic.
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
async function parseOptionalStyleAsync(context, parser) {
|
|
25
|
+
const innerState = typeof context.state === "undefined" ? parser.initialState : context.state[0];
|
|
26
|
+
const result = await parser.parse({
|
|
27
|
+
...context,
|
|
28
|
+
state: innerState
|
|
29
|
+
});
|
|
30
|
+
return processOptionalStyleResult(result, innerState, context);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Internal helper to process optional-style parse results.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
function processOptionalStyleResult(result, innerState, context) {
|
|
18
37
|
if (result.success) {
|
|
19
38
|
if (result.next.state !== innerState || result.consumed.length === 0) return {
|
|
20
39
|
success: true,
|
|
@@ -45,6 +64,7 @@ function parseOptionalStyle(context, parser) {
|
|
|
45
64
|
* without consuming input if the wrapped parser fails to match.
|
|
46
65
|
* If the wrapped parser succeeds, this returns its value.
|
|
47
66
|
* If the wrapped parser fails, this returns `undefined` without consuming input.
|
|
67
|
+
* @template M The execution mode of the parser.
|
|
48
68
|
* @template TValue The type of the value returned by the wrapped parser.
|
|
49
69
|
* @template TState The type of the state used by the wrapped parser.
|
|
50
70
|
* @param parser The {@link Parser} to make optional.
|
|
@@ -52,7 +72,25 @@ function parseOptionalStyle(context, parser) {
|
|
|
52
72
|
* or `undefined` if the wrapped parser fails to match.
|
|
53
73
|
*/
|
|
54
74
|
function optional(parser) {
|
|
75
|
+
const syncParser = parser;
|
|
76
|
+
const isAsync = parser.$mode === "async";
|
|
77
|
+
function* suggestSync(context, prefix) {
|
|
78
|
+
const innerState = typeof context.state === "undefined" ? syncParser.initialState : context.state[0];
|
|
79
|
+
yield* syncParser.suggest({
|
|
80
|
+
...context,
|
|
81
|
+
state: innerState
|
|
82
|
+
}, prefix);
|
|
83
|
+
}
|
|
84
|
+
async function* suggestAsync(context, prefix) {
|
|
85
|
+
const innerState = typeof context.state === "undefined" ? syncParser.initialState : context.state[0];
|
|
86
|
+
const suggestions = parser.suggest({
|
|
87
|
+
...context,
|
|
88
|
+
state: innerState
|
|
89
|
+
}, prefix);
|
|
90
|
+
for await (const s of suggestions) yield s;
|
|
91
|
+
}
|
|
55
92
|
return {
|
|
93
|
+
$mode: parser.$mode,
|
|
56
94
|
$valueType: [],
|
|
57
95
|
$stateType: [],
|
|
58
96
|
priority: parser.priority,
|
|
@@ -62,28 +100,27 @@ function optional(parser) {
|
|
|
62
100
|
}],
|
|
63
101
|
initialState: void 0,
|
|
64
102
|
parse(context) {
|
|
65
|
-
return
|
|
103
|
+
if (isAsync) return parseOptionalStyleAsync(context, parser);
|
|
104
|
+
return parseOptionalStyleSync(context, syncParser);
|
|
66
105
|
},
|
|
67
106
|
complete(state) {
|
|
68
107
|
if (typeof state === "undefined") return {
|
|
69
108
|
success: true,
|
|
70
109
|
value: void 0
|
|
71
110
|
};
|
|
72
|
-
return
|
|
111
|
+
if (!isAsync) return syncParser.complete(state[0]);
|
|
112
|
+
return (async () => await parser.complete(state[0]))();
|
|
73
113
|
},
|
|
74
114
|
suggest(context, prefix) {
|
|
75
|
-
|
|
76
|
-
return
|
|
77
|
-
...context,
|
|
78
|
-
state: innerState
|
|
79
|
-
}, prefix);
|
|
115
|
+
if (isAsync) return suggestAsync(context, prefix);
|
|
116
|
+
return suggestSync(context, prefix);
|
|
80
117
|
},
|
|
81
118
|
getDocFragments(state, defaultValue) {
|
|
82
119
|
const innerState = state.kind === "unavailable" ? { kind: "unavailable" } : state.state === void 0 ? { kind: "unavailable" } : {
|
|
83
120
|
kind: "available",
|
|
84
121
|
state: state.state[0]
|
|
85
122
|
};
|
|
86
|
-
return
|
|
123
|
+
return syncParser.getDocFragments(innerState, defaultValue);
|
|
87
124
|
}
|
|
88
125
|
};
|
|
89
126
|
}
|
|
@@ -122,7 +159,25 @@ var WithDefaultError = class extends Error {
|
|
|
122
159
|
}
|
|
123
160
|
};
|
|
124
161
|
function withDefault(parser, defaultValue, options) {
|
|
162
|
+
const syncParser = parser;
|
|
163
|
+
const isAsync = parser.$mode === "async";
|
|
164
|
+
function* suggestSync(context, prefix) {
|
|
165
|
+
const innerState = typeof context.state === "undefined" ? syncParser.initialState : context.state[0];
|
|
166
|
+
yield* syncParser.suggest({
|
|
167
|
+
...context,
|
|
168
|
+
state: innerState
|
|
169
|
+
}, prefix);
|
|
170
|
+
}
|
|
171
|
+
async function* suggestAsync(context, prefix) {
|
|
172
|
+
const innerState = typeof context.state === "undefined" ? syncParser.initialState : context.state[0];
|
|
173
|
+
const suggestions = parser.suggest({
|
|
174
|
+
...context,
|
|
175
|
+
state: innerState
|
|
176
|
+
}, prefix);
|
|
177
|
+
for await (const s of suggestions) yield s;
|
|
178
|
+
}
|
|
125
179
|
return {
|
|
180
|
+
$mode: parser.$mode,
|
|
126
181
|
$valueType: [],
|
|
127
182
|
$stateType: [],
|
|
128
183
|
priority: parser.priority,
|
|
@@ -132,7 +187,8 @@ function withDefault(parser, defaultValue, options) {
|
|
|
132
187
|
}],
|
|
133
188
|
initialState: void 0,
|
|
134
189
|
parse(context) {
|
|
135
|
-
return
|
|
190
|
+
if (isAsync) return parseOptionalStyleAsync(context, parser);
|
|
191
|
+
return parseOptionalStyleSync(context, syncParser);
|
|
136
192
|
},
|
|
137
193
|
complete(state) {
|
|
138
194
|
if (typeof state === "undefined") try {
|
|
@@ -147,14 +203,12 @@ function withDefault(parser, defaultValue, options) {
|
|
|
147
203
|
error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
|
|
148
204
|
};
|
|
149
205
|
}
|
|
150
|
-
return
|
|
206
|
+
if (!isAsync) return syncParser.complete(state[0]);
|
|
207
|
+
return (async () => await parser.complete(state[0]))();
|
|
151
208
|
},
|
|
152
209
|
suggest(context, prefix) {
|
|
153
|
-
|
|
154
|
-
return
|
|
155
|
-
...context,
|
|
156
|
-
state: innerState
|
|
157
|
-
}, prefix);
|
|
210
|
+
if (isAsync) return suggestAsync(context, prefix);
|
|
211
|
+
return suggestSync(context, prefix);
|
|
158
212
|
},
|
|
159
213
|
getDocFragments(state, upperDefaultValue) {
|
|
160
214
|
const innerState = state.kind === "unavailable" ? { kind: "unavailable" } : state.state === void 0 ? { kind: "unavailable" } : {
|
|
@@ -162,7 +216,7 @@ function withDefault(parser, defaultValue, options) {
|
|
|
162
216
|
state: state.state[0]
|
|
163
217
|
};
|
|
164
218
|
const actualDefaultValue = upperDefaultValue != null ? upperDefaultValue : typeof defaultValue === "function" ? defaultValue() : defaultValue;
|
|
165
|
-
const fragments =
|
|
219
|
+
const fragments = syncParser.getDocFragments(innerState, actualDefaultValue);
|
|
166
220
|
if (options?.message) {
|
|
167
221
|
const modifiedFragments = fragments.fragments.map((fragment) => {
|
|
168
222
|
if (fragment.type === "entry") return {
|
|
@@ -191,6 +245,7 @@ function withDefault(parser, defaultValue, options) {
|
|
|
191
245
|
* - Computing derived values from parsed input
|
|
192
246
|
* - Creating reusable transformations that can be applied to any parser
|
|
193
247
|
*
|
|
248
|
+
* @template M The execution mode of the parser.
|
|
194
249
|
* @template T The type of the value produced by the original parser.
|
|
195
250
|
* @template U The type of the value produced by the mapping function.
|
|
196
251
|
* @template TState The type of the state used by the original parser.
|
|
@@ -214,33 +269,68 @@ function withDefault(parser, defaultValue, options) {
|
|
|
214
269
|
* ```
|
|
215
270
|
*/
|
|
216
271
|
function map(parser, transform) {
|
|
217
|
-
|
|
272
|
+
const syncParser = parser;
|
|
273
|
+
const isAsync = parser.$mode === "async";
|
|
274
|
+
function* suggestSync(context, prefix) {
|
|
275
|
+
yield* syncParser.suggest(context, prefix);
|
|
276
|
+
}
|
|
277
|
+
async function* suggestAsync(context, prefix) {
|
|
278
|
+
const suggestions = parser.suggest(context, prefix);
|
|
279
|
+
for await (const s of suggestions) yield s;
|
|
280
|
+
}
|
|
281
|
+
const result = {
|
|
282
|
+
$mode: "sync",
|
|
218
283
|
$valueType: [],
|
|
219
284
|
$stateType: parser.$stateType,
|
|
220
285
|
priority: parser.priority,
|
|
221
286
|
usage: parser.usage,
|
|
222
287
|
initialState: parser.initialState,
|
|
223
|
-
parse
|
|
288
|
+
parse(context) {
|
|
289
|
+
if (isAsync) return parser.parse(context);
|
|
290
|
+
return syncParser.parse(context);
|
|
291
|
+
},
|
|
224
292
|
complete(state) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
success
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
293
|
+
if (!isAsync) {
|
|
294
|
+
const innerResult = syncParser.complete(state);
|
|
295
|
+
if (innerResult.success) return {
|
|
296
|
+
success: true,
|
|
297
|
+
value: transform(innerResult.value)
|
|
298
|
+
};
|
|
299
|
+
return {
|
|
300
|
+
success: false,
|
|
301
|
+
error: innerResult.error
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
return (async () => {
|
|
305
|
+
const innerResult = await parser.complete(state);
|
|
306
|
+
if (innerResult.success) return {
|
|
307
|
+
success: true,
|
|
308
|
+
value: transform(innerResult.value)
|
|
309
|
+
};
|
|
310
|
+
return {
|
|
311
|
+
success: false,
|
|
312
|
+
error: innerResult.error
|
|
313
|
+
};
|
|
314
|
+
})();
|
|
231
315
|
},
|
|
232
316
|
suggest(context, prefix) {
|
|
233
|
-
return
|
|
317
|
+
if (isAsync) return suggestAsync(context, prefix);
|
|
318
|
+
return suggestSync(context, prefix);
|
|
234
319
|
},
|
|
235
320
|
getDocFragments(state, _defaultValue) {
|
|
236
|
-
return
|
|
321
|
+
return syncParser.getDocFragments(state, void 0);
|
|
237
322
|
}
|
|
238
323
|
};
|
|
324
|
+
return {
|
|
325
|
+
...result,
|
|
326
|
+
$mode: parser.$mode
|
|
327
|
+
};
|
|
239
328
|
}
|
|
240
329
|
/**
|
|
241
330
|
* Creates a parser that allows multiple occurrences of a given parser.
|
|
242
331
|
* This parser can be used to parse multiple values of the same type,
|
|
243
332
|
* such as multiple command-line arguments or options.
|
|
333
|
+
* @template M The execution mode of the parser.
|
|
244
334
|
* @template TValue The type of the value that the parser produces.
|
|
245
335
|
* @template TState The type of the state used by the parser.
|
|
246
336
|
* @param parser The {@link Parser} to apply multiple times.
|
|
@@ -252,8 +342,59 @@ function map(parser, transform) {
|
|
|
252
342
|
* of type {@link TState}.
|
|
253
343
|
*/
|
|
254
344
|
function multiple(parser, options = {}) {
|
|
345
|
+
const syncParser = parser;
|
|
346
|
+
const isAsync = parser.$mode === "async";
|
|
255
347
|
const { min = 0, max = Infinity } = options;
|
|
256
|
-
|
|
348
|
+
const parseSync = (context) => {
|
|
349
|
+
let added = context.state.length < 1;
|
|
350
|
+
let result = syncParser.parse({
|
|
351
|
+
...context,
|
|
352
|
+
state: context.state.at(-1) ?? syncParser.initialState
|
|
353
|
+
});
|
|
354
|
+
if (!result.success) if (!added) {
|
|
355
|
+
result = syncParser.parse({
|
|
356
|
+
...context,
|
|
357
|
+
state: syncParser.initialState
|
|
358
|
+
});
|
|
359
|
+
if (!result.success) return result;
|
|
360
|
+
added = true;
|
|
361
|
+
} else return result;
|
|
362
|
+
return {
|
|
363
|
+
success: true,
|
|
364
|
+
next: {
|
|
365
|
+
...result.next,
|
|
366
|
+
state: [...added ? context.state : context.state.slice(0, -1), result.next.state]
|
|
367
|
+
},
|
|
368
|
+
consumed: result.consumed
|
|
369
|
+
};
|
|
370
|
+
};
|
|
371
|
+
const parseAsync = async (context) => {
|
|
372
|
+
let added = context.state.length < 1;
|
|
373
|
+
let resultOrPromise = parser.parse({
|
|
374
|
+
...context,
|
|
375
|
+
state: context.state.at(-1) ?? parser.initialState
|
|
376
|
+
});
|
|
377
|
+
let result = await resultOrPromise;
|
|
378
|
+
if (!result.success) if (!added) {
|
|
379
|
+
resultOrPromise = parser.parse({
|
|
380
|
+
...context,
|
|
381
|
+
state: parser.initialState
|
|
382
|
+
});
|
|
383
|
+
result = await resultOrPromise;
|
|
384
|
+
if (!result.success) return result;
|
|
385
|
+
added = true;
|
|
386
|
+
} else return result;
|
|
387
|
+
return {
|
|
388
|
+
success: true,
|
|
389
|
+
next: {
|
|
390
|
+
...result.next,
|
|
391
|
+
state: [...added ? context.state : context.state.slice(0, -1), result.next.state]
|
|
392
|
+
},
|
|
393
|
+
consumed: result.consumed
|
|
394
|
+
};
|
|
395
|
+
};
|
|
396
|
+
const resultParser = {
|
|
397
|
+
$mode: parser.$mode,
|
|
257
398
|
$valueType: [],
|
|
258
399
|
$stateType: [],
|
|
259
400
|
priority: parser.priority,
|
|
@@ -264,71 +405,79 @@ function multiple(parser, options = {}) {
|
|
|
264
405
|
}],
|
|
265
406
|
initialState: [],
|
|
266
407
|
parse(context) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
...context,
|
|
270
|
-
state: context.state.at(-1) ?? parser.initialState
|
|
271
|
-
});
|
|
272
|
-
if (!result.success) if (!added) {
|
|
273
|
-
result = parser.parse({
|
|
274
|
-
...context,
|
|
275
|
-
state: parser.initialState
|
|
276
|
-
});
|
|
277
|
-
if (!result.success) return result;
|
|
278
|
-
added = true;
|
|
279
|
-
} else return result;
|
|
280
|
-
return {
|
|
281
|
-
success: true,
|
|
282
|
-
next: {
|
|
283
|
-
...result.next,
|
|
284
|
-
state: [...added ? context.state : context.state.slice(0, -1), result.next.state]
|
|
285
|
-
},
|
|
286
|
-
consumed: result.consumed
|
|
287
|
-
};
|
|
408
|
+
if (isAsync) return parseAsync(context);
|
|
409
|
+
return parseSync(context);
|
|
288
410
|
},
|
|
289
411
|
complete(state) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
return {
|
|
302
|
-
success: false,
|
|
303
|
-
error: customMessage ? typeof customMessage === "function" ? customMessage(min, result.length) : customMessage : message`Expected at least ${text(min.toLocaleString("en"))} values, but got only ${text(result.length.toLocaleString("en"))}.`
|
|
304
|
-
};
|
|
305
|
-
} else if (result.length > max) {
|
|
306
|
-
const customMessage = options.errors?.tooMany;
|
|
307
|
-
return {
|
|
308
|
-
success: false,
|
|
309
|
-
error: customMessage ? typeof customMessage === "function" ? customMessage(max, result.length) : customMessage : message`Expected at most ${text(max.toLocaleString("en"))} values, but got ${text(result.length.toLocaleString("en"))}.`
|
|
310
|
-
};
|
|
412
|
+
if (!isAsync) {
|
|
413
|
+
const result = [];
|
|
414
|
+
for (const s of state) {
|
|
415
|
+
const valueResult = syncParser.complete(s);
|
|
416
|
+
if (valueResult.success) result.push(valueResult.value);
|
|
417
|
+
else return {
|
|
418
|
+
success: false,
|
|
419
|
+
error: valueResult.error
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
return validateMultipleResult(result);
|
|
311
423
|
}
|
|
312
|
-
return {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
424
|
+
return (async () => {
|
|
425
|
+
const result = [];
|
|
426
|
+
for (const s of state) {
|
|
427
|
+
const valueResult = await parser.complete(s);
|
|
428
|
+
if (valueResult.success) result.push(valueResult.value);
|
|
429
|
+
else return {
|
|
430
|
+
success: false,
|
|
431
|
+
error: valueResult.error
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
return validateMultipleResult(result);
|
|
435
|
+
})();
|
|
316
436
|
},
|
|
317
437
|
suggest(context, prefix) {
|
|
318
438
|
const innerState = context.state.length > 0 ? context.state.at(-1) : parser.initialState;
|
|
319
|
-
return
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
439
|
+
if (isAsync) return async function* () {
|
|
440
|
+
const suggestions = parser.suggest({
|
|
441
|
+
...context,
|
|
442
|
+
state: innerState
|
|
443
|
+
}, prefix);
|
|
444
|
+
for await (const s of suggestions) yield s;
|
|
445
|
+
}();
|
|
446
|
+
return function* () {
|
|
447
|
+
yield* syncParser.suggest({
|
|
448
|
+
...context,
|
|
449
|
+
state: innerState
|
|
450
|
+
}, prefix);
|
|
451
|
+
}();
|
|
323
452
|
},
|
|
324
453
|
getDocFragments(state, defaultValue) {
|
|
325
454
|
const innerState = state.kind === "unavailable" ? { kind: "unavailable" } : state.state.length > 0 ? {
|
|
326
455
|
kind: "available",
|
|
327
456
|
state: state.state.at(-1)
|
|
328
457
|
} : { kind: "unavailable" };
|
|
329
|
-
return
|
|
458
|
+
return syncParser.getDocFragments(innerState, defaultValue != null && defaultValue.length > 0 ? defaultValue[0] : void 0);
|
|
330
459
|
}
|
|
331
460
|
};
|
|
461
|
+
function validateMultipleResult(result) {
|
|
462
|
+
if (result.length < min) {
|
|
463
|
+
const customMessage = options.errors?.tooFew;
|
|
464
|
+
return {
|
|
465
|
+
success: false,
|
|
466
|
+
error: customMessage ? typeof customMessage === "function" ? customMessage(min, result.length) : customMessage : message`Expected at least ${text(min.toLocaleString("en"))} values, but got only ${text(result.length.toLocaleString("en"))}.`
|
|
467
|
+
};
|
|
468
|
+
} else if (result.length > max) {
|
|
469
|
+
const customMessage = options.errors?.tooMany;
|
|
470
|
+
return {
|
|
471
|
+
success: false,
|
|
472
|
+
error: customMessage ? typeof customMessage === "function" ? customMessage(max, result.length) : customMessage : message`Expected at most ${text(max.toLocaleString("en"))} values, but got ${text(result.length.toLocaleString("en"))}.`
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
return {
|
|
476
|
+
success: true,
|
|
477
|
+
value: result
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
return resultParser;
|
|
332
481
|
}
|
|
333
482
|
|
|
334
483
|
//#endregion
|