@systemfsoftware/stryker-js 12.1.1 → 13.0.0

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.
@@ -7,15 +7,15 @@ import * as Result from "effect/Result";
7
7
  import * as S from "effect/Schema";
8
8
  import * as Effect$1 from "effect/Effect";
9
9
  import { dual } from "effect/Function";
10
+ import * as Order from "effect/Order";
11
+ import * as SchemaGetter$1 from "effect/SchemaGetter";
10
12
  import * as Arr from "effect/Array";
11
- import * as SGetter from "effect/SchemaGetter";
12
13
  import * as Context from "effect/Context";
13
14
  import { Effect, SchemaGetter, SchemaIssue, SchemaTransformation } from "effect";
14
- import "effect/Exit";
15
15
  import * as Rpc from "effect/unstable/rpc/Rpc";
16
16
  import * as RpcGroup from "effect/unstable/rpc/RpcGroup";
17
17
  import * as RpcMiddleware from "effect/unstable/rpc/RpcMiddleware";
18
- //#region ../stryker-js-plugin-interface/dist/rolldown-runtime-D7D4PA-g.mjs
18
+ //#region ../stryker-js-instrumenter/dist/rolldown-runtime-D7D4PA-g.mjs
19
19
  var __defProp$1 = Object.defineProperty;
20
20
  var __exportAll$1 = (all, no_symbols) => {
21
21
  let target = {};
@@ -27,18 +27,6 @@ var __exportAll$1 = (all, no_symbols) => {
27
27
  return target;
28
28
  };
29
29
  //#endregion
30
- //#region ../stryker-js-instrumenter/dist/rolldown-runtime-D7D4PA-g.mjs
31
- var __defProp = Object.defineProperty;
32
- var __exportAll = (all, no_symbols) => {
33
- let target = {};
34
- for (var name in all) __defProp(target, name, {
35
- get: all[name],
36
- enumerable: true
37
- });
38
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
39
- return target;
40
- };
41
- //#endregion
42
30
  //#region ../../node_modules/.pnpm/@eslint-community+regexpp@4.12.2/node_modules/@eslint-community/regexpp/index.mjs
43
31
  const latestEcmaVersion = 2025;
44
32
  let largeIdStartRanges = void 0;
@@ -2445,14 +2433,12 @@ function visitRegExpAST(node, handlers) {
2445
2433
  }
2446
2434
  //#endregion
2447
2435
  //#region ../stryker-js-instrumenter/dist/index.mjs
2448
- var ErrorText = class ErrorText extends S.Class("ErrorText")({ text: S.NonEmptyString }) {
2449
- static fromCause = (cause) => Option$1.flatMap(nonEmptyText(errorTextOf$2(cause)), (text) => ErrorText.makeOption({ text }));
2450
- };
2451
- var CauseText = class CauseText extends S.Class("CauseText")({ text: S.NonEmptyString }) {
2452
- static fromCause = (cause) => Option$1.flatMap(nonEmptyText(causeChainTextOf(cause)), (text) => CauseText.makeOption({ text }));
2453
- };
2436
+ var ErrorText = class extends S.Class("ErrorText")({ text: S.NonEmptyString }) {};
2437
+ var CauseText = class extends S.Class("CauseText")({ text: S.NonEmptyString }) {};
2454
2438
  const nonEmptyText = Option$1.liftPredicate(S.is(S.NonEmptyString));
2455
- function errorTextOf$2(error) {
2439
+ const errorTextOf$2 = (cause) => Option$1.flatMap(nonEmptyText(errorTextValueOf(cause)), (text) => ErrorText.makeOption({ text }));
2440
+ const causeTextOf = (cause) => Option$1.flatMap(nonEmptyText(causeChainTextOf(cause)), (text) => CauseText.makeOption({ text }));
2441
+ function errorTextValueOf(error) {
2456
2442
  return Match.value(error).pipe(Match.when(isEmptyError, () => ""), Match.when(Match.instanceOf(Error), errorText), Match.orElse(() => stringifyNonError(error)));
2457
2443
  }
2458
2444
  function causeChainTextOf(cause) {
@@ -2520,102 +2506,99 @@ function causeText(cause, depth) {
2520
2506
  function missingCauseTextOf(cause, depth) {
2521
2507
  return Boolean$1$1.match(isMissingCause(cause), {
2522
2508
  onTrue: () => void 0,
2523
- onFalse: () => causeTextOfValue(cause, depth)
2509
+ onFalse: () => causeNodeTextOf(cause, depth)
2524
2510
  });
2525
2511
  }
2526
- function causeTextOfValue(cause, depth) {
2512
+ function causeNodeTextOf(cause, depth) {
2527
2513
  return Match.value(cause).pipe(Match.when(Match.string, (text) => textIfNonEmpty(text)), Match.orElse((value) => objectCauseTextOf(value, depth)));
2528
2514
  }
2529
2515
  function objectCauseTextOf(cause, depth) {
2530
2516
  return Option$1.getOrUndefined(Option$1.map(Option$1.filter(Option$1.some(cause), Predicate$1.isObjectOrArray), (object) => textWithNested(ownCauseText(object), causeText(fieldOf(object, "cause"), depth + 1))));
2531
2517
  }
2532
- var ErrorText_exports = /* @__PURE__ */ __exportAll({
2518
+ var ErrorText_exports = /* @__PURE__ */ __exportAll$1({
2533
2519
  CauseText: () => CauseText,
2534
- ErrorText: () => ErrorText
2520
+ ErrorText: () => ErrorText,
2521
+ causeTextOf: () => causeTextOf,
2522
+ errorTextOf: () => errorTextOf$2
2523
+ });
2524
+ const Offset = S.Int.check(S.isGreaterThanOrEqualTo(0));
2525
+ /** A 1-based line: the first line of a file is line 1. */
2526
+ const Line = S.Int.check(S.isGreaterThanOrEqualTo(1));
2527
+ /** A 1-based column: the first character of a line is column 1. */
2528
+ const Column = S.Int.check(S.isGreaterThanOrEqualTo(1));
2529
+ const Position = S.Struct({
2530
+ line: Line,
2531
+ column: Column
2532
+ });
2533
+ const positionOrder = Order.combine(Order.mapInput(Order.Number, (position) => position.line), Order.mapInput(Order.Number, (position) => position.column));
2534
+ const inOrder = (order) => (ends) => ({
2535
+ start: Order.min(order)(ends.start, ends.end),
2536
+ end: Order.max(order)(ends.start, ends.end)
2537
+ });
2538
+ const notReversed = (order) => (ends) => Order.isLessThanOrEqualTo(order)(ends.start, ends.end);
2539
+ const PositionEnds = S.Struct({
2540
+ start: Position,
2541
+ end: Position
2542
+ });
2543
+ const Location = S.declare((value) => S.is(PositionEnds)(value) && notReversed(positionOrder)(value), {
2544
+ expected: "a location whose end is not before its start",
2545
+ toCodecArbitrary: () => S.link()(PositionEnds, {
2546
+ decode: SchemaGetter$1.transform(inOrder(positionOrder)),
2547
+ encode: SchemaGetter$1.transform((ends) => ends)
2548
+ })
2535
2549
  });
2536
- /**
2537
- * File coordinates in the mutation-testing-report-schema contract: both line
2538
- * and column are 1-based. The first line of a file is line 1, and the first
2539
- * character of a line is column 1. Slicing a source line by one of these
2540
- * positions uses `line - 1` for the line index and `column - 1` for the
2541
- * character offset.
2542
- */
2543
- const PositionSchema = S.Struct({
2544
- line: S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(0))),
2545
- column: S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(0)))
2550
+ const OpenEnds = S.Struct({
2551
+ start: Position,
2552
+ end: S.optional(Position)
2546
2553
  });
2547
- const LocationSchema$1 = S.Struct({
2548
- start: PositionSchema,
2549
- end: PositionSchema
2554
+ const closedEnds = (ends) => Option$1.map(Option$1.fromUndefinedOr(ends.end), (end) => ({
2555
+ start: ends.start,
2556
+ end
2557
+ }));
2558
+ const OpenEndLocation = S.declare((value) => S.is(OpenEnds)(value) && Option$1.match(closedEnds(value), {
2559
+ onNone: () => true,
2560
+ onSome: notReversed(positionOrder)
2561
+ }), {
2562
+ expected: "a location whose end, when present, is not before its start",
2563
+ toCodecArbitrary: () => S.link()(OpenEnds, {
2564
+ decode: SchemaGetter$1.transform((ends) => Option$1.getOrElse(Option$1.map(closedEnds(ends), inOrder(positionOrder)), () => ends)),
2565
+ encode: SchemaGetter$1.transform((ends) => ends)
2566
+ })
2550
2567
  });
2551
- const OpenEndLocationSchema = S.Struct({
2552
- start: PositionSchema,
2553
- end: S.optional(PositionSchema)
2568
+ const OffsetEnds = S.Struct({
2569
+ start: Offset,
2570
+ end: Offset
2571
+ });
2572
+ const Span = S.declare((value) => S.is(OffsetEnds)(value) && notReversed(Order.Number)(value), {
2573
+ expected: "a span whose end is not before its start",
2574
+ toCodecArbitrary: () => S.link()(OffsetEnds, {
2575
+ decode: SchemaGetter$1.transform(inOrder(Order.Number)),
2576
+ encode: SchemaGetter$1.transform((ends) => ends)
2577
+ })
2578
+ });
2579
+ const ScriptOrigin = S.Struct({
2580
+ line: Line,
2581
+ columnShift: Offset
2582
+ });
2583
+ S.is(Offset), S.is(Line), S.is(Column), S.is(Location), S.is(Span);
2584
+ const MutatorNameSchema = S.String.pipe(S.check(S.isPattern(/^[a-zA-Z]+(?: [a-zA-Z]+)*$/)));
2585
+ const DirectiveReasonSchema = S.String.pipe(S.check(S.isPattern(/^\S(?:[^\r\n\u2028\u2029]*\S)?$/)));
2586
+ const DirectiveSchema = S.Struct({
2587
+ action: S.Literals(["disable", "restore"]),
2588
+ scope: S.Literals(["next-line", "block"]),
2589
+ mutatorNames: S.Array(MutatorNameSchema).check(S.isMinLength(1)),
2590
+ reason: DirectiveReasonSchema
2591
+ });
2592
+ const LocatedDirectiveSchema = S.Struct({
2593
+ directive: DirectiveSchema,
2594
+ at: Position,
2595
+ governedLine: Line
2596
+ });
2597
+ S.Struct({
2598
+ directive: DirectiveSchema,
2599
+ at: Position,
2600
+ mutatorName: MutatorNameSchema
2554
2601
  });
2555
- /**
2556
- * A mutant's `location` already speaks the report contract (1-based line and
2557
- * column), so the report's location is that location unchanged.
2558
- */
2559
- const ReportLocationFromMutant = LocationSchema$1;
2560
- const NonNegativeInt$1 = S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(0)));
2561
- var LineTable = class extends S.Class("LineTable")({ lineStarts: S.NonEmptyArray(NonNegativeInt$1) }) {
2562
- positionAt(offset) {
2563
- return positionOf(this.lineStarts, offset);
2564
- }
2565
- locationAt(span) {
2566
- return {
2567
- start: this.positionAt(span.start),
2568
- end: this.positionAt(span.end)
2569
- };
2570
- }
2571
- zeroBasedPositionAt(offset) {
2572
- return zeroBasedPositionOf(this.lineStarts, offset);
2573
- }
2574
- };
2575
- const LINE_TERMINATOR = /\r\n|[\n\r\u2028\u2029]/g;
2576
- const lineStartsOf = (text) => ({ lineStarts: [0, ...[...text.matchAll(LINE_TERMINATOR)].map((match) => endOfMatch(match))] });
2577
- const endOfMatch = (match) => (match.index ?? 0) + match[0].length;
2578
- const canonicalTextOf = (table) => Boolean$1$1.match(table.lineStarts.length === 1, {
2579
- onTrue: () => "",
2580
- onFalse: () => `${Arr.zip(table.lineStarts.slice(0, -1), table.lineStarts.slice(1)).map(([start, next]) => " ".repeat(next - start - 1)).join("\n")}\n`
2581
- });
2582
- const LineTableFromText = S.String.pipe(S.decodeTo(LineTable, {
2583
- decode: SGetter.transform(lineStartsOf),
2584
- encode: SGetter.transform(canonicalTextOf)
2585
- }));
2586
- const middleIndex = (low, high) => low + (high - low >> 1);
2587
- const zeroBasedPositionOf = (lineStarts, offset) => {
2588
- const search = (low, high, start) => Boolean$1$1.match(low > high, {
2589
- onTrue: () => ({
2590
- line: low - 1,
2591
- column: offset - start
2592
- }),
2593
- onFalse: () => Option$1.match(Arr.get(lineStarts, middleIndex(low, high)), {
2594
- onNone: () => ({
2595
- line: low - 1,
2596
- column: offset - start
2597
- }),
2598
- onSome: (found) => Boolean$1$1.match(found === offset, {
2599
- onTrue: () => ({
2600
- line: middleIndex(low, high),
2601
- column: offset - found
2602
- }),
2603
- onFalse: () => Boolean$1$1.match(found < offset, {
2604
- onTrue: () => search(middleIndex(low, high) + 1, high, found),
2605
- onFalse: () => search(low, middleIndex(low, high) - 1, start)
2606
- })
2607
- })
2608
- })
2609
- });
2610
- return search(0, lineStarts.length - 1, 0);
2611
- };
2612
- const positionOf = (lineStarts, offset) => {
2613
- const zeroBased = zeroBasedPositionOf(lineStarts, offset);
2614
- return {
2615
- line: zeroBased.line + 1,
2616
- column: zeroBased.column + 1
2617
- };
2618
- };
2619
2602
  const MutantStatusSchema = S.Literals([
2620
2603
  "Killed",
2621
2604
  "Survived",
@@ -2626,11 +2609,30 @@ const MutantStatusSchema = S.Literals([
2626
2609
  "Ignored",
2627
2610
  "Pending"
2628
2611
  ]);
2629
- const MutantId = S.NonEmptyString.pipe(S.brand("MutantId"));
2612
+ const SurvivorStatusSchema = S.Literals(["Survived", "NoCoverage"]);
2613
+ const RememberedStatusSchema = S.Literals([
2614
+ "Survived",
2615
+ "Killed",
2616
+ "Timeout",
2617
+ "NoCoverage",
2618
+ "Ignored"
2619
+ ]);
2620
+ const EphemeralStatusSchema = S.Literals([
2621
+ "CompileError",
2622
+ "RuntimeError",
2623
+ "Pending"
2624
+ ]);
2625
+ const ActionableStatusSchema = S.Literals([
2626
+ "Survived",
2627
+ "NoCoverage",
2628
+ "Timeout",
2629
+ "RuntimeError"
2630
+ ]);
2631
+ const MutantId = S.String.check(S.isPattern(/^(0|[1-9][0-9]*)$/)).pipe(S.brand("MutantId"));
2630
2632
  const MutatorName = S.NonEmptyString.pipe(S.brand("MutatorName"));
2631
2633
  const CanonicalFileName = S.String.pipe(S.decodeTo(S.String.pipe(S.check(S.isPattern(/^[^\\]+$/)), S.brand("CanonicalFileName")), {
2632
- decode: SGetter.transform((fileName) => fileName.replace(/\\/g, "/")),
2633
- encode: SGetter.transform((canonical) => canonical)
2634
+ decode: SchemaGetter$1.transform((fileName) => fileName.replace(/\\/g, "/")),
2635
+ encode: SchemaGetter$1.transform((canonical) => canonical)
2634
2636
  }));
2635
2637
  /**
2636
2638
  * A mutant's file location in the mutation-testing-report-schema contract:
@@ -2638,19 +2640,19 @@ const CanonicalFileName = S.String.pipe(S.decodeTo(S.String.pipe(S.check(S.isPat
2638
2640
  * machine stream emit. Every producer on the instrument path (node spans,
2639
2641
  * embedded-region shifts) targets this base; no downstream layer converts.
2640
2642
  */
2641
- var Mutant = class extends S.TaggedClass()("Mutant", {
2643
+ const Mutant = S.TaggedStruct("Mutant", {
2642
2644
  id: MutantId,
2643
2645
  fileName: CanonicalFileName,
2644
2646
  mutatorName: MutatorName,
2645
2647
  replacement: S.String,
2646
- location: LocationSchema$1,
2648
+ location: Location,
2647
2649
  status: S.optional(MutantStatusSchema),
2648
2650
  statusReason: S.optional(S.String),
2649
2651
  coveredBy: S.String.pipe(S.Array, S.optional),
2650
2652
  static: S.optional(S.Boolean),
2651
2653
  testsCompleted: S.optional(S.Finite),
2652
2654
  description: S.optional(S.String)
2653
- }) {};
2655
+ }).check(S.makeFilter((mutant) => mutant.statusReason === void 0 || mutant.status !== void 0, { message: "a mutant carries a status reason only together with a status" }));
2654
2656
  const MutantFromUnknown = S.Unknown.pipe(S.decodeTo(Mutant));
2655
2657
  const RunOptionsFields = {
2656
2658
  timeout: S.Finite.pipe(S.check(S.isGreaterThanOrEqualTo(0))),
@@ -2668,15 +2670,15 @@ const MutantRunOptionsSchema = S.Struct({
2668
2670
  hitLimit: S.optionalKey(HitCount)
2669
2671
  });
2670
2672
  const MutantCoverageSchema$1 = S.Struct({
2671
- perTest: S.Record(S.String, S.Record(S.String, HitCount)),
2672
- static: S.Record(S.String, HitCount)
2673
+ perTest: S.Record(S.String, S.Record(MutantId, HitCount)),
2674
+ static: S.Record(MutantId, HitCount)
2673
2675
  });
2674
2676
  var InstrumenterContext = class extends S.Class("InstrumenterContext")({
2675
2677
  activeMutant: S.optional(S.String),
2676
2678
  currentTestId: S.optional(S.String),
2677
2679
  mutantCoverage: S.optional(MutantCoverageSchema$1),
2678
- hitCount: S.optional(S.Finite),
2679
- hitLimit: S.optional(S.Finite)
2680
+ hitCount: S.optional(HitCount),
2681
+ hitLimit: S.optional(HitCount)
2680
2682
  }) {
2681
2683
  static NAMESPACE = "__stryker__";
2682
2684
  static MUTATION_COVERAGE_OBJECT = "mutantCoverage";
@@ -2697,21 +2699,15 @@ var InstrumentError = class extends S.TaggedError("@systemfsoftware/stryker-js-i
2697
2699
  });
2698
2700
  }
2699
2701
  };
2700
- const MutateDescriptionSchema = S.Union([S.Boolean, S.Array(LocationSchema$1)]);
2701
- const SourceLineSchema = S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(1)));
2702
- const SourceColumnSchema = S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(0)));
2703
- const NodePositionSchema = S.Struct({
2704
- line: S.Int,
2705
- column: S.Int
2706
- });
2702
+ const MutateDescriptionSchema = S.Union([S.Boolean, S.Array(Location)]);
2707
2703
  const FileSchema = S.Struct({
2708
- name: S.String,
2704
+ name: CanonicalFileName,
2709
2705
  content: S.String,
2710
2706
  mutate: MutateDescriptionSchema
2711
2707
  });
2712
2708
  const IgnorerSchema = S.Unknown;
2713
2709
  S.Struct({
2714
- excludedMutations: S.Array(S.String),
2710
+ excludedMutations: S.Array(MutatorNameSchema),
2715
2711
  ignorers: S.Array(IgnorerSchema),
2716
2712
  noHeader: S.optional(S.Boolean),
2717
2713
  optInMutations: S.String.pipe(S.Array, S.optional)
@@ -2741,16 +2737,66 @@ const PlacerNameSchema = S.Literals([
2741
2737
  var MutantsUnapplied = class extends S.TaggedError()("MutantsUnapplied", {
2742
2738
  fileName: S.String,
2743
2739
  placer: PlacerNameSchema,
2744
- mutatorNames: S.Array(S.String),
2740
+ mutatorNames: S.Array(MutatorNameSchema),
2745
2741
  cause: S.Defect()
2746
2742
  }) {};
2747
2743
  var MutantNotApplied = class extends S.TaggedError()("MutantNotApplied", {
2748
2744
  fileName: S.String,
2749
- mutatorName: S.String
2745
+ mutatorName: MutatorNameSchema
2746
+ }) {};
2747
+ var NodeWithoutSpan = class extends S.TaggedError()("NodeWithoutSpan", { fileName: S.String }) {};
2748
+ var MutantsUnplaced = class extends S.TaggedError()("MutantsUnplaced", {
2749
+ fileName: S.String,
2750
+ detail: S.String
2750
2751
  }) {};
2752
+ var PlacementRefused = class extends S.TaggedError()("PlacementRefused", { message: S.String }) {};
2753
+ const LINE_TERMINATOR = /\r\n|[\n\r\u2028\u2029]/g;
2754
+ const lineStartsOf = (text) => [0, ...[...text.matchAll(LINE_TERMINATOR)].map((match) => match.index + match[0].length)];
2755
+ const middleIndex = (low, high) => low + (high - low >> 1);
2756
+ const positionAtOffset = (lineStarts, offset, low, high, start) => Boolean$1$1.match(low > high, {
2757
+ onTrue: () => ({
2758
+ line: low,
2759
+ column: offset - start + 1
2760
+ }),
2761
+ onFalse: () => Option$1.match(Arr.get(lineStarts, middleIndex(low, high)), {
2762
+ onNone: () => ({
2763
+ line: low,
2764
+ column: offset - start + 1
2765
+ }),
2766
+ onSome: (found) => Boolean$1$1.match(found === offset, {
2767
+ onTrue: () => ({
2768
+ line: middleIndex(low, high) + 1,
2769
+ column: 1
2770
+ }),
2771
+ onFalse: () => Boolean$1$1.match(found < offset, {
2772
+ onTrue: () => positionAtOffset(lineStarts, offset, middleIndex(low, high) + 1, high, found),
2773
+ onFalse: () => positionAtOffset(lineStarts, offset, low, middleIndex(low, high) - 1, start)
2774
+ })
2775
+ })
2776
+ })
2777
+ });
2778
+ const positionAt = dual(2, (lineStarts, offset) => positionAtOffset(lineStarts, offset, 0, lineStarts.length - 1, 0));
2779
+ const locationOf = dual(2, (lineStarts, span) => Location.make({
2780
+ start: positionAt(lineStarts, span.start),
2781
+ end: positionAt(lineStarts, span.end)
2782
+ }));
2783
+ const originAt = dual(2, (lineStarts, offset) => {
2784
+ const position = positionAt(lineStarts, offset);
2785
+ return ScriptOrigin.make({
2786
+ line: position.line,
2787
+ columnShift: position.column - 1
2788
+ });
2789
+ });
2790
+ dual(2, (lineStarts, position) => Option$1.flatMap(Arr.get(lineStarts, position.line - 1), (start) => {
2791
+ const offset = start + position.column - 1;
2792
+ return Option$1.match(Arr.get(lineStarts, position.line), {
2793
+ onNone: () => Option$1.some(offset),
2794
+ onSome: (next) => Option$1.liftPredicate(offset, (candidate) => candidate < next)
2795
+ });
2796
+ }));
2751
2797
  const formatKeyOf = (ast) => ast.format === "embedded" ? ast.formatId : ast.format;
2752
- const TypeId$1 = Symbol.for("~systemfsoftware/stryker-js-instrumenter/Ast");
2753
- const AstHandleDef = Handle.make()(TypeId$1);
2798
+ const TypeId = Symbol.for("~systemfsoftware/stryker-js-instrumenter/Ast");
2799
+ const AstHandleDef = Handle.make()(TypeId);
2754
2800
  AstHandleDef.is;
2755
2801
  const make = (root) => AstHandleDef.make({ root });
2756
2802
  const EXPRESSION_KINDS = {
@@ -2983,14 +3029,14 @@ const switchCase = dual((args) => isDataFirstArity(args, 2), (test, consequent,
2983
3029
  consequent: [...consequent]
2984
3030
  }, loc));
2985
3031
  const cloneNode = (node) => structuredClone(node);
2986
- const attachComments = dual((args) => args.length >= 3, (self, comments, lineTable) => Boolean$1$1.match(comments.length === 0, {
3032
+ const attachComments = dual((args) => args.length >= 3, (self, comments, lineStarts) => Boolean$1$1.match(comments.length === 0, {
2987
3033
  onTrue: () => void 0,
2988
3034
  onFalse: () => {
2989
3035
  const nodes = collectNodes(self.root).filter((entry) => entry.node !== self.root);
2990
3036
  nodes.sort((a, b) => a.start - b.start);
2991
3037
  const groups = groupComments(nodes, comments);
2992
- assignComments(groups.leading, lineTable, "leadingComments");
2993
- assignComments(groups.trailing, lineTable, "trailingComments");
3038
+ assignComments(groups.leading, lineStarts, "leadingComments");
3039
+ assignComments(groups.trailing, lineStarts, "trailingComments");
2994
3040
  }
2995
3041
  }));
2996
3042
  const groupComments = (nodes, comments) => {
@@ -3016,12 +3062,12 @@ const commentHost = (nodes, comment) => {
3016
3062
  };
3017
3063
  const followingNode = (nodes, comment) => Option$1.getOrUndefined(Option$1.map(Option$1.fromNullishOr(nodes.find((candidate) => candidate.start >= comment.end)), (entry) => entry.node));
3018
3064
  const precedingStatement = (nodes, comment) => Option$1.getOrUndefined(Option$1.map(Option$1.fromNullishOr(nodes.findLast((candidate) => candidate.end <= comment.start && isStatementKind(candidate.node))), (entry) => entry.node));
3019
- const assignComments = (map, lineTable, field) => map.forEach((list, node) => Object.assign(node, { [field]: list.map((comment) => ({
3065
+ const assignComments = (map, lineStarts, field) => map.forEach((list, node) => Object.assign(node, { [field]: list.map((comment) => ({
3020
3066
  ...comment,
3021
- loc: {
3022
- start: lineTable.positionAt(comment.start),
3023
- end: lineTable.positionAt(comment.end)
3024
- }
3067
+ loc: locationOf(lineStarts, {
3068
+ start: comment.start,
3069
+ end: comment.end
3070
+ })
3025
3071
  })) }));
3026
3072
  const pushComment = (map, node, comment) => {
3027
3073
  Option$1.match(Option$1.fromNullishOr(map.get(node)), {
@@ -3038,72 +3084,41 @@ const WALK_SKIPPED_KEYS = {
3038
3084
  start: true,
3039
3085
  end: true
3040
3086
  };
3041
- const walkNodes = (root, visitors) => visitIfNode(root, {
3042
- key: null,
3043
- index: null
3044
- }, visitors);
3045
- const visitNode = (node, context, visitors) => {
3046
- const state = { skipped: false };
3047
- visitors.enter(node, context, { skip: () => {
3048
- state.skipped = true;
3049
- } });
3050
- Boolean$1$1.match(state.skipped, {
3051
- onTrue: () => void 0,
3052
- onFalse: () => visitChildren(node, visitors)
3053
- });
3054
- visitors.leave(node, context);
3055
- };
3056
- const visitChildren = (node, visitors) => Object.keys(node).forEach((key) => Boolean$1$1.match(WALK_SKIPPED_KEYS[key] === true, {
3057
- onTrue: () => void 0,
3058
- onFalse: () => visitSlot(node[key], key, visitors)
3059
- }));
3060
3087
  const isChildList = (value) => Array.isArray(value);
3061
- const visitSlot = (value, key, visitors) => Option$1.match(Option$1.filter(Option$1.some(value), isChildList), {
3062
- onSome: (items) => items.forEach((item, index) => visitIfNode(item, {
3063
- key,
3064
- index
3065
- }, visitors)),
3066
- onNone: () => visitIfNode(value, {
3088
+ const childSlotsOf = (node) => Object.keys(node).flatMap((key) => WALK_SKIPPED_KEYS[key] === true ? [] : childSlotsAt(key, node[key]));
3089
+ const childSlotsAt = (key, value) => isChildList(value) ? listSlotsAt(key, value) : singleSlotAt(key, value);
3090
+ const listSlotsAt = (key, value) => value.flatMap((item, index) => isAstNode(item) ? [{
3091
+ key,
3092
+ index,
3093
+ node: item
3094
+ }] : []);
3095
+ const singleSlotAt = (key, value) => Option$1.match(Option$1.filter(Option$1.some(value), isAstNode), {
3096
+ onNone: () => [],
3097
+ onSome: (node) => [{
3067
3098
  key,
3068
- index: null
3069
- }, visitors)
3099
+ index: null,
3100
+ node
3101
+ }]
3102
+ });
3103
+ const asWalkedNode = (value) => Option$1.filter(Option$1.some(value), isAstNode);
3104
+ const childNodes = (node) => Option$1.match(asWalkedNode(node), {
3105
+ onNone: () => [],
3106
+ onSome: (walked) => childSlotsOf(walked).filter((slot) => !isCommentKey(slot.key)).map((slot) => ({
3107
+ key: slot.key,
3108
+ index: slot.index,
3109
+ node: slot.node
3110
+ }))
3070
3111
  });
3071
- const visitIfNode = (value, context, visitors) => Option$1.match(Option$1.filter(Option$1.some(value), isAstNode), {
3072
- onNone: () => void 0,
3073
- onSome: (child) => visitNode(child, context, visitors)
3074
- });
3075
- const walker = (root, visitors) => {
3076
- const ancestors = [];
3077
- walkNodes(root, {
3078
- enter(node) {
3079
- visitors.enter?.(node, [...ancestors]);
3080
- ancestors.push(node);
3081
- },
3082
- leave(node) {
3083
- ancestors.pop();
3084
- visitors.leave?.(node, [...ancestors]);
3085
- }
3086
- });
3087
- };
3088
- const collectNodes = (root) => {
3089
- const out = [];
3090
- walker(root, { enter(node) {
3091
- appendEntry(node, out);
3092
- } });
3093
- return out;
3094
- };
3095
- const appendEntry = (node, out) => {
3096
- Option$1.match(Option$1.fromNullishOr(spanOf(node)), {
3097
- onNone: () => void 0,
3098
- onSome: (span) => {
3099
- out.push({
3100
- node,
3101
- start: span.start,
3102
- end: span.end
3103
- });
3104
- }
3105
- });
3106
- };
3112
+ const collectNodes = (root) => Option$1.toArray(nodeEntryOf(root)).concat(childEntriesOf(root));
3113
+ const childEntriesOf = (root) => Option$1.match(asWalkedNode(root), {
3114
+ onNone: () => [],
3115
+ onSome: (node) => childSlotsOf(node).flatMap((slot) => collectNodes(slot.node))
3116
+ });
3117
+ const nodeEntryOf = (node) => Option$1.map(Option$1.fromNullishOr(spanOf(node)), (span) => ({
3118
+ node,
3119
+ start: span.start,
3120
+ end: span.end
3121
+ }));
3107
3122
  function isAstNode(value) {
3108
3123
  return Predicate$1.isObject(value) && typeof value["type"] === "string";
3109
3124
  }
@@ -3112,32 +3127,41 @@ const COMMENT_KEYS = {
3112
3127
  trailingComments: true
3113
3128
  };
3114
3129
  const isCommentKey = (key) => typeof key === "string" && COMMENT_KEYS[key] === true;
3115
- const walkTraverse = (root, stack, visitors) => {
3116
- walkNodes(root, {
3117
- enter(node, context, controls) {
3118
- readPath(stack, node, controls, context, visitors);
3119
- },
3120
- leave(_node, context) {
3121
- closePath(stack, context, visitors);
3130
+ const walkTraverse = (root, visitors) => Option$1.match(asWalkedNode(root), {
3131
+ onNone: () => void 0,
3132
+ onSome: (node) => traverseNode(node, null, {
3133
+ key: null,
3134
+ index: null
3135
+ }, visitors)
3136
+ });
3137
+ const skipControls = () => {
3138
+ let skipped = false;
3139
+ return {
3140
+ skipped: () => skipped,
3141
+ skip: () => {
3142
+ skipped = true;
3122
3143
  }
3123
- });
3144
+ };
3124
3145
  };
3125
- const traverse = dual(2, (self, visitors) => walkTraverse(self.root, [], visitors));
3126
- const readPath = (stack, node, controls, context, visitors) => {
3146
+ const traverseNode = (node, parentPath, context, visitors) => {
3127
3147
  Boolean$1$1.match(isCommentKey(context.key), {
3128
3148
  onTrue: () => void 0,
3129
3149
  onFalse: () => {
3130
- const current = createPath(node, parentOf(stack), controls, context);
3131
- stack.push(current);
3132
- notify(visitors.enter, current);
3150
+ const controls = skipControls();
3151
+ const path = createPath(node, parentPath, controls, context);
3152
+ notify(visitors.enter, path);
3153
+ Boolean$1$1.match(controls.skipped(), {
3154
+ onTrue: () => void 0,
3155
+ onFalse: () => childSlotsOf(node).forEach((slot) => traverseNode(slot.node, path, {
3156
+ key: slot.key,
3157
+ index: slot.index
3158
+ }, visitors))
3159
+ });
3160
+ notify(visitors.exit, path);
3133
3161
  }
3134
3162
  });
3135
3163
  };
3136
- const closePath = (stack, context, visitors) => Boolean$1$1.match(isCommentKey(context.key), {
3137
- onTrue: () => void 0,
3138
- onFalse: () => notify(visitors.exit, stack.pop())
3139
- });
3140
- const parentOf = (stack) => Option$1.getOrNull(Arr.last(stack));
3164
+ const traverse = dual(2, (self, visitors) => walkTraverse(self.root, visitors));
3141
3165
  const notify = (visitor, path) => Option$1.match(Option$1.all({
3142
3166
  visitor: Option$1.fromNullishOr(visitor),
3143
3167
  path: Option$1.fromNullishOr(path)
@@ -3298,13 +3322,6 @@ const EMPTY_IMPORT_TABLE = Object.freeze({
3298
3322
  bareFunctions: /* @__PURE__ */ new Map(),
3299
3323
  pipeBindings: /* @__PURE__ */ new Set()
3300
3324
  });
3301
- const importTables = /* @__PURE__ */ new WeakMap();
3302
- const importTableFor = (program) => Option$1.getOrElse(Option$1.fromNullishOr(importTables.get(program)), () => rememberImportTable(program));
3303
- function rememberImportTable(program) {
3304
- const table = buildImportTable(program);
3305
- importTables.set(program, table);
3306
- return table;
3307
- }
3308
3325
  const buildImportTable = (program) => Arr.reduce(Arr.flatMap(Arr.filter(program.body, isImportDeclaration$1), importContributions), EMPTY_IMPORT_TABLE, applyContribution);
3309
3326
  const withEntry = (entries, key, value) => new Map([...entries, [key, value]]);
3310
3327
  const withMember = (members, value) => /* @__PURE__ */ new Set([...members, value]);
@@ -3356,7 +3373,7 @@ const namespaceBindingFor = (source) => Match.value(source).pipe(Match.when((can
3356
3373
  }))));
3357
3374
  const moduleNameFromName = (name) => Arr.findFirst(MODULE_NAMES, (module) => module === name);
3358
3375
  const moduleNameFromSource = (source) => Arr.findFirst(MODULE_NAMES, (module) => source === `${EFFECT_SOURCE}/${module}`);
3359
- const resolveEffectCallDataFirst = (node, context) => Option$1.flatMap(programOf(context), (program) => resolveIn(node, context, importTableFor(program)));
3376
+ const resolveEffectCallDataFirst = (node, context) => Option$1.flatMap(programOf(context), (program) => resolveIn(node, context, buildImportTable(program)));
3360
3377
  const resolveEffectCall = dual((args) => args.length >= 2, resolveEffectCallDataFirst);
3361
3378
  const programOf = (context) => Arr.findLast(context.ancestors, isProgram);
3362
3379
  const resolveIn = (node, context, table) => Match.value(node).pipe(Match.when(isCallExpression$1, (call) => resolveCall(call, context, table)), Match.when(isMemberExpression, (member) => resolveReference(member, context, table)), Match.when(isIdentifier$1, (reference) => resolveReference(reference, context, table)), Match.orElse(() => Option$1.none()));
@@ -3754,9 +3771,10 @@ function eqNode(a, b) {
3754
3771
  return identity !== void 0 && identity === nodeIdentity(b);
3755
3772
  }
3756
3773
  function nodeIdentity(node) {
3757
- const span = spanOf(node);
3758
- if (span === void 0) return;
3759
- return `${node.type}:${span.start}:${span.end}`;
3774
+ return Option$1.match(Option$1.fromNullishOr(spanOf(node)), {
3775
+ onNone: () => void 0,
3776
+ onSome: (span) => `${node.type}:${span.start}:${span.end}`
3777
+ });
3760
3778
  }
3761
3779
  function orDefault(value, fallback) {
3762
3780
  return value ?? fallback;
@@ -3804,14 +3822,15 @@ function cloneWithReplacement(mutant, originalTree) {
3804
3822
  function hasReplaced(root, original, replacement) {
3805
3823
  let applied = false;
3806
3824
  traverse(make(root), { enter(path) {
3807
- if (!applied) applied = replaceFirstMatch(path, original, replacement);
3825
+ applied = applied || replaceFirstMatch(path, original, replacement);
3808
3826
  } });
3809
3827
  return applied;
3810
3828
  }
3811
3829
  function replaceFirstMatch(path, original, replacement) {
3812
- if (eqNode(path.node, original) === false) return false;
3813
- path.replaceWith(replacement);
3814
- return true;
3830
+ return Match.value(eqNode(path.node, original)).pipe(Match.when(false, () => false), Match.orElse(() => {
3831
+ path.replaceWith(replacement);
3832
+ return true;
3833
+ }));
3815
3834
  }
3816
3835
  /**
3817
3836
  * The mutations of a regular expression pattern.
@@ -3840,17 +3859,16 @@ function replaceFirstMatch(path, original, replacement) {
3840
3859
  * quantifier removal ahead of class negation.
3841
3860
  */
3842
3861
  function mutateRegexPattern(pattern, flags) {
3843
- if (pattern.length === 0) return [];
3844
- return parseRegexMutants(pattern, orDefault(flags, ""));
3862
+ return pattern.length === 0 ? [] : parseRegexMutants(pattern, orDefault(flags, ""));
3845
3863
  }
3846
3864
  function parseRegexMutants(pattern, flags) {
3847
3865
  try {
3848
3866
  const groups = collectSplices(pattern, flags);
3849
- groups.rest.sort((a, b) => a.start - b.start || a.priority - b.priority);
3867
+ const rest = groups.rest.toSorted((a, b) => a.start - b.start || a.priority - b.priority);
3850
3868
  return [
3851
3869
  ...groups.bol,
3852
3870
  ...groups.eol,
3853
- ...groups.rest
3871
+ ...rest
3854
3872
  ].map((splice) => spliceText(pattern, splice));
3855
3873
  } catch {
3856
3874
  return [];
@@ -3912,18 +3930,17 @@ function negationMarker(negate) {
3912
3930
  }
3913
3931
  function collectCharacterClass(characterClass, groups) {
3914
3932
  const pos = characterClass.start + 1;
3915
- if (characterClass.negate) groups.rest.push({
3933
+ groups.rest.push(Match.value(characterClass.negate).pipe(Match.when(true, () => ({
3916
3934
  start: pos,
3917
3935
  end: pos + 1,
3918
3936
  text: "",
3919
3937
  priority: 1
3920
- });
3921
- else groups.rest.push({
3938
+ })), Match.orElse(() => ({
3922
3939
  start: pos,
3923
3940
  end: pos,
3924
3941
  text: "^",
3925
3942
  priority: 1
3926
- });
3943
+ }))));
3927
3944
  }
3928
3945
  function collectCharacterSet(characterSet, groups) {
3929
3946
  pushWhen(groups.rest, characterSetSplice(characterSet));
@@ -3953,12 +3970,10 @@ function classSplice(characterSet) {
3953
3970
  /** `\d`-style sets invert by letter case, `\p{}` by `p`/`P`. */
3954
3971
  function invertedMarker(marker) {
3955
3972
  const propertyMarker = PROPERTY_MARKERS[marker];
3956
- if (propertyMarker !== void 0) return propertyMarker;
3957
- return invertLetterCase(marker);
3973
+ return propertyMarker === void 0 ? invertLetterCase(marker) : propertyMarker;
3958
3974
  }
3959
3975
  function invertLetterCase(letter) {
3960
- if (letter === letter.toUpperCase()) return letter.toLowerCase();
3961
- return letter.toUpperCase();
3976
+ return letter === letter.toUpperCase() ? letter.toLowerCase() : letter.toUpperCase();
3962
3977
  }
3963
3978
  function collectQuantifier(quantifier, groups) {
3964
3979
  groups.rest.push({
@@ -3974,11 +3989,15 @@ function anchorRemoval(assertion, pattern) {
3974
3989
  end: assertion.end,
3975
3990
  text: ""
3976
3991
  };
3977
- if (spliceText(pattern, splice).length === 0) return;
3978
- return splice;
3992
+ return spliceText(pattern, splice).length === 0 ? void 0 : splice;
3979
3993
  }
3980
3994
  function pushWhen(list, splice) {
3981
- if (splice !== void 0) list.push(splice);
3995
+ Option$1.match(Option$1.fromNullishOr(splice), {
3996
+ onNone: () => void 0,
3997
+ onSome: (present) => {
3998
+ list.push(present);
3999
+ }
4000
+ });
3982
4001
  }
3983
4002
  function spliceText(pattern, splice) {
3984
4003
  return pattern.slice(0, splice.start) + splice.text + pattern.slice(splice.end);
@@ -4032,16 +4051,14 @@ function isStringConcatenation(node) {
4032
4051
  }
4033
4052
  /** A chained `a + b + c` carries its value on the innermost left operand's right side. */
4034
4053
  function outerLeftOperand(node) {
4035
- if (node.left.type === "BinaryExpression") return node.left.right;
4036
- return node.left;
4054
+ return node.left.type === "BinaryExpression" ? node.left.right : node.left;
4037
4055
  }
4038
4056
  const arrayDeclarationMutator = (node) => Match.value(node).pipe(Match.when(isArrayExpression, (array) => [arrayDeclarationReplacement(array)]), Match.when(isArrayConstructorCall, (construct) => [arrayConstructorReplacement(construct)]), Match.orElse(() => NO_MUTANTS));
4039
4057
  function isArrayExpression(node) {
4040
4058
  return node.type === "ArrayExpression";
4041
4059
  }
4042
4060
  function arrayDeclarationReplacement(array) {
4043
- if (array.elements.length > 0) return arrayExpression([]);
4044
- return arrayExpression([stringLiteral("Stryker was here")]);
4061
+ return array.elements.length > 0 ? arrayExpression([]) : arrayExpression([stringLiteral("Stryker was here")]);
4045
4062
  }
4046
4063
  function isArrayConstructorCall(node) {
4047
4064
  return isCallOrNewExpression(node) && isArrayIdentifier(node.callee);
@@ -4054,12 +4071,11 @@ function isArrayIdentifier(node) {
4054
4071
  }
4055
4072
  function arrayConstructorReplacement(construct) {
4056
4073
  const mutatedCallArgs = constructorArguments(construct.arguments);
4057
- if (construct.type === "NewExpression") return newExpression(cloneNode(construct.callee), mutatedCallArgs);
4058
- return callExpression(cloneNode(construct.callee), mutatedCallArgs);
4074
+ const callee = cloneNode(construct.callee);
4075
+ return construct.type === "NewExpression" ? newExpression(callee, mutatedCallArgs) : callExpression(callee, mutatedCallArgs);
4059
4076
  }
4060
4077
  function constructorArguments(args) {
4061
- if (args.length > 0) return [];
4062
- return [arrayExpression([])];
4078
+ return args.length > 0 ? [] : [arrayExpression([])];
4063
4079
  }
4064
4080
  const arrowFunctionMutator = (node) => Match.value(node).pipe(Match.when(isExpressionBodiedArrow, () => [arrowFunctionExpression([], identifier("undefined"))]), Match.orElse(() => NO_MUTANTS));
4065
4081
  function isExpressionBodiedArrow(node) {
@@ -4095,8 +4111,7 @@ function isStringLiteral(value) {
4095
4111
  return nodeType(value) === "Literal" && hasStringValue(value);
4096
4112
  }
4097
4113
  function hasStringValue(value) {
4098
- if (!Predicate$1.hasProperty(value, "value")) return false;
4099
- return typeof value["value"] === "string";
4114
+ return Predicate$1.hasProperty(value, "value") && typeof value["value"] === "string";
4100
4115
  }
4101
4116
  const stringAssignmentTypes = Object.freeze([
4102
4117
  "&&=",
@@ -4179,8 +4194,7 @@ function hasSuperInChildren(node) {
4179
4194
  return Object.keys(node).some((key) => containsSuperInValue(propertyOf(node, key)));
4180
4195
  }
4181
4196
  function containsSuperInValue(value) {
4182
- if (Array.isArray(value)) return value.some(containsSuperCall);
4183
- return containsSuperCall(value);
4197
+ return Array.isArray(value) ? value.some(containsSuperCall) : containsSuperCall(value);
4184
4198
  }
4185
4199
  const booleanLiteralMutator = (node) => Match.value(node).pipe(Match.when(isBooleanLiteral, (literal) => [booleanLiteral(!literal.value)]), Match.when(isNegatedPrefix, (unary) => [cloneNode(unary.argument)]), Match.orElse(() => NO_MUTANTS));
4186
4200
  function isBooleanLiteral(node) {
@@ -4331,8 +4345,12 @@ const baseReplacements = {
4331
4345
  setUTCSeconds: "setUTCMilliseconds"
4332
4346
  };
4333
4347
  const noReverseReplacements = ["getUTCDate", "setUTCDate"];
4334
- const replacements = new Map(Object.entries(baseReplacements));
4335
- for (const [key, value] of Object.entries(baseReplacements)) if (value !== null && !noReverseReplacements.includes(key)) replacements.set(value, key);
4348
+ const isReversible = (key, value) => value !== null && !noReverseReplacements.includes(key);
4349
+ const reverseReplacements = Object.fromEntries(Object.entries(baseReplacements).flatMap(([key, value]) => isReversible(key, value) ? [[value, key]] : []));
4350
+ const replacements = {
4351
+ ...baseReplacements,
4352
+ ...reverseReplacements
4353
+ };
4336
4354
  const methodExpressionMutator = (node) => Match.value(node).pipe(Match.when(isCallExpression, (call) => methodCallMutants(call)), Match.orElse(() => NO_MUTANTS));
4337
4355
  function methodCallMutants(call) {
4338
4356
  return Match.value(methodMutation(call)).pipe(Match.when(isMethodMutation, (mutation) => [methodExpressionReplacement(mutation)]), Match.orElse(() => NO_MUTANTS));
@@ -4346,7 +4364,9 @@ function methodMutation(call) {
4346
4364
  return Match.value(callee).pipe(Match.when(void 0, () => void 0), Match.orElse((member) => mutationFor(call, member)));
4347
4365
  }
4348
4366
  function mutationFor(call, callee) {
4349
- return Match.value(replacements.get(callee.property.name)).pipe(Match.when(void 0, () => void 0), Match.orElse((newName) => ({
4367
+ const methodName = callee.property.name;
4368
+ const replacement = Object.hasOwn(replacements, methodName) ? replacements[methodName] : void 0;
4369
+ return Match.value(replacement).pipe(Match.when(void 0, () => void 0), Match.orElse((newName) => ({
4350
4370
  call,
4351
4371
  callee,
4352
4372
  newName
@@ -4429,16 +4449,17 @@ const PLACEHOLDER = "Stryker was here!";
4429
4449
  const stringLiteralMutator = (node, context) => Match.value(node).pipe(Match.when(isTemplateLiteral, (template) => templateMutants(template)), Match.when(isStringLiteral, (literal) => mutantsWhen(isValidParent(literal, context), () => [stringLiteral(replacementText(literal.value.length === 0))])), Match.orElse(() => NO_MUTANTS));
4430
4450
  function templateMutants(template) {
4431
4451
  const first = template.quasis[0];
4432
- if (first === void 0) return NO_MUTANTS;
4433
- return [emptyOrPlaceholderTemplate(template, first)];
4452
+ return Option$1.match(Option$1.fromNullishOr(first), {
4453
+ onNone: () => NO_MUTANTS,
4454
+ onSome: (present) => [emptyOrPlaceholderTemplate(template, present)]
4455
+ });
4434
4456
  }
4435
4457
  function emptyOrPlaceholderTemplate(template, first) {
4436
4458
  const isEmptyTemplate = [template.quasis.length === 1, first.value.raw.length === 0].every(Boolean);
4437
4459
  return templateLiteral([templateElement(replacementText(isEmptyTemplate))], []);
4438
4460
  }
4439
4461
  function replacementText(isEmpty) {
4440
- if (isEmpty) return PLACEHOLDER;
4441
- return "";
4462
+ return isEmpty ? PLACEHOLDER : "";
4442
4463
  }
4443
4464
  function isValidParent(child, context) {
4444
4465
  const parent = context.parent;
@@ -4591,10 +4612,7 @@ const selectMutators = dual((args) => args.length >= 2, selectMutatorsDataFirst)
4591
4612
  var ParseFailed = class extends S.TaggedError("@systemfsoftware/stryker-js-instrumenter/Parser.schema/ParseFailed")("ParseFailed", {
4592
4613
  fileName: S.String,
4593
4614
  message: S.String,
4594
- location: S.Struct({
4595
- line: S.Finite,
4596
- column: S.Finite
4597
- }),
4615
+ location: Position,
4598
4616
  cause: S.Defect()
4599
4617
  }) {
4600
4618
  get message() {
@@ -4603,60 +4621,67 @@ var ParseFailed = class extends S.TaggedError("@systemfsoftware/stryker-js-instr
4603
4621
  };
4604
4622
  const oxcModule = Effect$1.cached(Effect$1.promise(() => import("./src-js-CvBdbRpe.mjs")));
4605
4623
  const loadOxc = Effect$1.flatMap(oxcModule, (load) => load);
4606
- const parseWithOxcDataFirst = (text, fileName, lang) => Effect$1.gen(function* () {
4624
+ const parseWithOxcDataFirst = Effect$1.fn("stryker.instrument.parser.parseWithOxc")(function* (text, fileName, lang) {
4607
4625
  const result = (yield* loadOxc).parseSync(fileName, text, {
4608
4626
  lang,
4609
4627
  range: true
4610
4628
  });
4611
- const lineTable = yield* Effect$1.orDie(S.decodeEffect(LineTableFromText)(text));
4612
- const failure = oxcParseFailure(result.errors, fileName, lineTable);
4613
- if (failure !== void 0) return yield* failure;
4614
- return {
4615
- root: result.program,
4616
- comments: result.comments
4617
- };
4629
+ const lineStarts = lineStartsOf(text);
4630
+ const failure = oxcParseFailure(result.errors, fileName, lineStarts);
4631
+ return yield* Option$1.match(Option$1.fromNullishOr(failure), {
4632
+ onNone: () => Effect$1.succeed({
4633
+ root: result.program,
4634
+ comments: result.comments
4635
+ }),
4636
+ onSome: (failed) => Effect$1.fail(failed)
4637
+ });
4618
4638
  });
4619
4639
  const parseWithOxc = dual((args) => args.length >= 3, parseWithOxcDataFirst);
4620
- const oxcParseFailure = (errors, fileName, lineTable) => {
4621
- const first = errors.at(0);
4622
- if (first === void 0) return;
4623
- return ParseFailed.make({
4640
+ const oxcParseFailure = (errors, fileName, lineStarts) => Option$1.match(Option$1.fromNullishOr(errors.at(0)), {
4641
+ onNone: () => void 0,
4642
+ onSome: (first) => ParseFailed.make({
4624
4643
  fileName,
4625
4644
  message: first.message,
4626
- location: lineTable.positionAt(oxcErrorLabelStart(first)),
4645
+ location: positionAt(lineStarts, oxcErrorLabelStart(first)),
4627
4646
  cause: errors.map((reported) => reported.message)
4628
- });
4629
- };
4630
- const oxcErrorLabelStart = (error) => {
4631
- const label = error.labels.at(0);
4632
- if (label === void 0) return 0;
4633
- return label.start;
4634
- };
4647
+ })
4648
+ });
4649
+ const oxcErrorLabelStart = (error) => Option$1.getOrElse(Option$1.map(Option$1.fromNullishOr(error.labels.at(0)), (label) => label.start), () => 0);
4635
4650
  const createParser = () => ({ parse: (code, fileName, scriptFormat) => Match.value(scriptFormat).pipe(Match.when("js", () => parseJS(code, fileName)), Match.when("ts", () => parseTS(code, fileName)), Match.when("tsx", () => parseTsx(code, fileName)), Match.exhaustive) });
4636
- const parseJSDataFirst = (text, fileName) => Effect$1.map(parseWithOxc(text, fileName, "js"), ({ root, comments }) => ({
4637
- originFileName: fileName,
4638
- rawContent: text,
4639
- format: "js",
4640
- root,
4641
- comments
4642
- }));
4651
+ const parseJSDataFirst = Effect$1.fn("stryker.instrument.parser.parseJS")(function* (text, fileName) {
4652
+ const parsed = yield* parseWithOxc(text, fileName, "js");
4653
+ return {
4654
+ originFileName: fileName,
4655
+ rawContent: text,
4656
+ format: "js",
4657
+ root: parsed.root,
4658
+ comments: parsed.comments
4659
+ };
4660
+ });
4643
4661
  const parseJS = dual((args) => args.length >= 2, parseJSDataFirst);
4644
- const parseTSDataFirst = (text, fileName) => Effect$1.map(parseWithOxc(text, fileName, "ts"), ({ root, comments }) => ({
4645
- originFileName: fileName,
4646
- rawContent: text,
4647
- format: "ts",
4648
- root,
4649
- comments
4650
- }));
4662
+ const parseTSDataFirst = Effect$1.fn("stryker.instrument.parser.parseTS")(function* (text, fileName) {
4663
+ const parsed = yield* parseWithOxc(text, fileName, "ts");
4664
+ return {
4665
+ originFileName: fileName,
4666
+ rawContent: text,
4667
+ format: "ts",
4668
+ root: parsed.root,
4669
+ comments: parsed.comments
4670
+ };
4671
+ });
4651
4672
  const parseTS = dual((args) => args.length >= 2, parseTSDataFirst);
4652
- const parseTsxDataFirst = (text, fileName) => Effect$1.map(parseWithOxc(text, fileName, "tsx"), ({ root, comments }) => ({
4653
- root,
4654
- comments,
4655
- format: "tsx",
4656
- originFileName: fileName,
4657
- rawContent: text
4658
- }));
4673
+ const parseTsxDataFirst = Effect$1.fn("stryker.instrument.parser.parseTsx")(function* (text, fileName) {
4674
+ const parsed = yield* parseWithOxc(text, fileName, "tsx");
4675
+ return {
4676
+ root: parsed.root,
4677
+ comments: parsed.comments,
4678
+ format: "tsx",
4679
+ originFileName: fileName,
4680
+ rawContent: text
4681
+ };
4682
+ });
4659
4683
  const parseTsx = dual((args) => args.length >= 2, parseTsxDataFirst);
4684
+ var PrintFailed = class extends S.TaggedError("@systemfsoftware/stryker-js-instrumenter/print/PrintFailed.schema/PrintFailed")("PrintFailed", { message: S.String }) {};
4660
4685
  const printProgramDataFirst = (program, opts = {}) => programText(opts, program);
4661
4686
  const printProgram = dual((args) => Predicate$1.hasProperty(args[0], "type"), printProgramDataFirst);
4662
4687
  const printNode = (node) => dispatchNode({ indentLevel: 0 }, node, PREC.Sequence);
@@ -5643,28 +5668,19 @@ const externalModuleArgumentText = (value) => Boolean$1$1.match(Predicate$1.isTr
5643
5668
  function printDataFirst(file, entryForFormat) {
5644
5669
  const context = { print: (inner) => print(inner, entryForFormat) };
5645
5670
  return Option$1.match(entryForFormat(formatKeyOf(file)), {
5646
- onNone: () => missingFormatPrint(file),
5647
- onSome: (entry) => entry.print(file, context)
5671
+ onNone: () => Result.fail(PrintFailed.make({ message: `No registered format renders the "${formatKeyOf(file)}" AST` })),
5672
+ onSome: (entry) => Result.succeed(entry.print(file, context))
5648
5673
  });
5649
5674
  }
5650
5675
  const print = dual((args) => args.length >= 2, printDataFirst);
5651
- function missingFormatPrint(file) {
5652
- throw new Error(`No registered format renders the "${formatKeyOf(file)}" AST`);
5653
- }
5654
- function hashbangOf(root) {
5655
- if (!hasHashbang(root)) return null;
5656
- return printHashbang(root.hashbang);
5657
- }
5676
+ const hashbangOf = (root) => hasHashbang(root) ? printHashbang(root.hashbang) : null;
5658
5677
  const hasHashbang = (root) => Predicate$1.hasProperty(root, "hashbang") && Predicate$1.isObject(root.hashbang);
5659
5678
  const printHashbang = (field) => ({
5660
5679
  type: "Hashbang",
5661
5680
  value: hashbangValue(field),
5662
5681
  start: field.start
5663
5682
  });
5664
- function hashbangValue(field) {
5665
- if (typeof field.value !== "string") return "";
5666
- return field.value;
5667
- }
5683
+ const hashbangValue = (field) => typeof field.value === "string" ? field.value : "";
5668
5684
  const printScriptAst$1 = (root) => printProgram(root, { hashbang: hashbangOf(root) });
5669
5685
  const jsPrintDataFirst = (file) => printScriptAst$1(file.root);
5670
5686
  const jsPrint = dual((args) => args.length >= 2, jsPrintDataFirst);
@@ -5745,48 +5761,9 @@ const resolveFormat = Workflow.make({
5745
5761
  error: FormatOverrideUnclaimed,
5746
5762
  decide: (command) => Match.value(selectionFor(command)).pipe(Match.tag("ClaimSelected", ({ claim }) => Result.succeed(assignedFrom(claim, command))), Match.tag("PinUnclaimed", ({ formatId }) => Result.fail(overrideUnclaimedFrom(command, formatId))), Match.tag("ExtensionUnclaimed", () => Result.succeed(skippedFrom(command))), Match.exhaustive)
5747
5763
  });
5748
- const MutatorNameSchema = S.String.pipe(S.check(S.isPattern(/^[a-zA-Z]+(?: [a-zA-Z]+)*$/)));
5749
- const DirectiveReasonSchema = S.String.pipe(S.check(S.isPattern(/^\S(?:[\s\S]*\S)?$/)));
5750
- const DirectiveSchema = S.Struct({
5751
- action: S.Literals(["disable", "restore"]),
5752
- scope: S.Literals(["next-line", "block"]),
5753
- mutatorNames: S.Array(MutatorNameSchema).check(S.isMinLength(1)),
5754
- reason: DirectiveReasonSchema
5755
- });
5756
- const LocatedPositionSchema = S.Struct({
5757
- line: SourceLineSchema,
5758
- column: SourceColumnSchema
5759
- });
5760
- const LocatedDirectiveSchema = S.Struct({
5761
- directive: DirectiveSchema,
5762
- at: LocatedPositionSchema,
5763
- governedLine: SourceLineSchema
5764
- });
5765
- S.Struct({
5766
- directive: DirectiveSchema,
5767
- at: LocatedPositionSchema,
5768
- mutatorName: S.String
5769
- });
5770
5764
  const DIRECTIVE_PATTERN = /^\s?Stryker (disable|restore)(?: (next-line))? ([a-zA-Z, ]+)(?::(.+)?)?/;
5771
5765
  const DEFAULT_REASON = "Ignored using a comment";
5772
5766
  const NEXT_LINE$1 = "next-line";
5773
- S.Struct({
5774
- clause: S.Literals([
5775
- " Stryker disable",
5776
- " Stryker restore",
5777
- " Stryker disable next-line",
5778
- " Stryker restore next-line",
5779
- " Stryker enable",
5780
- " nothing"
5781
- ]),
5782
- nameLetters: S.Array(S.Literals([
5783
- "a",
5784
- "b",
5785
- "Z",
5786
- ",",
5787
- " "
5788
- ])).check(S.isMinLength(1))
5789
- });
5790
5767
  var DecodeDirectiveCommand = class extends S.TaggedClass()("DecodeDirectiveCommand", { commentText: S.String }) {
5791
5768
  static [Workflow.InstrumentationBrand] = {};
5792
5769
  };
@@ -5890,27 +5867,34 @@ const loadHeader = Effect$1.map(parseWithOxc(INSTRUMENTATION_HEADER_SOURCE, "ins
5890
5867
  instrumentationHeaderValue = parsed.root.body;
5891
5868
  return parsed.root.body;
5892
5869
  });
5893
- const instrumentationHeader = instrumentationHeaderValue !== void 0 ? Effect$1.succeed(instrumentationHeaderValue) : loadHeader;
5870
+ const instrumentationHeader = Option$1.match(Option$1.fromNullishOr(instrumentationHeaderValue), {
5871
+ onNone: () => loadHeader,
5872
+ onSome: (header) => Effect$1.succeed(header)
5873
+ });
5894
5874
  const placeHeader = (root) => Effect$1.map(headerFor(root), (header) => {
5895
5875
  root.body.unshift(...header);
5896
5876
  });
5897
- const headerFor = (root) => Effect$1.map(instrumentationHeader, (header) => Option$1.match(leadingCommentsOf(root), {
5877
+ const headerFor = (root) => Effect$1.map(instrumentationHeader, (header) => Option$1.match(Option$1.all([Option$1.fromNullishOr(header[0]), leadingCommentsOf(root)]), {
5898
5878
  onNone: () => header,
5899
- onSome: (leadingComments) => [commentedHeader(leadingComments, header), ...header.slice(1)]
5879
+ onSome: ([firstHeader, leadingComments]) => commentedHeader(firstHeader, leadingComments, header.slice(1))
5900
5880
  }));
5901
- const placeHeaderIfNeededDataFirst = (placed, options, root) => placed ? placeHeaderWhenWanted(options, root) : Effect$1.void;
5881
+ const placeHeaderIfNeededDataFirst = (placed, options, root) => Boolean$1$1.match(placed, {
5882
+ onTrue: () => placeHeaderWhenWanted(options, root),
5883
+ onFalse: () => Effect$1.void
5884
+ });
5902
5885
  const placeHeaderIfNeeded = dual((args) => args.length >= 3, placeHeaderIfNeededDataFirst);
5903
- const placeHeaderWhenWanted = (options, root) => options.noHeader === true ? Effect$1.void : placeHeader(root);
5886
+ const placeHeaderWhenWanted = (options, root) => Boolean$1$1.match(options.noHeader === true, {
5887
+ onTrue: () => Effect$1.void,
5888
+ onFalse: () => placeHeader(root)
5889
+ });
5904
5890
  function leadingCommentsOf(root) {
5905
5891
  const first = root.body[0];
5906
- if (!hasLeadingComments$1(first)) return Option$1.none();
5907
- return Option$1.some(first.leadingComments);
5892
+ return Option$1.map(Option$1.liftPredicate(first, hasLeadingComments$1), (value) => value.leadingComments);
5908
5893
  }
5909
- function commentedHeader(leadingComments, header) {
5910
- const firstHeader = Option$1.getOrThrowWith(Option$1.fromNullishOr(header[0]), () => /* @__PURE__ */ new Error("Instrumentation header is empty"));
5894
+ function commentedHeader(firstHeader, leadingComments, rest) {
5911
5895
  const cloned = cloneNode(firstHeader);
5912
5896
  Object.assign(cloned, { leadingComments });
5913
- return cloned;
5897
+ return [cloned, ...rest];
5914
5898
  }
5915
5899
  const PlacementFactsSchema = S.Struct({
5916
5900
  isExpression: S.Boolean,
@@ -5924,8 +5908,8 @@ const ReplacementFactsSchema = S.Struct({
5924
5908
  isSwitchCase: S.Boolean
5925
5909
  });
5926
5910
  const PlacedMutantSchema = S.Struct({
5927
- id: S.String,
5928
- mutatorName: S.String,
5911
+ id: MutantId,
5912
+ mutatorName: MutatorNameSchema,
5929
5913
  replacement: ReplacementFactsSchema
5930
5914
  });
5931
5915
  var PlaceMutantsCommand = class extends S.TaggedClass()("PlaceMutantsCommand", {
@@ -5938,19 +5922,19 @@ var PlaceMutantsCommand = class extends S.TaggedClass()("PlaceMutantsCommand", {
5938
5922
  const PlacementDecisionTypeId = Symbol.for("@systemfsoftware/stryker-js-instrumenter/PlacementDecision");
5939
5923
  var ExpressionSite = class extends S.TaggedClass()("ExpressionSite", {
5940
5924
  fileName: S.String,
5941
- mutantIds: S.Array(S.String)
5925
+ mutantIds: S.Array(MutantId)
5942
5926
  }) {
5943
5927
  [PlacementDecisionTypeId] = PlacementDecisionTypeId;
5944
5928
  };
5945
5929
  var StatementSite = class extends S.TaggedClass()("StatementSite", {
5946
5930
  fileName: S.String,
5947
- mutantIds: S.Array(S.String)
5931
+ mutantIds: S.Array(MutantId)
5948
5932
  }) {
5949
5933
  [PlacementDecisionTypeId] = PlacementDecisionTypeId;
5950
5934
  };
5951
5935
  var SwitchCaseSite = class extends S.TaggedClass()("SwitchCaseSite", {
5952
5936
  fileName: S.String,
5953
- mutantIds: S.Array(S.String)
5937
+ mutantIds: S.Array(MutantId)
5954
5938
  }) {
5955
5939
  [PlacementDecisionTypeId] = PlacementDecisionTypeId;
5956
5940
  };
@@ -5962,8 +5946,8 @@ const ExpectedKindSchema = S.Literals([
5962
5946
  var MutantKindMismatch = class extends S.TaggedError()("MutantKindMismatch", {
5963
5947
  fileName: S.String,
5964
5948
  placer: PlacerNameSchema,
5965
- mutantId: S.String,
5966
- mutatorName: S.String,
5949
+ mutantId: MutantId,
5950
+ mutatorName: MutatorNameSchema,
5967
5951
  expected: ExpectedKindSchema
5968
5952
  }) {};
5969
5953
  var NoPlacerClaimsNode = class extends S.TaggedError()("NoPlacerClaimsNode", { fileName: S.String }) {};
@@ -6014,23 +5998,19 @@ const placeMutants = Workflow.make({
6014
5998
  return siteOf(command, placer);
6015
5999
  })
6016
6000
  });
6017
- const LocationSchema = S.Struct({
6018
- start: NodePositionSchema,
6019
- end: NodePositionSchema
6020
- });
6021
6001
  const WILDCARD = "all";
6022
6002
  const NEXT_LINE = "next-line";
6023
6003
  const MutantCandidateSchema = S.Struct({
6024
- mutatorName: S.String,
6004
+ mutatorName: MutatorNameSchema,
6025
6005
  replacementCode: S.String,
6026
- location: S.optional(LocationSchema),
6006
+ location: S.optional(Location),
6027
6007
  ignorerReason: S.optional(S.String)
6028
6008
  });
6029
6009
  const PlannedMutantSchema = S.Struct({
6030
- id: S.String,
6031
- mutatorName: S.String,
6010
+ id: MutantId,
6011
+ mutatorName: MutatorNameSchema,
6032
6012
  replacementCode: S.String,
6033
- location: LocationSchema,
6013
+ location: Location,
6034
6014
  ignoreReason: S.optional(S.String)
6035
6015
  });
6036
6016
  const MutantCounterSchema = S.Int.pipe(S.check(S.isBetween({
@@ -6041,10 +6021,10 @@ const MutantCountSchema = S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(0)));
6041
6021
  var PlanMutantsCommand = class extends S.TaggedClass()("PlanMutantsCommand", {
6042
6022
  fileName: S.String,
6043
6023
  firstIndex: MutantCounterSchema,
6044
- offset: NodePositionSchema,
6045
- line: SourceLineSchema,
6046
- mutatorNames: S.Array(S.String),
6047
- excludedMutations: S.Array(S.String),
6024
+ offset: ScriptOrigin,
6025
+ line: Line,
6026
+ mutatorNames: S.Array(MutatorNameSchema),
6027
+ excludedMutations: S.Array(MutatorNameSchema),
6048
6028
  rule: S.Array(LocatedDirectiveSchema),
6049
6029
  directives: S.Array(LocatedDirectiveSchema),
6050
6030
  candidates: S.Array(MutantCandidateSchema)
@@ -6069,7 +6049,7 @@ var MutantsFullyIgnored = class extends S.TaggedClass()("MutantsFullyIgnored", {
6069
6049
  };
6070
6050
  var MutantWithoutLocation = class extends S.TaggedError()("MutantWithoutLocation", {
6071
6051
  fileName: S.String,
6072
- mutatorName: S.String
6052
+ mutatorName: MutatorNameSchema
6073
6053
  }) {};
6074
6054
  const reachedLine = (located, line) => Match.value(located.directive.scope).pipe(Match.when(NEXT_LINE, () => located.governedLine === line), Match.when("block", () => true), Match.exhaustive);
6075
6055
  const namesMutator = (located, lowerMutatorName) => located.directive.mutatorNames.some((name) => [name === WILDCARD, name.toLowerCase() === lowerMutatorName].some(Boolean));
@@ -6087,12 +6067,13 @@ const unusedDirectiveWarning = (unused, fileName) => {
6087
6067
  };
6088
6068
  const warningsOf = (command) => unusedDirectives(command.directives, command.mutatorNames).map((unused) => unusedDirectiveWarning(unused, command.fileName));
6089
6069
  /**
6090
- * Both the node span (`source`) and the region origin (`offset`) are 1-based
6091
- * file coordinates: the region's first line carries its column origin, later
6092
- * lines start at column 1, so the shift adds `offset.line - 1` lines and —
6093
- * only when the node sits on the region's first line — `offset.column`.
6070
+ * The node span (`source`) is a 1-based position inside the embedded script;
6071
+ * the region origin (`offset`) is where that script begins in its host file.
6072
+ * The region's first line carries its column shift, later lines start at
6073
+ * column 1, so the shift adds `offset.line - 1` lines and — only when the node
6074
+ * sits on the region's first line — `offset.columnShift`.
6094
6075
  */
6095
- const columnOffsetOf = (source, offset) => Match.value(source.line === 1).pipe(Match.when(true, () => offset.column), Match.when(false, () => 0), Match.exhaustive);
6076
+ const columnOffsetOf = (source, offset) => Match.value(source.line === 1).pipe(Match.when(true, () => offset.columnShift), Match.when(false, () => 0), Match.exhaustive);
6096
6077
  const shiftedPosition = (source, offset) => ({
6097
6078
  column: source.column + columnOffsetOf(source, offset),
6098
6079
  line: source.line + offset.line - 1
@@ -6107,7 +6088,7 @@ const plannedMutant = (command, candidate, index) => Option$1.match(Option$1.fro
6107
6088
  mutatorName: candidate.mutatorName
6108
6089
  })),
6109
6090
  onSome: (location) => Result.succeed({
6110
- id: `${command.firstIndex + index}`,
6091
+ id: PlannedMutantSchema.fields.id.make(`${command.firstIndex + index}`),
6111
6092
  mutatorName: candidate.mutatorName,
6112
6093
  replacementCode: candidate.replacementCode,
6113
6094
  location: shiftedLocation(location, command.offset),
@@ -6141,7 +6122,11 @@ const comparePositions = (a, b) => {
6141
6122
  };
6142
6123
  const locationIncluded = (haystack, needle) => comparePositions(haystack.start, needle.start) <= 0 && comparePositions(haystack.end, needle.end) >= 0;
6143
6124
  const locationOverlaps = (a, b) => comparePositions(a.start, b.end) <= 0 && comparePositions(a.end, b.start) >= 0;
6144
- const errorTextOf$1 = (cause) => Option$1.getOrElse(Option$1.map(ErrorText.fromCause(cause), (rendered) => rendered.text), () => "");
6125
+ const errorTextOf$1 = (cause) => Option$1.getOrElse(Option$1.map(errorTextOf$2(cause), (rendered) => rendered.text), () => "");
6126
+ const traversalFailure = (cause) => InstrumentError.make({
6127
+ message: cause instanceof Error ? cause.message : errorTextOf$1(cause),
6128
+ cause
6129
+ });
6145
6130
  const DEFAULT_MUTATOR_REGISTRY = {
6146
6131
  defaults: defaultMutators,
6147
6132
  optIn: optInMutators
@@ -6164,28 +6149,20 @@ const locatedDirective = (comment, governedLine) => Option$1.flatMap(Option$1.fr
6164
6149
  at: loc.start,
6165
6150
  governedLine
6166
6151
  })));
6167
- const directivesOf = (node, governedLineOf) => attachedComments(node).flatMap((comment) => Option$1.toArray(locatedDirective(comment, governedLineOf(node))));
6152
+ const directivesOf = (node, governedLine) => attachedComments(node).flatMap((comment) => Option$1.toArray(locatedDirective(comment, governedLine)));
6168
6153
  const foldInto = (rule, directive) => Match.value(foldRule(FoldRuleCommand.make({
6169
6154
  rule,
6170
6155
  directive
6171
6156
  }))).pipe(Match.when(Result.isSuccess, (folded) => folded.success.rule), Match.orElse(() => rule));
6172
6157
  const NO_COMMENTS = [];
6173
- function attachedComments(node) {
6174
- if (!hasLeadingComments(node)) return NO_COMMENTS;
6175
- return node.leadingComments;
6176
- }
6158
+ const attachedComments = (node) => hasLeadingComments(node) ? node.leadingComments : NO_COMMENTS;
6177
6159
  const hasLeadingComments = (value) => Predicate$1.hasProperty(value, "leadingComments") && Array.isArray(value.leadingComments);
6178
- function ancestorsOf(path) {
6179
- const ancestors = [];
6180
- for (let current = path.parentPath; current !== null; current = current.parentPath) ancestors.push(current.node);
6181
- return ancestors;
6182
- }
6183
- function isTypeNode(path) {
6160
+ function isTypeNode(node) {
6184
6161
  return [
6185
- tsTypeAnnotationNodeTypes.includes(path.node.type),
6186
- flowTypeAnnotationNodeTypes.includes(path.node.type),
6187
- isDeclareVariableStatement(path.node),
6188
- isDeclareModule(path.node)
6162
+ tsTypeAnnotationNodeTypes.includes(node.type),
6163
+ flowTypeAnnotationNodeTypes.includes(node.type),
6164
+ isDeclareVariableStatement(node),
6165
+ isDeclareModule(node)
6189
6166
  ].some((isType) => isType);
6190
6167
  }
6191
6168
  function isDeclareVariableStatement(node) {
@@ -6221,8 +6198,8 @@ const flowTypeAnnotationNodeTypes = Object.freeze([
6221
6198
  "OpaqueType",
6222
6199
  "TypeAlias"
6223
6200
  ]);
6224
- function isImportDeclaration(path) {
6225
- return nodeType(path.node) === "TSImportEqualsDeclaration" || path.node.type === "ImportDeclaration";
6201
+ function isImportDeclaration(node) {
6202
+ return nodeType(node) === "TSImportEqualsDeclaration" || node.type === "ImportDeclaration";
6226
6203
  }
6227
6204
  function mutantTestExpression(mutantId) {
6228
6205
  return callExpression(identifier(IS_MUTANT_ACTIVE_HELPER), [stringLiteral(mutantId)]);
@@ -6230,41 +6207,33 @@ function mutantTestExpression(mutantId) {
6230
6207
  function mutationCoverageSequenceExpression(mutants, targetExpression) {
6231
6208
  const mutantIds = [...mutants].map((mutant) => stringLiteral(mutant.id));
6232
6209
  const sequence = [callExpression(identifier(COVER_MUTANT_HELPER), mutantIds)];
6233
- if (targetExpression !== void 0) sequence.push(targetExpression);
6234
- return sequenceExpression(sequence);
6210
+ return sequenceExpression(targetExpression === void 0 ? sequence : [...sequence, targetExpression]);
6235
6211
  }
6236
6212
  const refusalPlacer = (refusal) => Match.value(refusal).pipe(Match.tag("MutantKindMismatch", (mismatch) => mismatch.placer), Match.tag("MutantsUnapplied", (unapplied) => unapplied.placer), Match.tag("NoPlacerClaimsNode", () => "no placer"), Match.tag("MutantNotApplied", () => "no placer"), Match.exhaustive);
6237
6213
  const refusalDetail = (refusal) => Match.value(refusal).pipe(Match.tag("MutantKindMismatch", (mismatch) => `Expected ${mismatch.expected} for mutant ${mismatch.mutantId}`), Match.tag("MutantsUnapplied", (unapplied) => `Failed to apply ${unapplied.mutatorNames.join(", ")}`), Match.tag("NoPlacerClaimsNode", () => "No placer claims the node"), Match.tag("MutantNotApplied", (unapplied) => `Could not apply the ${unapplied.mutatorName} mutant`), Match.exhaustive);
6238
- const placementFailure = (refusal, nodePath, mutants, fileName, lineTable, basePath) => {
6214
+ const placementFailureMessage = (refusal, node, mutants, fileName, lineStarts, basePath) => {
6239
6215
  const message = `${refusalPlacer(refusal)} could not place mutants with type(s): "${placementListFormat.format(mutants.map((mutant) => mutant.mutatorName))}"`;
6240
- return /* @__PURE__ */ new Error(`${placementLocation(nodePath.node, fileName, lineTable, basePath)} ${message}. Either remove this file from the list of files to be mutated, or exclude the mutator (using \`mutator.excludedMutations\`). Original error: ${refusalDetail(refusal)}`);
6216
+ return `${placementLocation(node, fileName, lineStarts, basePath)} ${message}. Either remove this file from the list of files to be mutated, or exclude the mutator (using \`mutator.excludedMutations\`). Original error: ${refusalDetail(refusal)}`;
6241
6217
  };
6242
6218
  function nodeOfKind(mutant, node, isKind, kind) {
6243
- return narrowNode(node, isKind, `Cannot place mutant ${mutant.id}: expected ${kind}, got ${node.type}`);
6244
- }
6245
- function narrowNode(node, isKind, message) {
6246
- if (isKind(node)) return node;
6247
- throw new Error(message);
6219
+ return isKind(node) ? Result.succeed(node) : Result.fail(/* @__PURE__ */ new Error(`Cannot place mutant ${mutant.id}: expected ${kind}, got ${node.type}`));
6248
6220
  }
6249
6221
  function expressionOf(node) {
6250
- return narrowNode(node, isExpressionKind, `Expected an expression, got ${node.type}`);
6222
+ return isExpressionKind(node) ? Result.succeed(node) : Result.fail(/* @__PURE__ */ new Error(`Expected an expression, got ${node.type}`));
6251
6223
  }
6252
6224
  function statementOf(node) {
6253
- return narrowNode(node, isStatementKind, `Expected a statement, got ${node.type}`);
6225
+ return isStatementKind(node) ? Result.succeed(node) : Result.fail(/* @__PURE__ */ new Error(`Expected a statement, got ${node.type}`));
6254
6226
  }
6255
6227
  function isSwitchCase(node) {
6256
6228
  return nodeType(node) === "SwitchCase";
6257
6229
  }
6258
6230
  function switchCaseOf(node) {
6259
- return narrowNode(node, isSwitchCase, `Expected a switch case, got ${node.type}`);
6231
+ return isSwitchCase(node) ? Result.succeed(node) : Result.fail(/* @__PURE__ */ new Error(`Expected a switch case, got ${node.type}`));
6260
6232
  }
6261
- const fileNameWithin = (basePath, fileName) => {
6262
- if (basePath === void 0) return fileName;
6263
- return relativeTo(basePath, fileName);
6264
- };
6265
- function placementLocation(node, fileName, lineTable, basePath) {
6233
+ const fileNameWithin = (basePath, fileName) => basePath === void 0 ? fileName : relativeTo(basePath, fileName);
6234
+ function placementLocation(node, fileName, lineStarts, basePath) {
6266
6235
  const relativeFile = fileNameWithin(basePath, fileName);
6267
- const position = Option$1.map(Option$1.fromNullishOr(spanOf(node)), (span) => lineTable.positionAt(span.start));
6236
+ const position = Option$1.map(Option$1.fromNullishOr(spanOf(node)), (span) => positionAt(lineStarts, span.start));
6268
6237
  return Option$1.match(position, {
6269
6238
  onNone: () => `${relativeFile}:undefined:undefined`,
6270
6239
  onSome: (at) => `${relativeFile}:${at.line}:${at.column}`
@@ -6274,27 +6243,25 @@ const placementListFormat = new Intl.ListFormat("en");
6274
6243
  const normalizeSeparators = (value) => value.replace(/\\/g, "/");
6275
6244
  const withTrailingSlash = (basePath) => {
6276
6245
  const normalized = normalizeSeparators(basePath);
6277
- if (normalized.endsWith("/")) return normalized;
6278
- return `${normalized}/`;
6246
+ return normalized.endsWith("/") ? normalized : `${normalized}/`;
6279
6247
  };
6280
6248
  const relativeTo = (basePath, fileName) => {
6281
6249
  const prefix = withTrailingSlash(basePath);
6282
6250
  const normalizedFile = normalizeSeparators(fileName);
6283
- if (!normalizedFile.startsWith(prefix)) return fileName;
6284
- return normalizedFile.slice(prefix.length);
6251
+ return normalizedFile.startsWith(prefix) ? normalizedFile.slice(prefix.length) : fileName;
6285
6252
  };
6286
6253
  function classOrFunctionExpressionNamedIfNeeded(path) {
6287
- return Match.value(path.node).pipe(Match.when(isAnonymousFunctionOrClass, (node) => nameFromParent(path, node)), Match.orElse(() => void 0));
6254
+ return Option$1.flatMap(Option$1.filter(Option$1.some(path.node), isAnonymousFunctionOrClass), (node) => nameFromParent(path, node));
6288
6255
  }
6289
6256
  function nameFromParent(path, node) {
6290
6257
  return Match.value(path.parentPath?.node).pipe(Match.when(isVariableDeclarator, (declarator) => adoptDeclaredName(node, declarator)), Match.when({
6291
6258
  type: "Property",
6292
6259
  key: { type: "Identifier" }
6293
- }, () => namedPropertyValue(path, node)), Match.orElse(() => void 0));
6260
+ }, () => namedPropertyValue(path, node)), Match.orElse(() => Option$1.none()));
6294
6261
  }
6295
6262
  /** A property value only survives by name when the declaration above it carries one. */
6296
6263
  function namedPropertyValue(path, node) {
6297
- return Match.value(path.getStatementParent()?.node.type).pipe(Match.when("VariableDeclaration", () => node), Match.orElse(() => void 0));
6264
+ return Match.value(path.getStatementParent()?.node.type).pipe(Match.when("VariableDeclaration", () => Option$1.some(node)), Match.orElse(() => Option$1.none()));
6298
6265
  }
6299
6266
  function adoptIdentifier(node, identifier) {
6300
6267
  node.id = identifier;
@@ -6307,14 +6274,11 @@ function isFunctionOrClassExpression(node) {
6307
6274
  return node.type === "FunctionExpression" || node.type === "ClassExpression";
6308
6275
  }
6309
6276
  function arrowFunctionExpressionNamedIfNeeded(path) {
6310
- return Match.value(path.node).pipe(Match.when({ type: "ArrowFunctionExpression" }, (node) => arrowNamedByDeclarator(node, path.parentPath)), Match.orElse(() => void 0));
6277
+ return Match.value(path.node).pipe(Match.when({ type: "ArrowFunctionExpression" }, (node) => arrowNamedByDeclarator(node, path.parentPath)), Match.orElse(() => Option$1.none()));
6311
6278
  }
6312
6279
  /** An arrow bound to a named declaration is re-emitted as a named function. */
6313
6280
  function arrowNamedByDeclarator(node, parentPath) {
6314
- return Option$1.match(declaratorIdentifier(parentPath), {
6315
- onNone: () => void 0,
6316
- onSome: (identifier) => namedArrowExpression(node, identifier)
6317
- });
6281
+ return Option$1.map(declaratorIdentifier(parentPath), (identifier) => namedArrowExpression(node, identifier));
6318
6282
  }
6319
6283
  function namedArrowExpression(node, identifier) {
6320
6284
  const declaration = variableDeclaration("const", [variableDeclarator(identifier, node)]);
@@ -6327,10 +6291,7 @@ function isVariableDeclarator(node) {
6327
6291
  return nodeType(node) === "VariableDeclarator";
6328
6292
  }
6329
6293
  function adoptDeclaredName(node, declarator) {
6330
- return Option$1.match(declaredName(declarator), {
6331
- onNone: () => void 0,
6332
- onSome: (identifier) => adoptIdentifier(node, identifier)
6333
- });
6294
+ return Option$1.map(declaredName(declarator), (identifier) => adoptIdentifier(node, identifier));
6334
6295
  }
6335
6296
  function declaredName(declarator) {
6336
6297
  return Match.value(declarator.id).pipe(Match.when(isIdentifierReference, (identifier) => Option$1.some(identifier)), Match.orElse(() => Option$1.none()));
@@ -6339,10 +6300,10 @@ function isIdentifierReference(node) {
6339
6300
  return nodeType(node) === "Identifier";
6340
6301
  }
6341
6302
  function nameIfAnonymous(path) {
6342
- return classOrFunctionExpressionNamedIfNeeded(path) ?? arrowNameOrNode(path);
6343
- }
6344
- function arrowNameOrNode(path) {
6345
- return arrowFunctionExpressionNamedIfNeeded(path) ?? expressionOf(path.node);
6303
+ return Option$1.match(Option$1.orElse(classOrFunctionExpressionNamedIfNeeded(path), () => arrowFunctionExpressionNamedIfNeeded(path)), {
6304
+ onNone: () => expressionOf(path.node),
6305
+ onSome: (named) => Result.succeed(named)
6306
+ });
6346
6307
  }
6347
6308
  function isChainLink(node) {
6348
6309
  return [
@@ -6360,51 +6321,45 @@ function isCallExpressionNode(node) {
6360
6321
  function isNonNullExpression(node) {
6361
6322
  return nodeType(node) === "TSNonNullExpression";
6362
6323
  }
6363
- function isValidExpression(path) {
6364
- const parent = path.parentPath;
6365
- return parent === null || !isUnmutatableContext(path, parent);
6324
+ function isValidExpression(node, parent) {
6325
+ return parent === null || !isUnmutatableContext(node, parent);
6366
6326
  }
6367
- function isUnmutatableContext(path, parent) {
6327
+ function isUnmutatableContext(node, parent) {
6368
6328
  return [
6369
- isObjectPropertyKey(path, parent),
6370
- isPartOfChain(path, parent),
6329
+ isObjectPropertyKey(node, parent),
6330
+ isPartOfChain(node, parent),
6371
6331
  isTaggedTemplateTag(parent),
6372
- isDeletedOperand(path, parent),
6373
- isAssignedTarget(path, parent)
6332
+ isDeletedOperand(node, parent),
6333
+ isAssignedTarget(node, parent)
6374
6334
  ].some((invalid) => invalid);
6375
6335
  }
6376
- function isObjectPropertyKey(path, parent) {
6377
- const parentNode = parent.node;
6378
- return parentNode.type === "Property" && parentNode.key === path.node;
6336
+ function isObjectPropertyKey(node, parent) {
6337
+ return parent.type === "Property" && parent.key === node;
6379
6338
  }
6380
6339
  function isTaggedTemplateTag(parent) {
6381
- return parent.node.type === "TaggedTemplateExpression";
6340
+ return parent.type === "TaggedTemplateExpression";
6382
6341
  }
6383
- function isDeletedOperand(path, parent) {
6384
- const parentNode = parent.node;
6385
- return parentNode.type === "UnaryExpression" && parentNode.operator === "delete";
6342
+ function isDeletedOperand(node, parent) {
6343
+ return parent.type === "UnaryExpression" && parent.operator === "delete";
6386
6344
  }
6387
- function isAssignedTarget(path, parent) {
6388
- const parentNode = parent.node;
6389
- return parentNode.type === "AssignmentExpression" && parentNode.left === path.node;
6345
+ function isAssignedTarget(node, parent) {
6346
+ return parent.type === "AssignmentExpression" && parent.left === node;
6390
6347
  }
6391
- function isPartOfChain(path, parent) {
6392
- return isChainLink(path.node) && chainContinuesIn(path, parent);
6348
+ function isPartOfChain(node, parent) {
6349
+ return isChainLink(node) && chainContinuesIn(node, parent);
6393
6350
  }
6394
- function chainContinuesIn(path, parent) {
6351
+ function chainContinuesIn(node, parent) {
6395
6352
  return [
6396
- isMemberAccessParent(path, parent),
6397
- isNonNullExpression(parent.node),
6398
- isCalleeParent(path, parent)
6353
+ isMemberAccessParent(node, parent),
6354
+ isNonNullExpression(parent),
6355
+ isCalleeParent(node, parent)
6399
6356
  ].some((continues) => continues);
6400
6357
  }
6401
- function isMemberAccessParent(path, parent) {
6402
- const parentNode = parent.node;
6403
- return parentNode.type === "MemberExpression" && isNotACallOnTheNode(parentNode, path.node);
6358
+ function isMemberAccessParent(node, parent) {
6359
+ return parent.type === "MemberExpression" && isNotACallOnTheNode(parent, node);
6404
6360
  }
6405
- function isCalleeParent(path, parent) {
6406
- const parentNode = parent.node;
6407
- return parentNode.type === "CallExpression" && parentNode.callee === path.node;
6361
+ function isCalleeParent(node, parent) {
6362
+ return parent.type === "CallExpression" && parent.callee === node;
6408
6363
  }
6409
6364
  function isNotACallOnTheNode(member, node) {
6410
6365
  return !(member.computed && member.property === node);
@@ -6421,27 +6376,31 @@ function isParenthesizedWrapper(value) {
6421
6376
  const expressionMutantPlacer = {
6422
6377
  name: "expression",
6423
6378
  place(path, appliedMutants) {
6424
- let expression = nameIfAnonymous(path);
6425
- expression = mutationCoverageSequenceExpression(appliedMutants.keys(), expression);
6426
- for (const [mutant, appliedMutant] of appliedMutants) expression = conditionalExpression(mutantTestExpression(mutant.id), nodeOfKind(mutant, unwrapParenthesizedExpression(appliedMutant), isExpressionKind, "an expression"), expression);
6427
- path.replaceWith(expression);
6379
+ return Result.gen(function* () {
6380
+ const base = yield* nameIfAnonymous(path);
6381
+ const sequenced = mutationCoverageSequenceExpression(appliedMutants.keys(), base);
6382
+ const expression = yield* [...appliedMutants].reduce((accumulated, [mutant, appliedMutant]) => Result.flatMap(accumulated, (current) => Result.map(nodeOfKind(mutant, unwrapParenthesizedExpression(appliedMutant), isExpressionKind, "an expression"), (replacement) => conditionalExpression(mutantTestExpression(mutant.id), replacement, current))), Result.succeed(sequenced));
6383
+ path.replaceWith(expression);
6384
+ });
6428
6385
  }
6429
6386
  };
6430
6387
  const statementMutantPlacer = {
6431
6388
  name: "statement",
6432
6389
  place(path, appliedMutants) {
6433
- const body = [expressionStatement(mutationCoverageSequenceExpression(appliedMutants.keys())), ...statementsOf(path)];
6434
- const statement = [...appliedMutants].reduce(guardedStatement, blockStatement(body));
6435
- path.replaceWith(wrappedStatement(path, statement));
6390
+ return Result.gen(function* () {
6391
+ const statements = yield* statementsOf(path);
6392
+ const body = [expressionStatement(mutationCoverageSequenceExpression(appliedMutants.keys())), ...statements];
6393
+ const statement = yield* [...appliedMutants].reduce((accumulated, entry) => Result.flatMap(accumulated, (current) => guardedStatement(current, entry)), Result.succeed(blockStatement(body)));
6394
+ path.replaceWith(wrappedStatement(path, statement));
6395
+ });
6436
6396
  }
6437
6397
  };
6438
- function statementsOf(path) {
6398
+ const statementsOf = (path) => {
6439
6399
  const node = path.node;
6440
- if (node.type === "BlockStatement") return node.body;
6441
- return [statementOf(node)];
6442
- }
6400
+ return node.type === "BlockStatement" ? Result.succeed(node.body) : Result.map(statementOf(node), (statement) => [statement]);
6401
+ };
6443
6402
  function guardedStatement(statement, entry) {
6444
- return ifStatement(mutantTestExpression(entry[0].id), blockStatement([nodeOfKind(entry[0], entry[1], isStatementKind, "a statement")]), statement);
6403
+ return Result.map(nodeOfKind(entry[0], entry[1], isStatementKind, "a statement"), (narrowed) => ifStatement(mutantTestExpression(entry[0].id), blockStatement([narrowed]), statement));
6445
6404
  }
6446
6405
  function wrappedStatement(path, statement) {
6447
6406
  return Match.value(nodeType(path.node)).pipe(Match.when("BlockStatement", () => blockStatement([statement])), Match.orElse(() => statement));
@@ -6452,13 +6411,11 @@ const placerBuilders = Object.freeze({
6452
6411
  "switch-case": {
6453
6412
  name: "switch-case",
6454
6413
  place(path, appliedMutants) {
6455
- const currentCase = switchCaseOf(path.node);
6456
- let consequence = blockStatement([expressionStatement(mutationCoverageSequenceExpression(appliedMutants.keys())), ...currentCase.consequent]);
6457
- for (const [mutant, appliedMutant] of appliedMutants) {
6458
- const appliedCase = nodeOfKind(mutant, appliedMutant, isSwitchCase, "a switch case");
6459
- consequence = ifStatement(mutantTestExpression(mutant.id), blockStatement(appliedCase.consequent), consequence);
6460
- }
6461
- path.replaceWith(switchCase(currentCase.test, [consequence]));
6414
+ return Result.gen(function* () {
6415
+ const currentCase = yield* switchCaseOf(path.node);
6416
+ const consequence = yield* [...appliedMutants].reduce((accumulated, [mutant, appliedMutant]) => Result.flatMap(accumulated, (current) => Result.map(nodeOfKind(mutant, appliedMutant, isSwitchCase, "a switch case"), (appliedCase) => ifStatement(mutantTestExpression(mutant.id), blockStatement(appliedCase.consequent), current))), Result.succeed(blockStatement([expressionStatement(mutationCoverageSequenceExpression(appliedMutants.keys())), ...currentCase.consequent])));
6417
+ path.replaceWith(switchCase(currentCase.test, [consequence]));
6418
+ });
6462
6419
  }
6463
6420
  }
6464
6421
  });
@@ -6474,231 +6431,281 @@ const transformDataFirst = (ast, mutantCollector, transformerContext) => {
6474
6431
  }))));
6475
6432
  };
6476
6433
  const transform = dual((args) => args.length >= 3, transformDataFirst);
6477
- const emptyAppliedMutants = () => /* @__PURE__ */ new Map();
6478
- const traversalFailure = (cause) => InstrumentError.make({
6479
- message: cause instanceof Error ? cause.message : errorTextOf$1(cause),
6480
- cause
6481
- });
6482
6434
  function isMutateRangeList(value) {
6483
6435
  return Array.isArray(value);
6484
6436
  }
6485
- const transformScriptDataFirst = ({ root, originFileName, rawContent, offset, comments }, mutantCollector, { options, mutateDescription, basePath }) => {
6486
- const placementMap = /* @__PURE__ */ new Map();
6487
- return Effect$1.gen(function* () {
6488
- const lineTable = yield* Effect$1.orDie(S.decodeEffect(LineTableFromText)(rawContent));
6489
- attachComments(make(root), comments, lineTable);
6490
- let directiveRule = [];
6491
- let hasLiveMutants = false;
6492
- const selection = selectMutators(DEFAULT_MUTATOR_REGISTRY, options.optInMutations);
6493
- const mutatorEntries = selection.active;
6494
- const allMutatorNames = selection.known.map((name) => name.toLowerCase());
6495
- const warnings = [];
6496
- yield* Effect$1.try({
6497
- try: () => traverse(make(root), {
6498
- enter(path) {
6499
- const directives = directivesOf(path.node, (node) => getNodeLocation(node).start.line);
6500
- directiveRule = directives.reduce(foldInto, directiveRule);
6501
- visitNode(path, directives);
6502
- },
6503
- exit(path) {
6504
- const placement = placementMap.get(path.node);
6505
- if (hasAppliedMutants(placement)) applyPlacement(path, placement);
6506
- }
6507
- }),
6508
- catch: traversalFailure
6509
- });
6510
- yield* placeHeaderIfNeeded(hasLiveMutants, options, root);
6511
- return warnings;
6512
- function visitNode(path, directives) {
6513
- if (shouldSkip(path)) {
6514
- path.skip();
6515
- return;
6516
- }
6517
- addToPlacementMapIfPossible(path);
6518
- placeCollectedMutants(path, directives);
6519
- }
6520
- function placementFacts(path) {
6521
- return {
6522
- isExpression: path.isExpression(),
6523
- isStatement: path.isStatement(),
6524
- isSwitchCase: nodeType(path.node) === "SwitchCase",
6525
- expressionIsValid: isValidExpression(path)
6526
- };
6527
- }
6528
- function placerNameOf(site) {
6529
- return Match.value(site).pipe(Match.tag("ExpressionSite", () => "expression"), Match.tag("StatementSite", () => "statement"), Match.tag("SwitchCaseSite", () => "switch-case"), Match.exhaustive);
6530
- }
6531
- function addToPlacementMapIfPossible(path) {
6532
- const facts = placementFacts(path);
6533
- const claimed = placeMutants(PlaceMutantsCommand.make({
6534
- fileName: originFileName,
6535
- facts,
6536
- mutants: []
6537
- }));
6538
- Match.value(claimed).pipe(Match.when(Result.isSuccess, () => placementMap.set(path.node, {
6539
- appliedMutants: emptyAppliedMutants(),
6540
- facts
6541
- })), Match.orElse(() => void 0));
6542
- }
6543
- function hasAppliedMutants(placement) {
6544
- return placement !== void 0 && placement.appliedMutants.size > 0;
6545
- }
6546
- function replacementRecord(mutant, applied) {
6547
- const replacement = unwrapParenthesizedExpression(applied);
6548
- return {
6549
- id: mutant.id,
6550
- mutatorName: mutant.mutatorName,
6551
- replacement: {
6552
- isExpression: isExpressionKind(replacement),
6553
- isStatement: isStatementKind(replacement),
6554
- isSwitchCase: nodeType(replacement) === "SwitchCase"
6555
- }
6556
- };
6437
+ const MUTATION_OFFSET = {
6438
+ line: 1,
6439
+ columnShift: 0
6440
+ };
6441
+ const initialFoldState = (firstIndex) => ({
6442
+ directiveRule: [],
6443
+ nextIndex: firstIndex,
6444
+ mutants: [],
6445
+ warnings: [],
6446
+ claims: [],
6447
+ placements: [],
6448
+ hasLiveMutants: false
6449
+ });
6450
+ const framesUpward = (frame) => [frame, ...framesAbove(frame)];
6451
+ const framesAbove = (frame) => Option$1.match(Option$1.fromNullishOr(frame.parent), {
6452
+ onNone: () => [],
6453
+ onSome: (parent) => framesUpward(parent)
6454
+ });
6455
+ const parentNodeOf = (frame) => Option$1.getOrNull(Option$1.map(Option$1.fromNullishOr(frame.parent), (parent) => parent.node));
6456
+ const ancestorsOfFrame = (frame) => Option$1.match(Option$1.fromNullishOr(frame.parent), {
6457
+ onNone: () => [],
6458
+ onSome: (parent) => [parent.node, ...ancestorsOfFrame(parent)]
6459
+ });
6460
+ const placementFactsOf = (frame) => ({
6461
+ isExpression: isExpressionKind(frame.node),
6462
+ isStatement: isStatementKind(frame.node),
6463
+ isSwitchCase: nodeType(frame.node) === "SwitchCase",
6464
+ expressionIsValid: isValidExpression(frame.node, parentNodeOf(frame))
6465
+ });
6466
+ const placerNameOf = (site) => Match.value(site).pipe(Match.tag("ExpressionSite", () => "expression"), Match.tag("StatementSite", () => "statement"), Match.tag("SwitchCaseSite", () => "switch-case"), Match.exhaustive);
6467
+ const replacementRecord = (mutant, applied) => {
6468
+ const replacement = unwrapParenthesizedExpression(applied);
6469
+ return {
6470
+ id: mutant.id,
6471
+ mutatorName: mutant.mutatorName,
6472
+ replacement: {
6473
+ isExpression: isExpressionKind(replacement),
6474
+ isStatement: isStatementKind(replacement),
6475
+ isSwitchCase: nodeType(replacement) === "SwitchCase"
6557
6476
  }
6558
- function raisePlacementRefusal(refusal, placement, path) {
6559
- throw placementFailure(refusal, path, [...placement.appliedMutants.keys()], originFileName, lineTable, basePath);
6477
+ };
6478
+ };
6479
+ const plannedWithNodes = (candidates, planned, fileName) => candidates.flatMap((candidate, index) => Option$1.match(Option$1.fromNullishOr(planned[index]), {
6480
+ onNone: () => [],
6481
+ onSome: (mutant) => [createMutant(mutant, fileName, candidate.node, candidate.replacement)]
6482
+ }));
6483
+ const ignorersReasonFor = (node, ancestors, ignorers) => ignorers.reduce((reason, ignorer) => Option$1.orElse(reason, () => Option$1.fromNullishOr(ignorer.shouldIgnore(node, ancestors))), Option$1.none());
6484
+ const mutablesFor = (frame, location, context) => {
6485
+ const ancestors = ancestorsOfFrame(frame);
6486
+ const mutatorContext = toMutatorContext(ancestors);
6487
+ const replacements = context.mutatorEntries.flatMap(([mutatorName, mutate]) => [...mutate(frame.node, mutatorContext)].map((replacement) => ({
6488
+ mutatorName,
6489
+ replacement
6490
+ })));
6491
+ const ignorerReason = replacements.length === 0 ? void 0 : Option$1.getOrUndefined(ignorersReasonFor(frame.node, ancestors, context.ignorers));
6492
+ return replacements.map(({ mutatorName, replacement }) => ({
6493
+ node: frame.node,
6494
+ replacement,
6495
+ data: {
6496
+ mutatorName,
6497
+ replacementCode: printNode(replacement),
6498
+ location,
6499
+ ignorerReason
6560
6500
  }
6561
- function placeSite(site, placement, path) {
6562
- try {
6563
- placerBuilders[placerNameOf(site)].place(path, placement.appliedMutants);
6564
- path.skip();
6565
- } catch (error) {
6566
- raisePlacementRefusal(MutantsUnapplied.make({
6567
- fileName: originFileName,
6568
- placer: placerNameOf(site),
6569
- mutatorNames: [...placement.appliedMutants.keys()].map((mutant) => mutant.mutatorName),
6570
- cause: toError(error)
6571
- }), placement, path);
6501
+ }));
6502
+ };
6503
+ const mutateRangesOf = (mutateDescription) => Option$1.filter(Option$1.some(mutateDescription), isMutateRangeList);
6504
+ const isOutsideMutateRanges = (location, mutateDescription) => Option$1.exists(mutateRangesOf(mutateDescription), (ranges) => ranges.every((range) => !locationOverlaps(range, location)));
6505
+ const isInsideMutateRanges = (location, mutateDescription) => Option$1.exists(mutateRangesOf(mutateDescription), (ranges) => ranges.some((range) => locationIncluded(range, location)));
6506
+ const shouldMutateAt = (location, mutateDescription) => mutateDescription === true || isInsideMutateRanges(location, mutateDescription);
6507
+ const shouldSkipNode = (frame, location, mutateDescription) => [
6508
+ isTypeNode(frame.node),
6509
+ isImportDeclaration(frame.node),
6510
+ nodeType(frame.node) === "Decorator",
6511
+ mutateDescription === false,
6512
+ isOutsideMutateRanges(location, mutateDescription)
6513
+ ].some((skip) => skip);
6514
+ const locationOfNode = (frame, context) => Option$1.match(Option$1.map(Option$1.fromNullishOr(spanOf(frame.node)), (span) => locationOf(context.lineStarts, span)), {
6515
+ onNone: () => Result.fail(NodeWithoutSpan.make({ fileName: context.fileName })),
6516
+ onSome: Result.succeed
6517
+ });
6518
+ const refusedPlacement = (refusal, node, mutants, context) => PlacementRefused.make({ message: placementFailureMessage(refusal, node, mutants, context.fileName, context.lineStarts, context.basePath) });
6519
+ const applyMutantToClaim = (mutant, target, appliedSoFar, context) => Result.mapError(applyMutant(mutant, target), (failure) => refusedPlacement(failure, target, appliedSoFar, context));
6520
+ const applyToClaim = (mutants, target, state, context) => {
6521
+ const existing = state.claims.find((claim) => claim.node === target.node);
6522
+ const priorMutants = existing === void 0 ? [] : existing.applied.map(([mutant]) => mutant);
6523
+ const applied = mutants.reduce((accumulated, mutant) => Result.flatMap(accumulated, (entries) => Result.map(applyMutantToClaim(mutant, target.node, [...priorMutants, ...entries.map(([entry]) => entry)], context), (tree) => [...entries, [mutant, tree]])), Result.succeed([]));
6524
+ return Result.map(applied, (entries) => ({
6525
+ ...state,
6526
+ claims: state.claims.map((claim) => claim.node === target.node ? {
6527
+ ...claim,
6528
+ applied: [...claim.applied, ...entries]
6529
+ } : claim)
6530
+ }));
6531
+ };
6532
+ const attachPlaceable = (mutants, frame, state, context) => Match.value(mutants.length > 0).pipe(Match.when(false, () => Result.succeed(state)), Match.when(true, () => Option$1.match(Option$1.fromNullishOr(framesUpward(frame).find((candidate) => state.claims.some((claim) => claim.node === candidate.node))), {
6533
+ onNone: () => Result.fail(MutantsUnplaced.make({
6534
+ fileName: context.fileName,
6535
+ detail: JSON.stringify(mutants, null, 2)
6536
+ })),
6537
+ onSome: (target) => applyToClaim(mutants, target, state, context)
6538
+ })), Match.exhaustive);
6539
+ const collectPlan = (frame, candidates, plan, state, context) => {
6540
+ const collected = plannedWithNodes(candidates, plan.mutants, context.fileName);
6541
+ const nextState = {
6542
+ ...state,
6543
+ mutants: [...state.mutants, ...collected],
6544
+ warnings: [...state.warnings, ...plan.warnings],
6545
+ nextIndex: plan.nextIndex
6546
+ };
6547
+ return Match.value(plan).pipe(Match.tag("MutantsPlanned", (planned) => attachPlaceable(plannedWithNodes(candidates, planned.placeable, context.fileName), frame, {
6548
+ ...nextState,
6549
+ hasLiveMutants: true
6550
+ }, context)), Match.orElse(() => Result.succeed(nextState)));
6551
+ };
6552
+ const planMutantsAt = (frame, candidates, directives, location, state, context) => {
6553
+ const plan = planMutants(PlanMutantsCommand.make({
6554
+ fileName: context.fileName,
6555
+ firstIndex: state.nextIndex,
6556
+ offset: context.offset,
6557
+ line: location.start.line,
6558
+ mutatorNames: [...context.allMutatorNames],
6559
+ excludedMutations: [...context.excludedMutations],
6560
+ rule: [...state.directiveRule],
6561
+ directives: [...directives],
6562
+ candidates: candidates.map((candidate) => candidate.data)
6563
+ }));
6564
+ return Match.value(plan).pipe(Match.when(Result.isFailure, (failed) => Result.fail(failed.failure)), Match.orElse((succeeded) => collectPlan(frame, candidates, succeeded.success, state, context)));
6565
+ };
6566
+ const candidatesFor = (frame, location, context) => Match.value(shouldMutateAt(location, context.mutateDescription)).pipe(Match.when(true, () => mutablesFor(frame, location, context)), Match.orElse(() => []));
6567
+ const needsPlan = (candidates, directives) => [candidates.length > 0, directives.length > 0].some(Boolean);
6568
+ const planAtNode = (frame, directives, location, state, context) => {
6569
+ const candidates = candidatesFor(frame, location, context);
6570
+ return Match.value(needsPlan(candidates, directives)).pipe(Match.when(false, () => Result.succeed(state)), Match.when(true, () => planMutantsAt(frame, candidates, directives, location, state, context)), Match.exhaustive);
6571
+ };
6572
+ const claimSelf = (frame, facts, claims, context) => {
6573
+ const claimed = placeMutants(PlaceMutantsCommand.make({
6574
+ fileName: context.fileName,
6575
+ facts,
6576
+ mutants: []
6577
+ }));
6578
+ return Match.value(claimed.pipe(Result.isSuccess)).pipe(Match.when(true, () => [...claims, {
6579
+ node: frame.node,
6580
+ facts,
6581
+ applied: []
6582
+ }]), Match.orElse(() => claims));
6583
+ };
6584
+ const siteOfClaim = (claim, context) => {
6585
+ const mutants = claim.applied.map(([mutant]) => mutant);
6586
+ const decision = placeMutants(PlaceMutantsCommand.make({
6587
+ fileName: context.fileName,
6588
+ facts: claim.facts,
6589
+ mutants: claim.applied.map(([mutant, applied]) => replacementRecord(mutant, applied))
6590
+ }));
6591
+ return Match.value(decision).pipe(Match.when(Result.isFailure, (refused) => Result.fail(refusedPlacement(refused.failure, claim.node, mutants, context))), Match.orElse((decided) => Result.succeed(decided.success)));
6592
+ };
6593
+ const emitClaim = (claim, state, context) => Match.value(claim.applied.length > 0).pipe(Match.when(false, () => Result.succeed(state)), Match.when(true, () => Result.map(siteOfClaim(claim, context), (site) => ({
6594
+ ...state,
6595
+ placements: [...state.placements, {
6596
+ node: claim.node,
6597
+ placer: placerNameOf(site),
6598
+ applied: claim.applied
6599
+ }]
6600
+ }))), Match.exhaustive);
6601
+ const emitPlacement = (frame, state, context) => Option$1.match(Option$1.fromNullishOr(state.claims.find((claim) => claim.node === frame.node)), {
6602
+ onNone: () => Result.succeed(state),
6603
+ onSome: (claim) => emitClaim(claim, state, context)
6604
+ });
6605
+ const foldChildren = (frame, state, context) => childNodes(frame.node).reduce((accumulated, child) => Result.flatMap(accumulated, (current) => foldPlacements({
6606
+ node: child.node,
6607
+ parent: frame
6608
+ }, current, context)), Result.succeed(state));
6609
+ const visitFrame = (frame, directives, location, state, context) => {
6610
+ const facts = placementFactsOf(frame);
6611
+ const claimed = claimSelf(frame, facts, state.claims, context);
6612
+ return Result.flatMap(planAtNode(frame, directives, location, {
6613
+ ...state,
6614
+ claims: claimed
6615
+ }, context), (afterPlan) => Result.flatMap(foldChildren(frame, afterPlan, context), (afterChildren) => emitPlacement(frame, afterChildren, context)));
6616
+ };
6617
+ const foldPlacements = (frame, state, context) => Result.flatMap(locationOfNode(frame, context), (location) => {
6618
+ const directives = directivesOf(frame.node, location.start.line);
6619
+ const ruled = {
6620
+ ...state,
6621
+ directiveRule: directives.reduce(foldInto, state.directiveRule)
6622
+ };
6623
+ return Match.value(shouldSkipNode(frame, location, context.mutateDescription)).pipe(Match.when(true, () => Result.succeed(ruled)), Match.when(false, () => visitFrame(frame, directives, location, ruled, context)), Match.exhaustive);
6624
+ });
6625
+ const planInstrumentation = (root, firstIndex, context) => Result.map(foldPlacements({
6626
+ node: root,
6627
+ parent: null
6628
+ }, initialFoldState(firstIndex), context), (state) => ({
6629
+ mutants: state.mutants,
6630
+ placements: state.placements,
6631
+ warnings: state.warnings,
6632
+ hasLiveMutants: state.hasLiveMutants
6633
+ }));
6634
+ const applyOnePlacement = (placement, path, previous, context) => {
6635
+ const result = placerBuilders[placement.placer].place(path, new Map(placement.applied));
6636
+ return Result.match(result, {
6637
+ onFailure: (cause) => new Error(placementFailureMessage(MutantsUnapplied.make({
6638
+ fileName: context.fileName,
6639
+ placer: placement.placer,
6640
+ mutatorNames: placement.applied.map(([mutant]) => mutant.mutatorName),
6641
+ cause: toError(cause)
6642
+ }), placement.node, placement.applied.map(([mutant]) => mutant), context.fileName, context.lineStarts, context.basePath)),
6643
+ onSuccess: () => previous
6644
+ });
6645
+ };
6646
+ const applyPlacementsToAst = (root, places, context) => {
6647
+ let failure;
6648
+ traverse(make(root), { exit(path) {
6649
+ Option$1.match(Option$1.fromNullishOr(places.get(path.node)), {
6650
+ onNone: () => void 0,
6651
+ onSome: (placement) => {
6652
+ failure = applyOnePlacement(placement, path, failure, context);
6572
6653
  }
6573
- }
6574
- function applyPlacement(path, placement) {
6575
- const decision = placeMutants(PlaceMutantsCommand.make({
6576
- fileName: originFileName,
6577
- facts: placement.facts,
6578
- mutants: [...placement.appliedMutants].map(([mutant, applied]) => replacementRecord(mutant, applied))
6579
- }));
6580
- Match.value(decision).pipe(Match.when(Result.isFailure, (refused) => raisePlacementRefusal(refused.failure, placement, path)), Match.orElse((decided) => placeSite(decided.success, placement, path)));
6581
- }
6582
- function placeCollectedMutants(path, directives) {
6583
- const candidates = candidateSteps(path);
6584
- Match.value(needsPlan(candidates, directives)).pipe(Match.when(true, () => planAndPlace(path, candidates, directives)), Match.when(false, () => void 0), Match.exhaustive);
6585
- }
6586
- function candidateSteps(path) {
6587
- return Match.value(shouldMutate(path)).pipe(Match.when(true, () => mutablesFor(path)), Match.when(false, () => []), Match.exhaustive);
6588
- }
6589
- function needsPlan(candidates, directives) {
6590
- return [candidates.length > 0, directives.length > 0].some(Boolean);
6591
- }
6592
- function planAndPlace(path, candidates, directives) {
6593
- Match.value(planFor(path, candidates, directives)).pipe(Match.when(Option$1.isSome, (toPlace) => placeOnPath(path, toPlace.value)), Match.orElse(() => void 0));
6594
- }
6595
- function planFor(path, candidates, directives) {
6596
- const plan = planMutants(PlanMutantsCommand.make({
6597
- fileName: originFileName,
6598
- firstIndex: mutantCollector.nextIndex,
6599
- offset: offset ?? {
6600
- line: 1,
6601
- column: 0
6602
- },
6603
- line: getNodeLocation(path.node).start.line,
6604
- mutatorNames: allMutatorNames,
6605
- excludedMutations: options.excludedMutations,
6606
- rule: directiveRule,
6607
- directives: [...directives],
6608
- candidates: candidates.map((candidate) => candidate.data)
6609
- }));
6610
- return Match.value(plan).pipe(Match.when(Result.isFailure, (failed) => raisePlanFailure(failed.failure)), Match.orElse((succeeded) => collectPlanned(candidates, succeeded.success)));
6611
- }
6612
- function raisePlanFailure(failure) {
6613
- throw new Error(`Mutant without a source location: ${failure.mutatorName} in ${failure.fileName}`);
6614
- }
6615
- function collectPlanned(candidates, plan) {
6616
- mutantCollector.append(plannedWithNodes(candidates, plan.mutants));
6617
- warnings.push(...plan.warnings);
6618
- return Match.value(plan).pipe(Match.tag("MutantsPlanned", (planned) => {
6619
- hasLiveMutants = true;
6620
- return Option$1.some(plannedWithNodes(candidates, planned.placeable));
6621
- }), Match.orElse(() => Option$1.none()));
6622
- }
6623
- function plannedWithNodes(candidates, planned) {
6624
- return candidates.flatMap((candidate, index) => Option$1.match(Option$1.fromNullishOr(planned[index]), {
6625
- onNone: () => [],
6626
- onSome: (mutant) => [createMutant(mutant, originFileName, candidate.node, candidate.replacement)]
6627
- }));
6628
- }
6629
- function placeOnPath(path, mutantsToPlace) {
6630
- const placementPath = requiredPlacementPath(path, mutantsToPlace);
6631
- const placement = requiredPlacement(placementPath.node);
6632
- mutantsToPlace.forEach((mutant) => {
6633
- Match.value(applyMutant(mutant, placementPath.node)).pipe(Match.when(Result.isFailure, (failed) => raisePlacementRefusal(failed.failure, placement, path)), Match.orElse((applied) => placement.appliedMutants.set(mutant, applied.success)));
6634
- });
6635
- }
6636
- function requiredPlacementPath(path, mutantsToPlace) {
6637
- return Option$1.getOrThrowWith(Option$1.fromNullishOr(path.find((ancestor) => placementMap.has(ancestor.node))), () => unplacedMutantsError(mutantsToPlace));
6638
- }
6639
- function unplacedMutantsError(mutantsToPlace) {
6640
- return /* @__PURE__ */ new Error(`Mutants cannot be placed. This shouldn't happen! Unplaced mutants: ${JSON.stringify(mutantsToPlace, null, 2)}`);
6641
- }
6642
- function requiredPlacement(node) {
6643
- return Option$1.getOrThrowWith(Option$1.fromNullishOr(placementMap.get(node)), () => /* @__PURE__ */ new Error("Placement not found for node"));
6644
- }
6645
- function shouldSkip(path) {
6646
- return [
6647
- isTypeNode(path),
6648
- isImportDeclaration(path),
6649
- nodeType(path.node) === "Decorator",
6650
- mutateDescription === false,
6651
- isOutsideMutateRanges(path)
6652
- ].some((skip) => skip);
6653
- }
6654
- function mutateRanges() {
6655
- return Option$1.filter(Option$1.some(mutateDescription), isMutateRangeList);
6656
- }
6657
- function isOutsideMutateRanges(path) {
6658
- return Option$1.exists(mutateRanges(), (ranges) => ranges.every((range) => !locationOverlaps(range, getNodeLocation(path.node))));
6659
- }
6660
- function shouldMutate(path) {
6661
- return mutateDescription === true || isInsideMutateRanges(path);
6662
- }
6663
- function isInsideMutateRanges(path) {
6664
- return Option$1.exists(mutateRanges(), (ranges) => ranges.some((range) => locationIncluded(range, getNodeLocation(path.node))));
6665
- }
6666
- function getNodeLocation(node) {
6667
- const span = spanOf(node);
6668
- if (span === void 0) throw new Error("Node without a span");
6669
- return {
6670
- start: lineTable.positionAt(span.start),
6671
- end: lineTable.positionAt(span.end)
6672
- };
6673
- }
6674
- function mutablesFor(path) {
6675
- const ancestors = ancestorsOf(path);
6676
- const context = toMutatorContext(ancestors);
6677
- const location = Option$1.map(Option$1.fromNullishOr(spanOf(path.node)), (span) => ({
6678
- start: lineTable.positionAt(span.start),
6679
- end: lineTable.positionAt(span.end)
6680
- }));
6681
- const replacements = mutatorEntries.flatMap(([mutatorName, mutate]) => [...mutate(path.node, context)].map((replacement) => ({
6682
- mutatorName,
6683
- replacement
6684
- })));
6685
- const ignorerReason = replacements.length === 0 ? void 0 : Option$1.getOrUndefined(ignorersReason(path.node, ancestors));
6686
- return replacements.map(({ mutatorName, replacement }) => ({
6687
- node: path.node,
6688
- replacement,
6689
- data: {
6690
- mutatorName,
6691
- replacementCode: printNode(replacement),
6692
- location: Option$1.getOrUndefined(location),
6693
- ignorerReason
6694
- }
6695
- }));
6696
- }
6697
- function ignorersReason(node, ancestors) {
6698
- return options.ignorers.reduce((reason, ignorer) => Option$1.orElse(reason, () => Option$1.fromNullishOr(ignorer.shouldIgnore(node, ancestors))), Option$1.none());
6699
- }
6654
+ });
6655
+ } });
6656
+ return failure;
6657
+ };
6658
+ const applyPlan = (root, plan, context) => {
6659
+ const places = new Map(plan.placements.map((placement) => [placement.node, placement]));
6660
+ return Option$1.match(Option$1.fromNullishOr(applyPlacementsToAst(root, places, context)), {
6661
+ onNone: () => Effect$1.void,
6662
+ onSome: (error) => Effect$1.fail(InstrumentError.make({
6663
+ message: error.message,
6664
+ cause: error
6665
+ }))
6700
6666
  });
6701
6667
  };
6668
+ const refusalError = (refusal) => Match.value(refusal).pipe(Match.tag("NodeWithoutSpan", () => InstrumentError.make({
6669
+ message: "Node without a span",
6670
+ cause: void 0
6671
+ })), Match.tag("MutantsUnplaced", (unplaced) => InstrumentError.make({
6672
+ message: `Mutants cannot be placed. This shouldn't happen! Unplaced mutants: ${unplaced.detail}`,
6673
+ cause: void 0
6674
+ })), Match.tag("PlacementRefused", (refused) => InstrumentError.make({
6675
+ message: refused.message,
6676
+ cause: new Error(refused.message)
6677
+ })), Match.tag("MutantWithoutLocation", (failed) => InstrumentError.make({
6678
+ message: `Mutant without a source location: ${failed.mutatorName} in ${failed.fileName}`,
6679
+ cause: void 0
6680
+ })), Match.exhaustive);
6681
+ const transformScriptDataFirst = Effect$1.fn("stryker.instrument.transform.script")(function* ({ root, originFileName, rawContent, offset, comments }, mutantCollector, { options, mutateDescription, basePath }) {
6682
+ const lineStarts = lineStartsOf(rawContent);
6683
+ attachComments(make(root), comments, lineStarts);
6684
+ const selection = selectMutators(DEFAULT_MUTATOR_REGISTRY, options.optInMutations);
6685
+ const context = {
6686
+ fileName: originFileName,
6687
+ lineStarts,
6688
+ mutateDescription,
6689
+ offset: offset ?? MUTATION_OFFSET,
6690
+ basePath,
6691
+ mutatorEntries: selection.active,
6692
+ allMutatorNames: selection.known.map((name) => name.toLowerCase()),
6693
+ excludedMutations: options.excludedMutations,
6694
+ ignorers: options.ignorers
6695
+ };
6696
+ const planned = yield* Effect$1.try({
6697
+ try: () => planInstrumentation(root, mutantCollector.nextIndex, context),
6698
+ catch: traversalFailure
6699
+ });
6700
+ const plan = yield* Match.value(planned).pipe(Match.when(Result.isFailure, (refused) => {
6701
+ const error = refusalError(refused.failure);
6702
+ return Effect$1.fail(error);
6703
+ }), Match.orElse((succeeded) => Effect$1.succeed(succeeded.success)));
6704
+ mutantCollector.append(plan.mutants);
6705
+ yield* applyPlan(root, plan, context);
6706
+ yield* placeHeaderIfNeeded(plan.hasLiveMutants, options, root);
6707
+ return plan.warnings;
6708
+ });
6702
6709
  const transformScript = dual((args) => args.length >= 3, transformScriptDataFirst);
6703
6710
  function toMutatorContext(ancestors) {
6704
6711
  return {
@@ -6707,10 +6714,7 @@ function toMutatorContext(ancestors) {
6707
6714
  ancestors: [...ancestors]
6708
6715
  };
6709
6716
  }
6710
- function toError(value) {
6711
- if (value instanceof Error) return value;
6712
- return new Error("Unexpected error", { cause: value });
6713
- }
6717
+ const toError = (value) => value instanceof Error ? value : new Error("Unexpected error", { cause: value });
6714
6718
  const tsDirectiveLikeRegEx = /@(ts-[a-z-]+)/;
6715
6719
  const commentDirectiveRegEx = /^(\s*)@(ts-[a-z-]+).*$/;
6716
6720
  const STARTING_COMMENT = /^\s*\/\*[\s\S]*?\*\//;
@@ -6718,18 +6722,15 @@ function disableTypeCheckingInScript(ast) {
6718
6722
  return prefixWithNoCheck(removeTSDirectives(ast.rawContent, ast.comments));
6719
6723
  }
6720
6724
  function prefixWithNoCheck(code) {
6721
- if (code.startsWith("#")) return afterHashbang(code);
6722
- return afterLeadingComment(code);
6725
+ return code.startsWith("#") ? afterHashbang(code) : afterLeadingComment(code);
6723
6726
  }
6724
6727
  function afterHashbang(code) {
6725
6728
  const newLineIndex = code.indexOf("\n");
6726
- if (newLineIndex <= 0) return code;
6727
- return `${code.substring(0, newLineIndex)}\n// @ts-nocheck\n${code.substring(newLineIndex + 1)}`;
6729
+ return newLineIndex <= 0 ? code : `${code.substring(0, newLineIndex)}\n// @ts-nocheck\n${code.substring(newLineIndex + 1)}`;
6728
6730
  }
6729
6731
  function afterLeadingComment(code) {
6730
6732
  const leadingComment = leadingCommentOf(code);
6731
- if (leadingComment === void 0) return `// @ts-nocheck\n${code}`;
6732
- return `${leadingComment.concat("\n")}// @ts-nocheck\n${code.substring(leadingComment.length)}`;
6733
+ return leadingComment === void 0 ? `// @ts-nocheck\n${code}` : `${leadingComment.concat("\n")}// @ts-nocheck\n${code.substring(leadingComment.length)}`;
6733
6734
  }
6734
6735
  function leadingCommentOf(code) {
6735
6736
  return STARTING_COMMENT.exec(code)?.[0];
@@ -6751,29 +6752,24 @@ function removeRanges(text, ranges) {
6751
6752
  return remaining.pruned + text.substring(remaining.cursor);
6752
6753
  }
6753
6754
  function tryParseTSDirective(comment) {
6754
- const match = commentDirectiveRegEx.exec(comment.value);
6755
- if (match === null) return void 0;
6756
- const directivePrefix = requirePart(match[1], "TS directive match without prefix");
6757
- const directiveName = requirePart(match[2], "TS directive match without directive name");
6758
- const startPos = comment.start + directivePrefix.length + 2;
6755
+ return Option$1.match(Option$1.fromNullishOr(commentDirectiveRegEx.exec(comment.value)), {
6756
+ onNone: () => void 0,
6757
+ onSome: (match) => directiveRangeAt(comment.start, lengthOf(match[1]), lengthOf(match[2]))
6758
+ });
6759
+ }
6760
+ const lengthOf = (text) => Option$1.getOrElse(Option$1.map(Option$1.fromNullishOr(text), (value) => value.length), () => 0);
6761
+ const directiveRangeAt = (commentStart, prefixLength, nameLength) => {
6762
+ const startPos = commentStart + prefixLength + 2;
6759
6763
  return {
6760
6764
  startPos,
6761
- endPos: startPos + directiveName.length + 1
6765
+ endPos: startPos + nameLength + 1
6762
6766
  };
6763
- }
6764
- function requirePart(part, message) {
6765
- if (part === void 0) throw new Error(message);
6766
- return part;
6767
- }
6768
- const requireScriptAst = (ast) => {
6769
- if (ast.format === "embedded") return rejectAst(ast, "a script");
6770
- return ast;
6771
6767
  };
6772
- const requireJsAst = (ast) => ast.format === "js" ? ast : rejectAst(ast, "a js script");
6773
- const requireTsFamilyAst = (ast) => Match.value(ast).pipe(Match.when({ format: "ts" }, (ts) => ts), Match.when({ format: "tsx" }, (tsx) => tsx), Match.orElse((other) => rejectAst(other, "a ts script")));
6774
- function rejectAst(ast, expected) {
6775
- throw new Error(`Expected ${expected} AST, received the "${ast.format}" format`);
6776
- }
6768
+ const scriptAstError = (ast) => InstrumentError.make({
6769
+ message: `Expected a script AST, received the "${ast.format}" format`,
6770
+ cause: void 0
6771
+ });
6772
+ const scriptAstOf = (ast) => Match.value(ast).pipe(Match.when({ format: "embedded" }, () => Option$1.none()), Match.orElse((script) => Option$1.some(script)));
6777
6773
  const extensionOf = (fileName) => {
6778
6774
  const dot = fileName.lastIndexOf(".");
6779
6775
  return dot > Math.max(fileName.lastIndexOf("/"), fileName.lastIndexOf("\\")) ? fileName.slice(dot).toLowerCase() : "";
@@ -6805,12 +6801,19 @@ const resolutionCommandOfDataFirst = (registry, fileName, formatIdOverride) => F
6805
6801
  const resolutionCommandOf = dual((args) => typeof args[0] !== "string", resolutionCommandOfDataFirst);
6806
6802
  const scriptHooks = (scriptFormat) => ({
6807
6803
  parse: (text, fileName, _context) => parseScriptFormat(scriptFormat, text, fileName),
6808
- transform: (ast, mutantCollector, context) => transformScript(requireScriptAst(ast), mutantCollector, context),
6804
+ transform: (ast, mutantCollector, context) => Option$1.match(scriptAstOf(ast), {
6805
+ onNone: () => Effect$1.fail(scriptAstError(ast)),
6806
+ onSome: (script) => transformScript(script, mutantCollector, context)
6807
+ }),
6809
6808
  print: (ast, context) => printScriptAst(ast, context),
6810
- disableTypeChecks: (ast) => Effect$1.succeed(disableTypeCheckingInScript(requireScriptAst(ast)))
6809
+ disableTypeChecks: (ast) => Option$1.match(scriptAstOf(ast), {
6810
+ onNone: () => Effect$1.fail(scriptAstError(ast)),
6811
+ onSome: (script) => Effect$1.succeed(disableTypeCheckingInScript(script))
6812
+ })
6811
6813
  });
6812
6814
  const parseScriptFormat = (scriptFormat, text, fileName) => Match.value(scriptFormat).pipe(Match.when("js", () => parseJS(text, fileName)), Match.when("ts", () => parseTS(text, fileName)), Match.when("tsx", () => parseTsx(text, fileName)), Match.exhaustive);
6813
- const printScriptAst = (ast, context) => ast.format === "js" ? jsPrint(requireJsAst(ast), context) : tsPrint(requireTsFamilyAst(ast), context);
6815
+ const printScriptAst = (ast, context) => Match.value(ast).pipe(Match.when({ format: "js" }, (js) => jsPrint(js, context)), Match.when({ format: "ts" }, (ts) => tsPrint(ts, context)), Match.when({ format: "tsx" }, (tsx) => tsPrint(tsx, context)), Match.orElse(printNothingForEmbeddedAst));
6816
+ const printNothingForEmbeddedAst = () => "";
6814
6817
  const coreFormatRegistry = formatRegistry([
6815
6818
  {
6816
6819
  claim: {
@@ -6928,19 +6931,8 @@ const spliceForAssigned = (request) => Option$1.match(request.registry.entryForF
6928
6931
  onNone: () => Effect$1.succeed(request.file),
6929
6932
  onSome: (entry) => spliceFileFor(request.file, entry)
6930
6933
  });
6931
- const toOneBasedOrigin = (origin) => ({
6932
- line: origin.line + 1,
6933
- column: origin.column
6934
- });
6935
6934
  const EMBEDDED_SCRIPT_FILE = "embedded-script.js";
6936
- const loadFrameworkToolkit = Effect$1.gen(function* () {
6937
- const oxc = yield* loadOxc;
6938
- return {
6939
- parseScript: (source, scriptFormat) => parseScriptProgram(oxc, source, scriptFormat),
6940
- header: yield* instrumentationHeader
6941
- };
6942
- });
6943
- const parseScriptProgram = (oxc, source, scriptFormat) => {
6935
+ const makeScriptParser = (oxc) => (source, scriptFormat) => {
6944
6936
  const result = oxc.parseSync(EMBEDDED_SCRIPT_FILE, source, {
6945
6937
  lang: scriptFormat,
6946
6938
  range: true
@@ -6950,19 +6942,27 @@ const parseScriptProgram = (oxc, source, scriptFormat) => {
6950
6942
  fileName: EMBEDDED_SCRIPT_FILE,
6951
6943
  message: first.message,
6952
6944
  location: {
6953
- line: 0,
6954
- column: 0
6945
+ line: 1,
6946
+ column: 1
6955
6947
  },
6956
6948
  cause: first
6957
6949
  });
6958
6950
  return result.program;
6959
6951
  };
6952
+ const loadFrameworkToolkit = Effect$1.gen(function* () {
6953
+ const oxc = yield* loadOxc;
6954
+ const header = yield* instrumentationHeader;
6955
+ return {
6956
+ parseScript: makeScriptParser(oxc),
6957
+ header
6958
+ };
6959
+ });
6960
6960
  const frameworkContextOf = (toolkit) => ({
6961
6961
  parseScript: toolkit.parseScript,
6962
6962
  printScript: (script) => printProgram(script, { hashbang: null }),
6963
6963
  instrumentationHeader: () => toolkit.header
6964
6964
  });
6965
- const embeddedScriptsOf = (document, rawContent, originFileName, lineTable) => document.regions.flatMap((region, index) => {
6965
+ const embeddedScriptsOf = (document, rawContent, originFileName, lineStarts) => document.regions.flatMap((region, index) => {
6966
6966
  return [{
6967
6967
  region: index,
6968
6968
  ast: {
@@ -6971,14 +6971,16 @@ const embeddedScriptsOf = (document, rawContent, originFileName, lineTable) => d
6971
6971
  comments: [],
6972
6972
  rawContent: rawContent.slice(region.start, region.end),
6973
6973
  originFileName,
6974
- offset: toOneBasedOrigin(lineTable.zeroBasedPositionAt(region.start))
6974
+ offset: originAt(lineStarts, region.start)
6975
6975
  }
6976
6976
  }];
6977
6977
  });
6978
- const embeddedOf = (ast) => {
6979
- if (ast.format !== "embedded") throw new Error(`Expected an embedded document AST, received the "${ast.format}" format`);
6980
- return ast;
6981
- };
6978
+ const embeddedAstError = (ast) => InstrumentError.make({
6979
+ message: `Expected an embedded document AST, received the "${ast.format}" format`,
6980
+ cause: void 0
6981
+ });
6982
+ const embeddedOf = (ast) => Match.value(ast).pipe(Match.when({ format: "embedded" }, (embedded) => Option$1.some(embedded)), Match.orElse(() => Option$1.none()));
6983
+ const printNothingForNonEmbeddedAst = () => "";
6982
6984
  const frameworkFailure = (moduleName, fileName, detail) => InstrumentError.make({
6983
6985
  message: `The framework "${moduleName}" could not parse ${fileName}: ${detail}`,
6984
6986
  cause: new Error(detail)
@@ -6987,7 +6989,7 @@ const hookFailure = (moduleName, hook, fileName, cause) => InstrumentError.make(
6987
6989
  message: `The framework "${moduleName}" threw while running ${hook} for ${fileName}: ${errorTextOf(cause)}`,
6988
6990
  cause
6989
6991
  });
6990
- const errorTextOf = (cause) => Option$1.getOrElse(Option$1.map(ErrorText.fromCause(cause), (text) => text.text), () => "");
6992
+ const errorTextOf = (cause) => Option$1.getOrElse(Option$1.map(errorTextOf$2(cause), (rendered) => rendered.text), () => "");
6991
6993
  const runHook = (moduleName, hook, fileName, run) => Effect$1.try({
6992
6994
  try: run,
6993
6995
  catch: (cause) => hookFailure(moduleName, hook, fileName, cause)
@@ -7002,9 +7004,9 @@ const frameworkEntryOfDataFirst = (moduleName, framework) => ({
7002
7004
  },
7003
7005
  owner: moduleName,
7004
7006
  ownerVersion: framework.claim.ownerVersion,
7005
- parse: (text, fileName) => Effect$1.gen(function* () {
7007
+ parse: Effect$1.fn("stryker.instrument.framework_entry.parse")(function* (text, fileName) {
7006
7008
  const context = frameworkContextOf(yield* loadFrameworkToolkit);
7007
- const lineTable = yield* Effect$1.orDie(S.decodeEffect(LineTableFromText)(text));
7009
+ const lineStarts = lineStartsOf(text);
7008
7010
  const result = yield* runHook(moduleName, "parse", fileName, () => framework.parse(text, context));
7009
7011
  const document = yield* settled(moduleName, fileName, result);
7010
7012
  return {
@@ -7014,26 +7016,28 @@ const frameworkEntryOfDataFirst = (moduleName, framework) => ({
7014
7016
  rawContent: text,
7015
7017
  document,
7016
7018
  context,
7017
- scripts: embeddedScriptsOf(document, text, fileName, lineTable)
7019
+ scripts: embeddedScriptsOf(document, text, fileName, lineStarts)
7018
7020
  };
7019
7021
  }),
7020
- transform: (ast, mutantCollector, context) => Effect$1.gen(function* () {
7021
- const embedded = embeddedOf(ast);
7022
- const warnings = yield* Effect$1.forEach(embedded.scripts, (script) => context.transform(script.ast, mutantCollector, context));
7023
- embedded.document = yield* runHook(moduleName, "transform", embedded.originFileName, () => framework.transform(embedded.document, embedded.context));
7024
- return warnings.flat();
7022
+ transform: (ast, mutantCollector, context) => Option$1.match(embeddedOf(ast), {
7023
+ onNone: () => Effect$1.fail(embeddedAstError(ast)),
7024
+ onSome: Effect$1.fn("stryker.instrument.framework_entry.transform")(function* (embedded) {
7025
+ const warnings = yield* Effect$1.forEach(embedded.scripts, (script) => context.transform(script.ast, mutantCollector, context));
7026
+ embedded.document = yield* runHook(moduleName, "transform", embedded.originFileName, () => framework.transform(embedded.document, embedded.context));
7027
+ return warnings.flat();
7028
+ })
7025
7029
  }),
7026
- print: (ast) => {
7027
- const embedded = embeddedOf(ast);
7028
- return framework.print(embedded.document, embedded.context);
7029
- },
7030
- disableTypeChecks: (ast) => {
7031
- const embedded = embeddedOf(ast);
7032
- return runHook(moduleName, "disableTypeChecks", embedded.originFileName, () => framework.disableTypeChecks(embedded.rawContent)).pipe(Effect$1.flatMap((result) => settled(moduleName, embedded.originFileName, result)));
7033
- }
7030
+ print: (ast) => Option$1.match(embeddedOf(ast), {
7031
+ onNone: printNothingForNonEmbeddedAst,
7032
+ onSome: (embedded) => framework.print(embedded.document, embedded.context)
7033
+ }),
7034
+ disableTypeChecks: (ast) => Option$1.match(embeddedOf(ast), {
7035
+ onNone: () => Effect$1.fail(embeddedAstError(ast)),
7036
+ onSome: (embedded) => runHook(moduleName, "disableTypeChecks", embedded.originFileName, () => framework.disableTypeChecks(embedded.rawContent)).pipe(Effect$1.flatMap((result) => settled(moduleName, embedded.originFileName, result)))
7037
+ })
7034
7038
  });
7035
7039
  const frameworkEntryOf = dual((args) => args.length >= 2, frameworkEntryOfDataFirst);
7036
- var Format_exports = /* @__PURE__ */ __exportAll({
7040
+ var Format_exports = /* @__PURE__ */ __exportAll$1({
7037
7041
  coreFormatRegistry: () => coreFormatRegistry,
7038
7042
  extensionOf: () => extensionOf,
7039
7043
  frameworkEntryOf: () => frameworkEntryOf,
@@ -7085,22 +7089,26 @@ const admitInstrumentFiles = Workflow.make({
7085
7089
  skipped: command.skipped
7086
7090
  }))), Match.exhaustive)
7087
7091
  });
7088
- const printedFile = (raw, { file, ast }) => ({
7092
+ const printedFile = (raw, { file, ast }) => Result.map(print(ast, raw.registry.entryForFormat), (content) => ({
7089
7093
  name: file.name,
7090
7094
  mutate: file.mutate,
7091
- content: print(ast, raw.registry.entryForFormat)
7092
- });
7093
- const instrumentedResult = (raw) => InstrumentResult.make({
7094
- files: raw.parsed.map((parsed) => printedFile(raw, parsed)),
7095
+ content
7096
+ }));
7097
+ const printedFiles = (raw) => Effect$1.forEach(raw.parsed, (parsed) => Effect$1.fromResult(printedFile(raw, parsed)), { concurrency: 1 }).pipe(Effect$1.mapError((failure) => InstrumentError.make({
7098
+ message: failure.message,
7099
+ cause: failure
7100
+ })));
7101
+ const instrumentedResult = (raw) => Effect$1.map(printedFiles(raw), (files) => InstrumentResult.make({
7102
+ files: [...files],
7095
7103
  mutants: [...raw.mutants],
7096
7104
  skipped: [...raw.skipped]
7097
- });
7105
+ }));
7098
7106
  const skippedOnlyResult = (raw) => InstrumentResult.make({
7099
7107
  files: [],
7100
7108
  mutants: [],
7101
7109
  skipped: [...raw.skipped]
7102
7110
  });
7103
- const readInstrumentFiles = (input) => Effect$1.gen(function* () {
7111
+ const readInstrumentFiles = Effect$1.fn("stryker.instrument.read_files")(function* (input) {
7104
7112
  const outcomes = yield* Effect$1.forEach(input.files, (file) => fileOutcome({
7105
7113
  registry: input.registry,
7106
7114
  file
@@ -7129,7 +7137,7 @@ const readInstrumentFiles = (input) => Effect$1.gen(function* () {
7129
7137
  };
7130
7138
  });
7131
7139
  const instrumentFilesCell = Sandwich.named("stryker.instrument.files")((input) => readInstrumentFiles(input)).decide(admitInstrumentFiles).write({
7132
- InstrumentFilesAdmitted: (_admitted, raw) => Effect$1.succeed(instrumentedResult(raw)),
7140
+ InstrumentFilesAdmitted: (_admitted, raw) => instrumentedResult(raw),
7133
7141
  InstrumentFilesSkippedOnly: (_skipped, raw) => Effect$1.succeed(skippedOnlyResult(raw)),
7134
7142
  CommandRejected: ({ issue }) => Effect$1.fail(InstrumentError.make({
7135
7143
  message: issue,
@@ -7137,7 +7145,7 @@ const instrumentFilesCell = Sandwich.named("stryker.instrument.files")((input) =
7137
7145
  }))
7138
7146
  });
7139
7147
  const toSchemaFile = (file) => ({
7140
- name: file.name,
7148
+ name: CanonicalFileName.make(file.name),
7141
7149
  content: file.content,
7142
7150
  mutate: file.mutate
7143
7151
  });
@@ -7172,15 +7180,20 @@ const disableTypeChecksDataFirst = (file, registry = coreFormatRegistry) => disa
7172
7180
  cause
7173
7181
  })));
7174
7182
  const disableTypeChecks = dual((args) => Predicate$1.hasProperty(args[0], "content"), disableTypeChecksDataFirst);
7175
- var Instrument_exports = /* @__PURE__ */ __exportAll({
7183
+ var Instrument_exports = /* @__PURE__ */ __exportAll$1({
7176
7184
  InstrumentFileSkip: () => InstrumentFileSkip,
7177
7185
  disableTypeChecks: () => disableTypeChecks,
7178
7186
  instrument: () => instrument
7179
7187
  });
7180
- var Mutant_exports = /* @__PURE__ */ __exportAll({
7188
+ var Mutant_exports = /* @__PURE__ */ __exportAll$1({
7189
+ ActionableStatusSchema: () => ActionableStatusSchema,
7181
7190
  CanonicalFileName: () => CanonicalFileName,
7191
+ Column: () => Column,
7192
+ EphemeralStatusSchema: () => EphemeralStatusSchema,
7193
+ HitCount: () => HitCount,
7182
7194
  InstrumenterContext: () => InstrumenterContext,
7183
- LocationSchema: () => LocationSchema$1,
7195
+ Line: () => Line,
7196
+ Location: () => Location,
7184
7197
  Mutant: () => Mutant,
7185
7198
  MutantActivationSchema: () => MutantActivationSchema,
7186
7199
  MutantCoverageSchema: () => MutantCoverageSchema$1,
@@ -7189,32 +7202,48 @@ var Mutant_exports = /* @__PURE__ */ __exportAll({
7189
7202
  MutantRunOptionsSchema: () => MutantRunOptionsSchema,
7190
7203
  MutantStatusSchema: () => MutantStatusSchema,
7191
7204
  MutatorName: () => MutatorName,
7192
- OpenEndLocationSchema: () => OpenEndLocationSchema,
7193
- PositionSchema: () => PositionSchema,
7194
- ReportLocationFromMutant: () => ReportLocationFromMutant,
7195
- RunOptionsFields: () => RunOptionsFields
7205
+ Offset: () => Offset,
7206
+ OpenEndLocation: () => OpenEndLocation,
7207
+ Position: () => Position,
7208
+ RememberedStatusSchema: () => RememberedStatusSchema,
7209
+ RunOptionsFields: () => RunOptionsFields,
7210
+ ScriptOrigin: () => ScriptOrigin,
7211
+ Span: () => Span,
7212
+ SurvivorStatusSchema: () => SurvivorStatusSchema
7196
7213
  });
7197
7214
  //#endregion
7215
+ //#region ../stryker-js-plugin-interface/dist/rolldown-runtime-D7D4PA-g.mjs
7216
+ var __defProp = Object.defineProperty;
7217
+ var __exportAll = (all, no_symbols) => {
7218
+ let target = {};
7219
+ for (var name in all) __defProp(target, name, {
7220
+ get: all[name],
7221
+ enumerable: true
7222
+ });
7223
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
7224
+ return target;
7225
+ };
7226
+ //#endregion
7198
7227
  //#region ../stryker-js-plugin-interface/dist/index.mjs
7199
7228
  const CheckerMutantWire = S.Struct({
7200
7229
  id: Mutant_exports.MutantId,
7201
7230
  fileName: Mutant_exports.CanonicalFileName,
7202
7231
  mutatorName: Mutant_exports.MutatorName,
7203
7232
  replacement: S.String,
7204
- location: Mutant_exports.LocationSchema
7233
+ location: Mutant_exports.Location
7205
7234
  });
7206
- const CheckStatus = S.Literals(["passed", "compileError"]);
7207
7235
  const CheckResultSchema = S.Union([S.Struct({ status: S.Literal("passed") }), S.Struct({
7208
7236
  status: S.Literal("compileError"),
7209
7237
  reason: S.String
7210
- })]);
7238
+ })]).pipe(S.toTaggedUnion("status"));
7239
+ const CheckStatus = S.Literals(CheckResultSchema.discriminants);
7211
7240
  var CheckerFailed = class extends S.TaggedError()("CheckerFailed", {
7212
7241
  cause: S.String,
7213
7242
  checkerName: S.String,
7214
- mutantIds: S.Array(S.String)
7243
+ mutantIds: S.Array(Mutant_exports.MutantId)
7215
7244
  }) {};
7216
7245
  var Checker = class extends Context.Service()("@systemfsoftware/stryker-js-plugin-interface/Checker.service/Checker") {};
7217
- var Checker_exports = /* @__PURE__ */ __exportAll$1({
7246
+ var Checker_exports = /* @__PURE__ */ __exportAll({
7218
7247
  CheckResultSchema: () => CheckResultSchema,
7219
7248
  CheckStatus: () => CheckStatus,
7220
7249
  Checker: () => Checker,
@@ -7237,7 +7266,8 @@ const MutationScore = S.TaggedUnion({
7237
7266
  Scored: { percentage: Percentage },
7238
7267
  Unscored: {}
7239
7268
  });
7240
- var Metrics = class Metrics extends S.Class("Metrics")({
7269
+ const scorePercentageOf = (counts) => counts.counted > 0 ? Option$1.some(counts.detected / counts.counted * 100) : Option$1.none();
7270
+ var Metrics = class extends S.Class("Metrics")({
7241
7271
  pending: NonNegativeInt,
7242
7272
  killed: NonNegativeInt,
7243
7273
  timeout: NonNegativeInt,
@@ -7266,35 +7296,209 @@ var Metrics = class Metrics extends S.Class("Metrics")({
7266
7296
  return this.totalValid + this.totalInvalid + this.ignored + this.pending;
7267
7297
  }
7268
7298
  get mutationScore() {
7269
- return scoreOf(this.totalDetected, this.totalValid);
7299
+ return Option$1.match(scorePercentageOf({
7300
+ detected: this.totalDetected,
7301
+ counted: this.totalValid
7302
+ }), {
7303
+ onNone: () => MutationScore.cases.Unscored.make({}),
7304
+ onSome: (percentage) => MutationScore.cases.Scored.make({ percentage })
7305
+ });
7270
7306
  }
7271
7307
  get mutationScoreBasedOnCoveredCode() {
7272
- return scoreOf(this.totalDetected, this.totalCovered);
7273
- }
7274
- static fromMutants(mutants) {
7275
- return Metrics.make({
7276
- pending: metricCountOf(mutants, "Pending"),
7277
- killed: metricCountOf(mutants, "Killed"),
7278
- timeout: metricCountOf(mutants, "Timeout"),
7279
- survived: metricCountOf(mutants, "Survived"),
7280
- noCoverage: metricCountOf(mutants, "NoCoverage"),
7281
- runtimeErrors: metricCountOf(mutants, "RuntimeError"),
7282
- compileErrors: metricCountOf(mutants, "CompileError"),
7283
- ignored: metricCountOf(mutants, "Ignored")
7308
+ return Option$1.match(scorePercentageOf({
7309
+ detected: this.totalDetected,
7310
+ counted: this.totalCovered
7311
+ }), {
7312
+ onNone: () => MutationScore.cases.Unscored.make({}),
7313
+ onSome: (percentage) => MutationScore.cases.Scored.make({ percentage })
7284
7314
  });
7285
7315
  }
7286
7316
  };
7287
- const metricCountOf = (mutants, status) => mutants.filter((mutant) => mutant.status === status).length;
7288
- const scoreOf = (detected, counted) => Boolean$1$1.match(counted > 0, {
7289
- onTrue: () => MutationScore.cases.Scored.make({ percentage: detected / counted * 100 }),
7290
- onFalse: () => MutationScore.cases.Unscored.make({})
7291
- });
7292
7317
  const MetricsSchema = Metrics;
7293
7318
  const MetricsResultSchema = S.Struct({
7294
7319
  name: S.String,
7295
7320
  metrics: Metrics,
7296
7321
  childResults: S.Array(S.suspend(() => MetricsResultSchema))
7297
7322
  }).annotate({ identifier: "MetricsResult" });
7323
+ const TestId = S.NonEmptyString.pipe(S.brand("TestId"));
7324
+ const DryRunStatus = S.Literals([
7325
+ "complete",
7326
+ "error",
7327
+ "timeout"
7328
+ ]);
7329
+ const TestStatus = S.Literals([
7330
+ "success",
7331
+ "failed",
7332
+ "skipped"
7333
+ ]);
7334
+ const MutantRunStatus = S.Literals([
7335
+ "killed",
7336
+ "survived",
7337
+ "timeout",
7338
+ "error"
7339
+ ]);
7340
+ const TestResultBase = {
7341
+ id: TestId,
7342
+ name: S.String,
7343
+ timeSpentMs: NonNegativeFinite,
7344
+ fileName: S.optionalKey(S.String),
7345
+ startPosition: S.optionalKey(Mutant_exports.Position)
7346
+ };
7347
+ const TestResultSchema = S.Union([
7348
+ S.Struct({
7349
+ ...TestResultBase,
7350
+ status: S.Literal("failed"),
7351
+ failureMessage: S.String
7352
+ }),
7353
+ S.Struct({
7354
+ ...TestResultBase,
7355
+ status: S.Literal("skipped")
7356
+ }),
7357
+ S.Struct({
7358
+ ...TestResultBase,
7359
+ status: S.Literal("success")
7360
+ })
7361
+ ]);
7362
+ const MutantCoverageSchema = S.Struct({
7363
+ perTest: S.Record(S.String, S.Record(Mutant_exports.MutantId, S.Finite)),
7364
+ static: S.Record(Mutant_exports.MutantId, S.Finite)
7365
+ });
7366
+ const DryRunResultSchema = S.Union([
7367
+ S.Struct({
7368
+ status: S.Literal("complete"),
7369
+ tests: S.Array(TestResultSchema),
7370
+ mutantCoverage: S.optionalKey(MutantCoverageSchema)
7371
+ }),
7372
+ S.Struct({
7373
+ status: S.Literal("timeout"),
7374
+ reason: S.optionalKey(S.String)
7375
+ }),
7376
+ S.Struct({
7377
+ status: S.Literal("error"),
7378
+ errorMessage: S.String
7379
+ })
7380
+ ]);
7381
+ const MutantRunResultSchema = S.Union([
7382
+ S.Struct({
7383
+ status: S.Literal("killed"),
7384
+ killedBy: S.Array(TestId),
7385
+ failureMessage: S.String,
7386
+ nrOfTests: NonNegativeInt
7387
+ }),
7388
+ S.Struct({
7389
+ status: S.Literal("survived"),
7390
+ nrOfTests: NonNegativeInt
7391
+ }),
7392
+ S.Struct({
7393
+ status: S.Literal("timeout"),
7394
+ reason: S.optionalKey(S.String)
7395
+ }),
7396
+ S.Struct({
7397
+ status: S.Literal("error"),
7398
+ errorMessage: S.String
7399
+ })
7400
+ ]);
7401
+ const CoverageAnalysisSchema = S.Literals([
7402
+ "off",
7403
+ "all",
7404
+ "perTest"
7405
+ ]);
7406
+ const DryRunOptionsSchema = S.Struct({
7407
+ ...Mutant_exports.RunOptionsFields,
7408
+ coverageAnalysis: CoverageAnalysisSchema,
7409
+ files: S.String.pipe(S.Array, S.optionalKey),
7410
+ testFiles: S.String.pipe(S.Array, S.optionalKey)
7411
+ });
7412
+ const TestRunnerCapabilitiesSchema = S.Struct({ reloadEnvironment: S.Boolean });
7413
+ var TestRunnerFailed = class extends S.TaggedError()("TestRunnerFailed", {
7414
+ cause: S.String,
7415
+ phase: S.Literals([
7416
+ "capabilities",
7417
+ "dispose",
7418
+ "dryRun",
7419
+ "init",
7420
+ "mutantRun"
7421
+ ]),
7422
+ runnerName: S.String
7423
+ }) {};
7424
+ const MutantResultSchema = S.Struct({
7425
+ id: Mutant_exports.MutantId,
7426
+ mutatorName: S.String,
7427
+ status: Mutant_exports.MutantStatusSchema,
7428
+ location: Mutant_exports.Location,
7429
+ replacement: S.optional(S.String),
7430
+ description: S.optional(S.String),
7431
+ statusReason: S.optional(S.String),
7432
+ static: S.optional(S.Boolean),
7433
+ coveredBy: S.Array(TestId).pipe(S.optional),
7434
+ killedBy: S.Array(TestId).pipe(S.optional),
7435
+ testsCompleted: S.optional(NonNegativeInt),
7436
+ duration: S.optional(NonNegativeFinite)
7437
+ });
7438
+ const FileResultSchema = S.Struct({
7439
+ language: S.String,
7440
+ source: S.String,
7441
+ mutants: S.Array(MutantResultSchema)
7442
+ });
7443
+ const FileResultDictionarySchema = S.Record(S.String, FileResultSchema);
7444
+ const TestDefinitionSchema = S.Struct({
7445
+ id: TestId,
7446
+ name: S.String,
7447
+ location: S.optional(Mutant_exports.OpenEndLocation)
7448
+ });
7449
+ const TestFileSchema = S.Struct({
7450
+ source: S.optional(S.String),
7451
+ tests: S.Array(TestDefinitionSchema)
7452
+ });
7453
+ const TestFileDefinitionDictionarySchema = S.Record(S.String, TestFileSchema);
7454
+ const ThresholdsValuesSchema = S.Struct({
7455
+ high: Percentage,
7456
+ low: Percentage,
7457
+ break: S.NullOr(Percentage)
7458
+ });
7459
+ const isOrderedThresholds = (value) => S.is(ThresholdsValuesSchema)(value) && value.low <= value.high;
7460
+ const OrderedThresholds = S.declare(isOrderedThresholds, {
7461
+ message: "a mutation score threshold pair has low at or below high",
7462
+ toCodecArbitrary: () => S.link()(ThresholdsValuesSchema, {
7463
+ decode: SchemaGetter.transform(({ break: breaking, high, low }) => ({
7464
+ break: breaking,
7465
+ high: Math.max(high, low),
7466
+ low: Math.min(high, low)
7467
+ })),
7468
+ encode: SchemaGetter.transform((thresholds) => thresholds)
7469
+ })
7470
+ });
7471
+ const ThresholdsSchema = S.declare(isOrderedThresholds, {
7472
+ message: "a mutation score threshold pair has low at or below high",
7473
+ toCodecArbitrary: () => S.link()(ThresholdsValuesSchema, {
7474
+ decode: SchemaGetter.transform(({ break: breaking, high, low }) => ({
7475
+ break: breaking,
7476
+ high: Math.max(high, low),
7477
+ low: Math.min(low, high)
7478
+ })),
7479
+ encode: SchemaGetter.transform((thresholds) => thresholds)
7480
+ })
7481
+ });
7482
+ const BrandingInformationSchema = S.Struct({
7483
+ homepageUrl: S.String,
7484
+ imageUrl: S.optional(S.String)
7485
+ });
7486
+ const DependenciesSchema = S.Record(S.String, S.String);
7487
+ const FrameworkInformationSchema = S.Struct({
7488
+ name: S.String,
7489
+ version: S.optional(S.String),
7490
+ branding: S.optional(BrandingInformationSchema),
7491
+ dependencies: S.optional(DependenciesSchema)
7492
+ });
7493
+ const MutationTestResultSchema = S.Struct({
7494
+ schemaVersion: S.String,
7495
+ files: FileResultDictionarySchema,
7496
+ thresholds: ThresholdsSchema,
7497
+ config: S.optional(S.Record(S.String, S.Unknown)),
7498
+ testFiles: S.optional(TestFileDefinitionDictionarySchema),
7499
+ projectRoot: S.optional(S.String),
7500
+ framework: S.optional(FrameworkInformationSchema)
7501
+ });
7298
7502
  const StrykerCoverageAnalysis = S.Literal("perTest");
7299
7503
  const StrykerFileLogLevel = S.Literal("off");
7300
7504
  const StrykerLogLevel = S.Literal("info");
@@ -7367,7 +7571,7 @@ const ClearTextReporterOptions = openStruct({
7367
7571
  allowColor: defaulted(S.Boolean, true),
7368
7572
  allowEmojis: defaulted(S.Boolean, false),
7369
7573
  logTests: defaulted(S.Boolean, true),
7370
- maxTestsToLog: defaulted(S.Finite.pipe(S.check(S.isGreaterThanOrEqualTo(0))), 3),
7574
+ maxTestsToLog: defaulted(NonNegativeInt, 3),
7371
7575
  reportTests: defaulted(S.Boolean, true),
7372
7576
  reportMutants: defaulted(S.Boolean, true),
7373
7577
  reportScoreTable: defaulted(S.Boolean, true),
@@ -7375,32 +7579,11 @@ const ClearTextReporterOptions = openStruct({
7375
7579
  });
7376
7580
  const HtmlReporterOptions = S.Struct({ fileName: defaulted(S.String, "reports/mutation/mutation.html") });
7377
7581
  const JsonReporterOptions = S.Struct({ fileName: defaulted(S.String, "reports/mutation/mutation.json") });
7378
- const MutationScoreThresholdsValuesSchema = S.Struct({
7582
+ const MutationScoreThresholdsSchema = S.Struct({
7379
7583
  high: defaulted(Percentage, 80),
7380
7584
  low: defaulted(Percentage, 60),
7381
7585
  break: defaulted(S.NullOr(Percentage), null)
7382
- });
7383
- const isMutationScoreThresholds = (value) => S.is(MutationScoreThresholdsValuesSchema)(value) && value.low <= value.high;
7384
- /**
7385
- * The pair is *built* ordered — a drawn pair is sorted — rather than drawn at
7386
- * random and discarded until it happens to be ordered. The invariant lives on
7387
- * the declaration because a filter over the pair cannot express `low <= high`
7388
- * in the generation-constraint vocabulary, and only a declaration carries a
7389
- * `toCodecArbitrary` derivation. The struct stays the wire side, so decoding
7390
- * keeps member defaults and field paths.
7391
- */
7392
- const OrderedMutationScoreThresholds = S.declare(isMutationScoreThresholds, {
7393
- message: "expected thresholds where low <= high",
7394
- toCodecArbitrary: () => S.link()(MutationScoreThresholdsValuesSchema, {
7395
- decode: SchemaGetter.transform(({ break: breaking, high, low }) => ({
7396
- high: Math.max(high, low),
7397
- low: Math.min(high, low),
7398
- break: breaking
7399
- })),
7400
- encode: SchemaGetter.transform((thresholds) => thresholds)
7401
- })
7402
- });
7403
- const MutationScoreThresholdsSchema = MutationScoreThresholdsValuesSchema.pipe(S.decodeTo(OrderedMutationScoreThresholds, SchemaTransformation.passthrough()));
7586
+ }).pipe(S.decodeTo(OrderedThresholds, SchemaTransformation.passthrough()));
7404
7587
  const MutatorDescriptor = S.Struct({
7405
7588
  excludedMutations: defaulted(S.Array(S.String), []),
7406
7589
  optInMutations: defaulted(S.Array(S.String), [])
@@ -7411,7 +7594,7 @@ const WarningOptions = openStruct({
7411
7594
  unserializableOptions: defaulted(S.Boolean, true),
7412
7595
  slow: defaulted(S.Boolean, true)
7413
7596
  });
7414
- const ConcurrencyCount = S.Finite.pipe(S.check(S.isGreaterThanOrEqualTo(1)));
7597
+ const ConcurrencyCount = S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(1)));
7415
7598
  const ConcurrencyPercent = S.String.pipe(S.check(S.isPattern(/^(100|[1-9]?[0-9])%$/)));
7416
7599
  const pluginSpecifierArbitrary = S.link()(S.Literals([
7417
7600
  "file:///project/node_modules/@systemfsoftware/stryker-js-angular/index.mjs",
@@ -7469,8 +7652,8 @@ const StrykerOptionsSchema = S.StructWithRest(S.Struct({
7469
7652
  fileLogLevel: defaulted(LogLevel, StrykerFileLogLevel.literal),
7470
7653
  inPlace: defaulted(S.Boolean, false),
7471
7654
  logLevel: defaulted(LogLevel, StrykerLogLevel.literal),
7472
- maxConcurrentTestRunners: defaulted(S.Finite, 9007199254740991),
7473
- maxTestRunnerReuse: defaulted(S.Finite, 0),
7655
+ maxConcurrentTestRunners: defaulted(S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(1))), Number.MAX_SAFE_INTEGER),
7656
+ maxTestRunnerReuse: defaulted(NonNegativeInt, 0),
7474
7657
  mutate: defaulted(S.Array(S.String), ["{src,lib}/**/!(*.+(s|S)pec|*.+(t|T)est).+(cjs|mjs|js|ts|mts|cts|jsx|tsx|html|vue|svelte)", "!{src,lib}/**/__tests__/**/*.+(cjs|mjs|js|ts|mts|cts|jsx|tsx|html|vue|svelte)"]),
7475
7658
  mutator: defaulted(MutatorDescriptor, {
7476
7659
  excludedMutations: [],
@@ -7501,9 +7684,9 @@ const StrykerOptionsSchema = S.StructWithRest(S.Struct({
7501
7684
  low: 60,
7502
7685
  break: null
7503
7686
  }),
7504
- timeoutFactor: defaulted(S.Finite, 1.5),
7505
- timeoutMS: defaulted(S.Finite, 5e3),
7506
- dryRunTimeoutMinutes: defaulted(S.Finite.pipe(S.check(S.isGreaterThanOrEqualTo(0))), 5),
7687
+ timeoutFactor: defaulted(NonNegativeFinite, 1.5),
7688
+ timeoutMS: defaulted(NonNegativeInt, 5e3),
7689
+ dryRunTimeoutMinutes: defaulted(NonNegativeFinite, 5),
7507
7690
  tsconfigFile: defaulted(S.String, "tsconfig.json"),
7508
7691
  warnings: defaulted(S.Union([S.Boolean, WarningOptions]), true),
7509
7692
  disableBail: defaulted(S.Boolean, false),
@@ -7511,7 +7694,7 @@ const StrykerOptionsSchema = S.StructWithRest(S.Struct({
7511
7694
  ignorers: defaulted(S.Array(PluginFileUrl), []),
7512
7695
  testFiles: defaulted(S.Array(S.String), [])
7513
7696
  }), [S.Record(S.String, S.Unknown)]);
7514
- var Options_exports = /* @__PURE__ */ __exportAll$1({
7697
+ var Options_exports = /* @__PURE__ */ __exportAll({
7515
7698
  CheckerCustomConfigSchema: () => CheckerCustomConfigSchema,
7516
7699
  CheckerEntryConfigSchema: () => CheckerEntryConfigSchema,
7517
7700
  CommandRunnerOptionsSchema: () => CommandRunnerOptionsSchema,
@@ -7530,6 +7713,10 @@ var Options_exports = /* @__PURE__ */ __exportAll$1({
7530
7713
  TestRunnerCustomConfigSchema: () => TestRunnerCustomConfigSchema,
7531
7714
  isCustomTestRunner: () => isCustomTestRunner
7532
7715
  });
7716
+ const ExitCode = S.Int.pipe(S.check(S.isBetween({
7717
+ minimum: 0,
7718
+ maximum: 255
7719
+ })));
7533
7720
  const ExitClass = S.Literals([
7534
7721
  "VerdictFail",
7535
7722
  "ConfigError",
@@ -7560,193 +7747,13 @@ const ExitCodeFromClass = S.decodeTo(BaselineExitCode, SchemaTransformation.tran
7560
7747
  decode: codeOfClass,
7561
7748
  encode: classOfCode
7562
7749
  }))(ExitClass);
7563
- const MutantResultSchema = S.Struct({
7564
- id: S.String,
7565
- mutatorName: S.String,
7566
- status: Mutant_exports.MutantStatusSchema,
7567
- location: Mutant_exports.LocationSchema,
7568
- replacement: S.optional(S.String),
7569
- description: S.optional(S.String),
7570
- statusReason: S.optional(S.String),
7571
- static: S.optional(S.Boolean),
7572
- coveredBy: S.String.pipe(S.Array, S.optional),
7573
- killedBy: S.String.pipe(S.Array, S.optional),
7574
- testsCompleted: S.optional(NonNegativeInt),
7575
- duration: S.optional(NonNegativeFinite)
7576
- });
7577
- const FileResultSchema = S.Struct({
7578
- language: S.String,
7579
- source: S.String,
7580
- mutants: S.Array(MutantResultSchema)
7581
- });
7582
- const FileResultDictionarySchema = S.Record(S.String, FileResultSchema);
7583
- const TestDefinitionSchema = S.Struct({
7584
- id: S.String,
7585
- name: S.String,
7586
- location: S.optional(Mutant_exports.OpenEndLocationSchema)
7587
- });
7588
- const TestFileSchema = S.Struct({
7589
- source: S.optional(S.String),
7590
- tests: S.Array(TestDefinitionSchema)
7591
- });
7592
- const TestFileDefinitionDictionarySchema = S.Record(S.String, TestFileSchema);
7593
- const ThresholdsValuesSchema = S.Struct({
7594
- high: Percentage,
7595
- low: Percentage
7596
- });
7597
- const isThresholds = (value) => S.is(ThresholdsValuesSchema)(value) && value.low <= value.high;
7598
- /**
7599
- * The pair is *built* ordered — a drawn pair is sorted — rather than drawn at
7600
- * random and discarded until it happens to be ordered. The invariant lives on
7601
- * the declaration because a filter over the pair cannot express `low <= high`
7602
- * in the generation-constraint vocabulary, and only a declaration carries a
7603
- * `toCodecArbitrary` derivation. `ThresholdsValuesSchema` stays the wire side, so
7604
- * decoding keeps its field paths.
7605
- */
7606
- const OrderedThresholds = S.declare(isThresholds, {
7607
- message: "expected thresholds where low <= high",
7608
- toCodecArbitrary: () => S.link()(ThresholdsValuesSchema, {
7609
- decode: SchemaGetter.transform(({ high, low }) => ({
7610
- high: Math.max(high, low),
7611
- low: Math.min(high, low)
7612
- })),
7613
- encode: SchemaGetter.transform((thresholds) => thresholds)
7614
- })
7615
- });
7616
- const ThresholdsSchema = ThresholdsValuesSchema.pipe(S.decodeTo(OrderedThresholds, SchemaTransformation.passthrough()));
7617
- const BrandingInformationSchema = S.Struct({
7618
- homepageUrl: S.String,
7619
- imageUrl: S.optional(S.String)
7620
- });
7621
- const DependenciesSchema = S.Record(S.String, S.String);
7622
- const FrameworkInformationSchema = S.Struct({
7623
- name: S.String,
7624
- version: S.optional(S.String),
7625
- branding: S.optional(BrandingInformationSchema),
7626
- dependencies: S.optional(DependenciesSchema)
7627
- });
7628
- const MutationTestResultSchema = S.Struct({
7629
- schemaVersion: S.String,
7630
- files: FileResultDictionarySchema,
7631
- thresholds: ThresholdsSchema,
7632
- config: S.optional(S.Record(S.String, S.Unknown)),
7633
- testFiles: S.optional(TestFileDefinitionDictionarySchema),
7634
- projectRoot: S.optional(S.String),
7635
- framework: S.optional(FrameworkInformationSchema)
7636
- });
7637
- const DryRunStatus = S.Literals([
7638
- "complete",
7639
- "error",
7640
- "timeout"
7641
- ]);
7642
- const TestStatus = S.Literals([
7643
- "success",
7644
- "failed",
7645
- "skipped"
7646
- ]);
7647
- const MutantRunStatus = S.Literals([
7648
- "killed",
7649
- "survived",
7650
- "timeout",
7651
- "error"
7652
- ]);
7653
- const TestResultBase = {
7654
- id: S.String,
7655
- name: S.String,
7656
- timeSpentMs: S.Finite,
7657
- fileName: S.optionalKey(S.String),
7658
- startPosition: S.optionalKey(Mutant_exports.PositionSchema)
7659
- };
7660
- const TestResultSchema = S.Union([
7661
- S.Struct({
7662
- ...TestResultBase,
7663
- status: S.Literal("failed"),
7664
- failureMessage: S.String
7665
- }),
7666
- S.Struct({
7667
- ...TestResultBase,
7668
- status: S.Literal("skipped")
7669
- }),
7670
- S.Struct({
7671
- ...TestResultBase,
7672
- status: S.Literal("success")
7673
- })
7674
- ]);
7675
- const MutantCoverageSchema = S.Struct({
7676
- perTest: S.Record(S.String, S.Record(S.String, S.Finite)),
7677
- static: S.Record(S.String, S.Finite)
7678
- });
7679
- const DryRunResultSchema = S.Union([
7680
- S.Struct({
7681
- status: S.Literal("complete"),
7682
- tests: S.Array(TestResultSchema),
7683
- mutantCoverage: S.optionalKey(MutantCoverageSchema)
7684
- }),
7685
- S.Struct({
7686
- status: S.Literal("timeout"),
7687
- reason: S.optionalKey(S.String)
7688
- }),
7689
- S.Struct({
7690
- status: S.Literal("error"),
7691
- errorMessage: S.String
7692
- })
7693
- ]);
7694
- const MutantRunResultSchema = S.Union([
7695
- S.Struct({
7696
- status: S.Literal("killed"),
7697
- killedBy: S.Array(S.String),
7698
- failureMessage: S.String,
7699
- nrOfTests: S.Finite
7700
- }),
7701
- S.Struct({
7702
- status: S.Literal("survived"),
7703
- nrOfTests: S.Finite
7704
- }),
7705
- S.Struct({
7706
- status: S.Literal("timeout"),
7707
- reason: S.optionalKey(S.String)
7708
- }),
7709
- S.Struct({
7710
- status: S.Literal("error"),
7711
- errorMessage: S.String
7712
- })
7713
- ]);
7714
- const CoverageAnalysisSchema = S.Literals([
7715
- "off",
7716
- "all",
7717
- "perTest"
7718
- ]);
7719
- const DryRunOptionsSchema = S.Struct({
7720
- ...Mutant_exports.RunOptionsFields,
7721
- coverageAnalysis: CoverageAnalysisSchema,
7722
- files: S.String.pipe(S.Array, S.optionalKey),
7723
- testFiles: S.String.pipe(S.Array, S.optionalKey)
7724
- });
7725
- const TestRunnerCapabilitiesSchema = S.Struct({ reloadEnvironment: S.Boolean });
7726
- var TestRunnerFailed = class extends S.TaggedError()("TestRunnerFailed", {
7727
- cause: S.String,
7728
- phase: S.Literals([
7729
- "capabilities",
7730
- "dispose",
7731
- "dryRun",
7732
- "init",
7733
- "mutantRun"
7734
- ]),
7735
- runnerName: S.String
7736
- }) {};
7737
- const ReporterEventKind = S.Literals([
7738
- "dryRunCompleted",
7739
- "mutationTestingPlanReady",
7740
- "mutantTested",
7741
- "mutationTestReportReady"
7742
- ]);
7743
7750
  const RunTimingSchema = S.Struct({
7744
7751
  net: NonNegativeFinite,
7745
7752
  overhead: NonNegativeFinite
7746
7753
  });
7747
7754
  const ReporterPlanKind = S.Literals(["EarlyResult", "Run"]);
7748
7755
  const ReporterPlanDescriptorSchema = S.Struct({
7749
- mutantId: S.String,
7756
+ mutantId: Mutant_exports.MutantId,
7750
7757
  plan: ReporterPlanKind,
7751
7758
  netTime: NonNegativeFinite,
7752
7759
  reloadEnvironment: S.Boolean
@@ -7762,11 +7769,11 @@ var MutationTestingPlanReady = class extends S.TaggedClass()("mutationTestingPla
7762
7769
  plans: S.Array(ReporterPlanDescriptorSchema)
7763
7770
  }) {};
7764
7771
  var MutantTested = class extends S.TaggedClass()("mutantTested", {
7765
- id: S.String,
7772
+ id: Mutant_exports.MutantId,
7766
7773
  status: Mutant_exports.MutantStatusSchema,
7767
- file: S.String,
7768
- location: Mutant_exports.LocationSchema,
7769
- mutator: S.String,
7774
+ fileName: Mutant_exports.CanonicalFileName,
7775
+ location: Mutant_exports.Location,
7776
+ mutatorName: Mutant_exports.MutatorName,
7770
7777
  replacement: S.NullOr(S.String),
7771
7778
  completed: NonNegativeInt,
7772
7779
  total: NonNegativeInt
@@ -7780,18 +7787,91 @@ const ReporterEventUnion = S.Union([
7780
7787
  MutationTestingPlanReady,
7781
7788
  MutantTested,
7782
7789
  MutationTestReportReady
7783
- ]);
7790
+ ]).pipe(S.toTaggedUnion("_tag"));
7791
+ const ReporterEventKind = S.Literals(ReporterEventUnion.discriminants);
7784
7792
  const ReporterEventSchema = S.toStandardSchemaV1(ReporterEventUnion);
7785
7793
  var ReporterFailed = class extends S.TaggedError()("ReporterFailed", {
7786
7794
  cause: S.String,
7787
7795
  event: ReporterEventKind,
7788
7796
  reporterName: S.String
7789
7797
  }) {};
7798
+ const TraceparentHeader = S.Literal("traceparent");
7799
+ const TracestateHeader = S.Literal("tracestate");
7800
+ const VERSION = S.String.pipe(S.check(S.isPattern(/^([0-9a-e][0-9a-f]|[0-9a-f][0-9a-e])$/)));
7801
+ const TRACE_ID = S.String.pipe(S.check(S.isPattern(/^[0-9a-f]*[1-9a-f][0-9a-f]*$/)), S.check(S.isLengthBetween(32, 32)));
7802
+ const SPAN_ID = S.String.pipe(S.check(S.isPattern(/^[0-9a-f]*[1-9a-f][0-9a-f]*$/)), S.check(S.isLengthBetween(16, 16)));
7803
+ const TraceContextPartsSchema = S.Struct({
7804
+ version: VERSION,
7805
+ traceId: TRACE_ID,
7806
+ spanId: SPAN_ID,
7807
+ traceFlags: S.Int.pipe(S.check(S.isBetween({
7808
+ minimum: 0,
7809
+ maximum: 255
7810
+ }))),
7811
+ traceState: S.optional(S.String)
7812
+ });
7813
+ const TraceparentPartsSchema = S.Struct({
7814
+ version: VERSION,
7815
+ traceId: TRACE_ID,
7816
+ spanId: SPAN_ID,
7817
+ traceFlags: S.Int.pipe(S.check(S.isBetween({
7818
+ minimum: 0,
7819
+ maximum: 255
7820
+ })))
7821
+ });
7822
+ const HEX_VERSION = /^[0-9a-f]{2}$/;
7823
+ const HEX_TRACE_ID = /^[0-9a-f]{32}$/;
7824
+ const HEX_SPAN_ID = /^[0-9a-f]{16}$/;
7825
+ const HEX_FLAGS = /^[0-9a-f]{2}$/;
7826
+ const ALL_ZERO = /^0+$/;
7827
+ const FORBIDDEN_VERSION = "ff";
7828
+ const CURRENT_VERSION = "00";
7829
+ const TRACEPARENT_FIELD_COUNT = 4;
7830
+ const fieldAt = (fields, index) => fields[index] ?? "";
7831
+ const isNonZeroHex = (pattern, value) => pattern.test(value) && !ALL_ZERO.test(value);
7832
+ const acceptsFieldCount = (version, count) => version !== CURRENT_VERSION || count === TRACEPARENT_FIELD_COUNT;
7833
+ const isKnownVersion = (version) => HEX_VERSION.test(version) && version !== FORBIDDEN_VERSION;
7834
+ const isWellFormedTraceparent = (value) => {
7835
+ const fields = value.split("-");
7836
+ return [
7837
+ acceptsFieldCount(fieldAt(fields, 0), fields.length),
7838
+ isKnownVersion(fieldAt(fields, 0)),
7839
+ isNonZeroHex(HEX_TRACE_ID, fieldAt(fields, 1)),
7840
+ isNonZeroHex(HEX_SPAN_ID, fieldAt(fields, 2)),
7841
+ HEX_FLAGS.test(fieldAt(fields, 3))
7842
+ ].every((check) => check);
7843
+ };
7844
+ const partsOf = (value) => {
7845
+ const fields = value.split("-");
7846
+ return {
7847
+ version: fieldAt(fields, 0),
7848
+ traceId: fieldAt(fields, 1),
7849
+ spanId: fieldAt(fields, 2),
7850
+ traceFlags: Number.parseInt(fieldAt(fields, 3), 16)
7851
+ };
7852
+ };
7853
+ const formatOf = (parts) => `${parts.version}-${parts.traceId}-${parts.spanId}-${(parts.traceFlags & 255).toString(16).padStart(2, "0")}`;
7854
+ const malformedTraceparent = (value) => new SchemaIssue.InvalidValue({ message: "expected a W3C traceparent: version-traceId-spanId-flags" }, value);
7855
+ const decodeParts = SchemaGetter.transformEffect((value) => Boolean$1$1.match(isWellFormedTraceparent(value), {
7856
+ onTrue: () => Effect$1.succeed(partsOf(value)),
7857
+ onFalse: () => Effect$1.fail(malformedTraceparent(value))
7858
+ }));
7859
+ const encodeText = SchemaGetter.transform(formatOf);
7860
+ const Traceparent = S.String.pipe(S.decodeTo(TraceparentPartsSchema, SchemaTransformation.makeTransformation({
7861
+ decode: decodeParts,
7862
+ encode: encodeText
7863
+ })));
7864
+ const TRACESTATE_MEMBER = "[a-z][_0-9a-z\\-*/]{0,255}=[\\x20-\\x2b\\x2d-\\x3c\\x3e-\\x7e]{0,255}";
7865
+ const TRACESTATE_OWS = "[ \\t]*";
7866
+ const TRACESTATE = new RegExp(`^${TRACESTATE_MEMBER}(${TRACESTATE_OWS},${TRACESTATE_OWS}${TRACESTATE_MEMBER}){0,31}$`);
7867
+ const Tracestate = S.String.pipe(S.check(S.isPattern(TRACESTATE, { expected: "a W3C tracestate: comma-separated key=value members" })));
7790
7868
  const WorkerPluginKind = S.Literals([
7791
7869
  "TestRunner",
7792
7870
  "Checker",
7793
7871
  "Reporter"
7794
7872
  ]);
7873
+ const EvaluatorPluginKind = S.Literal("Evaluator");
7874
+ const PluginKindSchema = S.Union([WorkerPluginKind, EvaluatorPluginKind]);
7795
7875
  const TestRunnerDryRunRequest = S.Struct({ options: DryRunOptionsSchema });
7796
7876
  const TestRunnerMutantRunRequest = S.Struct({ options: Mutant_exports.MutantRunOptionsSchema });
7797
7877
  const CheckerRequest = S.Struct({
@@ -7801,8 +7881,8 @@ const CheckerRequest = S.Struct({
7801
7881
  const CheckerCheckResult = S.Record(S.String, CheckResultSchema);
7802
7882
  const CheckerGroupResult = S.String.pipe(S.Array, S.Array);
7803
7883
  const ReporterInitOptions = S.Struct({
7804
- traceparent: S.optionalKey(S.String),
7805
- tracestate: S.optionalKey(S.String)
7884
+ traceparent: S.optionalKey(Traceparent),
7885
+ tracestate: S.optionalKey(Tracestate)
7806
7886
  });
7807
7887
  const ReporterEventBatch = S.Array(ReporterEventUnion);
7808
7888
  const ReporterAck = S.Void;
@@ -7831,40 +7911,48 @@ const WorkerPluginSpawnSchema = S.Struct({
7831
7911
  });
7832
7912
  var PropagatedTrace = class extends Context.Service()("@systemfsoftware/stryker-js-plugin-interface/TraceContextRpc.service/PropagatedTrace") {};
7833
7913
  var TraceContextMiddleware = class extends RpcMiddleware.Service()("@systemfsoftware/stryker-js-plugin-interface/TraceContextMiddleware", { requiredForClient: true }) {};
7834
- const TestRunnerRpcs = RpcGroup.make(Rpc.make("capabilities", {
7914
+ const capabilities = Rpc.make("capabilities", {
7835
7915
  success: TestRunnerCapabilitiesSchema,
7836
7916
  error: TestRunnerFailed
7837
- }), Rpc.make("dryRun", {
7917
+ }).middleware(TraceContextMiddleware);
7918
+ const dryRun = Rpc.make("dryRun", {
7838
7919
  payload: TestRunnerDryRunRequest,
7839
7920
  success: DryRunResultSchema,
7840
7921
  error: TestRunnerFailed
7841
- }), Rpc.make("mutantRun", {
7922
+ }).middleware(TraceContextMiddleware);
7923
+ const mutantRun = Rpc.make("mutantRun", {
7842
7924
  payload: TestRunnerMutantRunRequest,
7843
7925
  success: MutantRunResultSchema,
7844
7926
  error: TestRunnerFailed
7845
- })).middleware(TraceContextMiddleware);
7846
- const CheckerRpcs = RpcGroup.make(Rpc.make("check", {
7927
+ }).middleware(TraceContextMiddleware);
7928
+ const check = Rpc.make("check", {
7847
7929
  payload: CheckerRequest,
7848
7930
  success: CheckerCheckResult,
7849
7931
  error: CheckerFailed
7850
- }), Rpc.make("group", {
7932
+ }).middleware(TraceContextMiddleware);
7933
+ const group = Rpc.make("group", {
7851
7934
  payload: CheckerRequest,
7852
7935
  success: CheckerGroupResult,
7853
7936
  error: CheckerFailed
7854
- })).middleware(TraceContextMiddleware);
7855
- const ReporterRpcs = RpcGroup.make(Rpc.make("init", {
7937
+ }).middleware(TraceContextMiddleware);
7938
+ const init = Rpc.make("init", {
7856
7939
  payload: ReporterInitOptions,
7857
7940
  success: ReporterAck,
7858
7941
  error: ReporterFailed
7859
- }), Rpc.make("onEventBatch", {
7942
+ }).middleware(TraceContextMiddleware);
7943
+ const onEventBatch = Rpc.make("onEventBatch", {
7860
7944
  payload: ReporterEventBatch,
7861
7945
  success: ReporterAck,
7862
7946
  error: ReporterFailed
7863
- }), Rpc.make("flush", {
7947
+ }).middleware(TraceContextMiddleware);
7948
+ const flush = Rpc.make("flush", {
7864
7949
  success: ReporterDrained,
7865
7950
  error: ReporterFailed
7866
- })).middleware(TraceContextMiddleware);
7867
- var Plugin_exports = /* @__PURE__ */ __exportAll$1({
7951
+ }).middleware(TraceContextMiddleware);
7952
+ const TestRunnerRpcs = RpcGroup.make(capabilities, dryRun, mutantRun);
7953
+ const CheckerRpcs = RpcGroup.make(check, group);
7954
+ const ReporterRpcs = RpcGroup.make(init, onEventBatch, flush);
7955
+ var Plugin_exports = /* @__PURE__ */ __exportAll({
7868
7956
  BoundaryErrorSchema: () => BoundaryErrorSchema,
7869
7957
  BoundaryPayloadRejected: () => BoundaryPayloadRejected,
7870
7958
  BoundaryUnrecognizedSignal: () => BoundaryUnrecognizedSignal,
@@ -7872,8 +7960,11 @@ var Plugin_exports = /* @__PURE__ */ __exportAll$1({
7872
7960
  CheckerGroupResult: () => CheckerGroupResult,
7873
7961
  CheckerRequest: () => CheckerRequest,
7874
7962
  CheckerRpcs: () => CheckerRpcs,
7963
+ EvaluatorPluginKind: () => EvaluatorPluginKind,
7875
7964
  ExitClass: () => ExitClass,
7965
+ ExitCode: () => ExitCode,
7876
7966
  ExitCodeFromClass: () => ExitCodeFromClass,
7967
+ PluginKindSchema: () => PluginKindSchema,
7877
7968
  ReporterAck: () => ReporterAck,
7878
7969
  ReporterDrained: () => ReporterDrained,
7879
7970
  ReporterEventBatch: () => ReporterEventBatch,
@@ -7886,7 +7977,18 @@ var Plugin_exports = /* @__PURE__ */ __exportAll$1({
7886
7977
  WorkerPluginKind: () => WorkerPluginKind,
7887
7978
  WorkerPluginSpawnSchema: () => WorkerPluginSpawnSchema
7888
7979
  });
7889
- var Report_exports = /* @__PURE__ */ __exportAll$1({
7980
+ const countOf = (mutants, status) => mutants.filter((mutant) => mutant.status === status).length;
7981
+ const metricsFromMutants = (mutants) => Metrics.make({
7982
+ pending: countOf(mutants, "Pending"),
7983
+ killed: countOf(mutants, "Killed"),
7984
+ timeout: countOf(mutants, "Timeout"),
7985
+ survived: countOf(mutants, "Survived"),
7986
+ noCoverage: countOf(mutants, "NoCoverage"),
7987
+ runtimeErrors: countOf(mutants, "RuntimeError"),
7988
+ compileErrors: countOf(mutants, "CompileError"),
7989
+ ignored: countOf(mutants, "Ignored")
7990
+ });
7991
+ var Report_exports = /* @__PURE__ */ __exportAll({
7890
7992
  BrandingInformationSchema: () => BrandingInformationSchema,
7891
7993
  DependenciesSchema: () => DependenciesSchema,
7892
7994
  DetectedStatus: () => DetectedStatus,
@@ -7902,15 +8004,17 @@ var Report_exports = /* @__PURE__ */ __exportAll$1({
7902
8004
  MutationTestResultSchema: () => MutationTestResultSchema,
7903
8005
  NonNegativeFinite: () => NonNegativeFinite,
7904
8006
  NonNegativeInt: () => NonNegativeInt,
8007
+ OrderedThresholds: () => OrderedThresholds,
7905
8008
  Percentage: () => Percentage,
7906
8009
  TestDefinitionSchema: () => TestDefinitionSchema,
7907
8010
  TestFileDefinitionDictionarySchema: () => TestFileDefinitionDictionarySchema,
7908
8011
  TestFileSchema: () => TestFileSchema,
7909
8012
  ThresholdsSchema: () => ThresholdsSchema,
7910
8013
  UndetectedStatus: () => UndetectedStatus,
7911
- UntestedStatus: () => UntestedStatus
8014
+ UntestedStatus: () => UntestedStatus,
8015
+ metricsFromMutants: () => metricsFromMutants
7912
8016
  });
7913
- var Reporter_exports = /* @__PURE__ */ __exportAll$1({
8017
+ var Reporter_exports = /* @__PURE__ */ __exportAll({
7914
8018
  DryRunCompleted: () => DryRunCompleted,
7915
8019
  MutantTested: () => MutantTested,
7916
8020
  MutationTestReportReady: () => MutationTestReportReady,
@@ -7951,7 +8055,7 @@ const HitLimitReason = HitLimitReasonText.pipe(S.decodeTo(S.Struct({
7951
8055
  encode: textOf
7952
8056
  })));
7953
8057
  var TestRunner = class extends Context.Service()("@systemfsoftware/stryker-js-plugin-interface/TestRunner.service/TestRunner") {};
7954
- var TestRunner_exports = /* @__PURE__ */ __exportAll$1({
8058
+ var TestRunner_exports = /* @__PURE__ */ __exportAll({
7955
8059
  CoverageAnalysisSchema: () => CoverageAnalysisSchema,
7956
8060
  DryRunOptionsSchema: () => DryRunOptionsSchema,
7957
8061
  DryRunResultSchema: () => DryRunResultSchema,
@@ -7962,6 +8066,7 @@ var TestRunner_exports = /* @__PURE__ */ __exportAll$1({
7962
8066
  MutantCoverageSchema: () => MutantCoverageSchema,
7963
8067
  MutantRunResultSchema: () => MutantRunResultSchema,
7964
8068
  MutantRunStatus: () => MutantRunStatus,
8069
+ TestId: () => TestId,
7965
8070
  TestResultSchema: () => TestResultSchema,
7966
8071
  TestRunner: () => TestRunner,
7967
8072
  TestRunnerCapabilitiesSchema: () => TestRunnerCapabilitiesSchema,
@@ -7969,306 +8074,16 @@ var TestRunner_exports = /* @__PURE__ */ __exportAll$1({
7969
8074
  TestStatus: () => TestStatus,
7970
8075
  WallClockTimeoutReason: () => WallClockTimeoutReason
7971
8076
  });
7972
- const TraceparentHeader = S.Literal("traceparent");
7973
- const TracestateHeader = S.Literal("tracestate");
7974
- const VERSION = S.String.pipe(S.check(S.isPattern(/^([0-9a-e][0-9a-f]|[0-9a-f][0-9a-e])$/)));
7975
- const TRACE_ID = S.String.pipe(S.check(S.isPattern(/^[0-9a-f]*[1-9a-f][0-9a-f]*$/)), S.check(S.isLengthBetween(32, 32)));
7976
- const SPAN_ID = S.String.pipe(S.check(S.isPattern(/^[0-9a-f]*[1-9a-f][0-9a-f]*$/)), S.check(S.isLengthBetween(16, 16)));
7977
- const TraceContextPartsSchema = S.Struct({
7978
- version: VERSION,
7979
- traceId: TRACE_ID,
7980
- spanId: SPAN_ID,
7981
- traceFlags: S.Int.pipe(S.check(S.isBetween({
7982
- minimum: 0,
7983
- maximum: 255
7984
- }))),
7985
- traceState: S.optional(S.String)
7986
- });
7987
- const TraceparentPartsSchema = S.Struct({
7988
- version: VERSION,
7989
- traceId: TRACE_ID,
7990
- spanId: SPAN_ID,
7991
- traceFlags: S.Int.pipe(S.check(S.isBetween({
7992
- minimum: 0,
7993
- maximum: 255
7994
- })))
7995
- });
7996
- const HEX_VERSION = /^[0-9a-f]{2}$/;
7997
- const HEX_TRACE_ID = /^[0-9a-f]{32}$/;
7998
- const HEX_SPAN_ID = /^[0-9a-f]{16}$/;
7999
- const HEX_FLAGS = /^[0-9a-f]{2}$/;
8000
- const ALL_ZERO = /^0+$/;
8001
- const FORBIDDEN_VERSION = "ff";
8002
- const CURRENT_VERSION = "00";
8003
- const TRACEPARENT_FIELD_COUNT = 4;
8004
- const fieldAt = (fields, index) => fields[index] ?? "";
8005
- const isNonZeroHex = (pattern, value) => pattern.test(value) && !ALL_ZERO.test(value);
8006
- const acceptsFieldCount = (version, count) => version !== CURRENT_VERSION || count === TRACEPARENT_FIELD_COUNT;
8007
- const isKnownVersion = (version) => HEX_VERSION.test(version) && version !== FORBIDDEN_VERSION;
8008
- const isWellFormedTraceparent = (value) => {
8009
- const fields = value.split("-");
8010
- return [
8011
- acceptsFieldCount(fieldAt(fields, 0), fields.length),
8012
- isKnownVersion(fieldAt(fields, 0)),
8013
- isNonZeroHex(HEX_TRACE_ID, fieldAt(fields, 1)),
8014
- isNonZeroHex(HEX_SPAN_ID, fieldAt(fields, 2)),
8015
- HEX_FLAGS.test(fieldAt(fields, 3))
8016
- ].every((check) => check);
8017
- };
8018
- const partsOf = (value) => {
8019
- const fields = value.split("-");
8020
- return {
8021
- version: fieldAt(fields, 0),
8022
- traceId: fieldAt(fields, 1),
8023
- spanId: fieldAt(fields, 2),
8024
- traceFlags: Number.parseInt(fieldAt(fields, 3), 16)
8025
- };
8026
- };
8027
- const formatOf = (parts) => `${parts.version}-${parts.traceId}-${parts.spanId}-${(parts.traceFlags & 255).toString(16).padStart(2, "0")}`;
8028
- const malformedTraceparent = (value) => new SchemaIssue.InvalidValue({ message: "expected a W3C traceparent: version-traceId-spanId-flags" }, value);
8029
- const decodeParts = SchemaGetter.transformEffect((value) => Boolean$1$1.match(isWellFormedTraceparent(value), {
8030
- onTrue: () => Effect$1.succeed(partsOf(value)),
8031
- onFalse: () => Effect$1.fail(malformedTraceparent(value))
8032
- }));
8033
- const encodeText = SchemaGetter.transform(formatOf);
8034
- const Traceparent = S.String.pipe(S.decodeTo(TraceparentPartsSchema, SchemaTransformation.makeTransformation({
8035
- decode: decodeParts,
8036
- encode: encodeText
8037
- })));
8038
8077
  const TraceContextReference = Context.Reference("@systemfsoftware/stryker-js-plugin-interface/TraceContextReference", { defaultValue: () => Option$1.none() });
8039
- var Trace_exports = /* @__PURE__ */ __exportAll$1({
8078
+ var Trace_exports = /* @__PURE__ */ __exportAll({
8040
8079
  PropagatedTrace: () => PropagatedTrace,
8041
8080
  TraceContextMiddleware: () => TraceContextMiddleware,
8042
8081
  TraceContextPartsSchema: () => TraceContextPartsSchema,
8043
8082
  TraceContextReference: () => TraceContextReference,
8044
8083
  Traceparent: () => Traceparent,
8045
8084
  TraceparentHeader: () => TraceparentHeader,
8085
+ Tracestate: () => Tracestate,
8046
8086
  TracestateHeader: () => TracestateHeader
8047
8087
  });
8048
8088
  //#endregion
8049
- //#region src/run-event.schema.ts
8050
- const RunPhase = S.Literals([
8051
- "prepare",
8052
- "instrument",
8053
- "dry-run",
8054
- "mutation-test"
8055
- ]);
8056
- const OutputMode = S.Literals(["human", "machine"]);
8057
- const ModeSignal = S.Literals([
8058
- "flag",
8059
- "env",
8060
- "tty",
8061
- "agent",
8062
- "tool"
8063
- ]);
8064
- var RunStarted = class extends S.TaggedClass()("stream", {
8065
- schemaVersion: S.String,
8066
- runId: S.String,
8067
- mode: OutputMode,
8068
- signal: ModeSignal
8069
- }) {};
8070
- var PhaseEntered = class extends S.TaggedClass()("phase", {
8071
- phase: RunPhase,
8072
- elapsedMs: Report_exports.NonNegativeFinite
8073
- }) {};
8074
- var PlanKnown = class extends S.TaggedClass()("plan", { total: Report_exports.NonNegativeInt }) {};
8075
- var RunMutantTested = class extends S.TaggedClass()("mutant", {
8076
- id: S.String,
8077
- status: Mutant_exports.MutantStatusSchema,
8078
- file: S.String,
8079
- location: Mutant_exports.LocationSchema,
8080
- mutator: S.String,
8081
- replacement: S.NullOr(S.String),
8082
- completed: Report_exports.NonNegativeInt,
8083
- total: Report_exports.NonNegativeInt
8084
- }) {};
8085
- var Heartbeat = class extends S.TaggedClass()("tick", {
8086
- elapsedMs: Report_exports.NonNegativeFinite,
8087
- completed: Report_exports.NonNegativeInt,
8088
- total: S.NullOr(Report_exports.NonNegativeInt)
8089
- }) {};
8090
- const VerdictThresholdsValuesSchema = S.Struct({
8091
- high: Report_exports.Percentage,
8092
- low: Report_exports.Percentage,
8093
- break: S.NullOr(Report_exports.Percentage)
8094
- });
8095
- const isVerdictThresholds = (value) => S.is(VerdictThresholdsValuesSchema)(value) && value.low <= value.high;
8096
- /**
8097
- * The pair is *built* ordered — a drawn pair is sorted — rather than drawn at
8098
- * random and discarded until it happens to be ordered. The invariant lives on
8099
- * the declaration because a filter over the pair cannot express `low <= high`
8100
- * in the generation-constraint vocabulary, and only a declaration carries a
8101
- * `toCodecArbitrary` derivation. The struct stays the wire side, so decoding
8102
- * keeps its field paths.
8103
- */
8104
- const OrderedVerdictThresholds = S.declare(isVerdictThresholds, {
8105
- message: "expected thresholds where low <= high",
8106
- toCodecArbitrary: () => S.link()(VerdictThresholdsValuesSchema, {
8107
- decode: SchemaGetter.transform(({ break: breaking, high, low }) => ({
8108
- break: breaking,
8109
- high: Math.max(high, low),
8110
- low: Math.min(high, low)
8111
- })),
8112
- encode: SchemaGetter.transform((thresholds) => thresholds)
8113
- })
8114
- });
8115
- const VerdictThresholds = VerdictThresholdsValuesSchema.pipe(S.decodeTo(OrderedVerdictThresholds, SchemaTransformation.passthrough()));
8116
- const VerdictMutant = S.Struct({
8117
- id: S.String,
8118
- file: S.String,
8119
- location: Mutant_exports.LocationSchema,
8120
- mutator: S.String,
8121
- replacement: S.NullOr(S.String),
8122
- status: Mutant_exports.MutantStatusSchema
8123
- });
8124
- var VerdictReached = class extends S.TaggedClass()("verdict", {
8125
- schemaVersion: S.String,
8126
- runId: S.String,
8127
- mode: OutputMode,
8128
- signal: ModeSignal,
8129
- score: S.NullOr(Report_exports.Percentage),
8130
- thresholds: VerdictThresholds,
8131
- reportFile: S.NullOr(S.String),
8132
- counts: Report_exports.Metrics,
8133
- mutants: S.Array(VerdictMutant)
8134
- }) {};
8135
- const FrameworkContributionRow = S.Struct({
8136
- name: S.String,
8137
- formatId: S.String,
8138
- extensions: S.Array(S.String)
8139
- });
8140
- const FrameworkModuleRow = S.Struct({
8141
- moduleName: S.String,
8142
- contributions: S.Array(FrameworkContributionRow)
8143
- });
8144
- const FormatClaimShadowingRow = S.Struct({
8145
- extension: S.String,
8146
- winner: S.String,
8147
- loser: S.String
8148
- });
8149
- var PluginsReported = class extends S.TaggedClass()("plugins", {
8150
- modules: S.Array(FrameworkModuleRow),
8151
- shadowings: S.Array(FormatClaimShadowingRow)
8152
- }) {};
8153
- const FormatRegistryRow = S.Struct({
8154
- extension: S.String,
8155
- formatId: S.String,
8156
- ownerModule: S.String,
8157
- language: S.String
8158
- });
8159
- var FormatRegistryResolved = class extends S.TaggedClass()("formats", { rows: S.Array(FormatRegistryRow) }) {};
8160
- const SkippedFileRow = S.Struct({
8161
- file: S.String,
8162
- extension: S.String,
8163
- reason: S.String
8164
- });
8165
- var SkippedReported = class extends S.TaggedClass()("skipped", { files: S.Array(SkippedFileRow) }) {};
8166
- const PluginFailureReason = S.Literals([
8167
- "PeerMissing",
8168
- "PeerVersionUnsupported",
8169
- "PeerUnrecognized",
8170
- "InvalidContribution",
8171
- "ImportFailed"
8172
- ]);
8173
- var RunFailed = class extends S.TaggedClass()("error", {
8174
- schemaVersion: S.String,
8175
- code: S.Finite,
8176
- error: S.String,
8177
- remediation: S.String,
8178
- reason: S.NullOr(PluginFailureReason)
8179
- }) {};
8180
- var HelpRendered = class extends S.TaggedClass()("help", {
8181
- schemaVersion: S.String,
8182
- code: S.Literals([0]),
8183
- help: S.String
8184
- }) {};
8185
- const RunEvent = Object.assign(S.Union([
8186
- RunStarted,
8187
- PhaseEntered,
8188
- PlanKnown,
8189
- RunMutantTested,
8190
- Heartbeat,
8191
- PluginsReported,
8192
- FormatRegistryResolved,
8193
- SkippedReported,
8194
- VerdictReached,
8195
- RunFailed,
8196
- HelpRendered
8197
- ]), { QUEUE_BOUND: 256 });
8198
- S.TaggedClass()("RunCommand", {
8199
- cliOptionsJson: S.String,
8200
- targetMutatePatterns: S.Array(S.String)
8201
- });
8202
- S.TaggedClass()("RunOutput", {
8203
- verdictJson: S.String,
8204
- exitCode: S.Finite
8205
- });
8206
- var RunDecodeError = class extends S.TaggedError()("RunDecodeError", { message: S.String }) {};
8207
- var RunReadError = class extends S.TaggedError()("RunReadError", { message: S.String }) {};
8208
- S.TaggedError()("RunWriteError", { message: S.String });
8209
- var PlanMutationRunCommand = class extends S.TaggedClass()("PlanMutationRunCommand", {
8210
- configMutatePatterns: S.Array(S.String),
8211
- configMutatorNames: S.Array(S.String),
8212
- targetMutatePatterns: S.Array(S.String),
8213
- availableMutators: S.Array(S.String)
8214
- }) {};
8215
- var MutationRunPlan = class extends S.TaggedClass()("MutationRunPlan", {
8216
- mutatePatterns: S.Array(S.String),
8217
- mutatorNames: S.Array(S.String)
8218
- }) {};
8219
- //#endregion
8220
- //#region src/Run.schema.ts
8221
- const TypeId = "~stryker/mutation-run/StageError";
8222
- var StageError = class extends S.TaggedError(TypeId)("StageError", {
8223
- stage: S.Literals([
8224
- "prepare",
8225
- "instrument",
8226
- "dryRun",
8227
- "dryRunNoTests",
8228
- "mutationTest"
8229
- ]),
8230
- reason: S.String,
8231
- cause: S.optional(S.Defect()),
8232
- command: S.optional(S.String)
8233
- }) {
8234
- [TypeId] = TypeId;
8235
- get exitClass() {
8236
- return STAGE_PRESENTATION[this.stage].exitClass;
8237
- }
8238
- get message() {
8239
- const failure = `${STAGE_PRESENTATION[this.stage].label} failed: ${this.reason}`;
8240
- return Match.value(this.command).pipe(Match.when(Match.nonEmptyString, (present) => `${failure} (command: ${present})`), Match.orElse(() => failure));
8241
- }
8242
- };
8243
- const STAGE_PRESENTATION = {
8244
- prepare: {
8245
- label: "Prepare",
8246
- exitClass: "ConfigError"
8247
- },
8248
- instrument: {
8249
- label: "Instrument",
8250
- exitClass: "RuntimeError"
8251
- },
8252
- dryRun: {
8253
- label: "Dry run",
8254
- exitClass: "RuntimeError"
8255
- },
8256
- dryRunNoTests: {
8257
- label: "Dry run",
8258
- exitClass: "ConfigError"
8259
- },
8260
- mutationTest: {
8261
- label: "Mutation testing",
8262
- exitClass: "RuntimeError"
8263
- }
8264
- };
8265
- var PrepareError = class extends S.TaggedError()("PrepareError", {
8266
- stage: S.Literal("prepare"),
8267
- reason: S.String
8268
- }) {
8269
- get message() {
8270
- return this.reason;
8271
- }
8272
- };
8273
- //#endregion
8274
- export { Plugin_exports as A, RunReadError as C, VerdictReached as D, SkippedReported as E, ErrorText_exports as F, Format_exports as I, Instrument_exports as L, Reporter_exports as M, TestRunner_exports as N, Checker_exports as O, Trace_exports as P, Mutant_exports as R, RunPhase as S, SkippedFileRow as T, PluginsReported as _, FormatRegistryRow as a, RunFailed as b, Heartbeat as c, MutationRunPlan as d, OutputMode as f, PluginFailureReason as g, PlanMutationRunCommand as h, FormatRegistryResolved as i, Report_exports as j, Options_exports as k, HelpRendered as l, PlanKnown as m, StageError as n, FrameworkContributionRow as o, PhaseEntered as p, FormatClaimShadowingRow as r, FrameworkModuleRow as s, PrepareError as t, ModeSignal as u, RunDecodeError as v, RunStarted as w, RunMutantTested as x, RunEvent as y };
8089
+ export { Reporter_exports as a, ErrorText_exports as c, Mutant_exports as d, Report_exports as i, Format_exports as l, Options_exports as n, TestRunner_exports as o, Plugin_exports as r, Trace_exports as s, Checker_exports as t, Instrument_exports as u };