@optique/core 0.9.0-dev.206 → 0.9.0-dev.211

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/modifiers.js CHANGED
@@ -9,31 +9,12 @@ 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 parseOptionalStyleSync(context, parser) {
12
+ function parseOptionalStyle(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) {
37
18
  if (result.success) {
38
19
  if (result.next.state !== innerState || result.consumed.length === 0) return {
39
20
  success: true,
@@ -64,7 +45,6 @@ function processOptionalStyleResult(result, innerState, context) {
64
45
  * without consuming input if the wrapped parser fails to match.
65
46
  * If the wrapped parser succeeds, this returns its value.
66
47
  * If the wrapped parser fails, this returns `undefined` without consuming input.
67
- * @template M The execution mode of the parser.
68
48
  * @template TValue The type of the value returned by the wrapped parser.
69
49
  * @template TState The type of the state used by the wrapped parser.
70
50
  * @param parser The {@link Parser} to make optional.
@@ -72,25 +52,7 @@ function processOptionalStyleResult(result, innerState, context) {
72
52
  * or `undefined` if the wrapped parser fails to match.
73
53
  */
74
54
  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
- }
92
55
  return {
93
- $mode: parser.$mode,
94
56
  $valueType: [],
95
57
  $stateType: [],
96
58
  priority: parser.priority,
@@ -100,27 +62,28 @@ function optional(parser) {
100
62
  }],
101
63
  initialState: void 0,
102
64
  parse(context) {
103
- if (isAsync) return parseOptionalStyleAsync(context, parser);
104
- return parseOptionalStyleSync(context, syncParser);
65
+ return parseOptionalStyle(context, parser);
105
66
  },
106
67
  complete(state) {
107
68
  if (typeof state === "undefined") return {
108
69
  success: true,
109
70
  value: void 0
110
71
  };
111
- if (!isAsync) return syncParser.complete(state[0]);
112
- return (async () => await parser.complete(state[0]))();
72
+ return parser.complete(state[0]);
113
73
  },
114
74
  suggest(context, prefix) {
115
- if (isAsync) return suggestAsync(context, prefix);
116
- return suggestSync(context, prefix);
75
+ const innerState = typeof context.state === "undefined" ? parser.initialState : context.state[0];
76
+ return parser.suggest({
77
+ ...context,
78
+ state: innerState
79
+ }, prefix);
117
80
  },
118
81
  getDocFragments(state, defaultValue) {
119
82
  const innerState = state.kind === "unavailable" ? { kind: "unavailable" } : state.state === void 0 ? { kind: "unavailable" } : {
120
83
  kind: "available",
121
84
  state: state.state[0]
122
85
  };
123
- return syncParser.getDocFragments(innerState, defaultValue);
86
+ return parser.getDocFragments(innerState, defaultValue);
124
87
  }
125
88
  };
126
89
  }
@@ -159,25 +122,7 @@ var WithDefaultError = class extends Error {
159
122
  }
160
123
  };
161
124
  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
- }
179
125
  return {
180
- $mode: parser.$mode,
181
126
  $valueType: [],
182
127
  $stateType: [],
183
128
  priority: parser.priority,
@@ -187,8 +132,7 @@ function withDefault(parser, defaultValue, options) {
187
132
  }],
188
133
  initialState: void 0,
189
134
  parse(context) {
190
- if (isAsync) return parseOptionalStyleAsync(context, parser);
191
- return parseOptionalStyleSync(context, syncParser);
135
+ return parseOptionalStyle(context, parser);
192
136
  },
193
137
  complete(state) {
194
138
  if (typeof state === "undefined") try {
@@ -203,12 +147,14 @@ function withDefault(parser, defaultValue, options) {
203
147
  error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
204
148
  };
205
149
  }
206
- if (!isAsync) return syncParser.complete(state[0]);
207
- return (async () => await parser.complete(state[0]))();
150
+ return parser.complete(state[0]);
208
151
  },
209
152
  suggest(context, prefix) {
210
- if (isAsync) return suggestAsync(context, prefix);
211
- return suggestSync(context, prefix);
153
+ const innerState = typeof context.state === "undefined" ? parser.initialState : context.state[0];
154
+ return parser.suggest({
155
+ ...context,
156
+ state: innerState
157
+ }, prefix);
212
158
  },
213
159
  getDocFragments(state, upperDefaultValue) {
214
160
  const innerState = state.kind === "unavailable" ? { kind: "unavailable" } : state.state === void 0 ? { kind: "unavailable" } : {
@@ -216,7 +162,7 @@ function withDefault(parser, defaultValue, options) {
216
162
  state: state.state[0]
217
163
  };
218
164
  const actualDefaultValue = upperDefaultValue != null ? upperDefaultValue : typeof defaultValue === "function" ? defaultValue() : defaultValue;
219
- const fragments = syncParser.getDocFragments(innerState, actualDefaultValue);
165
+ const fragments = parser.getDocFragments(innerState, actualDefaultValue);
220
166
  if (options?.message) {
221
167
  const modifiedFragments = fragments.fragments.map((fragment) => {
222
168
  if (fragment.type === "entry") return {
@@ -245,7 +191,6 @@ function withDefault(parser, defaultValue, options) {
245
191
  * - Computing derived values from parsed input
246
192
  * - Creating reusable transformations that can be applied to any parser
247
193
  *
248
- * @template M The execution mode of the parser.
249
194
  * @template T The type of the value produced by the original parser.
250
195
  * @template U The type of the value produced by the mapping function.
251
196
  * @template TState The type of the state used by the original parser.
@@ -269,68 +214,33 @@ function withDefault(parser, defaultValue, options) {
269
214
  * ```
270
215
  */
271
216
  function map(parser, transform) {
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",
217
+ return {
283
218
  $valueType: [],
284
219
  $stateType: parser.$stateType,
285
220
  priority: parser.priority,
286
221
  usage: parser.usage,
287
222
  initialState: parser.initialState,
288
- parse(context) {
289
- if (isAsync) return parser.parse(context);
290
- return syncParser.parse(context);
291
- },
223
+ parse: parser.parse.bind(parser),
292
224
  complete(state) {
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
- })();
225
+ const result = parser.complete(state);
226
+ if (result.success) return {
227
+ success: true,
228
+ value: transform(result.value)
229
+ };
230
+ return result;
315
231
  },
316
232
  suggest(context, prefix) {
317
- if (isAsync) return suggestAsync(context, prefix);
318
- return suggestSync(context, prefix);
233
+ return parser.suggest(context, prefix);
319
234
  },
320
235
  getDocFragments(state, _defaultValue) {
321
- return syncParser.getDocFragments(state, void 0);
236
+ return parser.getDocFragments(state, void 0);
322
237
  }
323
238
  };
324
- return {
325
- ...result,
326
- $mode: parser.$mode
327
- };
328
239
  }
329
240
  /**
330
241
  * Creates a parser that allows multiple occurrences of a given parser.
331
242
  * This parser can be used to parse multiple values of the same type,
332
243
  * such as multiple command-line arguments or options.
333
- * @template M The execution mode of the parser.
334
244
  * @template TValue The type of the value that the parser produces.
335
245
  * @template TState The type of the state used by the parser.
336
246
  * @param parser The {@link Parser} to apply multiple times.
@@ -342,59 +252,8 @@ function map(parser, transform) {
342
252
  * of type {@link TState}.
343
253
  */
344
254
  function multiple(parser, options = {}) {
345
- const syncParser = parser;
346
- const isAsync = parser.$mode === "async";
347
255
  const { min = 0, max = Infinity } = options;
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,
256
+ return {
398
257
  $valueType: [],
399
258
  $stateType: [],
400
259
  priority: parser.priority,
@@ -405,79 +264,71 @@ function multiple(parser, options = {}) {
405
264
  }],
406
265
  initialState: [],
407
266
  parse(context) {
408
- if (isAsync) return parseAsync(context);
409
- return parseSync(context);
267
+ let added = context.state.length < 1;
268
+ let result = parser.parse({
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
+ };
410
288
  },
411
289
  complete(state) {
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);
290
+ const result = [];
291
+ for (const s of state) {
292
+ const valueResult = parser.complete(s);
293
+ if (valueResult.success) result.push(valueResult.value);
294
+ else return {
295
+ success: false,
296
+ error: valueResult.error
297
+ };
423
298
  }
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
- })();
299
+ if (result.length < min) {
300
+ const customMessage = options.errors?.tooFew;
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
+ };
311
+ }
312
+ return {
313
+ success: true,
314
+ value: result
315
+ };
436
316
  },
437
317
  suggest(context, prefix) {
438
318
  const innerState = context.state.length > 0 ? context.state.at(-1) : parser.initialState;
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
- }();
319
+ return parser.suggest({
320
+ ...context,
321
+ state: innerState
322
+ }, prefix);
452
323
  },
453
324
  getDocFragments(state, defaultValue) {
454
325
  const innerState = state.kind === "unavailable" ? { kind: "unavailable" } : state.state.length > 0 ? {
455
326
  kind: "available",
456
327
  state: state.state.at(-1)
457
328
  } : { kind: "unavailable" };
458
- return syncParser.getDocFragments(innerState, defaultValue != null && defaultValue.length > 0 ? defaultValue[0] : void 0);
329
+ return parser.getDocFragments(innerState, defaultValue != null && defaultValue.length > 0 ? defaultValue[0] : void 0);
459
330
  }
460
331
  };
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;
481
332
  }
482
333
 
483
334
  //#endregion