@optique/core 1.0.0-dev.1681 → 1.0.0-dev.1682
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/facade.cjs +116 -69
- package/dist/facade.d.cts +0 -50
- package/dist/facade.d.ts +0 -50
- package/dist/facade.js +116 -69
- package/package.json +1 -1
package/dist/facade.cjs
CHANGED
|
@@ -12,6 +12,19 @@ const require_parser = require('./parser.cjs');
|
|
|
12
12
|
const require_constructs = require('./constructs.cjs');
|
|
13
13
|
|
|
14
14
|
//#region src/facade.ts
|
|
15
|
+
const SuppressedErrorCtor = typeof SuppressedError === "function" ? SuppressedError : (() => {
|
|
16
|
+
class SuppressedErrorPolyfill extends Error {
|
|
17
|
+
error;
|
|
18
|
+
suppressed;
|
|
19
|
+
constructor(error, suppressed, message$1) {
|
|
20
|
+
super(message$1);
|
|
21
|
+
this.name = "SuppressedError";
|
|
22
|
+
this.error = error;
|
|
23
|
+
this.suppressed = suppressed;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return SuppressedErrorPolyfill;
|
|
27
|
+
})();
|
|
15
28
|
function finalizeParsedForContext(context, parsed) {
|
|
16
29
|
return context.finalizeParsed != null ? context.finalizeParsed(parsed) : parsed;
|
|
17
30
|
}
|
|
@@ -1216,57 +1229,104 @@ function disposeContextsSync(contexts) {
|
|
|
1216
1229
|
* );
|
|
1217
1230
|
* ```
|
|
1218
1231
|
*/
|
|
1232
|
+
async function runWithBody(parser, programName, contexts, args, options) {
|
|
1233
|
+
require_validate.validateContextIds(contexts);
|
|
1234
|
+
if (needsEarlyExit(args, options)) {
|
|
1235
|
+
if (parser.$mode === "async") return runParser(parser, programName, args, options);
|
|
1236
|
+
return Promise.resolve(runParser(parser, programName, args, options));
|
|
1237
|
+
}
|
|
1238
|
+
const ctxOptions = options?.contextOptions;
|
|
1239
|
+
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, ctxOptions);
|
|
1240
|
+
if (!needsTwoPhase) {
|
|
1241
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1242
|
+
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1243
|
+
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1244
|
+
}
|
|
1245
|
+
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1246
|
+
let firstPassResult;
|
|
1247
|
+
let firstPassDeferred;
|
|
1248
|
+
let firstPassDeferredKeys;
|
|
1249
|
+
let firstPassFailed = false;
|
|
1250
|
+
try {
|
|
1251
|
+
if (parser.$mode === "async") firstPassResult = await require_parser.parseAsync(augmentedParser1, args);
|
|
1252
|
+
else firstPassResult = require_parser.parseSync(augmentedParser1, args);
|
|
1253
|
+
if (typeof firstPassResult === "object" && firstPassResult !== null && "success" in firstPassResult) {
|
|
1254
|
+
const result = firstPassResult;
|
|
1255
|
+
if (result.success) {
|
|
1256
|
+
firstPassResult = result.value;
|
|
1257
|
+
firstPassDeferred = result.deferred;
|
|
1258
|
+
firstPassDeferredKeys = result.deferredKeys;
|
|
1259
|
+
} else firstPassFailed = true;
|
|
1260
|
+
}
|
|
1261
|
+
} catch {
|
|
1262
|
+
firstPassFailed = true;
|
|
1263
|
+
}
|
|
1264
|
+
if (firstPassFailed) {
|
|
1265
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1266
|
+
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1267
|
+
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1268
|
+
}
|
|
1269
|
+
const { annotationsList: phase2AnnotationsList } = await collectAnnotations(contexts, firstPassResult, ctxOptions, firstPassDeferred, firstPassDeferredKeys);
|
|
1270
|
+
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1271
|
+
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1272
|
+
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
1273
|
+
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
1274
|
+
}
|
|
1219
1275
|
async function runWith(parser, programName, contexts, options) {
|
|
1220
1276
|
const args = options?.args ?? [];
|
|
1221
1277
|
if (contexts.length === 0) {
|
|
1222
1278
|
if (parser.$mode === "async") return runParser(parser, programName, args, options);
|
|
1223
1279
|
return Promise.resolve(runParser(parser, programName, args, options));
|
|
1224
1280
|
}
|
|
1281
|
+
let result;
|
|
1282
|
+
let primaryError;
|
|
1283
|
+
let hasPrimaryError = false;
|
|
1284
|
+
try {
|
|
1285
|
+
result = await runWithBody(parser, programName, contexts, args, options);
|
|
1286
|
+
} catch (error) {
|
|
1287
|
+
hasPrimaryError = true;
|
|
1288
|
+
primaryError = error;
|
|
1289
|
+
}
|
|
1225
1290
|
try {
|
|
1226
|
-
require_validate.validateContextIds(contexts);
|
|
1227
|
-
if (needsEarlyExit(args, options)) {
|
|
1228
|
-
if (parser.$mode === "async") return runParser(parser, programName, args, options);
|
|
1229
|
-
return Promise.resolve(runParser(parser, programName, args, options));
|
|
1230
|
-
}
|
|
1231
|
-
const ctxOptions = options?.contextOptions;
|
|
1232
|
-
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, ctxOptions);
|
|
1233
|
-
if (!needsTwoPhase) {
|
|
1234
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1235
|
-
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1236
|
-
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1237
|
-
}
|
|
1238
|
-
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1239
|
-
let firstPassResult;
|
|
1240
|
-
let firstPassDeferred;
|
|
1241
|
-
let firstPassDeferredKeys;
|
|
1242
|
-
let firstPassFailed = false;
|
|
1243
|
-
try {
|
|
1244
|
-
if (parser.$mode === "async") firstPassResult = await require_parser.parseAsync(augmentedParser1, args);
|
|
1245
|
-
else firstPassResult = require_parser.parseSync(augmentedParser1, args);
|
|
1246
|
-
if (typeof firstPassResult === "object" && firstPassResult !== null && "success" in firstPassResult) {
|
|
1247
|
-
const result = firstPassResult;
|
|
1248
|
-
if (result.success) {
|
|
1249
|
-
firstPassResult = result.value;
|
|
1250
|
-
firstPassDeferred = result.deferred;
|
|
1251
|
-
firstPassDeferredKeys = result.deferredKeys;
|
|
1252
|
-
} else firstPassFailed = true;
|
|
1253
|
-
}
|
|
1254
|
-
} catch {
|
|
1255
|
-
firstPassFailed = true;
|
|
1256
|
-
}
|
|
1257
|
-
if (firstPassFailed) {
|
|
1258
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1259
|
-
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1260
|
-
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1261
|
-
}
|
|
1262
|
-
const { annotationsList: phase2AnnotationsList } = await collectAnnotations(contexts, firstPassResult, ctxOptions, firstPassDeferred, firstPassDeferredKeys);
|
|
1263
|
-
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1264
|
-
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1265
|
-
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
1266
|
-
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
1267
|
-
} finally {
|
|
1268
1291
|
await disposeContexts(contexts);
|
|
1292
|
+
} catch (disposeError) {
|
|
1293
|
+
if (hasPrimaryError) throw new SuppressedErrorCtor(disposeError, primaryError, "An error was suppressed during context disposal.");
|
|
1294
|
+
throw disposeError;
|
|
1295
|
+
}
|
|
1296
|
+
if (hasPrimaryError) throw primaryError;
|
|
1297
|
+
return result;
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Body of {@link runWithSync}, extracted so that the caller can handle
|
|
1301
|
+
* disposal outside a `finally` block (avoiding `no-unsafe-finally` lint).
|
|
1302
|
+
*/
|
|
1303
|
+
function runWithSyncBody(parser, programName, contexts, args, options) {
|
|
1304
|
+
require_validate.validateContextIds(contexts);
|
|
1305
|
+
if (needsEarlyExit(args, options)) return runParser(parser, programName, args, options);
|
|
1306
|
+
const ctxOptions = options?.contextOptions;
|
|
1307
|
+
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, ctxOptions);
|
|
1308
|
+
if (!needsTwoPhase) {
|
|
1309
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1310
|
+
return runParser(augmentedParser, programName, args, options);
|
|
1311
|
+
}
|
|
1312
|
+
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1313
|
+
let firstPassResult;
|
|
1314
|
+
let firstPassDeferred;
|
|
1315
|
+
let firstPassDeferredKeys;
|
|
1316
|
+
try {
|
|
1317
|
+
const result = require_parser.parseSync(augmentedParser1, args);
|
|
1318
|
+
if (result.success) {
|
|
1319
|
+
firstPassResult = result.value;
|
|
1320
|
+
firstPassDeferred = result.deferred;
|
|
1321
|
+
firstPassDeferredKeys = result.deferredKeys;
|
|
1322
|
+
} else return runParser(augmentedParser1, programName, args, options);
|
|
1323
|
+
} catch {
|
|
1324
|
+
return runParser(augmentedParser1, programName, args, options);
|
|
1269
1325
|
}
|
|
1326
|
+
const { annotationsList: phase2AnnotationsList } = collectAnnotationsSync(contexts, firstPassResult, ctxOptions, firstPassDeferred, firstPassDeferredKeys);
|
|
1327
|
+
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1328
|
+
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1329
|
+
return runParser(augmentedParser2, programName, args, options);
|
|
1270
1330
|
}
|
|
1271
1331
|
/**
|
|
1272
1332
|
* Runs a synchronous parser with multiple source contexts.
|
|
@@ -1294,36 +1354,23 @@ function runWithSync(parser, programName, contexts, options) {
|
|
|
1294
1354
|
if (parser.$mode !== "sync") throw new TypeError("Cannot use an async parser with runWithSync(). Use runWith() or runWithAsync() instead.");
|
|
1295
1355
|
const args = options?.args ?? [];
|
|
1296
1356
|
if (contexts.length === 0) return runParser(parser, programName, args, options);
|
|
1357
|
+
let result;
|
|
1358
|
+
let primaryError;
|
|
1359
|
+
let hasPrimaryError = false;
|
|
1360
|
+
try {
|
|
1361
|
+
result = runWithSyncBody(parser, programName, contexts, args, options);
|
|
1362
|
+
} catch (error) {
|
|
1363
|
+
hasPrimaryError = true;
|
|
1364
|
+
primaryError = error;
|
|
1365
|
+
}
|
|
1297
1366
|
try {
|
|
1298
|
-
require_validate.validateContextIds(contexts);
|
|
1299
|
-
if (needsEarlyExit(args, options)) return runParser(parser, programName, args, options);
|
|
1300
|
-
const ctxOptions = options?.contextOptions;
|
|
1301
|
-
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, ctxOptions);
|
|
1302
|
-
if (!needsTwoPhase) {
|
|
1303
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1304
|
-
return runParser(augmentedParser, programName, args, options);
|
|
1305
|
-
}
|
|
1306
|
-
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1307
|
-
let firstPassResult;
|
|
1308
|
-
let firstPassDeferred;
|
|
1309
|
-
let firstPassDeferredKeys;
|
|
1310
|
-
try {
|
|
1311
|
-
const result = require_parser.parseSync(augmentedParser1, args);
|
|
1312
|
-
if (result.success) {
|
|
1313
|
-
firstPassResult = result.value;
|
|
1314
|
-
firstPassDeferred = result.deferred;
|
|
1315
|
-
firstPassDeferredKeys = result.deferredKeys;
|
|
1316
|
-
} else return runParser(augmentedParser1, programName, args, options);
|
|
1317
|
-
} catch {
|
|
1318
|
-
return runParser(augmentedParser1, programName, args, options);
|
|
1319
|
-
}
|
|
1320
|
-
const { annotationsList: phase2AnnotationsList } = collectAnnotationsSync(contexts, firstPassResult, ctxOptions, firstPassDeferred, firstPassDeferredKeys);
|
|
1321
|
-
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1322
|
-
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1323
|
-
return runParser(augmentedParser2, programName, args, options);
|
|
1324
|
-
} finally {
|
|
1325
1367
|
disposeContextsSync(contexts);
|
|
1368
|
+
} catch (disposeError) {
|
|
1369
|
+
if (hasPrimaryError) throw new SuppressedErrorCtor(disposeError, primaryError, "An error was suppressed during context disposal.");
|
|
1370
|
+
throw disposeError;
|
|
1326
1371
|
}
|
|
1372
|
+
if (hasPrimaryError) throw primaryError;
|
|
1373
|
+
return result;
|
|
1327
1374
|
}
|
|
1328
1375
|
/**
|
|
1329
1376
|
* Runs any parser asynchronously with multiple source contexts.
|
package/dist/facade.d.cts
CHANGED
|
@@ -402,56 +402,6 @@ type ContextOptionsParam<TContexts extends readonly SourceContext<unknown>[], TV
|
|
|
402
402
|
} : {
|
|
403
403
|
readonly contextOptions: ExtractRequiredOptions<TContexts, TValue>;
|
|
404
404
|
};
|
|
405
|
-
/**
|
|
406
|
-
* Runs a parser with multiple source contexts.
|
|
407
|
-
*
|
|
408
|
-
* This function automatically handles static and dynamic contexts with proper
|
|
409
|
-
* priority. Earlier contexts in the array override later ones.
|
|
410
|
-
*
|
|
411
|
-
* The function uses a smart two-phase approach:
|
|
412
|
-
*
|
|
413
|
-
* 1. *Phase 1*: Collect annotations from all contexts (static contexts return
|
|
414
|
-
* their data, dynamic contexts may return empty).
|
|
415
|
-
* 2. *First parse*: Parse with Phase 1 annotations.
|
|
416
|
-
* 3. *Phase 2*: Call `getAnnotations(parsed)` on all contexts with the first
|
|
417
|
-
* parse result.
|
|
418
|
-
* 4. *Second parse*: Parse again with merged annotations from both phases.
|
|
419
|
-
*
|
|
420
|
-
* If all contexts are static (no dynamic contexts), the second parse is skipped
|
|
421
|
-
* for optimization.
|
|
422
|
-
*
|
|
423
|
-
* @template TParser The parser type.
|
|
424
|
-
* @template THelp Return type when help is shown.
|
|
425
|
-
* @template TError Return type when an error occurs.
|
|
426
|
-
* @param parser The parser to execute.
|
|
427
|
-
* @param programName Name of the program for help/error output.
|
|
428
|
-
* @param contexts Source contexts to use (priority: earlier overrides later).
|
|
429
|
-
* @param options Run options including args, help, version, etc.
|
|
430
|
-
* @returns Promise that resolves to the parsed result.
|
|
431
|
-
* @throws {TypeError} If two or more contexts share the same
|
|
432
|
-
* {@link SourceContext.id}.
|
|
433
|
-
* @since 0.10.0
|
|
434
|
-
*
|
|
435
|
-
* @example
|
|
436
|
-
* ```typescript
|
|
437
|
-
* import { runWith } from "@optique/core/facade";
|
|
438
|
-
* import type { SourceContext } from "@optique/core/context";
|
|
439
|
-
*
|
|
440
|
-
* const envContext: SourceContext = {
|
|
441
|
-
* id: Symbol.for("@myapp/env"),
|
|
442
|
-
* getAnnotations() {
|
|
443
|
-
* return { [Symbol.for("@myapp/env")]: process.env };
|
|
444
|
-
* }
|
|
445
|
-
* };
|
|
446
|
-
*
|
|
447
|
-
* const result = await runWith(
|
|
448
|
-
* parser,
|
|
449
|
-
* "myapp",
|
|
450
|
-
* [envContext],
|
|
451
|
-
* { args: process.argv.slice(2) }
|
|
452
|
-
* );
|
|
453
|
-
* ```
|
|
454
|
-
*/
|
|
455
405
|
declare function runWith<TParser extends Parser<Mode, unknown, unknown>, TContexts extends readonly SourceContext<unknown>[], THelp = void, TError = never>(parser: TParser, programName: string, contexts: TContexts, options: RunWithOptions<THelp, TError> & ContextOptionsParam<TContexts, InferValue<TParser>>): Promise<InferValue<TParser>>;
|
|
456
406
|
/**
|
|
457
407
|
* Runs a synchronous parser with multiple source contexts.
|
package/dist/facade.d.ts
CHANGED
|
@@ -402,56 +402,6 @@ type ContextOptionsParam<TContexts extends readonly SourceContext<unknown>[], TV
|
|
|
402
402
|
} : {
|
|
403
403
|
readonly contextOptions: ExtractRequiredOptions<TContexts, TValue>;
|
|
404
404
|
};
|
|
405
|
-
/**
|
|
406
|
-
* Runs a parser with multiple source contexts.
|
|
407
|
-
*
|
|
408
|
-
* This function automatically handles static and dynamic contexts with proper
|
|
409
|
-
* priority. Earlier contexts in the array override later ones.
|
|
410
|
-
*
|
|
411
|
-
* The function uses a smart two-phase approach:
|
|
412
|
-
*
|
|
413
|
-
* 1. *Phase 1*: Collect annotations from all contexts (static contexts return
|
|
414
|
-
* their data, dynamic contexts may return empty).
|
|
415
|
-
* 2. *First parse*: Parse with Phase 1 annotations.
|
|
416
|
-
* 3. *Phase 2*: Call `getAnnotations(parsed)` on all contexts with the first
|
|
417
|
-
* parse result.
|
|
418
|
-
* 4. *Second parse*: Parse again with merged annotations from both phases.
|
|
419
|
-
*
|
|
420
|
-
* If all contexts are static (no dynamic contexts), the second parse is skipped
|
|
421
|
-
* for optimization.
|
|
422
|
-
*
|
|
423
|
-
* @template TParser The parser type.
|
|
424
|
-
* @template THelp Return type when help is shown.
|
|
425
|
-
* @template TError Return type when an error occurs.
|
|
426
|
-
* @param parser The parser to execute.
|
|
427
|
-
* @param programName Name of the program for help/error output.
|
|
428
|
-
* @param contexts Source contexts to use (priority: earlier overrides later).
|
|
429
|
-
* @param options Run options including args, help, version, etc.
|
|
430
|
-
* @returns Promise that resolves to the parsed result.
|
|
431
|
-
* @throws {TypeError} If two or more contexts share the same
|
|
432
|
-
* {@link SourceContext.id}.
|
|
433
|
-
* @since 0.10.0
|
|
434
|
-
*
|
|
435
|
-
* @example
|
|
436
|
-
* ```typescript
|
|
437
|
-
* import { runWith } from "@optique/core/facade";
|
|
438
|
-
* import type { SourceContext } from "@optique/core/context";
|
|
439
|
-
*
|
|
440
|
-
* const envContext: SourceContext = {
|
|
441
|
-
* id: Symbol.for("@myapp/env"),
|
|
442
|
-
* getAnnotations() {
|
|
443
|
-
* return { [Symbol.for("@myapp/env")]: process.env };
|
|
444
|
-
* }
|
|
445
|
-
* };
|
|
446
|
-
*
|
|
447
|
-
* const result = await runWith(
|
|
448
|
-
* parser,
|
|
449
|
-
* "myapp",
|
|
450
|
-
* [envContext],
|
|
451
|
-
* { args: process.argv.slice(2) }
|
|
452
|
-
* );
|
|
453
|
-
* ```
|
|
454
|
-
*/
|
|
455
405
|
declare function runWith<TParser extends Parser<Mode, unknown, unknown>, TContexts extends readonly SourceContext<unknown>[], THelp = void, TError = never>(parser: TParser, programName: string, contexts: TContexts, options: RunWithOptions<THelp, TError> & ContextOptionsParam<TContexts, InferValue<TParser>>): Promise<InferValue<TParser>>;
|
|
456
406
|
/**
|
|
457
407
|
* Runs a synchronous parser with multiple source contexts.
|
package/dist/facade.js
CHANGED
|
@@ -12,6 +12,19 @@ import { getDocPage, parseAsync, parseSync, suggest, suggestAsync } from "./pars
|
|
|
12
12
|
import { group, longestMatch, object } from "./constructs.js";
|
|
13
13
|
|
|
14
14
|
//#region src/facade.ts
|
|
15
|
+
const SuppressedErrorCtor = typeof SuppressedError === "function" ? SuppressedError : (() => {
|
|
16
|
+
class SuppressedErrorPolyfill extends Error {
|
|
17
|
+
error;
|
|
18
|
+
suppressed;
|
|
19
|
+
constructor(error, suppressed, message$1) {
|
|
20
|
+
super(message$1);
|
|
21
|
+
this.name = "SuppressedError";
|
|
22
|
+
this.error = error;
|
|
23
|
+
this.suppressed = suppressed;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return SuppressedErrorPolyfill;
|
|
27
|
+
})();
|
|
15
28
|
function finalizeParsedForContext(context, parsed) {
|
|
16
29
|
return context.finalizeParsed != null ? context.finalizeParsed(parsed) : parsed;
|
|
17
30
|
}
|
|
@@ -1216,57 +1229,104 @@ function disposeContextsSync(contexts) {
|
|
|
1216
1229
|
* );
|
|
1217
1230
|
* ```
|
|
1218
1231
|
*/
|
|
1232
|
+
async function runWithBody(parser, programName, contexts, args, options) {
|
|
1233
|
+
validateContextIds(contexts);
|
|
1234
|
+
if (needsEarlyExit(args, options)) {
|
|
1235
|
+
if (parser.$mode === "async") return runParser(parser, programName, args, options);
|
|
1236
|
+
return Promise.resolve(runParser(parser, programName, args, options));
|
|
1237
|
+
}
|
|
1238
|
+
const ctxOptions = options?.contextOptions;
|
|
1239
|
+
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, ctxOptions);
|
|
1240
|
+
if (!needsTwoPhase) {
|
|
1241
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1242
|
+
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1243
|
+
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1244
|
+
}
|
|
1245
|
+
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1246
|
+
let firstPassResult;
|
|
1247
|
+
let firstPassDeferred;
|
|
1248
|
+
let firstPassDeferredKeys;
|
|
1249
|
+
let firstPassFailed = false;
|
|
1250
|
+
try {
|
|
1251
|
+
if (parser.$mode === "async") firstPassResult = await parseAsync(augmentedParser1, args);
|
|
1252
|
+
else firstPassResult = parseSync(augmentedParser1, args);
|
|
1253
|
+
if (typeof firstPassResult === "object" && firstPassResult !== null && "success" in firstPassResult) {
|
|
1254
|
+
const result = firstPassResult;
|
|
1255
|
+
if (result.success) {
|
|
1256
|
+
firstPassResult = result.value;
|
|
1257
|
+
firstPassDeferred = result.deferred;
|
|
1258
|
+
firstPassDeferredKeys = result.deferredKeys;
|
|
1259
|
+
} else firstPassFailed = true;
|
|
1260
|
+
}
|
|
1261
|
+
} catch {
|
|
1262
|
+
firstPassFailed = true;
|
|
1263
|
+
}
|
|
1264
|
+
if (firstPassFailed) {
|
|
1265
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1266
|
+
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1267
|
+
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1268
|
+
}
|
|
1269
|
+
const { annotationsList: phase2AnnotationsList } = await collectAnnotations(contexts, firstPassResult, ctxOptions, firstPassDeferred, firstPassDeferredKeys);
|
|
1270
|
+
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1271
|
+
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1272
|
+
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
1273
|
+
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
1274
|
+
}
|
|
1219
1275
|
async function runWith(parser, programName, contexts, options) {
|
|
1220
1276
|
const args = options?.args ?? [];
|
|
1221
1277
|
if (contexts.length === 0) {
|
|
1222
1278
|
if (parser.$mode === "async") return runParser(parser, programName, args, options);
|
|
1223
1279
|
return Promise.resolve(runParser(parser, programName, args, options));
|
|
1224
1280
|
}
|
|
1281
|
+
let result;
|
|
1282
|
+
let primaryError;
|
|
1283
|
+
let hasPrimaryError = false;
|
|
1284
|
+
try {
|
|
1285
|
+
result = await runWithBody(parser, programName, contexts, args, options);
|
|
1286
|
+
} catch (error) {
|
|
1287
|
+
hasPrimaryError = true;
|
|
1288
|
+
primaryError = error;
|
|
1289
|
+
}
|
|
1225
1290
|
try {
|
|
1226
|
-
validateContextIds(contexts);
|
|
1227
|
-
if (needsEarlyExit(args, options)) {
|
|
1228
|
-
if (parser.$mode === "async") return runParser(parser, programName, args, options);
|
|
1229
|
-
return Promise.resolve(runParser(parser, programName, args, options));
|
|
1230
|
-
}
|
|
1231
|
-
const ctxOptions = options?.contextOptions;
|
|
1232
|
-
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, ctxOptions);
|
|
1233
|
-
if (!needsTwoPhase) {
|
|
1234
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1235
|
-
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1236
|
-
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1237
|
-
}
|
|
1238
|
-
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1239
|
-
let firstPassResult;
|
|
1240
|
-
let firstPassDeferred;
|
|
1241
|
-
let firstPassDeferredKeys;
|
|
1242
|
-
let firstPassFailed = false;
|
|
1243
|
-
try {
|
|
1244
|
-
if (parser.$mode === "async") firstPassResult = await parseAsync(augmentedParser1, args);
|
|
1245
|
-
else firstPassResult = parseSync(augmentedParser1, args);
|
|
1246
|
-
if (typeof firstPassResult === "object" && firstPassResult !== null && "success" in firstPassResult) {
|
|
1247
|
-
const result = firstPassResult;
|
|
1248
|
-
if (result.success) {
|
|
1249
|
-
firstPassResult = result.value;
|
|
1250
|
-
firstPassDeferred = result.deferred;
|
|
1251
|
-
firstPassDeferredKeys = result.deferredKeys;
|
|
1252
|
-
} else firstPassFailed = true;
|
|
1253
|
-
}
|
|
1254
|
-
} catch {
|
|
1255
|
-
firstPassFailed = true;
|
|
1256
|
-
}
|
|
1257
|
-
if (firstPassFailed) {
|
|
1258
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1259
|
-
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1260
|
-
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1261
|
-
}
|
|
1262
|
-
const { annotationsList: phase2AnnotationsList } = await collectAnnotations(contexts, firstPassResult, ctxOptions, firstPassDeferred, firstPassDeferredKeys);
|
|
1263
|
-
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1264
|
-
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1265
|
-
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
1266
|
-
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
1267
|
-
} finally {
|
|
1268
1291
|
await disposeContexts(contexts);
|
|
1292
|
+
} catch (disposeError) {
|
|
1293
|
+
if (hasPrimaryError) throw new SuppressedErrorCtor(disposeError, primaryError, "An error was suppressed during context disposal.");
|
|
1294
|
+
throw disposeError;
|
|
1295
|
+
}
|
|
1296
|
+
if (hasPrimaryError) throw primaryError;
|
|
1297
|
+
return result;
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Body of {@link runWithSync}, extracted so that the caller can handle
|
|
1301
|
+
* disposal outside a `finally` block (avoiding `no-unsafe-finally` lint).
|
|
1302
|
+
*/
|
|
1303
|
+
function runWithSyncBody(parser, programName, contexts, args, options) {
|
|
1304
|
+
validateContextIds(contexts);
|
|
1305
|
+
if (needsEarlyExit(args, options)) return runParser(parser, programName, args, options);
|
|
1306
|
+
const ctxOptions = options?.contextOptions;
|
|
1307
|
+
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, ctxOptions);
|
|
1308
|
+
if (!needsTwoPhase) {
|
|
1309
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1310
|
+
return runParser(augmentedParser, programName, args, options);
|
|
1311
|
+
}
|
|
1312
|
+
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1313
|
+
let firstPassResult;
|
|
1314
|
+
let firstPassDeferred;
|
|
1315
|
+
let firstPassDeferredKeys;
|
|
1316
|
+
try {
|
|
1317
|
+
const result = parseSync(augmentedParser1, args);
|
|
1318
|
+
if (result.success) {
|
|
1319
|
+
firstPassResult = result.value;
|
|
1320
|
+
firstPassDeferred = result.deferred;
|
|
1321
|
+
firstPassDeferredKeys = result.deferredKeys;
|
|
1322
|
+
} else return runParser(augmentedParser1, programName, args, options);
|
|
1323
|
+
} catch {
|
|
1324
|
+
return runParser(augmentedParser1, programName, args, options);
|
|
1269
1325
|
}
|
|
1326
|
+
const { annotationsList: phase2AnnotationsList } = collectAnnotationsSync(contexts, firstPassResult, ctxOptions, firstPassDeferred, firstPassDeferredKeys);
|
|
1327
|
+
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1328
|
+
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1329
|
+
return runParser(augmentedParser2, programName, args, options);
|
|
1270
1330
|
}
|
|
1271
1331
|
/**
|
|
1272
1332
|
* Runs a synchronous parser with multiple source contexts.
|
|
@@ -1294,36 +1354,23 @@ function runWithSync(parser, programName, contexts, options) {
|
|
|
1294
1354
|
if (parser.$mode !== "sync") throw new TypeError("Cannot use an async parser with runWithSync(). Use runWith() or runWithAsync() instead.");
|
|
1295
1355
|
const args = options?.args ?? [];
|
|
1296
1356
|
if (contexts.length === 0) return runParser(parser, programName, args, options);
|
|
1357
|
+
let result;
|
|
1358
|
+
let primaryError;
|
|
1359
|
+
let hasPrimaryError = false;
|
|
1360
|
+
try {
|
|
1361
|
+
result = runWithSyncBody(parser, programName, contexts, args, options);
|
|
1362
|
+
} catch (error) {
|
|
1363
|
+
hasPrimaryError = true;
|
|
1364
|
+
primaryError = error;
|
|
1365
|
+
}
|
|
1297
1366
|
try {
|
|
1298
|
-
validateContextIds(contexts);
|
|
1299
|
-
if (needsEarlyExit(args, options)) return runParser(parser, programName, args, options);
|
|
1300
|
-
const ctxOptions = options?.contextOptions;
|
|
1301
|
-
const { annotations: phase1Annotations, annotationsList: phase1AnnotationsList, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, ctxOptions);
|
|
1302
|
-
if (!needsTwoPhase) {
|
|
1303
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1304
|
-
return runParser(augmentedParser, programName, args, options);
|
|
1305
|
-
}
|
|
1306
|
-
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1307
|
-
let firstPassResult;
|
|
1308
|
-
let firstPassDeferred;
|
|
1309
|
-
let firstPassDeferredKeys;
|
|
1310
|
-
try {
|
|
1311
|
-
const result = parseSync(augmentedParser1, args);
|
|
1312
|
-
if (result.success) {
|
|
1313
|
-
firstPassResult = result.value;
|
|
1314
|
-
firstPassDeferred = result.deferred;
|
|
1315
|
-
firstPassDeferredKeys = result.deferredKeys;
|
|
1316
|
-
} else return runParser(augmentedParser1, programName, args, options);
|
|
1317
|
-
} catch {
|
|
1318
|
-
return runParser(augmentedParser1, programName, args, options);
|
|
1319
|
-
}
|
|
1320
|
-
const { annotationsList: phase2AnnotationsList } = collectAnnotationsSync(contexts, firstPassResult, ctxOptions, firstPassDeferred, firstPassDeferredKeys);
|
|
1321
|
-
const finalAnnotations = mergeTwoPhaseAnnotations(phase1AnnotationsList, phase2AnnotationsList);
|
|
1322
|
-
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1323
|
-
return runParser(augmentedParser2, programName, args, options);
|
|
1324
|
-
} finally {
|
|
1325
1367
|
disposeContextsSync(contexts);
|
|
1368
|
+
} catch (disposeError) {
|
|
1369
|
+
if (hasPrimaryError) throw new SuppressedErrorCtor(disposeError, primaryError, "An error was suppressed during context disposal.");
|
|
1370
|
+
throw disposeError;
|
|
1326
1371
|
}
|
|
1372
|
+
if (hasPrimaryError) throw primaryError;
|
|
1373
|
+
return result;
|
|
1327
1374
|
}
|
|
1328
1375
|
/**
|
|
1329
1376
|
* Runs any parser asynchronously with multiple source contexts.
|