@systemfsoftware/stryker-js 13.1.0 → 14.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.
@@ -0,0 +1,1473 @@
1
+ import * as S from "effect/Schema";
2
+ import * as Option$1 from "effect/Option";
3
+ import * as Order from "effect/Order";
4
+ import * as SchemaGetter$1 from "effect/SchemaGetter";
5
+ import * as SchemaTransformation$1 from "effect/SchemaTransformation";
6
+ import * as Context from "effect/Context";
7
+ import { Effect, Schema, SchemaGetter, SchemaIssue, SchemaTransformation } from "effect";
8
+ import * as Effect$1 from "effect/Effect";
9
+ import * as Boolean$1 from "effect/Boolean";
10
+ import * as Rpc from "effect/unstable/rpc/Rpc";
11
+ import * as RpcGroup from "effect/unstable/rpc/RpcGroup";
12
+ import * as RpcMiddleware from "effect/unstable/rpc/RpcMiddleware";
13
+ import * as Match$1 from "effect/Match";
14
+ import { dual } from "effect/Function";
15
+ import * as Record$1 from "effect/Record";
16
+ import * as Predicate$1 from "effect/Predicate";
17
+ //#region ../stryker-js-plugin-interface/dist/rolldown-runtime-D7D4PA-g.mjs
18
+ var __defProp = Object.defineProperty;
19
+ var __exportAll = (all, no_symbols) => {
20
+ let target = {};
21
+ for (var name in all) __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true
24
+ });
25
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
26
+ return target;
27
+ };
28
+ //#endregion
29
+ //#region ../stryker-js-plugin-interface/dist/index.mjs
30
+ /** A 1-based line: the first line of a file is line 1. */
31
+ const Line = S.Int.check(S.isGreaterThanOrEqualTo(1));
32
+ /** A 1-based column: the first character of a line is column 1. */
33
+ const Column = S.Int.check(S.isGreaterThanOrEqualTo(1));
34
+ const Position$1 = S.Struct({
35
+ line: Line,
36
+ column: Column
37
+ });
38
+ const positionOrder = Order.combine(Order.mapInput(Order.Number, (position) => position.line), Order.mapInput(Order.Number, (position) => position.column));
39
+ const inOrder = (order) => (ends) => ({
40
+ start: Order.min(order)(ends.start, ends.end),
41
+ end: Order.max(order)(ends.start, ends.end)
42
+ });
43
+ const notReversed = (order) => (ends) => Order.isLessThanOrEqualTo(order)(ends.start, ends.end);
44
+ const PositionEndsSchema = S.Struct({
45
+ start: Position$1,
46
+ end: Position$1
47
+ });
48
+ const OrderedEnds = S.declare((value) => S.is(PositionEndsSchema)(value) && notReversed(positionOrder)(value), {
49
+ expected: "a location whose end is not before its start",
50
+ toCodecArbitrary: () => S.link()(PositionEndsSchema, {
51
+ decode: SchemaGetter$1.transform(inOrder(positionOrder)),
52
+ encode: SchemaGetter$1.transform((ends) => ends)
53
+ })
54
+ });
55
+ const Location$1 = PositionEndsSchema.pipe(S.decodeTo(OrderedEnds, SchemaTransformation$1.passthrough()));
56
+ const OpenEndsSchema = S.Struct({
57
+ start: Position$1,
58
+ end: S.optional(Position$1)
59
+ });
60
+ const closedEnds = (ends) => Option$1.map(Option$1.fromUndefinedOr(ends.end), (end) => ({
61
+ start: ends.start,
62
+ end
63
+ }));
64
+ const OrderedOpenEnds = S.declare((value) => S.is(OpenEndsSchema)(value) && Option$1.match(closedEnds(value), {
65
+ onNone: () => true,
66
+ onSome: notReversed(positionOrder)
67
+ }), {
68
+ expected: "a location whose end, when present, is not before its start",
69
+ toCodecArbitrary: () => S.link()(OpenEndsSchema, {
70
+ decode: SchemaGetter$1.transform((ends) => Option$1.getOrElse(Option$1.map(closedEnds(ends), inOrder(positionOrder)), () => ends)),
71
+ encode: SchemaGetter$1.transform((ends) => ends)
72
+ })
73
+ });
74
+ const OpenEndLocation$1 = OpenEndsSchema.pipe(S.decodeTo(OrderedOpenEnds, SchemaTransformation$1.passthrough()));
75
+ S.is(Line), S.is(Column), S.is(Location$1);
76
+ const MutantStatusSchema = S.Literals([
77
+ "Killed",
78
+ "Survived",
79
+ "NoCoverage",
80
+ "CompileError",
81
+ "RuntimeError",
82
+ "Timeout",
83
+ "Ignored",
84
+ "Pending"
85
+ ]);
86
+ const SurvivorStatusSchema = S.Literals(["Survived", "NoCoverage"]);
87
+ const RememberedStatusSchema = S.Literals([
88
+ "Survived",
89
+ "Killed",
90
+ "Timeout",
91
+ "NoCoverage",
92
+ "Ignored"
93
+ ]);
94
+ const EphemeralStatusSchema = S.Literals([
95
+ "CompileError",
96
+ "RuntimeError",
97
+ "Pending"
98
+ ]);
99
+ const ActionableStatusSchema = S.Literals([
100
+ "Survived",
101
+ "NoCoverage",
102
+ "Timeout",
103
+ "RuntimeError"
104
+ ]);
105
+ const MutantId = S.String.check(S.isPattern(/^[0-9a-f]{16}$/, { expected: "a 16-character lowercase hexadecimal mutant id" })).pipe(S.brand("MutantId"));
106
+ const MutatorNameGrammar = S.String.check(S.isPattern(/^(?:[a-z][a-z0-9]*(?:-[a-z0-9]+)*\/)?[A-Z][A-Za-z0-9]*$/, { expected: "a PascalCase mutator name, optionally prefixed by a lowercase kebab-case namespace and a slash" }));
107
+ const MutatorName = MutatorNameGrammar.pipe(S.brand("MutatorName"));
108
+ const CanonicalFileName = S.String.pipe(S.decodeTo(S.String.pipe(S.check(S.isPattern(/^[^\\]+$/)), S.brand("CanonicalFileName")), {
109
+ decode: SchemaGetter$1.transform((fileName) => fileName.replace(/\\/g, "/")),
110
+ encode: SchemaGetter$1.transform((canonical) => canonical)
111
+ }));
112
+ /**
113
+ * A mutant's file location in the mutation-testing-report-schema contract:
114
+ * 1-based line and 1-based column, the same base the JSON report and the
115
+ * machine stream emit. Every producer on the instrument path (node spans,
116
+ * embedded-region shifts) targets this base; no downstream layer converts.
117
+ */
118
+ const Mutant = S.TaggedStruct("Mutant", {
119
+ id: MutantId,
120
+ fileName: CanonicalFileName,
121
+ mutatorName: MutatorName,
122
+ replacement: S.String,
123
+ location: Location$1,
124
+ status: S.optional(MutantStatusSchema),
125
+ statusReason: S.optional(S.String),
126
+ coveredBy: S.String.pipe(S.Array, S.optional),
127
+ static: S.optional(S.Boolean),
128
+ testsCompleted: S.optional(S.Finite),
129
+ description: S.optional(S.String)
130
+ }).check(S.makeFilter((mutant) => mutant.statusReason === void 0 || mutant.status !== void 0, { message: "a mutant carries a status reason only together with a status" }));
131
+ const MutantFromUnknown = S.Unknown.pipe(S.decodeTo(Mutant));
132
+ const RunOptionsFields = {
133
+ timeout: S.Finite.pipe(S.check(S.isGreaterThanOrEqualTo(0))),
134
+ disableBail: S.Boolean
135
+ };
136
+ const MutantActivationSchema = S.Literals(["runtime", "static"]);
137
+ const HitCount = S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(0)));
138
+ const MutantRunOptionsSchema = S.Struct({
139
+ ...RunOptionsFields,
140
+ activeMutant: Mutant,
141
+ sandboxFileName: S.String,
142
+ mutantActivation: MutantActivationSchema,
143
+ reloadEnvironment: S.Boolean,
144
+ testFilter: S.String.pipe(S.Array, S.optionalKey),
145
+ priorKillerTestIds: S.String.pipe(S.Array, S.optionalKey),
146
+ hitLimit: S.optionalKey(HitCount)
147
+ });
148
+ const asMutantIdKeyed = (counts) => Object.fromEntries(Object.entries(counts).filter(([key]) => S.is(MutantId)(key)));
149
+ const asStringKeyed = (counts) => Object.fromEntries(Object.entries(counts));
150
+ const MutantIdKeyedHitCounts = S.Record(S.String, HitCount).pipe(S.check(S.makeFilter((counts) => {
151
+ const unknownKey = Object.keys(counts).find((key) => !S.is(MutantId)(key));
152
+ return unknownKey === void 0 ? void 0 : {
153
+ path: [unknownKey],
154
+ issue: `hit counts must be keyed by mutant ids, got '${unknownKey}'`
155
+ };
156
+ }, { arbitraryConstraint: { patterns: [{
157
+ source: "^[0-9a-f]{16}$",
158
+ flags: ""
159
+ }] } })), S.decodeTo(S.Record(MutantId, HitCount), {
160
+ decode: SchemaGetter$1.transform(asMutantIdKeyed),
161
+ encode: SchemaGetter$1.transform(asStringKeyed)
162
+ }));
163
+ const MutantCoverageSchema = S.Struct({
164
+ perTest: S.Record(S.String, MutantIdKeyedHitCounts),
165
+ static: MutantIdKeyedHitCounts
166
+ });
167
+ SurvivorStatusSchema.literals, RememberedStatusSchema.literals, EphemeralStatusSchema.literals, ActionableStatusSchema.literals;
168
+ const CheckerMutantWire = S.Struct({
169
+ id: MutantId,
170
+ fileName: CanonicalFileName,
171
+ mutatorName: MutatorName,
172
+ replacement: S.String,
173
+ location: Location$1
174
+ });
175
+ const CheckResultSchema = S.Union([S.Struct({ status: S.Literal("passed") }), S.Struct({
176
+ status: S.Literal("compileError"),
177
+ reason: S.String
178
+ })]).pipe(S.toTaggedUnion("status"));
179
+ const CheckStatus = S.Literals(CheckResultSchema.discriminants);
180
+ var CheckerFailed = class extends S.TaggedError()("CheckerFailed", {
181
+ cause: S.String,
182
+ checkerName: S.String,
183
+ mutantIds: S.Array(MutantId)
184
+ }) {
185
+ get message() {
186
+ const mutants = this.mutantIds.length === 0 ? "" : ` for mutants ${this.mutantIds.join(", ")}`;
187
+ return `Checker "${this.checkerName}" failed${mutants}: ${this.cause}`;
188
+ }
189
+ };
190
+ var Checker = class extends Context.Service()("@systemfsoftware/stryker-js-plugin-interface/Checker.service/Checker") {};
191
+ var Checker_exports = /* @__PURE__ */ __exportAll({
192
+ CheckResultSchema: () => CheckResultSchema,
193
+ CheckStatus: () => CheckStatus,
194
+ Checker: () => Checker,
195
+ CheckerFailed: () => CheckerFailed,
196
+ CheckerMutantWire: () => CheckerMutantWire
197
+ });
198
+ S.TaggedError()("EvaluatorFailed", { cause: S.Unknown });
199
+ Context.Service()("@systemfsoftware/stryker-js-plugin-interface/Evaluator.service/Evaluator");
200
+ const RULE_IDS = [
201
+ "arid-logging",
202
+ "arid-telemetry",
203
+ "arid-time",
204
+ "arid-config-default",
205
+ "arid-memoization",
206
+ "redundant-relational",
207
+ "equivalent-to-original",
208
+ "duplicate-at-site",
209
+ "ignore-static",
210
+ "directive",
211
+ "excluded-mutator",
212
+ "ignorer"
213
+ ];
214
+ const IgnoreRuleId = S.Literals(RULE_IDS);
215
+ const SEPARATOR = ": ";
216
+ const asLiteralPattern = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
217
+ const REASON_SOURCE = `^(?:${RULE_IDS.map(asLiteralPattern).join("|")})${SEPARATOR}[\\s\\S]*$`;
218
+ const IgnoreStatusReasonText = S.String.check(S.isPattern(new RegExp(REASON_SOURCE), { arbitraryConstraint: { patterns: [{
219
+ source: REASON_SOURCE,
220
+ flags: ""
221
+ }] } }));
222
+ const ReasonPartsSchema = S.Struct({
223
+ ruleId: IgnoreRuleId,
224
+ detail: S.String
225
+ });
226
+ const reasonPartsOf = (text) => Option$1.map(Option$1.fromNullishOr(RULE_IDS.find((ruleId) => text.startsWith(`${ruleId}${SEPARATOR}`))), (ruleId) => ({
227
+ ruleId,
228
+ detail: text.slice(ruleId.length + 2)
229
+ }));
230
+ const malformedReason = (text) => new SchemaIssue.InvalidValue({ message: `expected "<rule-id>${SEPARATOR}<detail>"` }, text);
231
+ const partsOf$1 = SchemaGetter.transformEffect((text) => Effect$1.fromOption(reasonPartsOf(text), () => malformedReason(text)));
232
+ const textOf$1 = SchemaGetter.transform((parts) => `${parts.ruleId}${SEPARATOR}${parts.detail}`);
233
+ const IgnoreStatusReason = IgnoreStatusReasonText.pipe(S.decodeTo(ReasonPartsSchema, SchemaTransformation.makeTransformation({
234
+ decode: partsOf$1,
235
+ encode: textOf$1
236
+ })));
237
+ const Id = S.String.check(S.isPattern(/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/, { expected: "a lowercase kebab-case catalog entry id" })).pipe(S.brand("MutatorCatalogId"));
238
+ const Tier = S.Literals(["default", "optIn"]);
239
+ const Definition = S.NonEmptyString;
240
+ /**
241
+ * `after` lists the replacement texts in the order the mutator emits them, and
242
+ * is empty when the entry must not fire on `before`.
243
+ */
244
+ const Example = S.Struct({
245
+ before: S.String,
246
+ after: S.Array(S.String)
247
+ });
248
+ const EntryShape = S.Struct({
249
+ id: Id,
250
+ name: MutatorName,
251
+ tier: Tier,
252
+ definition: Definition,
253
+ examples: S.Array(Example)
254
+ });
255
+ const carriesExamples = S.makeFilter((entry) => entry.examples.length === 0 ? `mutator catalog entry "${entry.id}" carries no examples` : void 0);
256
+ const carriesASnippet = S.makeFilter((entry) => {
257
+ return entry.examples.find((example) => example.before.length === 0) === void 0 ? void 0 : `mutator catalog entry "${entry.id}" carries an example with an empty before`;
258
+ });
259
+ const Entry = EntryShape.check(carriesExamples, carriesASnippet);
260
+ const Provider = S.String.check(S.isPattern(/^(?:stryker|[a-z][a-z0-9]*(?:-[a-z0-9]+)*)$/, { expected: "the stock provider \"stryker\" or a lowercase kebab-case plugin namespace" })).pipe(S.brand("MutatorProvider"));
261
+ const CatalogShape = S.Struct({
262
+ provider: Provider,
263
+ entries: S.NonEmptyArray(Entry)
264
+ });
265
+ const duplicatedValue = (values) => values.find((value, index) => values.indexOf(value) !== index);
266
+ const namespaceOf = (name) => {
267
+ const slash = name.indexOf("/");
268
+ return slash === -1 ? void 0 : name.slice(0, slash);
269
+ };
270
+ const entryIdsAreUnique = S.makeFilter((catalog) => {
271
+ const duplicated = duplicatedValue(catalog.entries.map((entry) => entry.id));
272
+ return duplicated === void 0 ? void 0 : `mutator catalog entries share the id "${duplicated}"`;
273
+ });
274
+ const entryNamesAreUnique = S.makeFilter((catalog) => {
275
+ const duplicated = duplicatedValue(catalog.entries.map((entry) => entry.name));
276
+ return duplicated === void 0 ? void 0 : `mutator catalog entries share the mutator name "${duplicated}"`;
277
+ });
278
+ const ownedByProvider = (provider, name) => {
279
+ const namespace = namespaceOf(name);
280
+ return provider === "stryker" ? namespace === void 0 : namespace === provider;
281
+ };
282
+ const providerOwnsEveryName = S.makeFilter((catalog) => {
283
+ const unowned = catalog.entries.find((entry) => !ownedByProvider(catalog.provider, entry.name));
284
+ return unowned === void 0 ? void 0 : `provider "${catalog.provider}" does not own the mutator name "${unowned.name}"`;
285
+ });
286
+ const Catalog = CatalogShape.check(entryIdsAreUnique, entryNamesAreUnique, providerOwnsEveryName);
287
+ var Mutant_exports = /* @__PURE__ */ __exportAll({
288
+ ActionableStatusSchema: () => ActionableStatusSchema,
289
+ CanonicalFileName: () => CanonicalFileName,
290
+ Column: () => Column,
291
+ EphemeralStatusSchema: () => EphemeralStatusSchema,
292
+ HitCount: () => HitCount,
293
+ IgnoreRuleId: () => IgnoreRuleId,
294
+ IgnoreStatusReason: () => IgnoreStatusReason,
295
+ IgnoreStatusReasonText: () => IgnoreStatusReasonText,
296
+ Line: () => Line,
297
+ Location: () => Location$1,
298
+ Mutant: () => Mutant,
299
+ MutantActivationSchema: () => MutantActivationSchema,
300
+ MutantCoverageSchema: () => MutantCoverageSchema,
301
+ MutantFromUnknown: () => MutantFromUnknown,
302
+ MutantId: () => MutantId,
303
+ MutantRunOptionsSchema: () => MutantRunOptionsSchema,
304
+ MutantStatusSchema: () => MutantStatusSchema,
305
+ MutatorName: () => MutatorName,
306
+ OpenEndLocation: () => OpenEndLocation$1,
307
+ Position: () => Position$1,
308
+ RememberedStatusSchema: () => RememberedStatusSchema,
309
+ RunOptionsFields: () => RunOptionsFields,
310
+ SurvivorStatusSchema: () => SurvivorStatusSchema,
311
+ duplicatedValue: () => duplicatedValue,
312
+ inOrder: () => inOrder,
313
+ notReversed: () => notReversed
314
+ });
315
+ var MutatorCatalog_exports = /* @__PURE__ */ __exportAll({
316
+ Catalog: () => Catalog,
317
+ Definition: () => Definition,
318
+ Entry: () => Entry,
319
+ Example: () => Example,
320
+ Id: () => Id,
321
+ Name: () => MutatorName,
322
+ Provider: () => Provider,
323
+ Tier: () => Tier
324
+ });
325
+ const isMutator = (value) => typeof value === "function";
326
+ const implementsNothing = () => [];
327
+ const mutatorArbitrary = Schema.link()(Schema.Null, {
328
+ decode: SchemaGetter.transform(() => implementsNothing),
329
+ encode: SchemaGetter.transform(() => null)
330
+ });
331
+ const Implementation = Schema.declare(isMutator, { toCodecArbitrary: () => mutatorArbitrary });
332
+ const ProviderEntry = Schema.Struct({
333
+ id: Id,
334
+ name: MutatorName,
335
+ tier: Tier,
336
+ definition: Definition,
337
+ examples: Schema.NonEmptyArray(Example),
338
+ implementation: Implementation
339
+ });
340
+ const Contribution = Schema.Struct({
341
+ namespace: Provider,
342
+ entries: Schema.NonEmptyArray(ProviderEntry)
343
+ });
344
+ var MutatorProvider_exports = /* @__PURE__ */ __exportAll({
345
+ Contribution: () => Contribution,
346
+ Implementation: () => Implementation,
347
+ ProviderEntry: () => ProviderEntry
348
+ });
349
+ const statusBuckets = {
350
+ Detected: ["Killed", "Timeout"],
351
+ Undetected: ["Survived", "NoCoverage"],
352
+ Invalid: ["CompileError", "RuntimeError"],
353
+ Untested: ["Ignored", "Pending"]
354
+ };
355
+ const DetectedStatus = S.Literals(statusBuckets.Detected);
356
+ const UndetectedStatus = S.Literals(statusBuckets.Undetected);
357
+ const InvalidStatus = S.Literals(statusBuckets.Invalid);
358
+ const UntestedStatus = S.Literals(statusBuckets.Untested);
359
+ const NonNegativeInt = S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(0)));
360
+ const NonNegativeFinite = S.Finite.pipe(S.check(S.isGreaterThanOrEqualTo(0)));
361
+ const Percentage = S.Finite.pipe(S.check(S.isBetween({
362
+ minimum: 0,
363
+ maximum: 100
364
+ })));
365
+ const MutationScore = S.TaggedUnion({
366
+ Scored: { percentage: Percentage },
367
+ Unscored: {}
368
+ });
369
+ const StaticClassSummarySchema = S.Struct({
370
+ count: NonNegativeInt,
371
+ costMs: NonNegativeFinite
372
+ });
373
+ const scorePercentageOf = (counts) => counts.counted > 0 ? Option$1.some(counts.detected / counts.counted * 100) : Option$1.none();
374
+ var Metrics = class extends S.Class("Metrics")({
375
+ pending: NonNegativeInt,
376
+ killed: NonNegativeInt,
377
+ timeout: NonNegativeInt,
378
+ survived: NonNegativeInt,
379
+ noCoverage: NonNegativeInt,
380
+ runtimeErrors: NonNegativeInt,
381
+ compileErrors: NonNegativeInt,
382
+ ignored: NonNegativeInt
383
+ }) {
384
+ get totalDetected() {
385
+ return this.timeout + this.killed;
386
+ }
387
+ get totalUndetected() {
388
+ return this.survived + this.noCoverage;
389
+ }
390
+ get totalCovered() {
391
+ return this.totalDetected + this.survived;
392
+ }
393
+ get totalValid() {
394
+ return this.totalUndetected + this.totalDetected;
395
+ }
396
+ get totalInvalid() {
397
+ return this.runtimeErrors + this.compileErrors;
398
+ }
399
+ get totalMutants() {
400
+ return this.totalValid + this.totalInvalid + this.ignored + this.pending;
401
+ }
402
+ get mutationScore() {
403
+ return Option$1.match(scorePercentageOf({
404
+ detected: this.totalDetected,
405
+ counted: this.totalValid
406
+ }), {
407
+ onNone: () => MutationScore.cases.Unscored.make({}),
408
+ onSome: (percentage) => MutationScore.cases.Scored.make({ percentage })
409
+ });
410
+ }
411
+ get mutationScoreBasedOnCoveredCode() {
412
+ return Option$1.match(scorePercentageOf({
413
+ detected: this.totalDetected,
414
+ counted: this.totalCovered
415
+ }), {
416
+ onNone: () => MutationScore.cases.Unscored.make({}),
417
+ onSome: (percentage) => MutationScore.cases.Scored.make({ percentage })
418
+ });
419
+ }
420
+ };
421
+ const MetricsSchema = Metrics;
422
+ const MetricsResultSchema = S.Struct({
423
+ name: S.String,
424
+ metrics: Metrics,
425
+ childResults: S.Array(S.suspend(() => MetricsResultSchema))
426
+ }).annotate({ identifier: "MetricsResult" });
427
+ const StrykerCoverageAnalysis = S.Literal("perTest");
428
+ const StrykerFileLogLevel = S.Literal("off");
429
+ const StrykerLogLevel = S.Literal("info");
430
+ const StrykerTempDirName = S.Literal(".stryker-tmp");
431
+ /**
432
+ * The Stryker option set, declared as ONE Effect Schema.
433
+ *
434
+ * Replaces the vendored `schema/stryker-core.json` codegen chain
435
+ * (`tasks/generate-stryker-core.mjs` → `src-generated/stryker-core.ts`): every
436
+ * option name, type, optionality and default is preserved, and
437
+ * the JSON Schema document is **derived** from
438
+ * `StrykerOptionsSchema` (no file read).
439
+ *
440
+ * Layering mirrors the original document:
441
+ * - objects without `additionalProperties: false` there (the option set
442
+ * itself, `commandRunner`, `clearTextReporter`, `warnings`) are open here —
443
+ * `S.StructWithRest` with a `Record<string, unknown>` index keeps arbitrary
444
+ * plugin-proposed keys and makes the decoded type carry
445
+ * `[k: string]: unknown`;
446
+ * - objects with `additionalProperties: false` (`htmlReporter`, `jsonReporter`,
447
+ * `thresholds`, `mutator`) are closed here.
448
+ *
449
+ * `dashboard` and `eventReporter` are absent: the reporters they configured were
450
+ * removed, and the removed-option check rejects both names. Declaring them here
451
+ * with defaults meant the default option set carried two options the very next
452
+ * validation step refused - invisible only while the defaults were filled by a
453
+ * separate engine that happened not to inject them.
454
+ */
455
+ /** Open object: fixed fields plus an index signature accepting arbitrary plugin keys. */
456
+ const openStruct = (fields) => S.StructWithRest(S.Struct(fields), [S.Record(S.String, S.Unknown)]);
457
+ /**
458
+ * Field that decodes to a value but defaults when the key is absent.
459
+ *
460
+ * The default is typed by the schema's ENCODED side, which is what
461
+ * `withDecodingDefaultKey` consumes: a whole-object option can therefore default
462
+ * to `{}` exactly when every field inside it carries its own default, and
463
+ * the compiler decides that rather than the author asserting it.
464
+ *
465
+ * The annotation is applied to the schema BEFORE the default transform wraps it.
466
+ * Annotating the wrapper instead leaves `default` off the derived JSON Schema
467
+ * document, so a consumer filling defaults from that document (ajv
468
+ * `useDefaults`) silently injects nothing.
469
+ */
470
+ const defaulted = (schema, defaultValue) => {
471
+ const annotated = schema.annotate({ default: defaultValue });
472
+ return S.withDecodingDefaultKey(Effect.succeed(defaultValue))(annotated);
473
+ };
474
+ const LogLevel = S.Literals([
475
+ "off",
476
+ "fatal",
477
+ "error",
478
+ "warn",
479
+ "info",
480
+ "debug",
481
+ "trace"
482
+ ]);
483
+ const CoverageAnalysisMode = S.Literals([
484
+ "off",
485
+ "all",
486
+ "perTest"
487
+ ]);
488
+ const ReportType = S.Literals(["full", "mutationScore"]);
489
+ const PackageManager = S.Literals([
490
+ "npm",
491
+ "yarn",
492
+ "pnpm"
493
+ ]);
494
+ const MutantSetPolicy = S.Literals(["default", "full"]);
495
+ const CommandRunnerOptionsSchema = openStruct({ command: defaulted(S.String, "npm test") });
496
+ const ClearTextReporterOptions = openStruct({
497
+ allowColor: defaulted(S.Boolean, true),
498
+ allowEmojis: defaulted(S.Boolean, false),
499
+ logTests: defaulted(S.Boolean, true),
500
+ maxTestsToLog: defaulted(NonNegativeInt, 3),
501
+ reportTests: defaulted(S.Boolean, true),
502
+ reportMutants: defaulted(S.Boolean, true),
503
+ reportScoreTable: defaulted(S.Boolean, true),
504
+ skipFull: defaulted(S.Boolean, false)
505
+ });
506
+ const HtmlReporterOptions = S.Struct({ fileName: defaulted(S.String, "reports/mutation/mutation.html") });
507
+ const JsonReporterOptions = S.Struct({ fileName: defaulted(S.String, "reports/mutation/mutation.json") });
508
+ const MutationScoreThresholdsValuesSchema = S.Struct({
509
+ high: defaulted(Percentage, 80),
510
+ low: defaulted(Percentage, 60),
511
+ break: defaulted(S.NullOr(Percentage), null)
512
+ });
513
+ const OrderedThresholdsValuesSchema = S.Struct({
514
+ high: Percentage,
515
+ low: Percentage,
516
+ break: S.NullOr(Percentage)
517
+ });
518
+ const isOrderedThresholds = (value) => S.is(OrderedThresholdsValuesSchema)(value) && value.low <= value.high;
519
+ const OrderedThresholds = S.declare(isOrderedThresholds, {
520
+ message: "a mutation score threshold pair has low at or below high",
521
+ toCodecArbitrary: () => S.link()(OrderedThresholdsValuesSchema, {
522
+ decode: SchemaGetter.transform(({ break: breaking, high, low }) => ({
523
+ break: breaking,
524
+ high: Math.max(high, low),
525
+ low: Math.min(high, low)
526
+ })),
527
+ encode: SchemaGetter.transform((thresholds) => thresholds)
528
+ })
529
+ });
530
+ const MutationScoreThresholdsSchema = MutationScoreThresholdsValuesSchema.pipe(S.decodeTo(OrderedThresholds, SchemaTransformation.passthrough()));
531
+ const MutatorDescriptor = S.Struct({
532
+ excludedMutations: defaulted(S.Array(MutatorNameGrammar), []),
533
+ optInMutations: defaulted(S.Array(MutatorNameGrammar), []),
534
+ mutantSetPolicy: defaulted(MutantSetPolicy, "default")
535
+ });
536
+ const SurfacingOptions = S.Struct({
537
+ perLine: defaulted(NonNegativeInt, 1),
538
+ perFile: defaulted(NonNegativeInt, 7)
539
+ });
540
+ const WarningOptions = openStruct({
541
+ unknownOptions: defaulted(S.Boolean, true),
542
+ preprocessorErrors: defaulted(S.Boolean, true),
543
+ unserializableOptions: defaulted(S.Boolean, true),
544
+ slow: defaulted(S.Boolean, true)
545
+ });
546
+ const ConcurrencyCount = S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(1)));
547
+ const ConcurrencyPercent = S.String.pipe(S.check(S.isPattern(/^(100|[1-9]?[0-9])%$/)));
548
+ const pluginSpecifierArbitrary = S.link()(S.Literals([
549
+ "file:///project/node_modules/@systemfsoftware/stryker-js-angular/index.mjs",
550
+ "file:///home/user/project/plugins/custom-plugin.mjs",
551
+ "effect",
552
+ "@systemfsoftware/stryker-js-angular",
553
+ "@systemfsoftware/stryker-js-svelte",
554
+ "my-plugin",
555
+ "@scope/my-plugin/sub/entry",
556
+ "my-plugin/sub"
557
+ ]), {
558
+ decode: SchemaGetter.transform((sample) => sample),
559
+ encode: SchemaGetter.transform((sample) => sample)
560
+ });
561
+ const PluginFileUrl = S.declare((value) => typeof value === "string" && /^(?:file:\/\/\/\S+|(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*(?:\/(?!\.\.?\/)[^/\s]+)*)$/.test(value), { toCodecArbitrary: () => pluginSpecifierArbitrary });
562
+ const TestRunnerCustomConfigSchema = S.Struct({
563
+ plugin: PluginFileUrl,
564
+ nodeArgs: S.String.pipe(S.Array, S.optionalKey),
565
+ options: S.optionalKey(S.Record(S.String, S.Unknown))
566
+ });
567
+ const TestRunnerConfigSchema = S.Union([S.String, TestRunnerCustomConfigSchema]);
568
+ const AnyNonStringTestRunner = S.declare((value) => typeof value !== "string", { message: "expected a custom test runner config" });
569
+ const isCustomTestRunner = S.is(AnyNonStringTestRunner);
570
+ const CheckerCustomConfigSchema = S.Struct({
571
+ plugin: PluginFileUrl,
572
+ nodeArgs: S.String.pipe(S.Array, S.optionalKey),
573
+ options: S.optionalKey(S.Record(S.String, S.Unknown))
574
+ });
575
+ const CheckerEntryConfigSchema = CheckerCustomConfigSchema;
576
+ const StrykerOptionsSchema = S.StructWithRest(S.Struct({
577
+ allowConsoleColors: defaulted(S.Boolean, true),
578
+ buildCommand: S.optionalKey(S.String),
579
+ checkers: defaulted(S.Array(CheckerEntryConfigSchema), []),
580
+ checkerNodeArgs: defaulted(S.Array(S.String), []),
581
+ concurrency: S.optionalKey(S.Union([ConcurrencyCount, ConcurrencyPercent])),
582
+ commandRunner: defaulted(CommandRunnerOptionsSchema, { command: "npm test" }),
583
+ coverageAnalysis: defaulted(CoverageAnalysisMode, StrykerCoverageAnalysis.literal),
584
+ clearTextReporter: defaulted(ClearTextReporterOptions, {
585
+ allowColor: true,
586
+ allowEmojis: false,
587
+ logTests: true,
588
+ maxTestsToLog: 3,
589
+ reportTests: true,
590
+ reportMutants: true,
591
+ reportScoreTable: true,
592
+ skipFull: false
593
+ }),
594
+ dryRunOnly: defaulted(S.Boolean, false),
595
+ ignorePatterns: defaulted(S.Array(S.String), []),
596
+ ignoreStatic: defaulted(S.Boolean, false),
597
+ incremental: defaulted(S.Boolean, false),
598
+ incrementalFile: defaulted(S.String, "reports/stryker-incremental.json"),
599
+ incrementalSources: defaulted(S.Array(S.String), []),
600
+ progressStreamFile: defaulted(S.String, "reports/mutation-stream.jsonl"),
601
+ since: S.optionalKey(S.String),
602
+ force: defaulted(S.Boolean, false),
603
+ fileLogLevel: defaulted(LogLevel, StrykerFileLogLevel.literal),
604
+ inPlace: defaulted(S.Boolean, false),
605
+ logLevel: defaulted(LogLevel, StrykerLogLevel.literal),
606
+ maxConcurrentTestRunners: defaulted(S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(1))), Number.MAX_SAFE_INTEGER),
607
+ maxTestRunnerReuse: defaulted(NonNegativeInt, 0),
608
+ 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)"]),
609
+ mutator: defaulted(MutatorDescriptor, {
610
+ excludedMutations: [],
611
+ optInMutations: [],
612
+ mutantSetPolicy: "default"
613
+ }),
614
+ surfacing: defaulted(SurfacingOptions, {
615
+ perLine: 1,
616
+ perFile: 7
617
+ }),
618
+ packageManager: S.optionalKey(PackageManager),
619
+ plugins: defaulted(S.Array(PluginFileUrl), []),
620
+ appendPlugins: defaulted(S.Array(PluginFileUrl), []),
621
+ reporters: defaulted(S.Array(S.String), [
622
+ "clear-text",
623
+ "progress",
624
+ "html"
625
+ ]),
626
+ htmlReporter: defaulted(HtmlReporterOptions, { fileName: "reports/mutation/mutation.html" }),
627
+ jsonReporter: defaulted(JsonReporterOptions, { fileName: "reports/mutation/mutation.json" }),
628
+ disableTypeChecks: defaulted(S.Union([S.Boolean, S.String]), true),
629
+ symlinkNodeModules: defaulted(S.Boolean, true),
630
+ tempDirName: defaulted(S.String, StrykerTempDirName.literal),
631
+ cleanTempDir: defaulted(S.Literals([
632
+ "always",
633
+ false,
634
+ true
635
+ ]), true),
636
+ testRunner: defaulted(TestRunnerConfigSchema, "vm"),
637
+ testRunnerNodeArgs: defaulted(S.Array(S.String), []),
638
+ thresholds: defaulted(MutationScoreThresholdsSchema, {
639
+ high: 80,
640
+ low: 60,
641
+ break: null
642
+ }),
643
+ timeoutFactor: defaulted(NonNegativeFinite, 1.5),
644
+ timeoutMS: defaulted(NonNegativeInt, 5e3),
645
+ dryRunTimeoutMinutes: defaulted(NonNegativeFinite, 5),
646
+ tsconfigFile: defaulted(S.String, "tsconfig.json"),
647
+ warnings: defaulted(S.Union([S.Boolean, WarningOptions]), true),
648
+ disableBail: defaulted(S.Boolean, false),
649
+ allowEmpty: defaulted(S.Boolean, false),
650
+ ignorers: defaulted(S.Array(PluginFileUrl), []),
651
+ testFiles: defaulted(S.Array(S.String), [])
652
+ }), [S.Record(S.String, S.Unknown)]);
653
+ var Options_exports = /* @__PURE__ */ __exportAll({
654
+ CheckerCustomConfigSchema: () => CheckerCustomConfigSchema,
655
+ CheckerEntryConfigSchema: () => CheckerEntryConfigSchema,
656
+ CommandRunnerOptionsSchema: () => CommandRunnerOptionsSchema,
657
+ CoverageAnalysisMode: () => CoverageAnalysisMode,
658
+ LogLevel: () => LogLevel,
659
+ MutantSetPolicy: () => MutantSetPolicy,
660
+ MutationScoreThresholdsSchema: () => MutationScoreThresholdsSchema,
661
+ PackageManager: () => PackageManager,
662
+ PluginFileUrl: () => PluginFileUrl,
663
+ ReportType: () => ReportType,
664
+ StrykerCoverageAnalysis: () => StrykerCoverageAnalysis,
665
+ StrykerFileLogLevel: () => StrykerFileLogLevel,
666
+ StrykerLogLevel: () => StrykerLogLevel,
667
+ StrykerOptionsSchema: () => StrykerOptionsSchema,
668
+ StrykerTempDirName: () => StrykerTempDirName,
669
+ TestRunnerConfigSchema: () => TestRunnerConfigSchema,
670
+ TestRunnerCustomConfigSchema: () => TestRunnerCustomConfigSchema,
671
+ isCustomTestRunner: () => isCustomTestRunner
672
+ });
673
+ const ExitCode = S.Int.pipe(S.check(S.isBetween({
674
+ minimum: 0,
675
+ maximum: 255
676
+ })));
677
+ const ExitClass = S.Literals([
678
+ "VerdictFail",
679
+ "ConfigError",
680
+ "RuntimeError",
681
+ "InternalError"
682
+ ]);
683
+ const BASELINE_EXIT_CODES = {
684
+ VerdictFail: 1,
685
+ ConfigError: 2,
686
+ RuntimeError: 3,
687
+ InternalError: 4
688
+ };
689
+ const CLASS_BY_BASELINE_CODE = {
690
+ 1: "VerdictFail",
691
+ 2: "ConfigError",
692
+ 3: "RuntimeError",
693
+ 4: "InternalError"
694
+ };
695
+ const codeOfClass = (exitClass) => BASELINE_EXIT_CODES[exitClass];
696
+ const classOfCode = (code) => CLASS_BY_BASELINE_CODE[code];
697
+ const BaselineExitCode = S.Literals([
698
+ 1,
699
+ 2,
700
+ 3,
701
+ 4
702
+ ]);
703
+ const ExitCodeFromClass = S.decodeTo(BaselineExitCode, SchemaTransformation.transform({
704
+ decode: codeOfClass,
705
+ encode: classOfCode
706
+ }))(ExitClass);
707
+ const Position = S.StructWithRest(S.Struct({
708
+ "line": S.Finite.annotate({ "examples": [4] }).check(S.isInt().annotate({ "expected": "an integer" })).check(S.isGreaterThanOrEqualTo(1).annotate({ "expected": "a value greater than or equal to 1" })),
709
+ "column": S.Finite.annotate({ "examples": [3] }).check(S.isInt().annotate({ "expected": "an integer" })).check(S.isGreaterThanOrEqualTo(1).annotate({ "expected": "a value greater than or equal to 1" }))
710
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
711
+ "title": "Position",
712
+ "description": "Position of a mutation. Both line and column start at one.",
713
+ "identifier": "position"
714
+ });
715
+ const Thresholds = S.StructWithRest(S.Struct({
716
+ "high": S.Finite.annotate({
717
+ "description": "Higher bound threshold.",
718
+ "examples": [80]
719
+ }).check(S.isInt().annotate({ "expected": "an integer" })).check(S.isGreaterThanOrEqualTo(0).annotate({ "expected": "a value greater than or equal to 0" })).check(S.isLessThanOrEqualTo(100).annotate({ "expected": "a value less than or equal to 100" })),
720
+ "low": S.Finite.annotate({
721
+ "description": "Lower bound threshold.",
722
+ "examples": [60]
723
+ }).check(S.isInt().annotate({ "expected": "an integer" })).check(S.isGreaterThanOrEqualTo(0).annotate({ "expected": "a value greater than or equal to 0" })).check(S.isLessThanOrEqualTo(100).annotate({ "expected": "a value less than or equal to 100" })),
724
+ "break": S.optionalKey(S.Union([S.Finite.check(S.isFinite().annotate({ "expected": "a finite number" })).check(S.isGreaterThanOrEqualTo(0).annotate({ "expected": "a value greater than or equal to 0" })).check(S.isLessThanOrEqualTo(100).annotate({ "expected": "a value less than or equal to 100" })), S.Null]).annotate({ "description": "The mutation score below which the run breaks. Null disables the break." }))
725
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
726
+ "title": "Thresholds",
727
+ "description": "Thresholds for the status of the reported application.",
728
+ "identifier": "thresholds"
729
+ });
730
+ const PerformanceStatistics = S.StructWithRest(S.Struct({
731
+ "setup": S.Finite.annotate({ "description": "Time it took to run the setup phase in milliseconds." }).check(S.isFinite().annotate({ "expected": "a finite number" })),
732
+ "initialRun": S.Finite.annotate({ "description": "Time it took to run the initial test phase (dry-run) in milliseconds." }).check(S.isFinite().annotate({ "expected": "a finite number" })),
733
+ "mutation": S.Finite.annotate({ "description": "Time it took to run the mutation test phase in milliseconds." }).check(S.isFinite().annotate({ "expected": "a finite number" }))
734
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
735
+ "title": "PerformanceStatistics",
736
+ "description": "The performance statistics per phase. Total time should be roughly equal to the sum of all these.",
737
+ "identifier": "performanceStatistics"
738
+ });
739
+ const BrandingInformation = S.StructWithRest(S.Struct({
740
+ "homepageUrl": S.String.annotate({
741
+ "description": "URL to the homepage of the framework.",
742
+ "format": "uri"
743
+ }),
744
+ "imageUrl": S.optionalKey(S.String.annotate({ "description": "URL to an image for the framework, can be a data URL." }))
745
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
746
+ "title": "BrandingInformation",
747
+ "description": "Extra branding information about the framework used.",
748
+ "identifier": "brandingInformation"
749
+ });
750
+ const Dependencies = S.Record(S.String, S.String).annotate({
751
+ "title": "Dependencies",
752
+ "description": "Dependencies used by the framework. Key-value pair of dependencies and their versions.",
753
+ "identifier": "dependencies"
754
+ });
755
+ const OSInformation = S.StructWithRest(S.Struct({
756
+ "description": S.optionalKey(S.String.annotate({
757
+ "description": "Human-readable description of the OS",
758
+ "examples": [
759
+ "Windows 10 Pro",
760
+ "Debian Buster",
761
+ "Ubuntu 20.04.1 LTS"
762
+ ]
763
+ })),
764
+ "platform": S.String.annotate({
765
+ "description": "Platform identifier",
766
+ "examples": ["linux", "win32"]
767
+ }),
768
+ "version": S.optionalKey(S.String.annotate({
769
+ "description": "Version of the OS or distribution",
770
+ "examples": ["10.0.19041"]
771
+ }))
772
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
773
+ "title": "OSInformation",
774
+ "identifier": "oSInformation"
775
+ });
776
+ const CpuInformation = S.StructWithRest(S.Struct({
777
+ "baseClock": S.optionalKey(S.Finite.annotate({ "description": "Clock speed in MHz" }).check(S.isFinite().annotate({ "expected": "a finite number" }))),
778
+ "logicalCores": S.Finite.check(S.isFinite().annotate({ "expected": "a finite number" })),
779
+ "model": S.optionalKey(S.String.annotate({ "examples": ["Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz"] }))
780
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
781
+ "title": "CpuInformation",
782
+ "identifier": "cpuInformation"
783
+ });
784
+ const RamInformation = S.StructWithRest(S.Struct({ "total": S.Finite.annotate({ "description": "The total RAM of the system that performed mutation testing in MB." }).check(S.isFinite().annotate({ "expected": "a finite number" })) }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
785
+ "title": "RamInformation",
786
+ "identifier": "ramInformation"
787
+ });
788
+ const Location = S.StructWithRest(S.Struct({
789
+ "start": Position,
790
+ "end": Position
791
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
792
+ "title": "Location",
793
+ "description": "A location with start and end. Start is inclusive, end is exclusive.",
794
+ "identifier": "location"
795
+ });
796
+ const OpenEndLocation = S.StructWithRest(S.Struct({
797
+ "start": Position,
798
+ "end": S.optionalKey(Position)
799
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
800
+ "title": "OpenEndLocation",
801
+ "description": "A location where \"end\" is not required. Start is inclusive, end is exclusive.",
802
+ "identifier": "openEndLocation"
803
+ });
804
+ const FrameworkInformation = S.StructWithRest(S.Struct({
805
+ "name": S.String.annotate({
806
+ "description": "Name of the framework used.",
807
+ "examples": [
808
+ "Stryker",
809
+ "Stryker4s",
810
+ "Stryker.NET",
811
+ "Infection PHP",
812
+ "Pitest"
813
+ ]
814
+ }),
815
+ "version": S.optionalKey(S.String.annotate({ "description": "Version of the framework." })),
816
+ "branding": S.optionalKey(BrandingInformation),
817
+ "dependencies": S.optionalKey(Dependencies)
818
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
819
+ "title": "FrameworkInformation",
820
+ "description": "Extra information about the framework used",
821
+ "identifier": "frameworkInformation"
822
+ });
823
+ const SystemInformation = S.StructWithRest(S.Struct({
824
+ "ci": S.Boolean.annotate({ "description": "Did mutation testing run in a Continuous Integration environment (pipeline)? Note that there is no way of knowing this for sure. It's done on a best-effort basis." }),
825
+ "os": S.optionalKey(OSInformation),
826
+ "cpu": S.optionalKey(CpuInformation),
827
+ "ram": S.optionalKey(RamInformation)
828
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
829
+ "title": "SystemInformation",
830
+ "description": "Information about the system that performed mutation testing.",
831
+ "identifier": "systemInformation"
832
+ });
833
+ const MutantResult = S.StructWithRest(S.Struct({
834
+ "coveredBy": S.optionalKey(S.Array(S.String).annotate({ "description": "The test ids that covered this mutant. If a mutation testing framework doesn't measure this information, it can simply be left out." })),
835
+ "description": S.optionalKey(S.String.annotate({
836
+ "description": "Description of the applied mutation.",
837
+ "examples": ["removed call to java/io/Writer::write"]
838
+ })),
839
+ "duration": S.optionalKey(S.Finite.annotate({ "description": "The net time it took to test this mutant in milliseconds. This is the time measurement without overhead from the mutation testing framework." }).check(S.isFinite().annotate({ "expected": "a finite number" }))),
840
+ "id": S.String.annotate({
841
+ "description": "Unique id, can be used to correlate this mutant across reports.",
842
+ "examples": ["321321"]
843
+ }),
844
+ "killedBy": S.optionalKey(S.Array(S.String).annotate({ "description": "The test ids that killed this mutant. It is a best practice to \"bail\" on first failing test, in which case you can fill this array with that one test." })),
845
+ "location": Location,
846
+ "mutatorName": S.String.annotate({
847
+ "description": "Category of the mutation.",
848
+ "examples": [
849
+ "ConditionalExpression",
850
+ "EqualityOperator",
851
+ "LogicalOperator"
852
+ ]
853
+ }),
854
+ "replacement": S.optionalKey(S.String.annotate({
855
+ "description": "Actual mutation that has been applied.",
856
+ "examples": [
857
+ "-",
858
+ "+",
859
+ "&&",
860
+ "||"
861
+ ]
862
+ })),
863
+ "static": S.optionalKey(S.Boolean.annotate({ "description": "A static mutant means that it was loaded once at during initialization, this makes it slow or even impossible to test, depending on the mutation testing framework." })),
864
+ "status": MutantStatusSchema.annotate({
865
+ "title": "MutantStatus",
866
+ "description": "Result of the mutation."
867
+ }),
868
+ "statusReason": S.optionalKey(S.String.annotate({ "description": "The reason that this mutant has this status. In the case of a killed mutant, this should be filled with the failure message(s) of the failing tests. In case of an error mutant, this should be filled with the error message." })),
869
+ "testsCompleted": S.optionalKey(S.Finite.annotate({ "description": "The number of tests actually completed in order to test this mutant. Can differ from \"coveredBy\" because of bailing a mutant test run after first failing test." }).check(S.isFinite().annotate({ "expected": "a finite number" })))
870
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
871
+ "title": "MutantResult",
872
+ "description": "Single mutation.",
873
+ "identifier": "mutantResult"
874
+ });
875
+ const TestDefinition = S.StructWithRest(S.Struct({
876
+ "id": S.String.annotate({ "description": "Unique id of the test, used to correlate what test killed a mutant." }),
877
+ "name": S.String.annotate({ "description": "Name of the test, used to display the test." }),
878
+ "location": S.optionalKey(OpenEndLocation)
879
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
880
+ "title": "TestDefinition",
881
+ "description": "A test in your test file.",
882
+ "identifier": "testDefinition"
883
+ });
884
+ const FileResult = S.StructWithRest(S.Struct({
885
+ "language": S.String.annotate({
886
+ "description": "Programming language that is used. Used for code highlighting, see https://prismjs.com/#examples.",
887
+ "examples": [
888
+ "javascript",
889
+ "typescript",
890
+ "cs",
891
+ "scala",
892
+ "java"
893
+ ]
894
+ }),
895
+ "mutants": S.Array(MutantResult).check(S.isUnique().annotate({ "expected": "an array with unique items" })),
896
+ "source": S.String.annotate({
897
+ "description": "Full source code of the original file (without mutants), this is used to display exactly what was changed for each mutant.",
898
+ "examples": ["using System; using....."]
899
+ })
900
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
901
+ "title": "FileResult",
902
+ "description": "Mutated file, with the relative path of the file as the key.",
903
+ "identifier": "fileResult"
904
+ });
905
+ const TestFile = S.StructWithRest(S.Struct({
906
+ "source": S.optionalKey(S.String.annotate({ "description": "Full source code of the test file, this can be used to display in the report." })),
907
+ "tests": S.Array(TestDefinition)
908
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
909
+ "title": "TestFile",
910
+ "description": "A file containing one or more tests",
911
+ "identifier": "testFile"
912
+ });
913
+ const FileResultDictionary = S.Record(S.String, FileResult).annotate({
914
+ "title": "FileResultDictionary",
915
+ "description": "All mutated files.",
916
+ "identifier": "fileResultDictionary"
917
+ });
918
+ const TestFileDefinitionDictionary = S.Record(S.String, TestFile).annotate({
919
+ "title": "TestFileDefinitionDictionary",
920
+ "description": "Test file definitions by file path OR class name.",
921
+ "identifier": "testFileDefinitionDictionary"
922
+ });
923
+ const MutationTestResult = S.StructWithRest(S.Struct({
924
+ "config": S.optionalKey(S.Record(S.String, S.Json.annotate({ "expected": "JSON value" })).annotate({ "description": "Free-format object that represents the configuration used to run mutation testing." })),
925
+ "schemaVersion": S.String.annotate({
926
+ "description": "Major version of this report. Used for compatibility.",
927
+ "examples": [
928
+ "1",
929
+ "2.0",
930
+ "2.0.0"
931
+ ]
932
+ }).check(S.isPattern(/* @__PURE__ */ new RegExp("^([1-2])(\\.(([1-9]\\d*)|0)){0,2}$")).annotate({ "expected": "a string matching the RegExp ^([1-2])(\\.(([1-9]\\d*)|0)){0,2}$" })),
933
+ "files": FileResultDictionary,
934
+ "testFiles": S.optionalKey(TestFileDefinitionDictionary),
935
+ "thresholds": Thresholds,
936
+ "projectRoot": S.optionalKey(S.String.annotate({
937
+ "description": "The optional location of the project root.",
938
+ "examples": ["C:\\Projects\\project-under-test", "/home/user/projects/project-under-test"]
939
+ })),
940
+ "performance": S.optionalKey(PerformanceStatistics),
941
+ "framework": S.optionalKey(FrameworkInformation),
942
+ "system": S.optionalKey(SystemInformation)
943
+ }), [S.Record(S.String, S.Json.annotate({ "expected": "JSON value" }))]).annotate({
944
+ "title": "MutationTestResult",
945
+ "description": "Schema for a mutation testing report."
946
+ });
947
+ const TestId = S.NonEmptyString.pipe(S.brand("TestId"));
948
+ const DryRunStatus = S.Literals([
949
+ "complete",
950
+ "error",
951
+ "timeout"
952
+ ]);
953
+ const TestStatus = S.Literals([
954
+ "success",
955
+ "failed",
956
+ "skipped"
957
+ ]);
958
+ const MutantRunStatus = S.Literals([
959
+ "killed",
960
+ "survived",
961
+ "timeout",
962
+ "error"
963
+ ]);
964
+ const TestResultBase = {
965
+ id: TestId,
966
+ name: S.String,
967
+ timeSpentMs: NonNegativeFinite,
968
+ fileName: S.optionalKey(S.String),
969
+ startPosition: S.optionalKey(Position$1)
970
+ };
971
+ const TestResultSchema = S.Union([
972
+ S.Struct({
973
+ ...TestResultBase,
974
+ status: S.Literal("failed"),
975
+ failureMessage: S.String
976
+ }),
977
+ S.Struct({
978
+ ...TestResultBase,
979
+ status: S.Literal("skipped")
980
+ }),
981
+ S.Struct({
982
+ ...TestResultBase,
983
+ status: S.Literal("success")
984
+ })
985
+ ]);
986
+ const DryRunResultSchema = S.Union([
987
+ S.Struct({
988
+ status: S.Literal("complete"),
989
+ tests: S.Array(TestResultSchema),
990
+ mutantCoverage: S.optionalKey(MutantCoverageSchema),
991
+ globalTestInputs: S.String.pipe(S.Array, S.optionalKey)
992
+ }),
993
+ S.Struct({
994
+ status: S.Literal("timeout"),
995
+ reason: S.optionalKey(S.String)
996
+ }),
997
+ S.Struct({
998
+ status: S.Literal("error"),
999
+ errorMessage: S.String
1000
+ })
1001
+ ]);
1002
+ const ExecutedTestSchema = S.Struct({
1003
+ id: TestId,
1004
+ timeSpentMs: NonNegativeFinite
1005
+ });
1006
+ const MutantRunResultSchema = S.Union([
1007
+ S.Struct({
1008
+ status: S.Literal("killed"),
1009
+ killedBy: S.Array(TestId),
1010
+ failureMessage: S.String,
1011
+ nrOfTests: NonNegativeInt,
1012
+ executedTests: S.Array(ExecutedTestSchema)
1013
+ }),
1014
+ S.Struct({
1015
+ status: S.Literal("survived"),
1016
+ nrOfTests: NonNegativeInt,
1017
+ executedTests: S.Array(ExecutedTestSchema)
1018
+ }),
1019
+ S.Struct({
1020
+ status: S.Literal("timeout"),
1021
+ reason: S.optionalKey(S.String)
1022
+ }),
1023
+ S.Struct({
1024
+ status: S.Literal("error"),
1025
+ errorMessage: S.String
1026
+ })
1027
+ ]);
1028
+ const CoverageAnalysisSchema = S.Literals([
1029
+ "off",
1030
+ "all",
1031
+ "perTest"
1032
+ ]);
1033
+ const DryRunOptionsSchema = S.Struct({
1034
+ ...RunOptionsFields,
1035
+ coverageAnalysis: CoverageAnalysisSchema,
1036
+ files: S.String.pipe(S.Array, S.optionalKey),
1037
+ testFiles: S.String.pipe(S.Array, S.optionalKey)
1038
+ });
1039
+ const TestRunnerCapabilitiesSchema = S.Struct({ reloadEnvironment: S.Boolean });
1040
+ var TestRunnerFailed = class extends S.TaggedError()("TestRunnerFailed", {
1041
+ cause: S.String,
1042
+ phase: S.Literals([
1043
+ "capabilities",
1044
+ "dispose",
1045
+ "dryRun",
1046
+ "init",
1047
+ "mutantRun"
1048
+ ]),
1049
+ runnerName: S.String
1050
+ }) {
1051
+ get message() {
1052
+ return `Test runner "${this.runnerName}" failed during ${this.phase}: ${this.cause}`;
1053
+ }
1054
+ };
1055
+ const RunTimingSchema = S.Struct({
1056
+ net: NonNegativeFinite,
1057
+ overhead: NonNegativeFinite
1058
+ });
1059
+ const ReporterPlanKind = S.Literals(["EarlyResult", "Run"]);
1060
+ const ReporterPlanDescriptorSchema = S.Struct({
1061
+ mutantId: MutantId,
1062
+ plan: ReporterPlanKind,
1063
+ netTime: NonNegativeFinite,
1064
+ reloadEnvironment: S.Boolean
1065
+ });
1066
+ var DryRunCompleted = class extends S.TaggedClass()("dryRunCompleted", {
1067
+ timing: RunTimingSchema,
1068
+ capabilities: TestRunnerCapabilitiesSchema,
1069
+ testCount: NonNegativeInt,
1070
+ tests: S.Array(TestResultSchema)
1071
+ }) {};
1072
+ var MutationTestingPlanReady = class extends S.TaggedClass()("mutationTestingPlanReady", {
1073
+ total: NonNegativeInt,
1074
+ plans: S.Array(ReporterPlanDescriptorSchema)
1075
+ }) {};
1076
+ var MutantTested = class extends S.TaggedClass()("mutantTested", {
1077
+ id: MutantId,
1078
+ status: MutantStatusSchema,
1079
+ fileName: CanonicalFileName,
1080
+ location: Location$1,
1081
+ mutatorName: MutatorName,
1082
+ replacement: S.NullOr(S.String),
1083
+ completed: NonNegativeInt,
1084
+ total: NonNegativeInt
1085
+ }) {};
1086
+ var MutationTestReportReady = class extends S.TaggedClass()("mutationTestReportReady", {
1087
+ report: MutationTestResult,
1088
+ metrics: MetricsResultSchema,
1089
+ static: S.optional(StaticClassSummarySchema)
1090
+ }) {};
1091
+ const ReporterEventUnion = S.Union([
1092
+ DryRunCompleted,
1093
+ MutationTestingPlanReady,
1094
+ MutantTested,
1095
+ MutationTestReportReady
1096
+ ]).pipe(S.toTaggedUnion("_tag"));
1097
+ const ReporterEventKind = S.Literals(ReporterEventUnion.discriminants);
1098
+ const ReporterEventSchema = S.toStandardSchemaV1(ReporterEventUnion);
1099
+ var ReporterFailed = class extends S.TaggedError()("ReporterFailed", {
1100
+ cause: S.String,
1101
+ event: ReporterEventKind,
1102
+ reporterName: S.String
1103
+ }) {
1104
+ get message() {
1105
+ return `Reporter "${this.reporterName}" failed while handling ${this.event}: ${this.cause}`;
1106
+ }
1107
+ };
1108
+ const TraceparentHeader = S.Literal("traceparent");
1109
+ const TracestateHeader = S.Literal("tracestate");
1110
+ const VERSION = S.String.pipe(S.check(S.isPattern(/^([0-9a-e][0-9a-f]|[0-9a-f][0-9a-e])$/)));
1111
+ 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)));
1112
+ 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)));
1113
+ const TraceContextPartsSchema = S.Struct({
1114
+ version: VERSION,
1115
+ traceId: TRACE_ID,
1116
+ spanId: SPAN_ID,
1117
+ traceFlags: S.Int.pipe(S.check(S.isBetween({
1118
+ minimum: 0,
1119
+ maximum: 255
1120
+ }))),
1121
+ traceState: S.optional(S.String)
1122
+ });
1123
+ const TraceparentPartsSchema = S.Struct({
1124
+ version: VERSION,
1125
+ traceId: TRACE_ID,
1126
+ spanId: SPAN_ID,
1127
+ traceFlags: S.Int.pipe(S.check(S.isBetween({
1128
+ minimum: 0,
1129
+ maximum: 255
1130
+ })))
1131
+ });
1132
+ const HEX_VERSION = /^[0-9a-f]{2}$/;
1133
+ const HEX_TRACE_ID = /^[0-9a-f]{32}$/;
1134
+ const HEX_SPAN_ID = /^[0-9a-f]{16}$/;
1135
+ const HEX_FLAGS = /^[0-9a-f]{2}$/;
1136
+ const ALL_ZERO = /^0+$/;
1137
+ const FORBIDDEN_VERSION = "ff";
1138
+ const CURRENT_VERSION = "00";
1139
+ const TRACEPARENT_FIELD_COUNT = 4;
1140
+ const fieldAt = (fields, index) => fields[index] ?? "";
1141
+ const isNonZeroHex = (pattern, value) => pattern.test(value) && !ALL_ZERO.test(value);
1142
+ const acceptsFieldCount = (version, count) => version !== CURRENT_VERSION || count === TRACEPARENT_FIELD_COUNT;
1143
+ const isKnownVersion = (version) => HEX_VERSION.test(version) && version !== FORBIDDEN_VERSION;
1144
+ const isWellFormedTraceparent = (value) => {
1145
+ const fields = value.split("-");
1146
+ return [
1147
+ acceptsFieldCount(fieldAt(fields, 0), fields.length),
1148
+ isKnownVersion(fieldAt(fields, 0)),
1149
+ isNonZeroHex(HEX_TRACE_ID, fieldAt(fields, 1)),
1150
+ isNonZeroHex(HEX_SPAN_ID, fieldAt(fields, 2)),
1151
+ HEX_FLAGS.test(fieldAt(fields, 3))
1152
+ ].every((check) => check);
1153
+ };
1154
+ const partsOf = (value) => {
1155
+ const fields = value.split("-");
1156
+ return {
1157
+ version: fieldAt(fields, 0),
1158
+ traceId: fieldAt(fields, 1),
1159
+ spanId: fieldAt(fields, 2),
1160
+ traceFlags: Number.parseInt(fieldAt(fields, 3), 16)
1161
+ };
1162
+ };
1163
+ const formatOf = (parts) => `${parts.version}-${parts.traceId}-${parts.spanId}-${(parts.traceFlags & 255).toString(16).padStart(2, "0")}`;
1164
+ const malformedTraceparent = (value) => new SchemaIssue.InvalidValue({ message: "expected a W3C traceparent: version-traceId-spanId-flags" }, value);
1165
+ const decodeParts = SchemaGetter.transformEffect((value) => Boolean$1.match(isWellFormedTraceparent(value), {
1166
+ onTrue: () => Effect$1.succeed(partsOf(value)),
1167
+ onFalse: () => Effect$1.fail(malformedTraceparent(value))
1168
+ }));
1169
+ const encodeText = SchemaGetter.transform(formatOf);
1170
+ const Traceparent = S.String.pipe(S.decodeTo(TraceparentPartsSchema, SchemaTransformation.makeTransformation({
1171
+ decode: decodeParts,
1172
+ encode: encodeText
1173
+ })));
1174
+ const TRACESTATE_MEMBER = "[a-z][_0-9a-z\\-*/]{0,255}=[\\x20-\\x2b\\x2d-\\x3c\\x3e-\\x7e]{0,255}";
1175
+ const TRACESTATE_OWS = "[ \\t]*";
1176
+ const TRACESTATE = new RegExp(`^${TRACESTATE_MEMBER}(${TRACESTATE_OWS},${TRACESTATE_OWS}${TRACESTATE_MEMBER}){0,31}$`);
1177
+ const Tracestate = S.String.pipe(S.check(S.isPattern(TRACESTATE, { expected: "a W3C tracestate: comma-separated key=value members" })));
1178
+ const WorkerPluginKind = S.Literals([
1179
+ "TestRunner",
1180
+ "Checker",
1181
+ "Reporter"
1182
+ ]);
1183
+ const EvaluatorPluginKind = S.Literal("Evaluator");
1184
+ const PluginKindSchema = S.Union([WorkerPluginKind, EvaluatorPluginKind]);
1185
+ const TestRunnerDryRunRequest = S.Struct({ options: DryRunOptionsSchema });
1186
+ const TestRunnerMutantRunRequest = S.Struct({ options: MutantRunOptionsSchema });
1187
+ const CheckerRequest = S.Struct({
1188
+ checkerName: S.String,
1189
+ mutants: S.Array(CheckerMutantWire)
1190
+ });
1191
+ const CheckerCheckResult = S.Record(S.String, CheckResultSchema);
1192
+ const CheckerGroupResult = S.String.pipe(S.Array, S.Array);
1193
+ const ReporterInitOptions = S.Struct({
1194
+ traceparent: S.optionalKey(Traceparent),
1195
+ tracestate: S.optionalKey(Tracestate)
1196
+ });
1197
+ const ReporterEventBatch = S.Array(ReporterEventUnion);
1198
+ const ReporterAck = S.Void;
1199
+ const ReporterDrained = S.Void;
1200
+ var BoundaryPayloadRejected = class extends S.TaggedError()("BoundaryPayloadRejected", {
1201
+ pluginName: S.String,
1202
+ method: S.String,
1203
+ cause: S.String
1204
+ }) {
1205
+ get message() {
1206
+ return `Plugin "${this.pluginName}" rejected the payload for ${this.method}: ${this.cause}`;
1207
+ }
1208
+ };
1209
+ var BoundaryUnrecognizedSignal = class extends S.TaggedError()("BoundaryUnrecognizedSignal", {
1210
+ pluginName: S.String,
1211
+ method: S.String,
1212
+ signal: S.String
1213
+ }) {
1214
+ get message() {
1215
+ return `Plugin "${this.pluginName}" sent an unrecognized signal "${this.signal}" for ${this.method}`;
1216
+ }
1217
+ };
1218
+ const BoundaryErrorSchema = S.Union([
1219
+ BoundaryPayloadRejected,
1220
+ BoundaryUnrecognizedSignal,
1221
+ TestRunnerFailed,
1222
+ CheckerFailed,
1223
+ ReporterFailed
1224
+ ]);
1225
+ const WorkerEntryUrl = S.String.check(S.isPattern(/^file:\/\//, { expected: "a file: URL of the worker program" }));
1226
+ const WorkerPluginSpawnSchema = S.Struct({
1227
+ kind: WorkerPluginKind,
1228
+ entrypoint: WorkerEntryUrl
1229
+ });
1230
+ var PropagatedTrace = class extends Context.Service()("@systemfsoftware/stryker-js-plugin-interface/TraceContextRpc.service/PropagatedTrace") {};
1231
+ var TraceContextMiddleware = class extends RpcMiddleware.Service()("@systemfsoftware/stryker-js-plugin-interface/TraceContextMiddleware", { requiredForClient: true }) {};
1232
+ const capabilities = Rpc.make("capabilities", {
1233
+ success: TestRunnerCapabilitiesSchema,
1234
+ error: TestRunnerFailed
1235
+ }).middleware(TraceContextMiddleware);
1236
+ const dryRun = Rpc.make("dryRun", {
1237
+ payload: TestRunnerDryRunRequest,
1238
+ success: DryRunResultSchema,
1239
+ error: TestRunnerFailed
1240
+ }).middleware(TraceContextMiddleware);
1241
+ const mutantRun = Rpc.make("mutantRun", {
1242
+ payload: TestRunnerMutantRunRequest,
1243
+ success: MutantRunResultSchema,
1244
+ error: TestRunnerFailed
1245
+ }).middleware(TraceContextMiddleware);
1246
+ const check = Rpc.make("check", {
1247
+ payload: CheckerRequest,
1248
+ success: CheckerCheckResult,
1249
+ error: CheckerFailed
1250
+ }).middleware(TraceContextMiddleware);
1251
+ const group = Rpc.make("group", {
1252
+ payload: CheckerRequest,
1253
+ success: CheckerGroupResult,
1254
+ error: CheckerFailed
1255
+ }).middleware(TraceContextMiddleware);
1256
+ const init = Rpc.make("init", {
1257
+ payload: ReporterInitOptions,
1258
+ success: ReporterAck,
1259
+ error: ReporterFailed
1260
+ }).middleware(TraceContextMiddleware);
1261
+ const onEventBatch = Rpc.make("onEventBatch", {
1262
+ payload: ReporterEventBatch,
1263
+ success: ReporterAck,
1264
+ error: ReporterFailed
1265
+ }).middleware(TraceContextMiddleware);
1266
+ const flush = Rpc.make("flush", {
1267
+ success: ReporterDrained,
1268
+ error: ReporterFailed
1269
+ }).middleware(TraceContextMiddleware);
1270
+ const TestRunnerRpcs = RpcGroup.make(capabilities, dryRun, mutantRun);
1271
+ const CheckerRpcs = RpcGroup.make(check, group);
1272
+ const ReporterRpcs = RpcGroup.make(init, onEventBatch, flush);
1273
+ var Plugin_exports = /* @__PURE__ */ __exportAll({
1274
+ BoundaryErrorSchema: () => BoundaryErrorSchema,
1275
+ BoundaryPayloadRejected: () => BoundaryPayloadRejected,
1276
+ BoundaryUnrecognizedSignal: () => BoundaryUnrecognizedSignal,
1277
+ CheckerCheckResult: () => CheckerCheckResult,
1278
+ CheckerGroupResult: () => CheckerGroupResult,
1279
+ CheckerRequest: () => CheckerRequest,
1280
+ CheckerRpcs: () => CheckerRpcs,
1281
+ EvaluatorPluginKind: () => EvaluatorPluginKind,
1282
+ ExitClass: () => ExitClass,
1283
+ ExitCode: () => ExitCode,
1284
+ ExitCodeFromClass: () => ExitCodeFromClass,
1285
+ PluginKindSchema: () => PluginKindSchema,
1286
+ ReporterAck: () => ReporterAck,
1287
+ ReporterDrained: () => ReporterDrained,
1288
+ ReporterEventBatch: () => ReporterEventBatch,
1289
+ ReporterInitOptions: () => ReporterInitOptions,
1290
+ ReporterRpcs: () => ReporterRpcs,
1291
+ TestRunnerDryRunRequest: () => TestRunnerDryRunRequest,
1292
+ TestRunnerMutantRunRequest: () => TestRunnerMutantRunRequest,
1293
+ TestRunnerRpcs: () => TestRunnerRpcs,
1294
+ WorkerEntryUrl: () => WorkerEntryUrl,
1295
+ WorkerPluginKind: () => WorkerPluginKind,
1296
+ WorkerPluginSpawnSchema: () => WorkerPluginSpawnSchema
1297
+ });
1298
+ const countOf = (mutants, status) => mutants.filter((mutant) => mutant.status === status).length;
1299
+ const metricsFromMutants = (mutants) => Metrics.make({
1300
+ pending: countOf(mutants, "Pending"),
1301
+ killed: countOf(mutants, "Killed"),
1302
+ timeout: countOf(mutants, "Timeout"),
1303
+ survived: countOf(mutants, "Survived"),
1304
+ noCoverage: countOf(mutants, "NoCoverage"),
1305
+ runtimeErrors: countOf(mutants, "RuntimeError"),
1306
+ compileErrors: countOf(mutants, "CompileError"),
1307
+ ignored: countOf(mutants, "Ignored")
1308
+ });
1309
+ const WrittenSchemaVersion = S.Literal("1.0");
1310
+ var Report_exports = /* @__PURE__ */ __exportAll({
1311
+ BrandingInformation: () => BrandingInformation,
1312
+ CpuInformation: () => CpuInformation,
1313
+ Dependencies: () => Dependencies,
1314
+ DetectedStatus: () => DetectedStatus,
1315
+ FileResult: () => FileResult,
1316
+ FileResultDictionary: () => FileResultDictionary,
1317
+ FrameworkInformation: () => FrameworkInformation,
1318
+ InvalidStatus: () => InvalidStatus,
1319
+ Location: () => Location,
1320
+ Metrics: () => Metrics,
1321
+ MetricsResultSchema: () => MetricsResultSchema,
1322
+ MetricsSchema: () => MetricsSchema,
1323
+ MutantResult: () => MutantResult,
1324
+ MutationScore: () => MutationScore,
1325
+ MutationTestResult: () => MutationTestResult,
1326
+ NonNegativeFinite: () => NonNegativeFinite,
1327
+ NonNegativeInt: () => NonNegativeInt,
1328
+ OSInformation: () => OSInformation,
1329
+ OpenEndLocation: () => OpenEndLocation,
1330
+ Percentage: () => Percentage,
1331
+ PerformanceStatistics: () => PerformanceStatistics,
1332
+ Position: () => Position,
1333
+ RamInformation: () => RamInformation,
1334
+ StaticClassSummarySchema: () => StaticClassSummarySchema,
1335
+ SystemInformation: () => SystemInformation,
1336
+ TestDefinition: () => TestDefinition,
1337
+ TestFile: () => TestFile,
1338
+ TestFileDefinitionDictionary: () => TestFileDefinitionDictionary,
1339
+ Thresholds: () => Thresholds,
1340
+ UndetectedStatus: () => UndetectedStatus,
1341
+ UntestedStatus: () => UntestedStatus,
1342
+ WrittenSchemaVersion: () => WrittenSchemaVersion,
1343
+ metricsFromMutants: () => metricsFromMutants
1344
+ });
1345
+ var Reporter_exports = /* @__PURE__ */ __exportAll({
1346
+ DryRunCompleted: () => DryRunCompleted,
1347
+ MutantTested: () => MutantTested,
1348
+ MutationTestReportReady: () => MutationTestReportReady,
1349
+ MutationTestingPlanReady: () => MutationTestingPlanReady,
1350
+ ReporterEventKind: () => ReporterEventKind,
1351
+ ReporterEventSchema: () => ReporterEventSchema,
1352
+ ReporterEventUnion: () => ReporterEventUnion,
1353
+ ReporterFailed: () => ReporterFailed,
1354
+ ReporterPlanDescriptorSchema: () => ReporterPlanDescriptorSchema,
1355
+ ReporterPlanKind: () => ReporterPlanKind,
1356
+ RunTimingSchema: () => RunTimingSchema
1357
+ });
1358
+ const HitLimitReasonPrefix = S.Literal("Hit limit reached");
1359
+ const WallClockTimeoutReason = S.Literal("wall-clock-timeout");
1360
+ const HIT_LIMIT_REASON_PREFIX = HitLimitReasonPrefix.literal;
1361
+ const HitLimitReasonText = S.String.check(S.isStartsWith(HIT_LIMIT_REASON_PREFIX, { arbitraryConstraint: {
1362
+ patterns: [{
1363
+ source: `^${HIT_LIMIT_REASON_PREFIX}[\\s\\S]*$`,
1364
+ flags: ""
1365
+ }],
1366
+ minLength: HIT_LIMIT_REASON_PREFIX.length + 2
1367
+ } }));
1368
+ const HIT_LIMIT_REASON_SHAPE = /^Hit limit reached \((\d+)\/(\d+)\)$/;
1369
+ const limitsOf = SchemaGetter.transformEffect((text) => Option$1.match(Option$1.fromNullishOr(HIT_LIMIT_REASON_SHAPE.exec(text)), {
1370
+ onNone: () => Effect$1.fail(malformedHitLimit(text)),
1371
+ onSome: (matched) => Effect$1.succeed({
1372
+ count: Number.parseInt(String(matched[1]), 10),
1373
+ limit: Number.parseInt(String(matched[2]), 10)
1374
+ })
1375
+ }));
1376
+ const textOf = SchemaGetter.transform((limits) => `${HitLimitReasonPrefix.literal} (${limits.count}/${limits.limit})`);
1377
+ const malformedHitLimit = (text) => new SchemaIssue.InvalidValue({ message: "expected \"Hit limit reached (count/limit)\"" }, text);
1378
+ const HitLimitReason = HitLimitReasonText.pipe(S.decodeTo(S.Struct({
1379
+ count: S.Natural,
1380
+ limit: S.Natural
1381
+ }), SchemaTransformation.makeTransformation({
1382
+ decode: limitsOf,
1383
+ encode: textOf
1384
+ })));
1385
+ var TestRunner = class extends Context.Service()("@systemfsoftware/stryker-js-plugin-interface/TestRunner.service/TestRunner") {};
1386
+ var TestRunner_exports = /* @__PURE__ */ __exportAll({
1387
+ CoverageAnalysisSchema: () => CoverageAnalysisSchema,
1388
+ DryRunOptionsSchema: () => DryRunOptionsSchema,
1389
+ DryRunResultSchema: () => DryRunResultSchema,
1390
+ DryRunStatus: () => DryRunStatus,
1391
+ ExecutedTestSchema: () => ExecutedTestSchema,
1392
+ HitLimitReason: () => HitLimitReason,
1393
+ HitLimitReasonPrefix: () => HitLimitReasonPrefix,
1394
+ HitLimitReasonText: () => HitLimitReasonText,
1395
+ MutantRunResultSchema: () => MutantRunResultSchema,
1396
+ MutantRunStatus: () => MutantRunStatus,
1397
+ TestId: () => TestId,
1398
+ TestResultSchema: () => TestResultSchema,
1399
+ TestRunner: () => TestRunner,
1400
+ TestRunnerCapabilitiesSchema: () => TestRunnerCapabilitiesSchema,
1401
+ TestRunnerFailed: () => TestRunnerFailed,
1402
+ TestStatus: () => TestStatus,
1403
+ WallClockTimeoutReason: () => WallClockTimeoutReason
1404
+ });
1405
+ const TraceContextReference = Context.Reference("@systemfsoftware/stryker-js-plugin-interface/TraceContextReference", { defaultValue: () => Option$1.none() });
1406
+ var Trace_exports = /* @__PURE__ */ __exportAll({
1407
+ PropagatedTrace: () => PropagatedTrace,
1408
+ TraceContextMiddleware: () => TraceContextMiddleware,
1409
+ TraceContextPartsSchema: () => TraceContextPartsSchema,
1410
+ TraceContextReference: () => TraceContextReference,
1411
+ Traceparent: () => Traceparent,
1412
+ TraceparentHeader: () => TraceparentHeader,
1413
+ Tracestate: () => Tracestate,
1414
+ TracestateHeader: () => TracestateHeader
1415
+ });
1416
+ //#endregion
1417
+ //#region src/config/merge-config.ts
1418
+ /**
1419
+ * Whether an entry takes part in a merge: a key literally named `__proto__` never does — the
1420
+ * merged record must not gain a document-decided prototype — and an explicitly `undefined`
1421
+ * value states that the author left the key unset, not that they want it set to nothing.
1422
+ */
1423
+ const usable = (value, key) => key !== "__proto__" && value !== void 0;
1424
+ const usableEntries = (source) => Record$1.filter(source, usable);
1425
+ const isConfigRecord = (value) => Predicate$1.isObject(value);
1426
+ const asConfigRecord = (value) => Option$1.filter(Option$1.fromUndefinedOr(value), isConfigRecord);
1427
+ const mergeNested = (base, override) => Option$1.match(asConfigRecord(override), {
1428
+ onNone: () => override,
1429
+ onSome: (overrideRecord) => mergeRecords(base, overrideRecord)
1430
+ });
1431
+ const hasUsableMember = (key) => (merged) => merged.hasOwnProperty(key) && merged[key] !== void 0;
1432
+ const ownValueOf = (merged, key) => Option$1.map(Option$1.liftPredicate(merged, hasUsableMember(key)), (present) => present[key]);
1433
+ const baseRecordOf = (ownValue) => Option$1.filter(Option$1.flatMap(ownValue, Option$1.fromUndefinedOr), isConfigRecord);
1434
+ const mergeKeyInto = (merged, override, key) => ({
1435
+ ...merged,
1436
+ [key]: Option$1.match(baseRecordOf(ownValueOf(merged, key)), {
1437
+ onNone: () => override,
1438
+ onSome: (baseRecord) => mergeNested(baseRecord, override)
1439
+ })
1440
+ });
1441
+ const mergeRecords = (base, overrides) => Record$1.reduce(usableEntries(overrides), usableEntries(base), mergeKeyInto);
1442
+ const mergeConfig = dual(2, (defaults, overrides) => mergeRecords(defaults, overrides));
1443
+ const isNonNullObject = (value) => typeof value === "object" && value !== null;
1444
+ const asUnknownArray = (value) => Array.isArray(value) ? value : [];
1445
+ const isFirstDescriptorOccurrence = (descriptors) => (descriptor, index) => typeof descriptor !== "string" || descriptors.slice(0, index).includes(descriptor) === false;
1446
+ const mergePluginDescriptors = (parentPlugins, childPlugins) => {
1447
+ const merged = [...parentPlugins, ...childPlugins];
1448
+ return merged.filter(isFirstDescriptorOccurrence(merged));
1449
+ };
1450
+ const isConfigOptionsRecord = (value) => isNonNullObject(value) && Array.isArray(value) === false;
1451
+ const mergeConfigRecords = (parentNested, childNested) => ({
1452
+ ...parentNested,
1453
+ ...childNested
1454
+ });
1455
+ const toConfigRecordOption = (value) => isConfigOptionsRecord(value) ? Option$1.some(value) : Option$1.none();
1456
+ const inheritNested = (parentValue, childValue) => Option$1.match(Option$1.all([toConfigRecordOption(parentValue), toConfigRecordOption(childValue)]), {
1457
+ onSome: ([parentNested, childNested]) => mergeConfigRecords(parentNested, childNested),
1458
+ onNone: () => childValue
1459
+ });
1460
+ const inheritEntry = (out, key, parentValue, childValue) => Match$1.value(childValue).pipe(Match$1.when(null, () => {
1461
+ const next = { ...out };
1462
+ delete next[key];
1463
+ return next;
1464
+ }), Match$1.orElse(() => Match$1.value(key).pipe(Match$1.when("plugins", () => ({
1465
+ ...out,
1466
+ [key]: mergePluginDescriptors(asUnknownArray(parentValue), asUnknownArray(childValue))
1467
+ })), Match$1.orElse(() => ({
1468
+ ...out,
1469
+ [key]: inheritNested(parentValue, childValue)
1470
+ })))));
1471
+ const mergeConfigs = dual(2, (parent, child) => Object.entries(child).reduce((out, entry) => inheritEntry(out, entry[0], parent[entry[0]], entry[1]), { ...parent }));
1472
+ //#endregion
1473
+ export { MutatorCatalog_exports as a, Plugin_exports as c, TestRunner_exports as d, Trace_exports as f, Mutant_exports as i, Report_exports as l, mergeConfigs as n, MutatorProvider_exports as o, Checker_exports as r, Options_exports as s, mergeConfig as t, Reporter_exports as u };