From f56c8072e512117dd106bd3cd124b3dbcc6398d5 Mon Sep 17 00:00:00 2001 From: Nawid3333 <102778966+Nawid3333@users.noreply.github.com> Date: Thu, 22 Oct 2026 18:54:58 +0200 Subject: [PATCH] Stryker goes: the weekly mutation run, its two packages, patch, override, tools and tests Its reports (about 4,700 mutants not caught, 64.6% to 68%) were closed by hand every week and no fix came from them; it cost a 131-line patch of its vitest runner to re-cut on every update, the qs override and 34 MB of packages. LOCKSTEP, which only kept its two packages together, goes with it. The hand mutation check of each fix stays. Co-Authored-By: Claude Opus 5.5 --- .github/dependabot.yml | 17 +- .github/workflows/firefox-beta.yml | 4 +- .github/workflows/firefox-stable.yml | 4 +- .github/workflows/mutation-tests.yml | 204 --- .github/workflows/runner-images.yml | 4 +- .gitignore | 4 - docs/maintenance.md | 6 - docs/notes/mpv.md | 3 +- docs/notes/workflows.md | 42 +- docs/updating-patched-libraries.md | 7 +- eslint.config.js | 2 - package.json | 5 +- ...tryker-mutator__vitest-runner@10.0.0.patch | 131 -- pnpm-lock.yaml | 1168 ----------------- pnpm-workspace.yaml | 5 - stryker.config.mjs | 227 ---- tests/unit/checkPatchedUpdates.test.mjs | 20 +- tests/unit/decodeSubtitleBytes.test.mjs | 5 +- tests/unit/fetchAmoSigned.test.mjs | 4 +- tests/unit/helpers/stryker.mjs | 15 - tests/unit/mpvHostInstall.test.mjs | 5 +- tests/unit/mpvHostVersion.test.mjs | 6 +- tests/unit/mutationReport.test.mjs | 71 - tests/unit/recutPatch.test.mjs | 32 +- tests/unit/strykerShards.test.mjs | 97 -- tests/unit/typeChecked.test.mjs | 2 - tests/workflows/mutation-tests.test.sh | 175 --- tools/check-patched-updates.mjs | 10 - tools/merge-mutation-reports.mjs | 22 - tools/mutation-report.mjs | 149 --- tools/recut-patch.mjs | 19 +- 31 files changed, 42 insertions(+), 2423 deletions(-) delete mode 100644 .github/workflows/mutation-tests.yml delete mode 100644 patches/@stryker-mutator__vitest-runner@10.0.0.patch delete mode 100644 stryker.config.mjs delete mode 100644 tests/unit/helpers/stryker.mjs delete mode 100644 tests/unit/mutationReport.test.mjs delete mode 100644 tests/unit/strykerShards.test.mjs delete mode 100644 tests/workflows/mutation-tests.test.sh delete mode 100644 tools/merge-mutation-reports.mjs delete mode 100644 tools/mutation-report.mjs diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 67d5a1dca..642aa5b1b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -57,13 +57,6 @@ updates: shipped-minor-and-patch: patterns: ['fuse.js', 'mediabunny', 'sortablejs'] update-types: ['minor', 'patch'] - # Stryker's packages come out together, and each requires the others at its own - # version exactly (@stryker-mutator/vitest-runner's peerDependencies): one pull - # request for all of them, majors included. Before tooling-minor-and-patch, which - # would take them otherwise. While the vitest runner carries a patch, both are - # ignored below and move together through the Patched libraries workflow. - stryker: - patterns: ['@stryker-mutator/*'] # WebdriverIO's packages come out together and only work at the same version: one pull # request for all of them, majors included (10.0.0 came as four, each red alone, # 2026-10-10). Before tooling-minor-and-patch, which would take them otherwise. @@ -79,14 +72,10 @@ updates: # from the Patched libraries workflow instead, which re-cuts the patch with # tools/recut-patch.mjs and opens the pull request itself when that is clean # (docs/updating-patched-libraries.md). Keep this list in step with - # patchedDependencies, and the packages that move with a patched one (LOCKSTEP in - # tools/check-patched-updates.mjs: @stryker-mutator/core with the vitest runner, which - # requires its exact version). When every change of a patch has landed upstream, - # tools/recut-patch.mjs drops the patch and takes the library and those packages off - # this list in the same pull request. + # patchedDependencies. When every change of a patch has landed upstream, + # tools/recut-patch.mjs drops the patch and takes the library off this list in the same + # pull request. ignore: - - dependency-name: '@stryker-mutator/core' - - dependency-name: '@stryker-mutator/vitest-runner' - dependency-name: 'Coloris' - dependency-name: 'dashjs' - dependency-name: 'gif.js' diff --git a/.github/workflows/firefox-beta.yml b/.github/workflows/firefox-beta.yml index 987905f20..ba5406514 100644 --- a/.github/workflows/firefox-beta.yml +++ b/.github/workflows/firefox-beta.yml @@ -131,8 +131,8 @@ jobs: fi exit 0 fi - # A suite that runs out of its time ends cancelled, not failed (as in - # mutation-tests.yml): a Firefox that hangs the suites said nothing. + # A suite that runs out of its time ends cancelled, not failed: a Firefox that + # hangs the suites said nothing. if [ "$RESULT" != failure ] && [ "$RESULT" != cancelled ]; then echo "e2e result: $RESULT - nothing to report." exit 0 diff --git a/.github/workflows/firefox-stable.yml b/.github/workflows/firefox-stable.yml index d295bfe50..d269c3eeb 100644 --- a/.github/workflows/firefox-stable.yml +++ b/.github/workflows/firefox-stable.yml @@ -192,8 +192,8 @@ jobs: done exit 0 fi - # A suite that runs out of its time ends cancelled, not failed (as in - # mutation-tests.yml): a Firefox that hangs the suites said nothing. + # A suite that runs out of its time ends cancelled, not failed: a Firefox that + # hangs the suites said nothing. if [ "$RESULT" != failure ] && [ "$RESULT" != cancelled ]; then echo "e2e result: $RESULT - nothing to report." exit 0 diff --git a/.github/workflows/mutation-tests.yml b/.github/workflows/mutation-tests.yml deleted file mode 100644 index 0e0f9a2c9..000000000 --- a/.github/workflows/mutation-tests.yml +++ /dev/null @@ -1,204 +0,0 @@ -name: Mutation tests - -# Once a week, Stryker (stryker.config.mjs) changes the pure-logic modules one thing at a -# time - a comparison, a bound, a call left out - and runs the unit tests against each -# change. A change they still pass is a place where a fix could ship without a test that -# fails without it: the rule every fix here follows, checked by hand until now (T4). -# -# A report, not a gate: the run summary gets a table per file, the full HTML reports are the -# mutation-reports- artifacts (30 days), and when the tests missed mutants, one issue, -# "Mutation testing: week to ", assigned to the owner and @mentioning them, lists them. -# The next week's issue closes it, and so does a week in which every mutant was caught. -# -# The modules are in four areas, one shard each (stryker.config.mjs, SHARDS), each run by a -# job of its own side by side; the report job puts their reports together. With the command -# runner every mutant ran the whole unit suite, and seven shards took 2 to 4.7 hours (#349); -# with the vitest runner, a mutant runs only the tests that reach it, and the same seven took -# 2 to 10 minutes (2026-10-06). The mpv host keeps the command runner (its message loop runs -# in a process its tests start), about an hour and a half. - -on: - schedule: - - cron: '40 6 * * 1' - workflow_dispatch: - -permissions: - contents: read # the checkout - -concurrency: - group: mutation-tests - cancel-in-progress: false - -jobs: - mutation: - name: Stryker over the ${{ matrix.shard }} modules - runs-on: ubuntu-latest - # Minutes for a vitest-runner shard; the host's command-runner shard about an hour and a - # half (stryker.config.mjs). 350 minutes leaves room, under the runners' 360. - timeout-minutes: 350 - strategy: - # One shard that fails or runs out of time leaves the others' reports. - fail-fast: false - matrix: - shard: [core-1, network-1, tools-1, host-1] - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - - - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 - with: - node-version-file: .nvmrc - check-latest: true - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run Stryker - env: - STRYKER_SHARD: ${{ matrix.shard }} - run: pnpm run test:mutation - - - name: Upload the mutation report - if: always() - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 - with: - name: mutation-reports-${{ matrix.shard }} - path: reports/mutation/ - if-no-files-found: ignore - retention-days: 30 - - report: - name: The week's report - needs: mutation - # The shards that wrote a report are reported, also when another one failed. - if: always() - runs-on: ubuntu-latest - timeout-minutes: 15 - # Only this job writes: the shards run the code under test and need nothing but the checkout. - permissions: - contents: read # the checkout - issues: write # the week's issue, and this workflow's own failure - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_REPO: ${{ github.repository }} - OWNER: ${{ github.repository_owner }} - PREFIX: 'Mutation testing: week to ' - RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 - with: - node-version-file: .nvmrc - check-latest: true - - - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 - with: - pattern: mutation-reports-* - path: shards - - - name: Put the shards' reports together - run: | - set -euo pipefail - found=0 - missing='' - for shard in core-1 network-1 tools-1 host-1; do - if [ -f "shards/mutation-reports-$shard/mutation.json" ]; then - found=$((found + 1)) - else - missing="$missing $shard" - fi - done - echo "MISSING_SHARDS=${missing# }" >> "$GITHUB_ENV" - if [ "$found" -gt 0 ]; then - node tools/merge-mutation-reports.mjs - fi - - - name: Write the summary - run: | - set -euo pipefail - if [ -n "$MISSING_SHARDS" ]; then - echo "No mutation report from: $MISSING_SHARDS (Stryker stopped before writing one)." >> "$GITHUB_STEP_SUMMARY" - echo >> "$GITHUB_STEP_SUMMARY" - fi - if [ -f reports/mutation/mutation.json ]; then - node tools/mutation-report.mjs reports/mutation/mutation.json summary >> "$GITHUB_STEP_SUMMARY" - fi - - - name: Open, update or close the week's issue - run: | - set -euo pipefail - if [ ! -f reports/mutation/mutation.json ]; then - echo "No shard wrote a report." - exit 0 - fi - today=$(date -u +%F) - title="$PREFIX$today" - missed=$(node tools/mutation-report.mjs reports/mutation/mutation.json count) - - # Every issue this workflow opened, open or closed. - gh api --paginate "repos/$GH_REPO/issues?state=all&per_page=100" \ - --jq '.[] | select(.pull_request == null and .user.login == "github-actions[bot]" and (.title | startswith(env.PREFIX))) | [.number, .state, .title] | @tsv' \ - > "$RUNNER_TEMP/mine.tsv" - - # A shard without a report says nothing of its mutants: its week is not done. - if [ "$missed" -eq 0 ] && [ -n "${MISSING_SHARDS:-}" ]; then - echo "Every mutant of the reports was caught; no report from: $MISSING_SHARDS." - exit 0 - fi - if [ "$missed" -eq 0 ]; then - echo "The unit tests caught every mutant." - while IFS=$'\t' read -r number state old; do - if [ "$state" != open ]; then continue; fi - gh issue close "$number" --reason completed --comment "The unit tests caught every mutant in the week to $today: $RUN_URL" - echo "Closed #$number ($old)" - done < "$RUNNER_TEMP/mine.tsv" - exit 0 - fi - - node tools/mutation-report.mjs reports/mutation/mutation.json issue "$OWNER" "$RUN_URL" > "$RUNNER_TEMP/body.md" - current=$(awk -F '\t' -v title="$title" '$2 == "open" && $3 == title {print $1; exit}' "$RUNNER_TEMP/mine.tsv") - if [ -n "$current" ]; then - gh issue edit "$current" --body-file "$RUNNER_TEMP/body.md" - echo "Updated #$current" - else - url=$(gh issue create --title "$title" --assignee "$OWNER" --body-file "$RUNNER_TEMP/body.md") - current=${url##*/} - echo "Opened $url" - fi - - # The last weeks' open issues: this one replaces them. - while IFS=$'\t' read -r number state old; do - if [ "$state" != open ] || [ "$number" = "$current" ]; then continue; fi - gh issue close "$number" --reason completed --comment "#$current lists the week to $today." - echo "Closed #$number ($old)" - done < "$RUNNER_TEMP/mine.tsv" - - # A failed run of this workflow is emailed only to whoever started it (for the schedule, - # whoever last changed the cron line): one issue while it is open, assigned and - # @mentioning the owner, as toolchain-updates.yml does. A failure while it is open adds a - # comment to it. A shard that failed or ran out of time counts too (the latter ends - # cancelled, see the condition). - - name: Report this workflow's own failure - # cancelled: a shard that ran out of its time ends cancelled, not failed, and such a run - # (no report at all, 2026-10-05) said nothing. - if: failure() || needs.mutation.result == 'failure' || needs.mutation.result == 'cancelled' - env: - TITLE: 'Mutation tests workflow failed' - run: | - set -euo pipefail - number=$(gh issue list --state open --limit 200 --json number,title \ - --jq '[.[] | select(.title == env.TITLE)][0].number // empty') || number='' - if [ -n "$number" ]; then - printf '@%s Failed again: %s\n' "$OWNER" "$RUN_URL" > "$RUNNER_TEMP/comment.md" - gh issue comment "$number" --body-file "$RUNNER_TEMP/comment.md" - exit 0 - fi - printf '@%s mutation-tests.yml failed: %s\n\nThe run log names the failed command. Close this issue once it is fixed; a later failure opens a new one.\n' \ - "$OWNER" "$RUN_URL" > "$RUNNER_TEMP/body.md" - gh issue create --title "$TITLE" --assignee "$OWNER" --body-file "$RUNNER_TEMP/body.md" diff --git a/.github/workflows/runner-images.yml b/.github/workflows/runner-images.yml index 58325aee2..dc98036f7 100644 --- a/.github/workflows/runner-images.yml +++ b/.github/workflows/runner-images.yml @@ -226,8 +226,8 @@ jobs: } report() { # result, images, what the image is to -latest local result=$1 images=$2 role=$3 title number - # A job that runs out of its time ends cancelled, not failed (as in - # mutation-tests.yml): an image that hangs CI said nothing. + # A job that runs out of its time ends cancelled, not failed: an image that + # hangs CI said nothing. if [ "$result" != success ] && [ "$result" != failure ] && [ "$result" != cancelled ]; then echo "$images: ${result:-not run} - nothing to report." return diff --git a/.gitignore b/.gitignore index 7b5996149..299371c11 100644 --- a/.gitignore +++ b/.gitignore @@ -40,9 +40,5 @@ lint-*.json # vitest --coverage output. coverage/ -# Stryker (pnpm run test:mutation): its reports and its sandboxes -reports/mutation/ -.stryker-tmp/ - # The helper's launch lock (faststream-mpv-host.mjs launchLockFile), next to it while mpv starts. native-host/faststream-mpv-launch-*.lock diff --git a/docs/maintenance.md b/docs/maintenance.md index 073405a38..d7fa15bd6 100644 --- a/docs/maintenance.md +++ b/docs/maintenance.md @@ -207,12 +207,6 @@ third attempt was cancelled too or GitHub refused the re-run: re-run it from the tab, and the issue closes at the next green CI run on `main`. "Auto release failed" means such a run was red or its release failed; the issue links the run. -Once a week, `mutation-tests.yml` changes the code the unit tests cover one thing at a -time and checks the tests notice. When they miss some, "Mutation testing: week to " -lists them: each is a place a fix could ship without a test that fails without it. Nothing -waits on it; the next week's issue replaces it, and a week with every change caught closes -it. - ## What update-prs.yml checks before it says "ready to merge" Nothing merges itself (the owner's choice, 2026-10-02; from 2026-10-01 every kind of update diff --git a/docs/notes/mpv.md b/docs/notes/mpv.md index 5d1a6903a..568f10178 100644 --- a/docs/notes/mpv.md +++ b/docs/notes/mpv.md @@ -34,8 +34,7 @@ the new hashes). The installer counts because `update-local.ps1` tells an instal from the repository's by the host file alone; a raised `HostVersion` changes that file. The extension changes with it, so such a push releases, Firefox updates the extension, and the next hand-off on the owner's PC shows the "!" until `update-local.cmd` (or -`install.ps1`) has run. The hash check is skipped in Stryker's sandbox, whose copy of -the host holds every mutant. +`install.ps1`) has run. **The thin helper (host 15, 2026-10-13).** The host changed 14 times in 10 days, each one a reinstall by hand, because policy lived in it. The owner chose to move the policy into the diff --git a/docs/notes/workflows.md b/docs/notes/workflows.md index 8783c15c0..67efd2588 100644 --- a/docs/notes/workflows.md +++ b/docs/notes/workflows.md @@ -327,8 +327,7 @@ start: gh can give a log with every step "UNKNOWN STEP"). Without E2E_SHARD a config runs all its spec files (local `pnpm run verify`). The private browsing suite (one spec file) runs in the first extension group only. A run is 18 jobs - at once of the account's 20, so more groups would only queue; the weekly mutation run - (Mondays, 7 jobs for hours) leaves 13, and a push during it runs in two waves. + at once of the account's 20, so more groups would only queue. `fail-fast: false`, so one failing group does not cancel the others and their lists of retried specs. Per-job artifacts: `e2e-retried---`, `e2e-logs---`; `e2e-moz-logs-windows--` only from the Windows @@ -647,37 +646,8 @@ - All of it was dry-run with a stub `gh` against the real upstream history (sync: adopted -> closed, push -> no rebuild, new release named, comment only on upstream movement; patched libraries: open once, no duplicates, close when caught up or unpatched). -- **`mutation-tests.yml`** (Mondays 06:40 UTC), 2026-10-01, T4: Stryker - (`stryker.config.mjs`, `pnpm run test:mutation`) over 25 pure-logic modules with unit - tests (10 small ones added 2026-10-03, #253; the config says which wait, and why). A report, not a gate: the run summary gets a table per file - (`tools/mutation-report.mjs`), the HTML report is the `mutation-reports` artifact, and when - the unit tests missed mutants (survived, or no test reaches them), one issue "Mutation - testing: week to " lists them, assigned + @mention; next week's replaces it, a week - with all caught closes it. **The command runner**, not the vitest one: every mutant runs the - whole unit suite (`__STRYKER_ACTIVE_MUTANT__`), about 1.2 s each with 4 workers locally - on - CI a mutant the tests miss runs the whole ~18 s suite, and one job per area ran out of its - 240 minutes at 51-74% with no report (#349, 2026-10-05): since then the three areas are - seven shards (`PARTS` in the config, split by file size), each in a job of 350 minutes, and - a shard that runs out of time (it ends cancelled) is reported as a failure. **Since - 2026-10-06 the vitest runner** with per-test coverage: a mutant runs only the tests that - reached its code, in a Vitest that stays up (143 mutants in 31 s locally, ~12.5 tests a - mutant). Its 10.0.0 release (August 2026) predates vitest 5, which joins a test's suite - chain with ' > ', so its test filter matched nothing and every mutant "survived" - (stryker-js #6210); FastStream carries the fix, stryker-js PR #6214, as a pnpm patch - (`patches/@stryker-mutator__vitest-runner@10.0.0.patch`, the compiled files). When a - release has it, the Patched libraries workflow opens the pull request that drops the patch, - moves @stryker-mutator/core along (LOCKSTEP in `tools/check-patched-updates.mjs`: the runner - requires its core's exact version) and hands both back to Dependabot, whose `stryker` group - then keeps all of Stryker's packages in one pull request. A test that runs a module as a - process of its own (mpvHostVersion's host; the Windows-only installer and update-local - tests) does not see a mutant there. Compared mutant by mutant (command-runner run - 37384050152, 4.7 hours; vitest-runner run 37393654214, 10 minutes): 11,313 of 11,370 alike. - The rest: each tool's entry line (`if (process.argv[1] ...`) a crashed run where the command - runner caught, two swapped on one line of SubtitleUtils - and the mpv host's message loop - (`main()`, `sendMessage()`), 24 mutants with no test reaching them. So the host is an area of - its own on the command runner (`COMMAND_AREAS`, `host-1`, about an hour and a half), and core, - network and tools are one vitest-runner shard each: four jobs. The sandbox leaves out `tsconfig.json`: Stryker rewrites it through - TypeScript's JS API, which TypeScript 7 does not have. `tests/workflows/mutation-tests.test.sh`. - Baseline, 2026-10-01 (73 min locally): 71.8% of 3,614 mutants caught; the weakest are the - mpv host (47.7%), MpvBackend (58.4%), SubtitleUtils (63.2%) and TabTracker (68.4%), the - best SubtitleSyncUtils (96%), MultiRegexMatcher, UrlMatchList and StreamPick (92%). +- **`mutation-tests.yml`** (2026-10-01 to 2026-10-22): Stryker over the unit-tested modules, + weekly. Removed with Stryker: its reports (about 4,700 mutants not caught, 64.6% to 68%) + were closed by hand each week and no fix came from them, while it carried a 131-line patch + of its vitest runner, an override and 34 MB of packages. The fixes kept their own check: a + hand-made mutation of each one, which its test must catch. diff --git a/docs/updating-patched-libraries.md b/docs/updating-patched-libraries.md index 22ba2202d..37f18db8e 100644 --- a/docs/updating-patched-libraries.md +++ b/docs/updating-patched-libraries.md @@ -62,15 +62,10 @@ regenerated files in `chrome/player/modules/`. Then commit on a branch and open request (the regenerated files are git-ignored, so they are not part of the commit). When every one of FastStream's changes has landed upstream, `--apply` drops the -patch instead of committing one, takes the library (and what moves with it, below) off +patch instead of committing one, takes the library off `.github/dependabot.yml`'s ignore list, and says to remove any `patched: true` marks in `tools/sync-vendor.mjs`. -Some packages must stay at a patched library's exact version: `LOCKSTEP` in -`tools/check-patched-updates.mjs` (`@stryker-mutator/core` with -`@stryker-mutator/vitest-runner`, which requires its core's version exactly). `--apply` -moves them to the library's new version in the same pull request, and Dependabot ignores -them while the library is patched, where it would bump them alone. If `tools/sync-vendor.mjs` then fails (an unpatched file renamed too), the tool exits 2 with the version, lockfile and patch already changed: fix `sync-vendor.mjs`, then run `pnpm run verify`. diff --git a/eslint.config.js b/eslint.config.js index 4c0f6ba6a..1e3b90e51 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -19,8 +19,6 @@ module.exports = [ '.git/', '.vscode/', '.claude/', - // Stryker's copies of the repo; one outlives a run that could not delete it. - '.stryker-tmp/', // The e2e fixtures are all generated (gitignored): the media buildFixtures makes, and the // hls.js and dash.js releases the live suite downloads (live-libs), 136,000 errors. 'tests/e2e/fixtures/', diff --git a/package.json b/package.json index 3a45cf9b4..ff640faa5 100644 --- a/package.json +++ b/package.json @@ -38,8 +38,7 @@ "verify:fsaunpack": "node tools/verify-fsaunpack.mjs", "sign:amo": "node tools/sign-amo.mjs", "sign:amo:listed": "node tools/sign-amo.mjs --listed", - "release": "node tools/cut-release.mjs", - "test:mutation": "stryker run" + "release": "node tools/cut-release.mjs" }, "repository": { "type": "git", @@ -51,8 +50,6 @@ }, "homepage": "https://github.com/Nawid3333/FastStream#readme", "devDependencies": { - "@stryker-mutator/core": "10.0.0", - "@stryker-mutator/vitest-runner": "10.0.0", "@stylistic/eslint-plugin": "^5.10.0", "@types/chrome": "^0.3.5", "@types/node": "^26.6.5", diff --git a/patches/@stryker-mutator__vitest-runner@10.0.0.patch b/patches/@stryker-mutator__vitest-runner@10.0.0.patch deleted file mode 100644 index 0c9f478af..000000000 --- a/patches/@stryker-mutator__vitest-runner@10.0.0.patch +++ /dev/null @@ -1,131 +0,0 @@ -diff --git a/dist/src/stryker-setup.js b/dist/src/stryker-setup.js -index aecfacbe47b285c272c47e54b3d66a716adfdc41..57b0f9897c29d8fd0303082945362893c4f1e622 100644 ---- a/dist/src/stryker-setup.js -+++ b/dist/src/stryker-setup.js -@@ -7,6 +7,8 @@ const mode = inject('mode'); - const ns = globalThis[globalNamespace] || (globalThis[globalNamespace] = {}); - ns.hitLimit = inject('hitLimit'); - const isGreaterThanVitest4Point1 = inject('isGreaterThanVitest4Point1'); -+// Must match the separator the runner filters with; see test-helpers.js -+const testNameSeparator = inject('testNameSeparator'); - if (mode === 'mutant') { - beforeAll(() => { - ns.hitCount = 0; -@@ -36,7 +38,7 @@ if (mode === 'mutant') { - else { - ns.activeMutant = undefined; - beforeEach(({ task }) => { -- ns.currentTestId = toRawTestId(task); -+ ns.currentTestId = toRawTestId(task, testNameSeparator); - }); - afterEach(() => { - ns.currentTestId = undefined; -@@ -56,16 +58,16 @@ else { - } - } - // Stryker disable all: this file is copied to the sandbox dir --function collectTestName({ name, suite, }) { -+function collectTestName({ name, suite, }, separator) { - const nameParts = [name]; - let currentSuite = suite; - while (currentSuite) { - nameParts.unshift(currentSuite.name); - currentSuite = currentSuite.suite; - } -- return nameParts.join(' ').trim(); -+ return nameParts.join(separator).trim(); - } --function toRawTestId(test) { -- return `${test.file?.filepath ?? 'unknown.js'}#${collectTestName(test)}`; -+function toRawTestId(test, separator) { -+ return `${test.file?.filepath ?? 'unknown.js'}#${collectTestName(test, separator)}`; - } - //# sourceMappingURL=stryker-setup.js.map -\ No newline at end of file -diff --git a/dist/src/test-helpers.js b/dist/src/test-helpers.js -index 56cc786f30c524ae18ce87eef1a67fdf26b703c5..87c7756220c1a3d7b8121acc6462042417029d22 100644 ---- a/dist/src/test-helpers.js -+++ b/dist/src/test-helpers.js -@@ -1,16 +1,21 @@ - // Don't merge this file into 'vitest-helpers.ts'! - // This file is used from the testing environment (via stryker-setup.js) and thus could be loaded into the browser (when using vitest with browser mode). - // Thus we should avoid unnecessary dependencies in this file. --export function collectTestName({ name, suite, }) { -+// The separator Vitest itself uses between the suite chain and the test name: Vitest 5 -+// matches `testNamePattern` against the chain joined with ' > '; before, a plain space. -+// (stryker-js PR #6214, carried as a pnpm patch until a release has it.) -+export const VITEST_5_TEST_NAME_SEPARATOR = ' > '; -+export const LEGACY_TEST_NAME_SEPARATOR = ' '; -+export function collectTestName({ name, suite, }, separator = LEGACY_TEST_NAME_SEPARATOR) { - const nameParts = [name]; - let currentSuite = suite; - while (currentSuite) { - nameParts.unshift(currentSuite.name); - currentSuite = currentSuite.suite; - } -- return nameParts.join(' ').trim(); -+ return nameParts.join(separator).trim(); - } --export function toRawTestId(test) { -- return `${test.file?.filepath ?? 'unknown.js'}#${collectTestName(test)}`; -+export function toRawTestId(test, separator = LEGACY_TEST_NAME_SEPARATOR) { -+ return `${test.file?.filepath ?? 'unknown.js'}#${collectTestName(test, separator)}`; - } - //# sourceMappingURL=test-helpers.js.map -\ No newline at end of file -diff --git a/dist/src/vitest-helpers.js b/dist/src/vitest-helpers.js -index fa4f8138ab3b2aba64f4e715be2d8126da6ccf8b..14349c6e0e51b20369a3e10a5b91f0c8b671aa28 100644 ---- a/dist/src/vitest-helpers.js -+++ b/dist/src/vitest-helpers.js -@@ -17,11 +17,11 @@ function convertTaskStateToTestStatus(taskState, testMode) { - } - return TestStatus.Failed; - } --export function convertTestToTestResult(test) { -+export function convertTestToTestResult(test, separator) { - const status = convertTaskStateToTestStatus(test.result?.state, test.mode); - const baseTestResult = { -- id: normalizeTestId(toRawTestId(test)), -- name: collectTestName(test), -+ id: normalizeTestId(toRawTestId(test, separator)), -+ name: collectTestName(test, separator), - timeSpentMs: test.result?.duration ?? 0, - fileName: test.file?.filepath && path.resolve(test.file.filepath), - }; -diff --git a/dist/src/vitest-test-runner.js b/dist/src/vitest-test-runner.js -index 84f1ca026503b8e92b7adc952ec6c6a401943656..3fabeb45098fa483aee07dce4b74fad7cebdce10 100644 ---- a/dist/src/vitest-test-runner.js -+++ b/dist/src/vitest-test-runner.js -@@ -7,6 +7,15 @@ import { commonTokens, tokens, } from '@stryker-mutator/api/plugin'; - import { DryRunStatus, toMutantRunResult, determineHitLimitReached, TestStatus, } from '@stryker-mutator/api/test-runner'; - import { errorToString, escapeRegExp, normalizeFileName, notEmpty, testFilesProvided, } from '@stryker-mutator/util'; - import { vitestWrapper } from './vitest-wrapper.js'; -+import { LEGACY_TEST_NAME_SEPARATOR, VITEST_5_TEST_NAME_SEPARATOR, } from './test-helpers.js'; -+// Vitest 5 matches `testNamePattern` against the suite chain joined with ' > ' rather -+// than a space, so a filter built from space-joined names matches nothing and every -+// covered mutant runs zero tests (stryker-js #6210, PR #6214). -+function testNameSeparator() { -+ return semver.satisfies(vitestWrapper.version, '>=5.0.0') -+ ? VITEST_5_TEST_NAME_SEPARATOR -+ : LEGACY_TEST_NAME_SEPARATOR; -+} - import { convertTestToTestResult, fromTestId, collectTestsFromSuite, normalizeCoverage, isErrorCodeError, VITEST_ERROR_CODES, } from './vitest-helpers.js'; - const STRYKER_SETUP = fileURLToPath(new URL('./stryker-setup.js', import.meta.url)); - export class VitestTestRunner { -@@ -83,6 +92,7 @@ export class VitestTestRunner { - }); - this.ctx.provide('globalNamespace', this.globalNamespace); - this.ctx.provide('isGreaterThanVitest4Point1', semver.satisfies(vitestWrapper.version, '>=4.1.0')); -+ this.ctx.provide('testNameSeparator', testNameSeparator()); - this.ctx.config.browser.screenshotFailures = false; - this.ctx.projects.forEach((project) => { - project.config.setupFiles = [ -@@ -173,7 +183,7 @@ export class VitestTestRunner { - .filter((test) => test.result); // if no result: it was skipped because of bail - let failure = false; - const testResults = tests.map((test) => { -- const testResult = convertTestToTestResult(test); -+ const testResult = convertTestToTestResult(test, testNameSeparator()); - failure ||= testResult.status === TestStatus.Failed; - return testResult; - }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bf2139de2..2d1851595 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,13 +10,11 @@ overrides: extract-zip: npm:@electron-internal/extract-zip@^1.0.5 undici@6: ^6.28.1 undici@7: ^7.29.1 - qs: ^6.16.0 basic-ftp: ^6.2.1 shell-quote: ^1.11.0 web-ext>@devicefarmer/adbkit: '-' patchedDependencies: - '@stryker-mutator/vitest-runner@10.0.0': c5d635178da5a48e07051030a6d2eb3f33f4b31a71f4232c05f099e8e90f3dc2 Coloris@0.25.0: d8a066fa49aa80466d054aad0f7a2c767b2f62cf365492c155bb9b4ce30fb2ec dashjs@5.2.1: f09c7ddbd4aedea040b042bfc600ab65b3b6131d6bfdd8dbfaf3ea580fd20ffc gif.js@0.2.0: 7f90135cc94c36690ec1e9725f81b9ec0386d2b62e08e8e6defbd864d58cc1ae @@ -27,12 +25,6 @@ importers: .: devDependencies: - '@stryker-mutator/core': - specifier: 10.0.0 - version: 10.0.0(@types/node@26.6.5) - '@stryker-mutator/vitest-runner': - specifier: 10.0.0 - version: 10.0.0(patch_hash=c5d635178da5a48e07051030a6d2eb3f33f4b31a71f4232c05f099e8e90f3dc2)(@stryker-mutator/core@10.0.0(@types/node@26.6.5))(vitest@5.0.5) '@stylistic/eslint-plugin': specifier: ^5.10.0 version: 5.10.0(eslint@10.13.0(jiti@2.7.0)(supports-color@8.1.1)) @@ -127,211 +119,26 @@ packages: resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} - '@babel/code-frame@8.0.6': - resolution: {integrity: sha512-uMHhvmDmwFiLuiozaoRYTZHqMFuu3fem/X9JY78lohAuLoh8LSGGC8JqUzo2cVuBsBxkjMZNk56CE7ock8Xxkw==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/compat-data@8.0.5': - resolution: {integrity: sha512-YLsYoQMvL8l8WrGpN3Zj7O1wK5LEBN+cQtux7BcuHyxIXve724XG+zuJ1n3U1cUweRtTzQOA4IHbuQw3N34SZw==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/core@8.0.6': - resolution: {integrity: sha512-5zwYt1V4ji3mXKKRIAkohSJ29WepxNwxQi+7y7P5AcVPh1dcxnZBU2cfxHnPwS+u9+lZnXPsv30TQaF2xg+Tfg==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/generator@8.0.6': - resolution: {integrity: sha512-/pcanjdRsonCexCuxgGD8fKnBLLzk2i9uM4kmcmGyyev2R5YDs+rafMYZ89RvaGY1mW8T7C5au0TyYaEeHBGng==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-annotate-as-pure@8.0.0': - resolution: {integrity: sha512-NSpMkMsvvZqzThJ0p1B02cbtA2ObEyfBvq950bmNkyxsxvcxwhvvCB036rKhlEnuBBo30bOrk13u3FzlKSoRrw==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-compilation-targets@8.0.6': - resolution: {integrity: sha512-HTrtZ4+iA0+kzdbCgvdSk1U4pEl3BvpGnlUbualCGNbrVhhQvhgBzurTUmqpWyvyHbWYWaIfdx2mOlL9LJjsew==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-create-class-features-plugin@8.0.6': - resolution: {integrity: sha512-Hy7wG2Pk1LnAkFMq0CbBk789XMTYVzYGxR7tKgk+TOpZckQRME3Tdou4mMT/8DFjJFxFZ8R6UsS4DR/duBKlVA==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/helper-globals@8.0.6': - resolution: {integrity: sha512-OdnA/N52LhzFpeUuVz5YGuSWjc7TPHiFmVYZbPlSgExocO2GwbxVpSni9MVs5wwW+wZ4kPuwBEBN9pIPDYz1mA==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-member-expression-to-functions@8.0.5': - resolution: {integrity: sha512-GLe05QD98BkNFTkjaqeqF9QSRoHLKrrB4tpoplyQuuPrQJ72rtmkM4wvqJLX/sjZPqkbK5MUYSsuUTqdJoOVjA==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-module-imports@8.0.0': - resolution: {integrity: sha512-NZ7mSS93o4ndX4KrbD7W8Sf3QT8Qe24PrnFyUcuOPDzK6faqDFKjY9RG7he7+I7FdiQ4llpnosFqzrXa+Vy3Ew==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-module-transforms@8.0.6': - resolution: {integrity: sha512-YUi+3X0cb0v97xKhuqkLdrwQtP6XXv1eVbhLRCFyMwG481UskbMQk4mjH7K/Jg3oJ1KLskvFwwq4kF/QnABkWQ==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/helper-optimise-call-expression@8.0.0': - resolution: {integrity: sha512-3W6satvtPuCUkUx63S2jMoW9EQNYkADgs1HTfufmL7gCmAulHMKupA/12WNz4A0GMMFn/YnWWwqOT9IZrJHQjg==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-plugin-utils@8.0.1': - resolution: {integrity: sha512-3PKFgjTyPlhFhorfP+SjKQxLViIL++zWjFOO4hGriYU+Bsm983DxEM1JmDRJVWXV0O9npu+xXRqz7Pbd3mh70g==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/helper-replace-supers@8.0.1': - resolution: {integrity: sha512-B1SZADIcy3tmH8CmWvj4SHi/oAPom4UL3uknTc2QRNsPVLFk/sPnZvQL/8kj7Y5omvjMqie0vklvs6XM4OLW5Q==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/helper-skip-transparent-expression-wrappers@8.0.0': - resolution: {integrity: sha512-xmCA9kP3IhySsqhzwIdWGlDN/1A4cCKNBO/uwZx/3YzmDoMePwno2Q5/Bq0q+tYaKbeF940YiKV/kaW8Mzvpjw==} - engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-string-parser@7.29.7': resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@8.0.6': - resolution: {integrity: sha512-+6HYEBnsDRZHJtUTAEfMQd0zMDqdFHS7C+5vAsEZqBUr3vEMWOWlHJ0Jz1gS8jJIlCvLsuA6ivmeoqzH936YcA==} - engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-validator-identifier@7.29.7': resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@8.0.6': - resolution: {integrity: sha512-HYx0YmuchRxRSpnjvcNffnPS8DCauKNmnumIuHG3jnQAVewRA7kfJGwF13ayEpSZs7s4R/oBH4eppuXcAQd5JQ==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-validator-option@8.0.0': - resolution: {integrity: sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helpers@8.0.5': - resolution: {integrity: sha512-fQtPOXjYOYv85PIdwotp2TJGVYOycX0PQq+l844fFAxOULtBy8BVF35GyeueX0r4KvDthqPH5xAI1clQPk/2uA==} - engines: {node: ^22.18.0 || >=24.11.0} - '@babel/parser@7.29.8': resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@8.0.6': - resolution: {integrity: sha512-LpGDIYJAzc3Y3PT9x+FxBrGYu2PlWxLmyN7SwPTzaX0LSwEmFJBsRnPBqmaXF2r1v+Zhz6lNiEJ+7yKtM5+Ugg==} - engines: {node: ^22.18.0 || >=24.11.0} - hasBin: true - - '@babel/plugin-proposal-decorators@8.0.2': - resolution: {integrity: sha512-+C6O6KKXU7BBq1GNaIkFJxrALUVGRcr+WeWm4OcuRl3h+l/CmNfcTLMrT2Lm3uvGBimBH/8pEBRrXJFLoO67Gg==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-syntax-decorators@8.0.1': - resolution: {integrity: sha512-NI+0S/6MvR6GlcQFwjDZ+WIc2qvG6TXN534lYs9llNldwW4b7Dh6KTtk030FA0xWdYGs4t1lWo+OEWN8wGB+Nw==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-syntax-jsx@8.0.1': - resolution: {integrity: sha512-n0jtCOxEovhU7METqSQjcZO9pX53nu9uNIjMS+hEt+Nt9jA7oOZoBIgbCxhhASmF6T6rPDGge5UAvh6Z4eFz/g==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-syntax-typescript@8.0.3': - resolution: {integrity: sha512-jmTPwps7oSQSZaV1SxkQ3C12UWyufGysGc5OzDpZzvPAIX4mO7dJT3hoqkWVrSImvkcMiknir1iLN1SNV/CZzg==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-transform-destructuring@8.0.5': - resolution: {integrity: sha512-evjxc5fGvpXG2WMGSalpX8IJZVumLIDgk5r5eRhvXRDqFX/GPWq1BeRfJalPCcwJfrR5A/wvegUhx9W5Nr7/mg==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-transform-explicit-resource-management@8.0.5': - resolution: {integrity: sha512-Vr20jk/ZxRGu30o0jYvcKl2Pf0tiyr8H9q2ZGxYD6yjOpv9DdP6//I85q0cSOdADZhsu/ZZoApjGVCfl4xnVJw==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-transform-modules-commonjs@8.0.1': - resolution: {integrity: sha512-PMuzulWrrzFNmY3lXSk/tV9NRb7y0eZZLJY4UEo2TKszroxvUZHAPPi+T9FDyrQhod+TQA+t+8/QYaaMpiEuhA==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-transform-react-display-name@8.0.1': - resolution: {integrity: sha512-soLishXlkyu6jcICPyO3HEP7A3GCzKEnn7XfvYrImuWEOwFAz93qShmWSYPf5ww0ZkO4By0zsN2bVIDF54fSdA==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-transform-react-jsx-development@8.0.1': - resolution: {integrity: sha512-Hb+HUZpV9KFHjm+F+P3aLDMi8QXU9l3ROCQv20z18Me2sGyW5nNNR5YTevNlgHvCpFek3BnAwhDGq/BRndXViw==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-transform-react-jsx@8.0.1': - resolution: {integrity: sha512-NgkoF7Uq+30TmOPDdNUimT0Nta02uVjqJRFNlVWKrbOCu/CkzfHa4aMnIs0lMpkMmZmWA1e42Va+F04i/pY1zw==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-transform-react-pure-annotations@8.0.1': - resolution: {integrity: sha512-7/8UwU8hoPBurXa9tUiTTC8aACTRy5tCqLUtqikHp2eGiWoEB57AduOdbQ71OOMTEvawKrGhv3WfzkDpI+/oSg==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-transform-typescript@8.0.6': - resolution: {integrity: sha512-WF3yRlQtClzScvQbWct00ix63+w3DPiyU0WmCBU4YqK539n3VvJFElElpevoD8wfu6953CbiNoUZBi2B7/5jXw==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/preset-react@8.0.1': - resolution: {integrity: sha512-jrFuPp/pTddFZbtmWhdLNAYc6UMcpboeUPnw0BBrm4nOmcAko/1TRcFi1PzWCeOFRU+VaSiKmat87W1HvR7mIg==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/preset-typescript@8.0.1': - resolution: {integrity: sha512-qrPhQIN1NLrPmzgazF9XKQqXrOcp/WJly+K+6ReFonn24FZqRJO7clxOJo6Ni75L+2vAqI3cHVU2OJLBxoPp5A==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - '@babel/runtime@8.0.7': resolution: {integrity: sha512-k0hagDDq/6w4v+0Sp4wFvIz/yswH5O7Va6aRTnD7N62Tnborp4X+YB+H3XUcWVSR4aE47WPEXiIIZchBs0GmYg==} - '@babel/template@8.0.0': - resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/traverse@8.0.6': - resolution: {integrity: sha512-ilYV+qLStGzSKLipJlETdvdtpK3rAuwfCmCoGKv15MU4EoeIuLkespSNoNLFGOPSciEHx9TLWtN5mv0fz5w5mQ==} - engines: {node: ^22.18.0 || >=24.11.0} - '@babel/types@7.29.8': resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} - '@babel/types@8.0.6': - resolution: {integrity: sha512-c+xgSWboV2pdwXP67BUWDVRHi2BO5Q3KwxyFVs7taVTY+fsK47/L51ZXQoV9rozHJDNHvJ4v4WEsI/IlxV2l2A==} - engines: {node: ^22.18.0 || >=24.11.0} - '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} @@ -588,10 +395,6 @@ packages: resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} engines: {node: '>=18'} - '@inquirer/ansi@2.0.8': - resolution: {integrity: sha512-WpQM+Ti6Z40EFwwt+uL2p4UabT+W179zHp6HhLVOzfbwnVn05IPO/eXIZXGNqcT1jbQ15SujNLzQ39k4QPPxBQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/checkbox@4.3.2': resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} engines: {node: '>=18'} @@ -601,15 +404,6 @@ packages: '@types/node': optional: true - '@inquirer/checkbox@5.2.5': - resolution: {integrity: sha512-bRt8J8m+Fot9CXv+zNQGXUq2ET0MggR1fPz7v6edN6MFYmsbfGnMmkmWZJEegMKqrAC8ej/o1sqisHZXZJMAfQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/confirm@5.1.21': resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} engines: {node: '>=18'} @@ -619,15 +413,6 @@ packages: '@types/node': optional: true - '@inquirer/confirm@6.3.2': - resolution: {integrity: sha512-Xvr/0HggjddPtGppuqVmxhTw+Hr8PvsZ/k0HmOEaAqQEt80OITNkFWnsdNmyT0/eM4Ab+iJLx2R8rctlEyfSVg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/core@10.3.2': resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} engines: {node: '>=18'} @@ -637,15 +422,6 @@ packages: '@types/node': optional: true - '@inquirer/core@12.0.3': - resolution: {integrity: sha512-wsSy0sznmXwkty+2PzZwx00Cazc/E0r0B7mAzdGROz2Ct+DFZXaK7WDjGZvgjRldxH5ZhFVfF2lgkYrqgOw2KA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/editor@4.2.23': resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} engines: {node: '>=18'} @@ -655,15 +431,6 @@ packages: '@types/node': optional: true - '@inquirer/editor@5.3.3': - resolution: {integrity: sha512-YsKkS2q63IiLtaDK/9nqzdComN97SDQrmKiyNggN+ceP4ty+Z6VwyTz3FpjeUWeW1Efss2xHFKCC9sx7hnrsxg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/expand@4.0.23': resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} engines: {node: '>=18'} @@ -673,15 +440,6 @@ packages: '@types/node': optional: true - '@inquirer/expand@5.1.5': - resolution: {integrity: sha512-uHuXLmXW+TtIfT/9vSBotypAkqn1n34Ul+CLGPos/xANyO4Ff5xZzkYhbKR4NEcfVK4a9mHQOpwVZzluSHFRGw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/external-editor@1.0.3': resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} engines: {node: '>=18'} @@ -691,23 +449,10 @@ packages: '@types/node': optional: true - '@inquirer/external-editor@3.0.5': - resolution: {integrity: sha512-f3QQJRIX5ZEneBHNUIuPjmbdzHnmRFJA8r2dkcb8q+OM5Uv5KtnuAttQumnrjcBVBM3mcTX1CkmtAkU58VRZxg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/figures@1.0.15': resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} engines: {node: '>=18'} - '@inquirer/figures@2.0.9': - resolution: {integrity: sha512-EAWgUTGQ/Umgga51dE3B2PUHbufuXarDfg86uVgoSgNHNNQnyFKcOrQLWVqYMghuSyHh8+2HUH0Js9cTC1WAdg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/input@4.3.1': resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} engines: {node: '>=18'} @@ -717,15 +462,6 @@ packages: '@types/node': optional: true - '@inquirer/input@5.1.6': - resolution: {integrity: sha512-HtcJhB2QFVXbLuJ5S3syhNbTUVxYvwqV4VRBDkQceBloC9bmTViUoRFP5PbSaDZb3HzfPmpuU/gG4ybVBz4FHA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/number@3.0.23': resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} engines: {node: '>=18'} @@ -735,15 +471,6 @@ packages: '@types/node': optional: true - '@inquirer/number@4.2.3': - resolution: {integrity: sha512-6Yuwh1NGSbu1Lo4N1EWjXs1jKRntLg/ZCwhmeorEHde90v1XxAozdbd4Iu30eOQLW+6h1hp2O9ujNfLSbTPJnA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/password@4.0.23': resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} engines: {node: '>=18'} @@ -753,15 +480,6 @@ packages: '@types/node': optional: true - '@inquirer/password@5.2.2': - resolution: {integrity: sha512-W9zYdyzogK+6110mqwaSJWCBu2yA5Q/OfnGSjjZB1bNpHlmUozXxTl0+QOZBNeVd6Qo81/qT75gW05gLAtITxw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/prompts@7.10.1': resolution: {integrity: sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==} engines: {node: '>=18'} @@ -771,15 +489,6 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.7.2': - resolution: {integrity: sha512-QoRB4wFIjgH5iOhSjoIKMkTvSHDuV+O3OITlIqAYO0oK5x364GJILXiMBvlPiE+klg7Xx9tq5XVqQHcGUDYYPA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/rawlist@4.1.11': resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} engines: {node: '>=18'} @@ -789,15 +498,6 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@5.3.5': - resolution: {integrity: sha512-1oHky1ONfCOwNrnkQGDE1oaSij/3fI6HFMSf2H/WsGO2lEyDX9My82iggITSy9ddSZ8yk8j9v41OI0fVoSIoaA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/search@3.2.2': resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} engines: {node: '>=18'} @@ -807,15 +507,6 @@ packages: '@types/node': optional: true - '@inquirer/search@4.3.3': - resolution: {integrity: sha512-fyuIU1Nbpvwlikjg3gXwJFDI11+EFjqQ7P+iByfmivIKQ1vmaykNrD/vy5unHuUqUpsOsnvJ25//tPF7E/RBRA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/select@4.4.2': resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} engines: {node: '>=18'} @@ -825,15 +516,6 @@ packages: '@types/node': optional: true - '@inquirer/select@5.2.5': - resolution: {integrity: sha512-9kc15hr8r/kI+3DO/xLog5nOzTz1jqsHXa6JBFzmQKhkoJ8Slda1I1L/uD8ZSZ9tF1yp79wwXe7mclvX1rqR2Q==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/type@3.0.10': resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} engines: {node: '>=18'} @@ -843,15 +525,6 @@ packages: '@types/node': optional: true - '@inquirer/type@4.1.1': - resolution: {integrity: sha512-yJoHYrMnxIsJZCY+0Vb66Dy3he3kL3e2wOBKhoSwWWAzZAY82emlxwgprCtp6yRixvNRNq9ztfRWQYPNr3Go7A==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -880,9 +553,6 @@ packages: resolution: {integrity: sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jridgewell/gen-mapping@0.4.0-beta.0': - resolution: {integrity: sha512-JdGNkbE4GlNPYQhM0L95fBQr7ctLZJ276QXQLTad4t1oSdnnCI3fDq9DW3BqYAWv8Wc3+HS+4Gsii1oPMCfz1w==} - '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -1052,29 +722,6 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@stryker-mutator/api@10.0.0': - resolution: {integrity: sha512-ZtAJ0ZT3MVRCWJTBE2h90XB/6E+4lifHYtcTyNG6nU2nLekPgTo4gD5esjX6Okxo1b/JB4jJzyxYB54fwKAoJw==} - engines: {node: '>=22.0.0'} - - '@stryker-mutator/core@10.0.0': - resolution: {integrity: sha512-ZvMsRyaXQQ5e6Thcid9pkuODv6Fn9E3nrBQJUap+hcJuGJ4unm26afo3m6YKSjn8kinyxJ/3TXf0cTWRDaTxVw==} - engines: {node: '>=22.0.0'} - hasBin: true - - '@stryker-mutator/instrumenter@10.0.0': - resolution: {integrity: sha512-B7Wmn1KlEWyFeOz6D6oGvQGRfi5Xw3VemG6dEKvFQp4qLvxD9Mf4kcZghfxffgnYwXd3bFgqXsJ+ZGlhdfIOrQ==} - engines: {node: '>=22.0.0'} - - '@stryker-mutator/util@10.0.0': - resolution: {integrity: sha512-LzOpHiJaCp2ABQgnPMlrQQcsK43bd5Vo/2FGL78aN62yDoeRQ+4j3tzeuXxK5OAHdC3fUz6TDoy4IsoAuLAd3w==} - - '@stryker-mutator/vitest-runner@10.0.0': - resolution: {integrity: sha512-SHK2/vfvRUpiz7jXPnQMBnr6zLdm69DK03Mo5mPhaZWcRSygrKUqYsPqWsXsK+5ySHzlMTfCyFK5NQ/X9sJFFw==} - engines: {node: '>=22.0.0'} - peerDependencies: - '@stryker-mutator/core': 10.0.0 - vitest: '>=2.0.0' - '@stylistic/eslint-plugin@5.10.0': resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1170,9 +817,6 @@ packages: '@types/filewriter@0.0.33': resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} - '@types/gensync@1.0.5': - resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} - '@types/har-format@1.2.16': resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==} @@ -1185,9 +829,6 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - '@types/jsesc@2.5.1': - resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} - '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -1547,10 +1188,6 @@ packages: ajv@8.20.0: resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - angular-html-parser@10.11.0: - resolution: {integrity: sha512-3vERzJ65UFDr3C7uozLJwsNcQS3FS784dSh583oDgDTTZMgXe3/pdyXgKndxiP5R2lvYRfW6gSl145Hnyf2OFA==} - engines: {node: '>= 14'} - ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -1672,11 +1309,6 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.11.26: - resolution: {integrity: sha512-GLQdD3y6UF8iVuMJl5fHgE4jdn/ua7n+toKfLgNlg3BqQtOZjpy68T8Tup8/wGWZCDlm7KMg7tPb4MPn7oN0TQ==} - engines: {node: '>=6.0.0'} - hasBin: true - bcp-47-match@2.0.3: resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} @@ -1700,11 +1332,6 @@ packages: browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - browserslist@4.29.3: - resolution: {integrity: sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - buffer-crc32@1.0.0: resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} engines: {node: '>=8.0.0'} @@ -1725,14 +1352,6 @@ packages: cacheable@2.5.0: resolution: {integrity: sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==} - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1741,9 +1360,6 @@ packages: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} - caniuse-lite@1.0.30001814: - resolution: {integrity: sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==} - chai@6.3.0: resolution: {integrity: sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==} engines: {node: '>=18'} @@ -1942,16 +1558,10 @@ packages: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} - des.js@1.1.0: - resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} - detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - diff-match-patch@1.0.5: - resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} - diff@8.0.4: resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} engines: {node: '>=0.3.1'} @@ -1981,10 +1591,6 @@ packages: resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} engines: {node: '>=12'} - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -2020,10 +1626,6 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - empathic@2.1.0: - resolution: {integrity: sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==} - engines: {node: '>=14'} - encoding-sniffer@0.2.1: resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} @@ -2042,21 +1644,9 @@ packages: error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - es-module-lexer@2.3.2: resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} - es-object-atoms@1.1.2: - resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} - engines: {node: '>= 0.4'} - es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} @@ -2218,18 +1808,9 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-string-truncated-width@3.0.3: - resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} - - fast-string-width@3.0.2: - resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-uri@3.1.8: resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} - fast-wrap-ansi@0.2.2: - resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -2284,10 +1865,6 @@ packages: flatted@3.4.4: resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} - flru@1.0.2: - resolution: {integrity: sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==} - engines: {node: '>=6'} - foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -2301,9 +1878,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - fuse.js@7.5.0: resolution: {integrity: sha512-sQtrEfA+ez/3G0cCZecF70oqpCRttCexYUG4mUrtWL49ULUzUyxokt5kyqwtKzj1270RaKih+hcP3qLcumccow==} engines: {node: '>=10'} @@ -2324,10 +1898,6 @@ packages: peerDependencies: '@wdio/logger': ^9.18.0 || ^10.0.0 - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -2336,18 +1906,10 @@ packages: resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - get-port@7.2.0: resolution: {integrity: sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==} engines: {node: '>=16'} - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - get-stream@9.0.1: resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} engines: {node: '>=18'} @@ -2380,10 +1942,6 @@ packages: resolution: {integrity: sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==} engines: {node: '>=18'} - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -2397,18 +1955,10 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - hashery@1.5.1: resolution: {integrity: sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==} engines: {node: '>=20'} - hasown@2.0.4: - resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} - engines: {node: '>= 0.4'} - hls.js@1.7.3: resolution: {integrity: sha512-MsPlx6yVW4Qv4C7mEVou4/gk/5cN2dVxOTnrNjPSmyH2f0Ln+/UkG10Ax1PE6OvrmTVPKgQYozTtBaPOuCzq7A==} @@ -2642,9 +2192,6 @@ packages: jose@5.9.6: resolution: {integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==} - js-md4@0.3.2: - resolution: {integrity: sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==} - js-tokens@10.0.0: resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} @@ -2659,11 +2206,6 @@ packages: resolution: {integrity: sha512-paNr4LFIFPjeeSmwNYdrb8FafLLG/Cr2Af3GjbsHJ5CxIjH4r0c2emlmRdAtpPAieP1gRVzk6buBbVP5gBMGAg==} hasBin: true - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -2674,9 +2216,6 @@ packages: resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - json-rpc-2.0@1.8.1: - resolution: {integrity: sha512-BmN42JKn6FI36pcMMzHCXQhpKNEfbeqgSIcUYHKnifq0/4Ey6PDinovwUOgajT7NsgUtpWdDXaCWlpI4LHXN3g==} - json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -2686,11 +2225,6 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - jsonfile@6.2.1: resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} @@ -2836,9 +2370,6 @@ packages: lodash.flattendeep@4.4.0: resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} - lodash.groupby@4.6.0: - resolution: {integrity: sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==} - lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} @@ -2898,19 +2429,12 @@ packages: marky@1.3.0: resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==} - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - mdn-data@2.27.1: resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} mediabunny@1.61.6: resolution: {integrity: sha512-VHEZ53/7jGl4dQ+uOdndsZufFYwEUFWv9UXgvrGun3OapyzoqI9iaPOD7z3xxY/nAttLZBNwswgJzMtGJAquOQ==} - minimalistic-assert@1.0.1: - resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - minimatch@10.2.6: resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} engines: {node: 18 || 20 || >=22} @@ -2956,27 +2480,10 @@ packages: resolution: {integrity: sha512-I7tSVxHGPlmPN/enE3mS1aOSo6bWBfls+3HmuEeCUBCE7gWnm3cBXCBkpurzFjVRwC6Kld8lLaZ1Iv5vOcjvcQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - mutation-server-protocol@0.4.1: - resolution: {integrity: sha512-SBGK0j8hLDne7bktgThKI8kGvGTx3rY3LAeQTmOKZ5bVnL/7TorLMvcVF7dIPJCu5RNUWhkkuF53kurygYVt3g==} - engines: {node: '>=18'} - - mutation-testing-elements@3.8.4: - resolution: {integrity: sha512-5CF1SNa7at5ZH33vEr+21wNebTSrtNIVvnzaUlxortHajOrIPaSLczIWvg6sI/fsExekQ7jookwf2cHftkckqQ==} - - mutation-testing-metrics@3.8.4: - resolution: {integrity: sha512-DZcmndJBH6nrNs3tpiB3OcMVq9KkG2cHCpJSnDxSxPwi9qrafRmoec40xjhkbzOoX1n7/4UkDqg5tIj4A6nvCw==} - - mutation-testing-report-schema@3.8.4: - resolution: {integrity: sha512-s4G71R6Lt/PpZ0cqeglIcgyBdzLM8E+SeCHZAPg1wkSsPtRBa4XfPzAozYKdiJk/TLbNEEb7En9t0/bveuPuxA==} - mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} - mute-stream@3.0.0: - resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} - engines: {node: ^20.17.0 || >=22.9.0} - nanoid@3.3.20: resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2985,10 +2492,6 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - node-releases@2.0.57: - resolution: {integrity: sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==} - engines: {node: '>=18'} - normalize-package-data@6.0.2: resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} engines: {node: ^16.14.0 || >=18.0.0} @@ -3012,10 +2515,6 @@ packages: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} - obug@2.2.1: - resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} - engines: {node: '>=12.20.0'} - obug@3.0.0: resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} engines: {node: '>=12.20.0'} @@ -3171,10 +2670,6 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - promise-toolbox@0.21.0: resolution: {integrity: sha512-NV8aTmpwrZv+Iys54sSFOBx3tuVaOBvvrft5PNppnxy9xpU/akHbaWIril22AB22zaPgrgwKdD0KsrM0ptUtpg==} engines: {node: '>=6'} @@ -3197,10 +2692,6 @@ packages: resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==} engines: {node: '>=20'} - qs@6.16.0: - resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==} - engines: {node: '>=0.6'} - query-selector-shadow-dom@1.0.1: resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} @@ -3350,22 +2841,6 @@ packages: resolution: {integrity: sha512-PcByqNyT/38F2kDNi006HAMRJaULuBzq/FOsw3qdZvX/GA9W/jamDaRskgHjubHiftXK5sIFxLNkvrXUwcof6Q==} engines: {node: '>= 0.4'} - side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.1: - resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} - engines: {node: '>= 0.4'} - signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} @@ -3391,10 +2866,6 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} - spacetrim@0.11.59: resolution: {integrity: sha512-lLYsktklSRKprreOm7NXReW8YiX2VBjbgmXYEziOoGf/qsJqAEACaDvoTtUOycwjpaSh+bT8eu0KrJn7UNxiCg==} @@ -3537,10 +3008,6 @@ packages: resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} engines: {node: '>=14.14'} - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -3549,10 +3016,6 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - tunnel@0.0.6: - resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} - engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} - type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -3569,22 +3032,11 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - typed-inject@5.0.0: - resolution: {integrity: sha512-0Ql2ORqBORLMdAW89TQKZsb1PQkFGImFfVmncXWe7a+AA3+7dh7Se9exxZowH4kbnlvKEFkMxUYdHUpjYWFJaA==} - engines: {node: '>=18'} - - typed-rest-client@2.3.1: - resolution: {integrity: sha512-k4kX5Up6qA68D0Cby2AK+6+vM5k3qTxe+/3FqhnHRExjY5cfbOnzjQZbP/LXleF8hVoDvDqxlgk9KK83HoBZlQ==} - engines: {node: '>= 16.0.0'} - typescript@7.0.2: resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} engines: {node: '>=16.20.0'} hasBin: true - underscore@1.13.8: - resolution: {integrity: sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==} - undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -3611,12 +3063,6 @@ packages: resolution: {integrity: sha512-YAsrLMIlhfSCm9rga5TZsJ1mXgahs7N0qOTokzU8mFz35hUrYMvVkaEPefI3rEb/vkAWAOj1Km/qdije9RC1kQ==} engines: {node: '>=20'} - update-browserslist-db@1.3.3: - resolution: {integrity: sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - update-notifier@7.3.1: resolution: {integrity: sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA==} engines: {node: '>=18'} @@ -3637,10 +3083,6 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - verkit@0.3.2: - resolution: {integrity: sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==} - engines: {node: '>=18.12.0'} - vite@8.3.4: resolution: {integrity: sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3737,9 +3179,6 @@ packages: wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - weapon-regex@2.0.5: - resolution: {integrity: sha512-BJZkSdtcae9Wb8+hKNtAqR+Q61EMOAuQnpCCHKwT50K7fIWg7/2/RnbKR27YB+sMcYxYLUVj+Asm5Y2XhD8mZg==} - web-ext@10.8.0: resolution: {integrity: sha512-UdZJkdZZ9TTqDUDZLf1Tb9MCFQsi2P7FmHGx2e00VB+1U9iJPA1WUUHUtdjh2m7Cnh6su27wivhmEkaSkcl2+g==} engines: {node: '>=20.0.0', npm: '>=8.0.0'} @@ -3895,9 +3334,6 @@ packages: resolution: {integrity: sha512-dSvYKdvLsAHCDqPOhIwk/q5CvuWtTB3Dgpoe0uVEFjTzIOAmsQpprX25InCvrvJsirEbu1OHyy67n/kAj1Sw/w==} engines: {node: '>=18'} - zod@4.6.5: - resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} - snapshots: '@babel/code-frame@7.29.7': @@ -3906,245 +3342,21 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/code-frame@8.0.6': - dependencies: - '@babel/helper-validator-identifier': 8.0.6 - js-tokens: 10.0.0 - - '@babel/compat-data@8.0.5': {} - - '@babel/core@8.0.6': - dependencies: - '@babel/code-frame': 8.0.6 - '@babel/generator': 8.0.6 - '@babel/helper-compilation-targets': 8.0.6 - '@babel/helpers': 8.0.5 - '@babel/parser': 8.0.6 - '@babel/template': 8.0.0 - '@babel/traverse': 8.0.6 - '@babel/types': 8.0.6 - '@types/gensync': 1.0.5 - convert-source-map: 2.0.0 - empathic: 2.1.0 - gensync: 1.0.0-beta.2 - import-meta-resolve: 4.2.0 - json5: 2.2.3 - obug: 2.2.1 - verkit: 0.3.2 - - '@babel/generator@8.0.6': - dependencies: - '@babel/parser': 8.0.6 - '@babel/types': 8.0.6 - '@jridgewell/gen-mapping': 0.4.0-beta.0 - '@jridgewell/trace-mapping': 0.3.31 - '@types/jsesc': 2.5.1 - jsesc: 3.1.0 - - '@babel/helper-annotate-as-pure@8.0.0': - dependencies: - '@babel/types': 8.0.6 - - '@babel/helper-compilation-targets@8.0.6': - dependencies: - '@babel/compat-data': 8.0.5 - '@babel/helper-validator-option': 8.0.0 - browserslist: 4.29.3 - flru: 1.0.2 - verkit: 0.3.2 - - '@babel/helper-create-class-features-plugin@8.0.6(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-member-expression-to-functions': 8.0.5 - '@babel/helper-optimise-call-expression': 8.0.0 - '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.6) - '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 - '@babel/traverse': 8.0.6 - verkit: 0.3.2 - - '@babel/helper-globals@8.0.6': {} - - '@babel/helper-member-expression-to-functions@8.0.5': - dependencies: - '@babel/traverse': 8.0.6 - '@babel/types': 8.0.6 - - '@babel/helper-module-imports@8.0.0': - dependencies: - '@babel/traverse': 8.0.6 - '@babel/types': 8.0.6 - - '@babel/helper-module-transforms@8.0.6(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-module-imports': 8.0.0 - '@babel/helper-validator-identifier': 8.0.6 - '@babel/traverse': 8.0.6 - - '@babel/helper-optimise-call-expression@8.0.0': - dependencies: - '@babel/types': 8.0.6 - - '@babel/helper-plugin-utils@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - - '@babel/helper-replace-supers@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-member-expression-to-functions': 8.0.5 - '@babel/helper-optimise-call-expression': 8.0.0 - '@babel/traverse': 8.0.6 - - '@babel/helper-skip-transparent-expression-wrappers@8.0.0': - dependencies: - '@babel/traverse': 8.0.6 - '@babel/types': 8.0.6 - '@babel/helper-string-parser@7.29.7': {} - '@babel/helper-string-parser@8.0.6': {} - '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helper-validator-identifier@8.0.6': {} - - '@babel/helper-validator-option@8.0.0': {} - - '@babel/helpers@8.0.5': - dependencies: - '@babel/template': 8.0.0 - '@babel/types': 8.0.6 - '@babel/parser@7.29.8': dependencies: '@babel/types': 7.29.8 - '@babel/parser@8.0.6': - dependencies: - '@babel/types': 8.0.6 - - '@babel/plugin-proposal-decorators@8.0.2(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.6) - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - '@babel/plugin-syntax-decorators': 8.0.1(@babel/core@8.0.6) - - '@babel/plugin-syntax-decorators@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - - '@babel/plugin-syntax-jsx@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - - '@babel/plugin-syntax-typescript@8.0.3(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - - '@babel/plugin-transform-destructuring@8.0.5(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - - '@babel/plugin-transform-explicit-resource-management@8.0.5(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - '@babel/plugin-transform-destructuring': 8.0.5(@babel/core@8.0.6) - - '@babel/plugin-transform-modules-commonjs@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-module-transforms': 8.0.6(@babel/core@8.0.6) - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - - '@babel/plugin-transform-react-display-name@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - - '@babel/plugin-transform-react-jsx-development@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/plugin-transform-react-jsx': 8.0.1(@babel/core@8.0.6) - - '@babel/plugin-transform-react-jsx@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-module-imports': 8.0.0 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - '@babel/plugin-syntax-jsx': 8.0.1(@babel/core@8.0.6) - '@babel/types': 8.0.6 - - '@babel/plugin-transform-react-pure-annotations@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - - '@babel/plugin-transform-typescript@8.0.6(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.6) - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 - '@babel/plugin-syntax-typescript': 8.0.3(@babel/core@8.0.6) - - '@babel/preset-react@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - '@babel/helper-validator-option': 8.0.0 - '@babel/plugin-transform-react-display-name': 8.0.1(@babel/core@8.0.6) - '@babel/plugin-transform-react-jsx': 8.0.1(@babel/core@8.0.6) - '@babel/plugin-transform-react-jsx-development': 8.0.1(@babel/core@8.0.6) - '@babel/plugin-transform-react-pure-annotations': 8.0.1(@babel/core@8.0.6) - - '@babel/preset-typescript@8.0.1(@babel/core@8.0.6)': - dependencies: - '@babel/core': 8.0.6 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.6) - '@babel/helper-validator-option': 8.0.0 - '@babel/plugin-transform-modules-commonjs': 8.0.1(@babel/core@8.0.6) - '@babel/plugin-transform-typescript': 8.0.6(@babel/core@8.0.6) - '@babel/runtime@8.0.7': {} - '@babel/template@8.0.0': - dependencies: - '@babel/code-frame': 8.0.6 - '@babel/parser': 8.0.6 - '@babel/types': 8.0.6 - - '@babel/traverse@8.0.6': - dependencies: - '@babel/code-frame': 8.0.6 - '@babel/generator': 8.0.6 - '@babel/helper-globals': 8.0.6 - '@babel/parser': 8.0.6 - '@babel/template': 8.0.0 - '@babel/types': 8.0.6 - obug: 2.2.1 - '@babel/types@7.29.8': dependencies: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@babel/types@8.0.6': - dependencies: - '@babel/helper-string-parser': 8.0.6 - '@babel/helper-validator-identifier': 8.0.6 - '@bcoe/v8-coverage@1.0.2': {} '@cacheable/memory@2.2.0': @@ -4333,8 +3545,6 @@ snapshots: '@inquirer/ansi@1.0.2': {} - '@inquirer/ansi@2.0.8': {} - '@inquirer/checkbox@4.3.2(@types/node@26.6.5)': dependencies: '@inquirer/ansi': 1.0.2 @@ -4345,15 +3555,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/checkbox@5.2.5(@types/node@26.6.5)': - dependencies: - '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@26.6.5) - '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/confirm@5.1.21(@types/node@26.6.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@26.6.5) @@ -4361,13 +3562,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/confirm@6.3.2(@types/node@26.6.5)': - dependencies: - '@inquirer/core': 12.0.3(@types/node@26.6.5) - '@inquirer/type': 4.1.1(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/core@10.3.2(@types/node@26.6.5)': dependencies: '@inquirer/ansi': 1.0.2 @@ -4381,18 +3575,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/core@12.0.3(@types/node@26.6.5)': - dependencies: - '@inquirer/ansi': 2.0.8 - '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@26.6.5) - cli-width: 4.1.0 - fast-wrap-ansi: 0.2.2 - mute-stream: 3.0.0 - signal-exit: 4.1.0 - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/editor@4.2.23(@types/node@26.6.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@26.6.5) @@ -4401,14 +3583,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/editor@5.3.3(@types/node@26.6.5)': - dependencies: - '@inquirer/core': 12.0.3(@types/node@26.6.5) - '@inquirer/external-editor': 3.0.5(@types/node@26.6.5) - '@inquirer/type': 4.1.1(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/expand@4.0.23(@types/node@26.6.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@26.6.5) @@ -4417,13 +3591,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/expand@5.1.5(@types/node@26.6.5)': - dependencies: - '@inquirer/core': 12.0.3(@types/node@26.6.5) - '@inquirer/type': 4.1.1(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/external-editor@1.0.3(@types/node@26.6.5)': dependencies: chardet: 2.2.0 @@ -4431,17 +3598,8 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/external-editor@3.0.5(@types/node@26.6.5)': - dependencies: - chardet: 2.2.0 - iconv-lite: 0.7.3 - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/figures@1.0.15': {} - '@inquirer/figures@2.0.9': {} - '@inquirer/input@4.3.1(@types/node@26.6.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@26.6.5) @@ -4449,13 +3607,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/input@5.1.6(@types/node@26.6.5)': - dependencies: - '@inquirer/core': 12.0.3(@types/node@26.6.5) - '@inquirer/type': 4.1.1(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/number@3.0.23(@types/node@26.6.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@26.6.5) @@ -4463,13 +3614,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/number@4.2.3(@types/node@26.6.5)': - dependencies: - '@inquirer/core': 12.0.3(@types/node@26.6.5) - '@inquirer/type': 4.1.1(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/password@4.0.23(@types/node@26.6.5)': dependencies: '@inquirer/ansi': 1.0.2 @@ -4478,14 +3622,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/password@5.2.2(@types/node@26.6.5)': - dependencies: - '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@26.6.5) - '@inquirer/type': 4.1.1(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/prompts@7.10.1(@types/node@26.6.5)': dependencies: '@inquirer/checkbox': 4.3.2(@types/node@26.6.5) @@ -4501,21 +3637,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/prompts@8.7.2(@types/node@26.6.5)': - dependencies: - '@inquirer/checkbox': 5.2.5(@types/node@26.6.5) - '@inquirer/confirm': 6.3.2(@types/node@26.6.5) - '@inquirer/editor': 5.3.3(@types/node@26.6.5) - '@inquirer/expand': 5.1.5(@types/node@26.6.5) - '@inquirer/input': 5.1.6(@types/node@26.6.5) - '@inquirer/number': 4.2.3(@types/node@26.6.5) - '@inquirer/password': 5.2.2(@types/node@26.6.5) - '@inquirer/rawlist': 5.3.5(@types/node@26.6.5) - '@inquirer/search': 4.3.3(@types/node@26.6.5) - '@inquirer/select': 5.2.5(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/rawlist@4.1.11(@types/node@26.6.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@26.6.5) @@ -4524,13 +3645,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/rawlist@5.3.5(@types/node@26.6.5)': - dependencies: - '@inquirer/core': 12.0.3(@types/node@26.6.5) - '@inquirer/type': 4.1.1(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/search@3.2.2(@types/node@26.6.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@26.6.5) @@ -4540,14 +3654,6 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/search@4.3.3(@types/node@26.6.5)': - dependencies: - '@inquirer/core': 12.0.3(@types/node@26.6.5) - '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/select@4.4.2(@types/node@26.6.5)': dependencies: '@inquirer/ansi': 1.0.2 @@ -4558,23 +3664,10 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 - '@inquirer/select@5.2.5(@types/node@26.6.5)': - dependencies: - '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@26.6.5) - '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@26.6.5) - optionalDependencies: - '@types/node': 26.6.5 - '@inquirer/type@3.0.10(@types/node@26.6.5)': optionalDependencies: '@types/node': 26.6.5 - '@inquirer/type@4.1.1(@types/node@26.6.5)': - optionalDependencies: - '@types/node': 26.6.5 - '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -4611,11 +3704,6 @@ snapshots: '@types/yargs': 17.0.35 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.4.0-beta.0': - dependencies: - '@jridgewell/sourcemap-codec': 1.6.0 - '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.6.0': {} @@ -4718,72 +3806,6 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@stryker-mutator/api@10.0.0': - dependencies: - mutation-testing-metrics: 3.8.4 - mutation-testing-report-schema: 3.8.4 - tslib: 2.8.1 - typed-inject: 5.0.0 - - '@stryker-mutator/core@10.0.0(@types/node@26.6.5)': - dependencies: - '@inquirer/prompts': 8.7.2(@types/node@26.6.5) - '@stryker-mutator/api': 10.0.0 - '@stryker-mutator/instrumenter': 10.0.0 - '@stryker-mutator/util': 10.0.0 - ajv: 8.20.0 - chalk: 5.6.2 - commander: 14.0.3 - diff-match-patch: 1.0.5 - emoji-regex: 10.6.0 - execa: 9.6.1 - json-rpc-2.0: 1.8.1 - lodash.groupby: 4.6.0 - minimatch: 10.2.6 - mutation-server-protocol: 0.4.1 - mutation-testing-elements: 3.8.4 - mutation-testing-metrics: 3.8.4 - mutation-testing-report-schema: 3.8.4 - npm-run-path: 6.0.0 - progress: 2.0.3 - rxjs: 7.8.2 - semver: 7.8.5 - source-map: 0.7.6 - tree-kill: 1.2.2 - tslib: 2.8.1 - typed-inject: 5.0.0 - typed-rest-client: 2.3.1 - transitivePeerDependencies: - - '@types/node' - - '@stryker-mutator/instrumenter@10.0.0': - dependencies: - '@babel/core': 8.0.6 - '@babel/generator': 8.0.6 - '@babel/parser': 8.0.6 - '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.6) - '@babel/plugin-transform-explicit-resource-management': 8.0.5(@babel/core@8.0.6) - '@babel/preset-react': 8.0.1(@babel/core@8.0.6) - '@babel/preset-typescript': 8.0.1(@babel/core@8.0.6) - '@babel/traverse': 8.0.6 - '@stryker-mutator/api': 10.0.0 - '@stryker-mutator/util': 10.0.0 - angular-html-parser: 10.11.0 - semver: 7.8.5 - tslib: 2.8.1 - weapon-regex: 2.0.5 - - '@stryker-mutator/util@10.0.0': {} - - '@stryker-mutator/vitest-runner@10.0.0(patch_hash=c5d635178da5a48e07051030a6d2eb3f33f4b31a71f4232c05f099e8e90f3dc2)(@stryker-mutator/core@10.0.0(@types/node@26.6.5))(vitest@5.0.5)': - dependencies: - '@stryker-mutator/api': 10.0.0 - '@stryker-mutator/core': 10.0.0(@types/node@26.6.5) - '@stryker-mutator/util': 10.0.0 - semver: 7.8.5 - tslib: 2.8.1 - vitest: 5.0.5(@types/node@26.6.5)(@vitest/coverage-v8@5.0.5)(vite@8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)) - '@stylistic/eslint-plugin@5.10.0(eslint@10.13.0(jiti@2.7.0)(supports-color@8.1.1))': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.13.0(jiti@2.7.0)(supports-color@8.1.1)) @@ -4864,8 +3886,6 @@ snapshots: '@types/filewriter@0.0.33': {} - '@types/gensync@1.0.5': {} - '@types/har-format@1.2.16': {} '@types/istanbul-lib-coverage@2.0.6': {} @@ -4878,8 +3898,6 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 - '@types/jsesc@2.5.1': {} - '@types/json-schema@7.0.15': {} '@types/minimatch@3.0.5': {} @@ -5352,8 +4370,6 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - angular-html-parser@10.11.0: {} - ansi-align@3.0.1: dependencies: string-width: 4.2.3 @@ -5452,8 +4468,6 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.11.26: {} - bcp-47-match@2.0.3: {} boolbase@1.0.0: {} @@ -5484,14 +4498,6 @@ snapshots: browser-stdout@1.3.1: {} - browserslist@4.29.3: - dependencies: - baseline-browser-mapping: 2.11.26 - caniuse-lite: 1.0.30001814 - electron-to-chromium: 1.5.443 - node-releases: 2.0.57 - update-browserslist-db: 1.3.3(browserslist@4.29.3) - buffer-crc32@1.0.0: {} buffer-equal-constant-time@1.0.1: {} @@ -5515,22 +4521,10 @@ snapshots: keyv: 5.6.0 qified: 0.10.1 - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - callsites@3.1.0: {} camelcase@8.0.0: {} - caniuse-lite@1.0.30001814: {} - chai@6.3.0: {} chalk@4.1.2: @@ -5752,15 +4746,8 @@ snapshots: define-lazy-prop@3.0.0: {} - des.js@1.1.0: - dependencies: - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - detect-libc@2.1.2: {} - diff-match-patch@1.0.5: {} - diff@8.0.4: {} diff@9.0.0: {} @@ -5789,12 +4776,6 @@ snapshots: dotenv@17.4.2: {} - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - eastasianwidth@0.2.0: {} easy-table@1.2.0: @@ -5836,8 +4817,6 @@ snapshots: emoji-regex@9.2.2: {} - empathic@2.1.0: {} - encoding-sniffer@0.2.1: dependencies: iconv-lite: 0.6.3 @@ -5853,16 +4832,8 @@ snapshots: dependencies: is-arrayish: 0.2.1 - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - es-module-lexer@2.3.2: {} - es-object-atoms@1.1.2: - dependencies: - es-errors: 1.3.0 - es6-error@4.1.1: {} esbuild@0.28.2: @@ -6102,18 +5073,8 @@ snapshots: fast-levenshtein@2.0.6: {} - fast-string-truncated-width@3.0.3: {} - - fast-string-width@3.0.2: - dependencies: - fast-string-truncated-width: 3.0.3 - fast-uri@3.1.8: {} - fast-wrap-ansi@0.2.2: - dependencies: - fast-string-width: 3.0.2 - fdir@6.5.0(picomatch@4.0.7): optionalDependencies: picomatch: 4.0.7 @@ -6169,8 +5130,6 @@ snapshots: flatted@3.4.4: {} - flru@1.0.2: {} - foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -6185,8 +5144,6 @@ snapshots: fsevents@2.3.3: optional: true - function-bind@1.1.2: {} - fuse.js@7.5.0: {} fx-runner@1.7.0: @@ -6215,32 +5172,12 @@ snapshots: modern-tar: 0.8.5 undici: 8.11.2 - gensync@1.0.0-beta.2: {} - get-caller-file@2.0.5: {} get-east-asian-width@1.6.0: {} - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.2 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.4 - math-intrinsics: 1.1.0 - get-port@7.2.0: {} - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.2 - get-stream@9.0.1: dependencies: '@sec-ant/readable-stream': 0.4.1 @@ -6275,8 +5212,6 @@ snapshots: globals@17.13.0: {} - gopd@1.2.0: {} - graceful-fs@4.2.10: {} graceful-fs@4.2.11: {} @@ -6285,16 +5220,10 @@ snapshots: has-flag@4.0.0: {} - has-symbols@1.1.0: {} - hashery@1.5.1: dependencies: hookified: 1.15.1 - hasown@2.0.4: - dependencies: - function-bind: 1.1.2 - hls.js@1.7.3(patch_hash=7bf3c8187174dcdd9951f64f89092432f2c76698ca18dc4b55b45b62c78c9b5a): {} hookified@1.15.1: {} @@ -6505,8 +5434,6 @@ snapshots: jose@5.9.6: {} - js-md4@0.3.2: {} - js-tokens@10.0.0: {} js-tokens@4.0.0: {} @@ -6519,8 +5446,6 @@ snapshots: dependencies: argparse: 3.0.3 - jsesc@3.1.0: {} - json-buffer@3.0.1: {} json-merge-patch@1.0.2: @@ -6529,16 +5454,12 @@ snapshots: json-parse-even-better-errors@3.0.2: {} - json-rpc-2.0@1.8.1: {} - json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: {} json-stable-stringify-without-jsonify@1.0.1: {} - json5@2.2.3: {} - jsonfile@6.2.1: dependencies: universalify: 2.0.1 @@ -6687,8 +5608,6 @@ snapshots: lodash.flattendeep@4.4.0: {} - lodash.groupby@4.6.0: {} - lodash.includes@4.3.0: {} lodash.isboolean@3.0.3: {} @@ -6735,8 +5654,6 @@ snapshots: marky@1.3.0: {} - math-intrinsics@1.1.0: {} - mdn-data@2.27.1: {} mediabunny@1.61.6: @@ -6744,8 +5661,6 @@ snapshots: '@types/dom-mediacapture-transform': 0.1.12 '@types/dom-webcodecs': 0.1.13 - minimalistic-assert@1.0.1: {} - minimatch@10.2.6: dependencies: brace-expansion: 5.0.12 @@ -6800,28 +5715,12 @@ snapshots: array-union: 3.0.1 minimatch: 3.1.5 - mutation-server-protocol@0.4.1: - dependencies: - zod: 4.6.5 - - mutation-testing-elements@3.8.4: {} - - mutation-testing-metrics@3.8.4: - dependencies: - mutation-testing-report-schema: 3.8.4 - - mutation-testing-report-schema@3.8.4: {} - mute-stream@2.0.0: {} - mute-stream@3.0.0: {} - nanoid@3.3.20: {} natural-compare@1.4.0: {} - node-releases@2.0.57: {} - normalize-package-data@6.0.2: dependencies: hosted-git-info: 7.0.2 @@ -6847,8 +5746,6 @@ snapshots: object-inspect@1.13.4: {} - obug@2.2.1: {} - obug@3.0.0: {} on-exit-leak-free@2.1.2: {} @@ -7022,8 +5919,6 @@ snapshots: process@0.11.10: {} - progress@2.0.3: {} - promise-toolbox@0.21.0: dependencies: make-error: 1.3.6 @@ -7042,11 +5937,6 @@ snapshots: dependencies: hookified: 2.2.0 - qs@6.16.0: - dependencies: - es-define-property: 1.0.1 - side-channel: 1.1.1 - query-selector-shadow-dom@1.0.1: {} quick-format-unescaped@4.0.4: {} @@ -7188,34 +6078,6 @@ snapshots: shell-quote@1.12.0: {} - side-channel-list@1.0.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.1 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - signal-exit@4.1.0: {} slash@3.0.0: {} @@ -7235,8 +6097,6 @@ snapshots: source-map@0.6.1: {} - source-map@0.7.6: {} - spacetrim@0.11.59: {} spdx-correct@3.2.0: @@ -7387,8 +6247,6 @@ snapshots: tmp@0.2.7: {} - tree-kill@1.2.2: {} - tslib@2.8.1: {} tsx@4.23.15: @@ -7397,8 +6255,6 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - tunnel@0.0.6: {} - type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -7409,16 +6265,6 @@ snapshots: type-fest@4.41.0: {} - typed-inject@5.0.0: {} - - typed-rest-client@2.3.1: - dependencies: - des.js: 1.1.0 - js-md4: 0.3.2 - qs: 6.16.0 - tunnel: 0.0.6 - underscore: 1.13.8 - typescript@7.0.2: optionalDependencies: '@typescript/typescript-aix-ppc64': 7.0.2 @@ -7442,8 +6288,6 @@ snapshots: '@typescript/typescript-win32-arm64': 7.0.2 '@typescript/typescript-win32-x64': 7.0.2 - underscore@1.13.8: {} - undici-types@6.21.0: {} undici-types@8.9.0: {} @@ -7458,12 +6302,6 @@ snapshots: upath@3.0.8: {} - update-browserslist-db@1.3.3(browserslist@4.29.3): - dependencies: - browserslist: 4.29.3 - escalade: 3.2.0 - picocolors: 1.1.1 - update-notifier@7.3.1: dependencies: boxen: 8.0.1 @@ -7492,8 +6330,6 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - verkit@0.3.2: {} - vite@8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15): dependencies: lightningcss: 1.33.0 @@ -7546,8 +6382,6 @@ snapshots: dependencies: defaults: 1.0.4 - weapon-regex@2.0.5: {} - web-ext@10.8.0(jiti@2.7.0)(supports-color@8.1.1): dependencies: '@babel/runtime': 8.0.7 @@ -7755,5 +6589,3 @@ snapshots: compress-commons: 7.0.1 normalize-path: 3.0.0 readable-stream: 4.7.0 - - zod@4.6.5: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b771c687c..1a7c767de 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -20,10 +20,6 @@ overrides: # so each keeps its own. undici@6: ^6.28.1 undici@7: ^7.29.1 - # Dependabot #56-#58: @stryker-mutator/core 10.0.0 (its newest) wants typed-rest-client - # ~2.3.0, which pins qs to exactly 6.15.1; typed-rest-client 3 moved to ^6.16.0. Stryker - # uses it only for `stryker init` and its dashboard reporter, neither of which runs here. - qs: ^6.16.0 # Dependabot #59 (high): basic-ftp <= 6.2.0 parses a directory listing in quadratic time. # @puppeteer/browsers -> proxy-agent -> pac-proxy-agent -> get-uri, whose newest release # (8.0.1) still asks for ^5.3.1, brings 5.3.1, so the fix (6.2.1) needs this. 6.0.0's one @@ -55,7 +51,6 @@ allowBuilds: dtrace-provider: false spawn-sync: false patchedDependencies: - '@stryker-mutator/vitest-runner@10.0.0': patches/@stryker-mutator__vitest-runner@10.0.0.patch Coloris@0.25.0: patches/Coloris@0.25.0.patch dashjs@5.2.1: patches/dashjs@5.2.1.patch gif.js@0.2.0: patches/gif.js@0.2.0.patch diff --git a/stryker.config.mjs b/stryker.config.mjs deleted file mode 100644 index e6344bbcb..000000000 --- a/stryker.config.mjs +++ /dev/null @@ -1,227 +0,0 @@ -// Mutation testing (T4): `pnpm run test:mutation`, and weekly on CI (mutation-tests.yml). -// -// Stryker changes one thing at a time in the modules below - a comparison, a bound, a -// call left out - and runs the unit tests against each change. A change the tests still -// pass is a place where a fix could ship without a test that fails without it: the rule -// every fix here follows, checked by hand until now. The weekly run reports; it does not -// gate (no break threshold). -// -// Only pure-logic modules with unit tests: the DOM and the player are the e2e suites'. -// In four areas (#253): `core`, `network` (the downloader, the loaders and what they use), -// `tools` (the tools and e2e harness modules with unit tests) and `host` (the mpv host, on -// the command runner), each split into shards (SHARDS, below) that mutation-tests.yml runs -// side by side, each in a job of its own. STRYKER_SHARD picks one; without it, all of them run (`pnpm run test:mutation`, -// locally). -// -// How long an area took with the command runner, measured on CI (#349, run 37333779402, -// 2026-10-05): network 7 mutants a minute, core 14, tools 10 - with ~3,300, ~5,100 and -// ~3,200 mutants, 7.7, 6 and 5.3 hours. The first estimate (1.2 s a mutant, 2026-10-04) was a local run's: on CI a -// mutant the tests do not catch runs the whole suite (~18 s), and a third to a half of -// them survive. One job an area ran out of its 240 minutes at 51-74%, and no report came. -// So each area was cut into PARTS shards of about the same size, each a few hours; with the -// vitest runner (below) a shard should take minutes, measured on its first CI run. -// -// The weekly job runs on Linux: the mpv host's Windows-only tests (mpvHostInstall, the -// PowerShell cases of mpvHostSecurity) are skipped there, so its PowerShell and WMI -// mutants can only survive, and count against its score. -// -// Stryker's vitest runner, with per-test coverage: a mutant runs only the tests that reached -// its code, in a Vitest that stays up between mutants - 143 mutants in 31 s on a PC -// (2026-10-06), where the command runner ran the whole unit suite for each, ~18 s a mutant -// on CI, the hours above. Its 10.0.0 release (August 2026) predates Vitest 5, which joins a -// test's suite chain with ' > ': its test filter matched nothing and every mutant -// "survived" (stryker-js #6210). FastStream carries the fix, stryker-js PR #6214, as a pnpm -// patch (patches/@stryker-mutator__vitest-runner@10.0.0.patch); the Patched libraries -// workflow drops it once a release has it, and moves @stryker-mutator/core with the runner -// (LOCKSTEP in tools/check-patched-updates.mjs). -// -// A mutant is switched on inside the test worker, so a test that runs a module as a process -// of its own does not see it there. For the mpv host that left its message loop untested, -// so the host keeps the command runner (COMMAND_AREAS); the tools' tests that start their -// tool as a process only reach its entry line, where the vitest runner sees a crashed run. -import fs from 'node:fs'; - -export const AREAS = { - core: [ - 'chrome/background/CustomSourcePatterns.mjs', - 'chrome/background/DownloadFilename.mjs', - 'chrome/background/KeyShortcut.mjs', - 'chrome/background/ManifestTypes.mjs', - 'chrome/background/MpvBackend.mjs', - 'chrome/background/MultiRegexMatcher.mjs', - 'chrome/background/StreamLengths.mjs', - 'chrome/background/TabTracker.mjs', - 'chrome/background/UrlMatchList.mjs', - 'chrome/player/modules/LargeBuffer.mjs', - 'chrome/player/modules/hls2mp4/ptsNormalize.mjs', - 'chrome/player/modules/remux/TimestampRebaser.mjs', - 'chrome/player/network/OpQueue.mjs', - 'chrome/player/network/SpeedTracker.mjs', - 'chrome/player/options/KeybindUtils.mjs', - 'chrome/player/players/hls/HLSDecrypter.mjs', - 'chrome/player/players/mp4/SourceBufferWrapper.mjs', - 'chrome/player/players/mp4/StallWatchdog.mjs', - 'chrome/player/ui/FrameStepper.mjs', - 'chrome/player/utils/StreamLength.mjs', - 'chrome/player/utils/StreamPick.mjs', - 'chrome/player/utils/SubtitleSyncUtils.mjs', - 'chrome/player/utils/SubtitleUtils.mjs', - 'chrome/player/utils/URLUtils.mjs', - ], - network: [ - 'chrome/background/BackgroundUtils.mjs', - 'chrome/background/NetRequestRuleManager.mjs', - 'chrome/player/modules/SecureMemory.mjs', - 'chrome/player/network/DownloadEntry.mjs', - 'chrome/player/network/DownloadManager.mjs', - 'chrome/player/network/OPFSManager.mjs', - 'chrome/player/network/StandardDownloader.mjs', - 'chrome/player/network/FetchLoader.mjs', - 'chrome/player/players/LevelManager.mjs', - 'chrome/player/players/SyncedAudioPlayer.mjs', - 'chrome/player/players/dash/DashLoader.mjs', - 'chrome/player/players/hls/HLSFragmentRequester.mjs', - 'chrome/player/players/hls/HLSLoader.mjs', - 'chrome/player/utils/StringUtils.mjs', - ], - tools: [ - 'tests/e2e/bidi.mjs', - 'tests/e2e/mozLog.mjs', - 'tests/e2e/mp4Fixture.mjs', - 'tests/e2e/reportRetried.mjs', - 'tests/e2e/retriedSpecs.mjs', - 'tests/e2e/serveFile.mjs', - 'tests/e2e/setupGuard.mjs', - 'tests/e2e/shardSpecs.mjs', - 'tests/e2e/testTimeout.mjs', - 'tools/check-patched-updates.mjs', - 'tools/check-toolchain.mjs', - 'tools/check-update-path.mjs', - 'tools/e2e-spec-weights.mjs', - 'tools/fetch-amo-signed.mjs', - 'tools/mutation-report.mjs', - 'tools/newest-release.mjs', - 'tools/recut-patch.mjs', - 'tools/sign-amo.mjs', - 'tools/verify-linux.mjs', - ], - // The mpv host, with the command runner (COMMAND_AREAS, below). - host: ['native-host/faststream-mpv-host.mjs'], -}; - -// The areas Stryker runs with the command runner, every mutant against the whole unit suite -// in a process of its own, which hands the active mutant to the processes a test starts -// (__STRYKER_ACTIVE_MUTANT__). The vitest runner switches a mutant on inside the test worker -// only, and the mpv host's message loop - main() and sendMessage(), which run only in the -// host process mpvHostVersion.test.mjs starts and talks to - had no test reaching it there: -// 24 of its mutants the command runner caught were "no coverage" (CI runs 37384050152 and -// 37393654214, compared mutant by mutant, 2026-10-06). Every other module came out the same -// (11,313 of 11,370 alike; the rest a crashed run for a caught one, or two swapped on a line). -export const COMMAND_AREAS = ['host']; - -// How many shards each area is cut into. With the vitest runner one each: on CI the seven -// shards of 2026-10-06 took 2 to 10 minutes (core 7 and 10, network 2 to 3, tools 2 to 3). -// The host, on the command runner, about an hour and a half at core's 14 mutants a minute, -// inside its job's 350 minutes (mutation-tests.yml). -export const PARTS = {core: 1, network: 1, tools: 1, host: 1}; - -/** - * An area's modules in `parts` groups of about the same size, the size of a file standing - * for how many mutants it gives: the largest first, each to the group with the least so far. - * The same files give the same groups, so a shard's name always means the same modules. - * @param {string[]} modules - The area's modules. - * @param {number} parts - How many groups. - * @return {string[][]} The groups, each in the area's own order. - */ -export function splitArea(modules, parts) { - const size = (file) => { - try { - return fs.statSync(new URL(file, import.meta.url)).size; - } catch { - return 0; - } - }; - const groups = Array.from({length: parts}, () => ({files: new Set(), size: 0})); - const bySize = modules.map((file) => ({file, size: size(file)})) - .sort((a, b) => b.size - a.size || a.file.localeCompare(b.file)); - for (const {file, size: bytes} of bySize) { - const lightest = groups.reduce((min, group) => group.size < min.size ? group : min); - lightest.files.add(file); - lightest.size += bytes; - } - return groups.map((group) => modules.filter((file) => group.files.has(file))); -} - -// core-1, network-1, tools-1, host-1: the shards mutation-tests.yml runs, one job each. -export const SHARDS = Object.fromEntries(Object.entries(AREAS).flatMap(([area, modules]) => - splitArea(modules, PARTS[area]).map((group, i) => [`${area}-${i + 1}`, group]))); - -/** - * The modules a run mutates. - * @param {string|undefined} shard - STRYKER_SHARD: a key of SHARDS, or empty for all. - * @return {string[]} - */ -export function modulesOf(shard) { - if (!shard) { - return Object.values(SHARDS).flat(); - } - if (!Object.hasOwn(SHARDS, shard)) { - throw new Error(`STRYKER_SHARD is ${shard}: it is one of ${Object.keys(SHARDS).join(', ')}`); - } - return SHARDS[shard]; -} - -/** - * The test runner settings for a shard: the command runner for one of COMMAND_AREAS, the - * vitest runner otherwise - and for a run of everything at once (`pnpm run test:mutation` - * with no STRYKER_SHARD), where the host's message loop then shows as no coverage. - * @param {string|undefined} shard - STRYKER_SHARD. - * @return {Object} - */ -export function runnerOf(shard) { - if (shard && COMMAND_AREAS.some((area) => shard.startsWith(`${area}-`))) { - return { - testRunner: 'command', - commandRunner: {command: 'node node_modules/vitest/vitest.mjs run --bail=1 --reporter=dot'}, - coverageAnalysis: 'off', - }; - } - return { - testRunner: 'vitest', - // pnpm's layout: Stryker looks for @stryker-mutator/* plugins beside its own core only. - plugins: ['@stryker-mutator/vitest-runner'], - vitest: {configFile: 'vitest.config.mjs'}, - coverageAnalysis: 'perTest', - }; -} - -export default { - ...runnerOf(process.env.STRYKER_SHARD), - // What the sandbox leaves out: builds, profiles, logs and fixtures the unit tests never - // read, and tsconfig.json, which Stryker would rewrite through TypeScript's JS API - - // TypeScript 7 has none (`ts.parseConfigFileTextToJson is not a function`). - ignorePatterns: [ - 'tsconfig.json', - '/.dev-profile*', - '/build_firefox_*', - '/built', - '/logs', - '/logs-moz', - '/.e2e-downloads', - '/reports', - '/coverage', - '/tests/e2e/fixtures', - '/fsaunpack', - '/docs', - ], - // Nothing here is TypeScript, and its HTML files do not parse as Stryker expects. - disableTypeChecks: false, - mutate: modulesOf(process.env.STRYKER_SHARD), - reporters: ['clear-text', 'progress', 'html', 'json'], - htmlReporter: {fileName: 'reports/mutation/index.html'}, - jsonReporter: {fileName: 'reports/mutation/mutation.json'}, - thresholds: {high: 80, low: 60, break: null}, - concurrency: 4, - timeoutMS: 60000, - incremental: false, -}; diff --git a/tests/unit/checkPatchedUpdates.test.mjs b/tests/unit/checkPatchedUpdates.test.mjs index 776cf2c99..c7b0ae008 100644 --- a/tests/unit/checkPatchedUpdates.test.mjs +++ b/tests/unit/checkPatchedUpdates.test.mjs @@ -1,6 +1,6 @@ import fs from 'node:fs'; import {describe, expect, it} from 'vitest'; -import {LOCKSTEP, compareVersions, githubRepo, patchedDependencies} from '../../tools/check-patched-updates.mjs'; +import {compareVersions, githubRepo, patchedDependencies} from '../../tools/check-patched-updates.mjs'; // The patched libraries are left out of Dependabot, and this script is what still notices // their updates. Reading the list wrongly, or comparing versions as text, would hide an @@ -11,7 +11,7 @@ const yaml = fs.readFileSync(new URL('../../pnpm-workspace.yaml', import.meta.ur describe('patchedDependencies', () => { it('reads every patched library with the version its patch is cut against', () => { const libraries = patchedDependencies(yaml); - expect(libraries.length).toBeGreaterThanOrEqual(6); + expect(libraries.length).toBeGreaterThanOrEqual(5); expect(libraries).toContainEqual({name: 'hls.js', version: '1.7.3'}); expect(libraries).toContainEqual({name: 'Coloris', version: '0.25.0'}); for (const {name, version} of libraries) { @@ -43,22 +43,10 @@ describe('patchedDependencies', () => { } }); - it('is the list Dependabot is told to ignore, with the packages that move with them', () => { + it('is the list Dependabot is told to ignore', () => { const dependabot = fs.readFileSync(new URL('../../.github/dependabot.yml', import.meta.url), 'utf8'); const ignored = [...dependabot.matchAll(/dependency-name: '([^']+)'/g)].map((match) => match[1]).sort(); - const patched = patchedDependencies(yaml).map(({name}) => name); - expect(ignored).toEqual([...patched, ...patched.flatMap((name) => LOCKSTEP[name] || [])].sort()); - }); - - it('pins what moves with a patched library to the library\'s own version', () => { - // @stryker-mutator/vitest-runner requires @stryker-mutator/core at its version exactly: - // apart, Stryker runs with a runner its core was not made for. - const pkg = JSON.parse(fs.readFileSync(new URL('../../package.json', import.meta.url), 'utf8')); - const declared = {...pkg.dependencies, ...pkg.devDependencies}; - for (const {name, version} of patchedDependencies(yaml)) { - for (const companion of LOCKSTEP[name] || []) expect(declared[companion], companion).toBe(version); - } - expect(LOCKSTEP['@stryker-mutator/vitest-runner']).toEqual(['@stryker-mutator/core']); + expect(ignored).toEqual(patchedDependencies(yaml).map(({name}) => name).sort()); }); it('leaves the other libraries the build copies to Dependabot\'s shipped group', () => { diff --git a/tests/unit/decodeSubtitleBytes.test.mjs b/tests/unit/decodeSubtitleBytes.test.mjs index 7344db250..bc3644206 100644 --- a/tests/unit/decodeSubtitleBytes.test.mjs +++ b/tests/unit/decodeSubtitleBytes.test.mjs @@ -4,7 +4,6 @@ import {afterEach, describe, expect, it, vi} from 'vitest'; import {RequestUtils} from '../../chrome/player/utils/RequestUtils.mjs'; import {SubtitleUtils} from '../../chrome/player/utils/SubtitleUtils.mjs'; import {installFakeDom} from './fakeCueDom.mjs'; -import {isMutationSandboxCopy} from './helpers/stryker.mjs'; // Subtitle files reach the player as bytes, from six places. Read the browser's way (UTF-8 // unless the file or the server says otherwise), an older SubRip file saved as @@ -149,9 +148,7 @@ describe('decodeSubtitleBytes at the places subtitle files come in', () => { expect(read('player/ui/subtitles/SubtitlesManager.mjs').match(/decodeSubtitleBytes\(/g)).toHaveLength(2); }); - // Not where Stryker rewrote SubtitleUtils: its copy is no longer the text content.js - // carries (helpers/stryker.mjs). - it.skipIf(isMutationSandboxCopy(read('player/utils/SubtitleUtils.mjs')))('content.js carries the same decodeSubtitleBytes', () => { + it('content.js carries the same decodeSubtitleBytes', () => { // content.js is a classic script and cannot import SubtitleUtils, so it has a copy. const body = (source, signature) => { const start = source.indexOf(signature); diff --git a/tests/unit/fetchAmoSigned.test.mjs b/tests/unit/fetchAmoSigned.test.mjs index 9a5aec23c..551941f7d 100644 --- a/tests/unit/fetchAmoSigned.test.mjs +++ b/tests/unit/fetchAmoSigned.test.mjs @@ -1,7 +1,6 @@ import fs from 'node:fs'; import {describe, expect, it} from 'vitest'; import {EXIT, isNetworkError, parseArgs, signingState, waitForSigned} from '../../tools/fetch-amo-signed.mjs'; -import {isMutationSandboxCopy} from './helpers/stryker.mjs'; // The AMO signing failsafe acts on what signingState answers: collect the xpi, wait, // upload again, or tell the owner. A wrong answer either never collects a signed build @@ -10,8 +9,7 @@ import {isMutationSandboxCopy} from './helpers/stryker.mjs'; describe('authentication', () => { const source = fs.readFileSync(new URL('../../tools/fetch-amo-signed.mjs', import.meta.url), 'utf8'); - // Stryker's rewrite of the module says nothing about its imports (helpers/stryker.mjs). - it.skipIf(isMutationSandboxCopy(source))('uses the AMO authentication of web-ext, which every release signs with', () => { + it('uses the AMO authentication of web-ext, which every release signs with', () => { // A token built by hand could drift from what AMO accepts; web-ext's is proven by // every release.yml run. expect(source).toMatch(/import \{JwtApiAuth\} from 'web-ext\/util\/submit-addon';/); diff --git a/tests/unit/helpers/stryker.mjs b/tests/unit/helpers/stryker.mjs deleted file mode 100644 index 335947edd..000000000 --- a/tests/unit/helpers/stryker.mjs +++ /dev/null @@ -1,15 +0,0 @@ -// Stryker's mutation runs (stryker.config.mjs) run the unit suite in a copy of the -// repository in which every module they mutate is rewritten: each expression wrapped in -// stryMutAct_/stryCov_ calls. A test that reads such a module as text - to check what it -// says, not what it does - cannot pass there, and it failed the run's first, unmutated pass -// (mutation-tests.yml, #349). It skips in that copy instead; in a normal run the file is the -// repository's own, and the test runs. - -/** - * Whether a module's text is Stryker's rewrite of it. - * @param {string} source - The file's text. - * @return {boolean} - */ -export function isMutationSandboxCopy(source) { - return /\bstry(?:MutAct|Cov)_[0-9a-f]+\(/.test(source); -} diff --git a/tests/unit/mpvHostInstall.test.mjs b/tests/unit/mpvHostInstall.test.mjs index d76bdb439..b41742324 100644 --- a/tests/unit/mpvHostInstall.test.mjs +++ b/tests/unit/mpvHostInstall.test.mjs @@ -15,9 +15,8 @@ import {Capabilities, HostVersion} from '../../native-host/faststream-mpv-host.m const root = path.resolve(import.meta.dirname, '../..'); // "José 中文", from code points: the file tools used to write this suite mangle escapes. const FOLDER = 'Jos' + String.fromCodePoint(0xE9) + ' ' + String.fromCodePoint(0x4E2D, 0x6587); -// A host that never answers (a mutation test's endless read loop, a real hang) used to outlive -// the run: Stryker gives up on a mutant about a minute in, before this test's own timeout, and -// nothing stopped the host, which spun a core for good. A ping answers well within this. +// A host that never answers (an endless read loop, a real hang) would outlive the run: nothing +// would stop it, and it would spin a core for good. A ping answers well within this. const REPLY_TIMEOUT_MS = 15000; let dir; diff --git a/tests/unit/mpvHostVersion.test.mjs b/tests/unit/mpvHostVersion.test.mjs index 4279a99ab..0ed415033 100644 --- a/tests/unit/mpvHostVersion.test.mjs +++ b/tests/unit/mpvHostVersion.test.mjs @@ -37,10 +37,6 @@ const RECORDED = { installer: 'db3b8027b508556b8af66eb4b8188460c2a5a6e1feb32d32b490f2e234b29b3a', }; -// Stryker runs this suite on a copy of the host with every mutant written into it -// (.stryker-tmp/sandbox-*), which is never the recorded file. -const inMutationSandbox = root.split(path.sep).includes('.stryker-tmp'); - /** * A file's SHA-256, its line ends read as LF (a Windows checkout may have CRLF). * @param {string} file - The file. @@ -52,7 +48,7 @@ function sha256Of(file) { } describe('the mpv host\'s version', () => { - it.skipIf(inMutationSandbox)('is raised with every change to the host or its installer', () => { + it('is raised with every change to the host or its installer', () => { const next = HostVersion === RECORDED.version ? HostVersion + 1 : HostVersion; expect({version: HostVersion, host: sha256Of(hostFile), installer: sha256Of(installerFile)}, 'native-host/faststream-mpv-host.mjs or install.ps1 changed. A PC keeps running its ' + diff --git a/tests/unit/mutationReport.test.mjs b/tests/unit/mutationReport.test.mjs deleted file mode 100644 index 0d51a2582..000000000 --- a/tests/unit/mutationReport.test.mjs +++ /dev/null @@ -1,71 +0,0 @@ -import {describe, expect, it} from 'vitest'; -import {issueBody, merge, missed, perFile, summary} from '../../tools/mutation-report.mjs'; - -// mutation-tests.yml's summary table and weekly issue, from Stryker's report. - -const mutant = (status, line, mutatorName = 'EqualityOperator', replacement = 'a <= b') => - ({status, mutatorName, replacement, location: {start: {line, column: 1}, end: {line, column: 9}}}); - -const report = { - files: { - 'chrome/player/utils/StreamPick.mjs': {mutants: [ - mutant('Killed', 3), mutant('Killed', 4), mutant('Timeout', 5), mutant('Survived', 9, 'ConditionalExpression', 'true'), - ]}, - 'chrome/background/DownloadFilename.mjs': {mutants: [ - mutant('NoCoverage', 20, 'StringLiteral', '""'), mutant('Killed', 2), mutant('Ignored', 1), mutant('CompileError', 7), - ]}, - }, -}; - -describe('mutation-report', () => { - it('counts each file\'s caught (killed, timed out) and not caught (survived, no coverage) mutants', () => { - expect(perFile(report)).toEqual([ - {file: 'chrome/background/DownloadFilename.mjs', total: 4, caught: 1, missed: 1, score: 50}, - {file: 'chrome/player/utils/StreamPick.mjs', total: 4, caught: 3, missed: 1, score: 75}, - ]); - }); - - it('writes a row per file and the total', () => { - const text = summary(report); - expect(text).toContain('| chrome/player/utils/StreamPick.mjs | 4 | 3 | 1 | 75% |'); - expect(text).toContain('| **All** | 8 | 4 | 2 | 66.7% |'); - }); - - it('lists what was not caught, by file and line', () => { - expect(missed(report).map((m) => `${m.file}:${m.line} ${m.status}`)).toEqual([ - 'chrome/background/DownloadFilename.mjs:20 NoCoverage', - 'chrome/player/utils/StreamPick.mjs:9 Survived', - ]); - }); - - it('writes the issue: who to tell, the run, and each mutant with what the line became', () => { - const body = issueBody(report, 'Nawid3333', 'https://github.com/x/y/actions/runs/1'); - expect(body).toMatch(/^@Nawid3333 The unit tests did not catch 2 of this week's mutants/); - expect(body).toContain('Run: https://github.com/x/y/actions/runs/1'); - expect(body).toContain('- line 20: no test reaches it - StringLiteral: `""`'); - expect(body).toContain('- line 9: survived - ConditionalExpression: `true`'); - }); - - it('keeps a replacement from breaking the list, and shows at most 100 mutants', () => { - const many = {files: {'a.mjs': {mutants: Array.from({length: 150}, (_, i) => mutant('Survived', i + 1, 'X', 'a | `b`\nc'))}}}; - const body = issueBody(many, 'o', 'r'); - expect(body).toContain('### Not caught (the first 100 of 150)'); - expect(body).toContain('- line 1: survived - X: `a \\| \'b\' c`'); - expect(body.match(/^- line /gm)).toHaveLength(100); - }); - - it('puts the shards\' reports together, every file of each (#253)', () => { - const network = {schemaVersion: '2', files: {'chrome/player/network/FetchLoader.mjs': {mutants: [mutant('Survived', 4)]}}}; - const merged = merge([{schemaVersion: '2', ...report}, network]); - expect(merged.schemaVersion).toBe('2'); - expect(Object.keys(merged.files).sort()).toEqual([ - 'chrome/background/DownloadFilename.mjs', 'chrome/player/network/FetchLoader.mjs', 'chrome/player/utils/StreamPick.mjs', - ]); - expect(missed(merged)).toHaveLength(3); - expect(merge([])).toEqual({files: {}}); - }); - - it('refuses a module two shards both report', () => { - expect(() => merge([report, report])).toThrow(/is in two reports/); - }); -}); diff --git a/tests/unit/recutPatch.test.mjs b/tests/unit/recutPatch.test.mjs index 5fbf8b89b..bd0208c28 100644 --- a/tests/unit/recutPatch.test.mjs +++ b/tests/unit/recutPatch.test.mjs @@ -160,32 +160,18 @@ describe('checkJavaScript', () => { }); }); -// The update pull request for a patched library also moves what must stay at its version -// (LOCKSTEP: Stryker's core with its vitest runner), and once the patch is dropped hands -// both back to Dependabot. Left apart, Stryker would run a runner its core was not made for. +// The update pull request for a patched library moves it, and only it, to the new version. describe('bumpPackageJson', () => { - const pj = JSON.stringify({devDependencies: { - '@stryker-mutator/core': '10.0.0', '@stryker-mutator/vitest-runner': '10.0.0', 'hls.js': '^1.7.3', - }}, null, 2); + const pj = JSON.stringify({devDependencies: {'dashjs': '5.2.1', 'hls.js': '^1.7.3'}}, null, 2); - it('moves Stryker\'s core with its vitest runner', () => { - const out = JSON.parse(bumpPackageJson(pj, '@stryker-mutator/vitest-runner', '10.0.0', '10.1.0')); - expect(out.devDependencies['@stryker-mutator/vitest-runner']).toBe('10.1.0'); - expect(out.devDependencies['@stryker-mutator/core']).toBe('10.1.0'); - expect(out.devDependencies['hls.js']).toBe('^1.7.3'); - }); - - it('moves a library without companions alone, and keeps its range prefix', () => { + it('moves the library alone, and keeps its range prefix', () => { const out = JSON.parse(bumpPackageJson(pj, 'hls.js', '1.7.3', '1.8.0')); expect(out.devDependencies['hls.js']).toBe('^1.8.0'); - expect(out.devDependencies['@stryker-mutator/core']).toBe('10.0.0'); + expect(out.devDependencies['dashjs']).toBe('5.2.1'); }); - it('refuses when the library is not at the version its patch is cut against, or a companion is missing', () => { + it('refuses when the library is not at the version its patch is cut against', () => { expect(() => bumpPackageJson(pj, 'hls.js', '1.7.2', '1.8.0')).toThrow(/no "hls.js" at 1.7.2/); - const noCore = JSON.stringify({devDependencies: {'@stryker-mutator/vitest-runner': '10.0.0'}}); - expect(() => bumpPackageJson(noCore, '@stryker-mutator/vitest-runner', '10.0.0', '10.1.0')) - .toThrow(/no "@stryker-mutator\/core", which moves with/); }); }); @@ -196,14 +182,14 @@ describe('dropDependabotIgnores', () => { const file = path.join(dir, 'dependabot.yml'); fs.writeFileSync(file, [ ' ignore:', - ' - dependency-name: \'@stryker-mutator/core\'', - ' - dependency-name: \'@stryker-mutator/vitest-runner\'', + ' - dependency-name: \'dashjs\'', + ' - dependency-name: \'gif.js\'', ' - dependency-name: \'hls.js\'', ' # - dependency-name: \'commented\'', '', ].join('\n')); - expect(dropDependabotIgnores(['@stryker-mutator/vitest-runner', '@stryker-mutator/core', 'not-there'], file)) - .toEqual(['@stryker-mutator/core', '@stryker-mutator/vitest-runner']); + expect(dropDependabotIgnores(['gif.js', 'dashjs', 'not-there'], file)) + .toEqual(['dashjs', 'gif.js']); expect(fs.readFileSync(file, 'utf8')).toBe([ ' ignore:', ' - dependency-name: \'hls.js\'', diff --git a/tests/unit/strykerShards.test.mjs b/tests/unit/strykerShards.test.mjs deleted file mode 100644 index eda795da2..000000000 --- a/tests/unit/strykerShards.test.mjs +++ /dev/null @@ -1,97 +0,0 @@ -import fs from 'node:fs'; -import path from 'node:path'; -import {describe, expect, it} from 'vitest'; -import config, {AREAS, COMMAND_AREAS, PARTS, SHARDS, modulesOf, runnerOf, splitArea} from '../../stryker.config.mjs'; - -// The weekly mutation run's modules are in shards, each run by a job of its own -// (mutation-tests.yml), because all of them in one job were past its 240 minutes (#253). -// A module no shard lists is never mutated; a shard the workflow does not run is never -// reported; a module with no unit test can only "survive". - -const root = path.resolve(import.meta.dirname, '../..'); -const workflow = fs.readFileSync(path.join(root, '.github/workflows/mutation-tests.yml'), 'utf8'); - -describe('stryker.config.mjs: the shards', () => { - it('mutates every shard\'s modules when no shard is picked, as a local run does', () => { - expect(config.mutate).toEqual(modulesOf(process.env.STRYKER_SHARD)); - expect(modulesOf(undefined)).toEqual(Object.values(SHARDS).flat()); - expect(modulesOf('')).toHaveLength(modulesOf(undefined).length); - }); - - it('runs one shard\'s modules, and refuses a shard it does not have', () => { - expect(modulesOf('network-1')).toEqual(SHARDS['network-1']); - // An area's name is no shard: its modules are in its parts. - expect(() => modulesOf('network')).toThrow(/STRYKER_SHARD is network/); - expect(() => modulesOf('everything')).toThrow(/STRYKER_SHARD is everything/); - }); - - it('lists each module once, each a file of the repository', () => { - const all = modulesOf(undefined); - expect(new Set(all).size).toBe(all.length); - expect(all.filter((file) => !fs.existsSync(path.join(root, file)))).toEqual([]); - }); - - it('lists only modules a unit test imports', () => { - const tests = fs.readdirSync(path.join(root, 'tests/unit'), {recursive: true}) - .filter((file) => file.endsWith('.mjs')) - .map((file) => fs.readFileSync(path.join(root, 'tests/unit', file), 'utf8')).join('\n'); - const untested = modulesOf(undefined).filter((file) => !tests.includes(path.basename(file))); - expect(untested).toEqual([]); - }); - - it('cuts each area into its parts, each module in one, none empty', () => { - // One job an area ran out of its 240 minutes at 51-74% on CI, and no report came (#349). - for (const [area, modules] of Object.entries(AREAS)) { - const parts = Object.keys(SHARDS).filter((name) => name.startsWith(area + '-')); - expect(parts).toHaveLength(PARTS[area]); - expect(parts.flatMap((name) => SHARDS[name]).sort()).toEqual([...modules].sort()); - expect(parts.filter((name) => SHARDS[name].length === 0)).toEqual([]); - } - }); - - it('makes parts of about the same size, the same ones each time', () => { - const sizes = splitArea(AREAS.core, PARTS.core) - .map((group) => group.reduce((sum, file) => sum + fs.statSync(path.join(root, file)).size, 0)); - expect(Math.max(...sizes) / Math.min(...sizes)).toBeLessThan(1.25); - expect(splitArea(AREAS.core, PARTS.core)).toEqual(splitArea(AREAS.core, PARTS.core)); - }); - - it('reports a shard that ran out of its time: it ends cancelled, not failed', () => { - expect(workflow).toContain('needs.mutation.result == \'cancelled\''); - expect(workflow).toContain('timeout-minutes: 350'); - }); - - it('has the workflow run, and report, exactly these shards', () => { - const names = Object.keys(SHARDS); - expect(workflow).toContain(`shard: [${names.join(', ')}]`); - expect(workflow).toContain(`for shard in ${names.join(' ')}; do`); - expect(workflow).toContain('STRYKER_SHARD: ${{ matrix.shard }}'); - }); -}); - -// The vitest runner switches a mutant on inside the test worker; the mpv host's message loop -// runs only in the host process its tests start, so the host keeps the command runner, -// which hands the mutant to that process. Compared mutant by mutant on CI (2026-10-06), the -// host was the one module the vitest runner left untested where the command runner caught. -describe('stryker.config.mjs: the test runner a shard gets', () => { - it('runs the mpv host, alone, with the command runner and the whole suite a mutant', () => { - expect(COMMAND_AREAS).toEqual(['host']); - expect(AREAS.host).toEqual(['native-host/faststream-mpv-host.mjs']); - expect(Object.values(AREAS).flat().filter((m) => m === 'native-host/faststream-mpv-host.mjs')).toHaveLength(1); - const host = runnerOf('host-1'); - expect(host.testRunner).toBe('command'); - expect(host.coverageAnalysis).toBe('off'); - expect(host.commandRunner.command).toContain('vitest.mjs run'); - }); - - it('runs every other shard, and a run of everything, with the vitest runner and per-test coverage', () => { - for (const shard of [...Object.keys(SHARDS).filter((name) => !name.startsWith('host-')), undefined, '']) { - const runner = runnerOf(shard); - expect(runner.testRunner, String(shard)).toBe('vitest'); - expect(runner.coverageAnalysis).toBe('perTest'); - // Without it Stryker finds no runner under pnpm's layout. - expect(runner.plugins).toEqual(['@stryker-mutator/vitest-runner']); - } - expect(config.testRunner).toBe(runnerOf(process.env.STRYKER_SHARD).testRunner); - }); -}); diff --git a/tests/unit/typeChecked.test.mjs b/tests/unit/typeChecked.test.mjs index e23623325..b6af93712 100644 --- a/tests/unit/typeChecked.test.mjs +++ b/tests/unit/typeChecked.test.mjs @@ -196,8 +196,6 @@ const CHECKED = [ 'tools/hash-build.mjs', 'tools/launch-ff-fresh.mjs', 'tools/launch-ff.mjs', - 'tools/merge-mutation-reports.mjs', - 'tools/mutation-report.mjs', 'tools/newest-release.mjs', 'tools/rebuild.mjs', 'tools/recut-patch.mjs', diff --git a/tests/workflows/mutation-tests.test.sh b/tests/workflows/mutation-tests.test.sh deleted file mode 100644 index f227e6c9e..000000000 --- a/tests/workflows/mutation-tests.test.sh +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env bash -# mutation-tests.yml: the weekly "Mutation testing: week to " issue it opens when the -# unit tests missed mutants, the older issues it closes, the issues a week with every -# mutant caught closes, and the issue it opens when it fails. The step runs the real -# tools/mutation-report.mjs on a fixture report; the stub gh records what it creates, -# edits and closes. -source "$(dirname "$0")/lib.sh" - -here=$(mktemp -d) -trap 'rm -rf "$here"' EXIT -issue_step=$here/issue.sh -report_step=$here/report.sh -step_script mutation-tests.yml "Open, update or close the week's issue" > "$issue_step" || exit 1 -step_script mutation-tests.yml "Report this workflow's own failure" > "$report_step" || exit 1 - -mkdir -p "$here/bin" -cat > "$here/bin/gh" <<'EOF' -#!/usr/bin/env bash -set -euo pipefail -jqf='' -args=("$@") -for ((i = 0; i < ${#args[@]}; i++)); do - if [ "${args[i]}" = --jq ]; then jqf=${args[i + 1]-}; fi -done -logbody() { - while [ $# -gt 0 ]; do - if [ "$1" = --body-file ]; then echo '--- body:'; cat "$2"; echo '--- end body'; fi - shift - done -} -case "$1 $2" in - 'api --paginate') - [ "$3" = "repos/$GH_REPO/issues?state=all&per_page=100" ] || { echo "stub gh: unexpected api path $3" >&2; exit 2; } - jq -r "$jqf" "$FIX/issues.json" ;; - 'issue create') - { printf 'CREATE'; printf ' [%s]' "${@:3}"; printf '\n'; logbody "$@"; } >> "$LOG" - echo "https://github.com/$GH_REPO/issues/99" ;; - 'issue edit') - { printf 'EDIT'; printf ' [%s]' "${@:3}"; printf '\n'; logbody "$@"; } >> "$LOG" ;; - 'issue close') - { printf 'CLOSE'; printf ' [%s]' "${@:3}"; printf '\n'; } >> "$LOG" ;; - 'issue comment') - { printf 'COMMENT'; printf ' [%s]' "${@:3}"; printf '\n'; logbody "$@"; } >> "$LOG" ;; - 'issue list') - [[ " $* " == *' --state open --limit 200 '* ]] || { echo "stub gh: not a list of all open issues: $*" >&2; exit 2; } - jq -r "$jqf" "$FIX/open.json" ;; - *) - echo "stub gh: unexpected call: $*" >&2; exit 2 ;; -esac -EOF -chmod +x "$here/bin/gh" - -export GH_TOKEN=stub GH_REPO='Nawid3333/FastStream' OWNER='Nawid3333' PREFIX='Mutation testing: week to ' -export RUN_URL='https://github.com/Nawid3333/FastStream/actions/runs/1' -TITLE='Mutation tests workflow failed' -export -n TITLE -check "the job's env: gives the prefix" contains "$WORKFLOWS_DIR/mutation-tests.yml" "PREFIX: '$PREFIX'" -check "the report step's env: gives the title" contains "$WORKFLOWS_DIR/mutation-tests.yml" "TITLE: '$TITLE'" - -today=$(date -u +%F) -bot='{"login":"github-actions[bot]"}' -human='{"login":"Nawid3333"}' -script="$(cd "$(dirname "$0")/../.." && pwd)/tools/mutation-report.mjs" - -# A mutant of Stryker's report. -m() { printf '{"status":"%s","mutatorName":"%s","replacement":"%s","location":{"start":{"line":%s,"column":1}}}' "$1" "$2" "$3" "$4"; } -missing="{\"files\":{\"chrome/player/utils/StreamPick.mjs\":{\"mutants\":[$(m Killed EqualityOperator 'a <= b' 3),$(m Survived ConditionalExpression true 9)]},\"chrome/background/DownloadFilename.mjs\":{\"mutants\":[$(m NoCoverage StringLiteral '' 20)]}}}" -allcaught="{\"files\":{\"chrome/player/utils/StreamPick.mjs\":{\"mutants\":[$(m Killed EqualityOperator 'a <= b' 3),$(m Timeout BlockStatement '{}' 4)]}}}" - -# run [open json]: the step, in a folder holding -# the report and the real report script, as in the job's checkout. -run() { - echo "$1" - export FIX="$here/fix" RUNNER_TEMP="$here/fix/tmp" LOG="$here/fix/log" - rm -rf "$FIX" - mkdir -p "$RUNNER_TEMP" "$FIX/work/reports/mutation" "$FIX/work/tools" - : > "$LOG" - cp "$script" "$FIX/work/tools/" - printf '%s' "$3" > "$FIX/work/reports/mutation/mutation.json" - printf '%s' "$4" > "$FIX/issues.json" - printf '%s' "${5:-[]}" > "$FIX/open.json" - ( - cd "$FIX/work" || exit 9 - if [ "$2" = "$report_step" ]; then export TITLE; fi - PATH="$here/bin:$PATH" run_step "$2" - ) > "$FIX/out" 2>&1 - status=$? -} - -run 's1 mutants not caught -> opens this week'"'"'s issue, closes last week'"'"'s' "$issue_step" "$missing" \ - "[{\"number\":5,\"state\":\"open\",\"title\":\"${PREFIX}2026-09-01\",\"user\":$bot},{\"number\":3,\"state\":\"closed\",\"title\":\"${PREFIX}2026-08-25\",\"user\":$bot},{\"number\":6,\"state\":\"open\",\"title\":\"${PREFIX}notes\",\"user\":$human},{\"number\":8,\"state\":\"open\",\"title\":\"${PREFIX}2026-09-08\",\"user\":$bot,\"pull_request\":{}}]" -check 'succeeds' test "$status" -eq 0 -check "opens \"${PREFIX}$today\", assigned to the owner" contains "$LOG" "CREATE [--title] [${PREFIX}$today] [--assignee] [Nawid3333]" -check 'mentions the owner and the count' contains "$LOG" "@Nawid3333 The unit tests did not catch 2 of this week's mutants" -check 'links the run' contains "$LOG" "Run: $RUN_URL" -check 'lists the survivor' contains "$LOG" '- line 9: survived - ConditionalExpression: `true`' -check 'and the line no test reaches' contains "$LOG" '- line 20: no test reaches it - StringLiteral: `(removed)`' -check "closes last week's #5, pointing at the new one" contains "$LOG" "CLOSE [5] [--reason] [completed] [--comment] [#99 lists the week to $today.]" -check 'leaves closed #3 alone' lacks "$LOG" 'CLOSE [3]' -check "leaves a person's issue alone" lacks "$LOG" 'CLOSE [6]' -check 'leaves a pull request alone' lacks "$LOG" 'CLOSE [8]' - -run 's2 run again the same day -> updates today'"'"'s issue' "$issue_step" "$missing" \ - "[{\"number\":7,\"state\":\"open\",\"title\":\"${PREFIX}$today\",\"user\":$bot},{\"number\":5,\"state\":\"open\",\"title\":\"${PREFIX}2026-09-01\",\"user\":$bot}]" -check 'succeeds' test "$status" -eq 0 -check 'opens nothing' lacks "$LOG" 'CREATE' -check "updates #7" contains "$LOG" 'EDIT [7] [--body-file]' -check 'closes #5, pointing at #7' contains "$LOG" "CLOSE [5] [--reason] [completed] [--comment] [#7 lists the week to $today.]" -check 'leaves #7 open' lacks "$LOG" 'CLOSE [7]' - -run 's3 every mutant caught -> opens nothing, closes the open one' "$issue_step" "$allcaught" \ - "[{\"number\":5,\"state\":\"open\",\"title\":\"${PREFIX}2026-09-01\",\"user\":$bot},{\"number\":6,\"state\":\"open\",\"title\":\"${PREFIX}notes\",\"user\":$human}]" -check 'succeeds' test "$status" -eq 0 -check 'opens nothing' lacks "$LOG" 'CREATE' -check 'closes #5, saying why' contains "$LOG" "CLOSE [5] [--reason] [completed] [--comment] [The unit tests caught every mutant in the week to $today: $RUN_URL]" -check "leaves a person's issue alone" lacks "$LOG" 'CLOSE [6]' - -export MISSING_SHARDS=host-1 -run 's3b every mutant of the reports caught, but a shard wrote none -> closes nothing' "$issue_step" "$allcaught" \ - "[{\"number\":5,\"state\":\"open\",\"title\":\"${PREFIX}2026-09-01\",\"user\":$bot}]" -check 'succeeds' test "$status" -eq 0 -check 'opens nothing' lacks "$LOG" 'CREATE' -check 'leaves #5 open: the missing shard said nothing of its mutants' lacks "$LOG" 'CLOSE [5]' -check 'says which shard wrote none' contains "$FIX/out" 'no report from: host-1' -run 's3c mutants not caught, and a shard wrote none -> still opens the issue' "$issue_step" "$missing" '[]' -check 'succeeds' test "$status" -eq 0 -check 'opens the week'"'"'s issue' contains "$LOG" "CREATE [--title] [${PREFIX}$today]" -export -n MISSING_SHARDS -unset MISSING_SHARDS - -# The report job's merge: the shards' reports from their artifacts, one each, into one. -merge_step=$here/merge.sh -step_script mutation-tests.yml "Put the shards' reports together" > "$merge_step" || exit 1 -merge() { - echo "$1" - export FIX="$here/fix" GITHUB_ENV="$here/fix/env" - rm -rf "$FIX" - mkdir -p "$FIX/work/tools" - : > "$GITHUB_ENV" - cp "$script" "$(dirname "$script")/merge-mutation-reports.mjs" "$FIX/work/tools/" - shift - while [ $# -gt 0 ]; do - mkdir -p "$FIX/work/shards/mutation-reports-$1" - printf '%s' "$2" > "$FIX/work/shards/mutation-reports-$1/mutation.json" - shift 2 - done - (cd "$FIX/work" && run_step "$merge_step") > "$FIX/out" 2>&1 - status=$? -} -network="{\"files\":{\"chrome/player/network/FetchLoader.mjs\":{\"mutants\":[$(m Survived ConditionalExpression true 4)]}}}" -merge 's6 two shards of four -> one report of both, the others named missing' core-1 "$missing" network-1 "$network" -check 'succeeds' test "$status" -eq 0 -check 'names the missing shards' contains "$GITHUB_ENV" 'MISSING_SHARDS=tools-1 host-1' -check 'the report has both shards'"'"' files' contains "$FIX/work/reports/mutation/mutation.json" 'chrome/player/network/FetchLoader.mjs' -check '... and the first shard'"'"'s' contains "$FIX/work/reports/mutation/mutation.json" 'chrome/player/utils/StreamPick.mjs' -merge 's7 every shard -> none missing' core-1 "$missing" network-1 "$network" tools-1 '{"files":{}}' host-1 '{"files":{}}' -check 'succeeds' test "$status" -eq 0 -check 'names none missing' contains "$GITHUB_ENV" 'MISSING_SHARDS=' -check '... and no shard' lacks "$GITHUB_ENV" 'MISSING_SHARDS=core' -merge 's8 no shard wrote a report -> no report, all four missing' -check 'succeeds' test "$status" -eq 0 -check 'names all four' contains "$GITHUB_ENV" 'MISSING_SHARDS=core-1 network-1 tools-1 host-1' -check 'writes no report' test ! -e "$FIX/work/reports/mutation/mutation.json" - -run 's4 failure report, none open -> opens the failure issue' "$report_step" '{}' '[]' '[{"title":"Other"}]' -check 'succeeds' test "$status" -eq 0 -check 'opens "Mutation tests workflow failed", assigned to the owner' contains "$LOG" \ - 'CREATE [--title] [Mutation tests workflow failed] [--assignee] [Nawid3333]' - -run 's5 failure report, already open -> a comment on it' "$report_step" '{}' '[]' '[{"number":12,"title":"Mutation tests workflow failed"}]' -check 'succeeds' test "$status" -eq 0 -check 'comments on the open one' contains "$LOG" 'COMMENT [12] [--body-file]' -check 'creates nothing' lacks "$LOG" 'CREATE' - -finish diff --git a/tools/check-patched-updates.mjs b/tools/check-patched-updates.mjs index 9d43ddc5f..c8fcc16a6 100644 --- a/tools/check-patched-updates.mjs +++ b/tools/check-patched-updates.mjs @@ -21,16 +21,6 @@ import {fileURLToPath} from 'node:url'; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); -/** - * Packages that must stay at a patched library's exact version, by the library's name. They - * move with it: its update pull request bumps them too (tools/recut-patch.mjs), and - * Dependabot leaves them alone while the library is patched (.github/dependabot.yml), where - * it would bump them alone. @stryker-mutator/vitest-runner requires the @stryker-mutator/core - * of its own version, exactly (its peerDependencies). - * @type {Object} - */ -export const LOCKSTEP = {'@stryker-mutator/vitest-runner': ['@stryker-mutator/core']}; - /** * @param {string} yaml - pnpm-workspace.yaml. * @return {Array<{name: string, version: string}>} The patched libraries. diff --git a/tools/merge-mutation-reports.mjs b/tools/merge-mutation-reports.mjs deleted file mode 100644 index 48e51287e..000000000 --- a/tools/merge-mutation-reports.mjs +++ /dev/null @@ -1,22 +0,0 @@ -// @ts-check -// mutation-tests.yml's report job: the shards' reports, as their artifacts were downloaded -// (shards/mutation-reports-/mutation.json), put together into the one report the -// summary and the week's issue read (reports/mutation/mutation.json). No arguments: the -// paths are the job's own, and a shard without a report is left out (the step names it). -import fs from 'node:fs'; -import path from 'node:path'; -import {merge} from './mutation-report.mjs'; - -const reports = []; -for (const artifact of fs.readdirSync('shards').sort()) { - let text; - try { - text = fs.readFileSync(path.join('shards', artifact, 'mutation.json'), 'utf8'); - } catch (e) { - if (e.code === 'ENOENT') continue; - throw e; - } - reports.push(JSON.parse(text)); -} -fs.mkdirSync('reports/mutation', {recursive: true}); -fs.writeFileSync('reports/mutation/mutation.json', JSON.stringify(merge(reports))); diff --git a/tools/mutation-report.mjs b/tools/mutation-report.mjs deleted file mode 100644 index b70467669..000000000 --- a/tools/mutation-report.mjs +++ /dev/null @@ -1,149 +0,0 @@ -// @ts-check -// Turns Stryker's report (reports/mutation/mutation.json) into what mutation-tests.yml -// shows: a table per file for the run's summary, and the body of the week's issue, which -// lists the mutants the unit tests did not catch. -// -// node tools/mutation-report.mjs summary -// node tools/mutation-report.mjs issue -// node tools/mutation-report.mjs count -// -// merge() puts the shards' reports together (tools/merge-mutation-reports.mjs). -// -// "Not caught" is Survived (the tests ran and passed) and NoCoverage (no test reached it). -// Killed and Timeout count as caught, as Stryker counts them. - -import fs from 'node:fs'; -import * as url from 'node:url'; - -const CAUGHT = new Set(['Killed', 'Timeout']); -const MISSED = new Set(['Survived', 'NoCoverage']); -const LISTED = 100; - -/** - * Each file's mutants, by status. - * @param {Object} report - Stryker's mutation-testing report. - * @return {Array<{file: string, total: number, caught: number, missed: number, score: number}>} - * Sorted by file; score is caught in percent of the mutants that ran, one decimal. - */ -export function perFile(report) { - return Object.entries(report.files || {}).sort(([a], [b]) => a.localeCompare(b)).map(([file, {mutants}]) => { - const caught = mutants.filter((m) => CAUGHT.has(m.status)).length; - const missed = mutants.filter((m) => MISSED.has(m.status)).length; - const ran = caught + missed; - return {file, total: mutants.length, caught, missed, score: ran ? Math.round(caught * 1000 / ran) / 10 : 100}; - }); -} - -/** - * Text from a report, safe in a table cell or inline code: one line, no pipe, no backtick. - * @param {*} value - * @return {string} - */ -function cell(value) { - return String(value ?? '').replace(/\s+/g, ' ').replace(/\\/g, '\\\\').replace(/\|/g, '\\|').replace(/`/g, '\''); -} - -/** - * The run summary: one row per file and a total. - * @param {Object} report - * @return {string} Markdown. - */ -export function summary(report) { - const rows = perFile(report); - const total = rows.reduce((t, r) => ({total: t.total + r.total, caught: t.caught + r.caught, missed: t.missed + r.missed}), - {total: 0, caught: 0, missed: 0}); - const ran = total.caught + total.missed; - return [ - '### Mutation testing', - '', - 'Caught: the unit tests failed with the change (or timed out). Not caught: they passed, or none reached it.', - '', - '| File | Mutants | Caught | Not caught | Score |', - '| --- | --- | --- | --- | --- |', - ...rows.map((r) => `| ${cell(r.file)} | ${r.total} | ${r.caught} | ${r.missed} | ${r.score}% |`), - `| **All** | ${total.total} | ${total.caught} | ${total.missed} | ${ran ? Math.round(total.caught * 1000 / ran) / 10 : 100}% |`, - '', - ].join('\n'); -} - -/** - * The mutants not caught, by file and line. - * @param {Object} report - * @return {Array<{file: string, line: number, status: string, mutator: string, replacement: string}>} - */ -export function missed(report) { - const out = []; - for (const [file, {mutants}] of Object.entries(report.files || {})) { - for (const m of mutants) { - if (MISSED.has(m.status)) { - out.push({file, line: m.location?.start?.line ?? 0, status: m.status, mutator: m.mutatorName, replacement: m.replacement ?? ''}); - } - } - } - return out.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line); -} - -/** - * The week's issue: what was not caught, the first LISTED of it by file. - * @param {Object} report - * @param {string} owner - Who to @mention. - * @param {string} runUrl - The run, whose artifact has the full report. - * @return {string} Markdown. - */ -export function issueBody(report, owner, runUrl) { - const list = missed(report); - const shown = list.slice(0, LISTED); - const lines = [ - `@${owner} The unit tests did not catch ${list.length} of this week's mutants: changes to the code they still passed, or that no test reached. Each is a place where a fix could ship without a test that fails without it.`, - '', - `Run: ${runUrl} (its mutation-reports artifact has the full report, kept 30 days).`, - '', - summary(report), - `### Not caught${list.length > LISTED ? ` (the first ${LISTED} of ${list.length})` : ''}`, - ]; - /** @type {string|null} */ - let file = null; - for (const m of shown) { - if (m.file !== file) { - file = m.file; - lines.push('', `**${cell(file)}**`, ''); - } - lines.push(`- line ${m.line}: ${m.status === 'NoCoverage' ? 'no test reaches it' : 'survived'} - ${cell(m.mutator)}: \`${cell(m.replacement) || '(removed)'}\``); - } - lines.push('', 'Next week\'s issue replaces this one; a week with every mutant caught closes it.', ''); - return lines.join('\n'); -} - -/** - * One report of several: mutation-tests.yml runs the modules in shards, a job each, and - * each writes its own report (stryker.config.mjs, SHARDS). - * @param {Object[]} reports - Stryker's reports, of disjoint modules. - * @return {Object} The first report, with every report's files. - */ -export function merge(reports) { - const files = new Map(); - for (const report of reports) { - for (const [file, entry] of Object.entries(report.files || {})) { - if (files.has(file)) { - throw new Error(`${file} is in two reports: each module belongs to one shard`); - } - files.set(file, entry); - } - } - return {...(reports[0] || {}), files: Object.fromEntries(files)}; -} - -if (process.argv[1] && import.meta.url === url.pathToFileURL(process.argv[1]).href) { - const [file, what, owner, runUrl] = process.argv.slice(2); - const report = JSON.parse(fs.readFileSync(file, 'utf8')); - if (what === 'summary') { - process.stdout.write(summary(report)); - } else if (what === 'issue') { - process.stdout.write(issueBody(report, owner, runUrl)); - } else if (what === 'count') { - process.stdout.write(String(missed(report).length) + '\n'); - } else { - console.error('usage: mutation-report.mjs summary|issue |count'); - process.exit(2); - } -} diff --git a/tools/recut-patch.mjs b/tools/recut-patch.mjs index 096ba2724..ecab0d106 100644 --- a/tools/recut-patch.mjs +++ b/tools/recut-patch.mjs @@ -47,7 +47,7 @@ import path from 'node:path'; import * as url from 'node:url'; import {spawnSync} from 'node:child_process'; -import {LOCKSTEP, patchedDependencies} from './check-patched-updates.mjs'; +import {patchedDependencies} from './check-patched-updates.mjs'; const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); // This repository, always. An environment variable could point it elsewhere until 2026-10-06; @@ -618,7 +618,7 @@ async function main() { /** * Takes names off .github/dependabot.yml's ignore list, so Dependabot updates them again: - * a library whose patch is dropped, and the packages that moved with it (LOCKSTEP). + * a library whose patch is dropped. * @param {string[]} names * @param {string} [file] - The Dependabot config. * @return {string[]} The names that were on the list. @@ -636,8 +636,7 @@ function dropDependabotIgnores(names, file = path.join(root, '.github/dependabot } /** - * package.json with a library moved from one version to another, and the packages that must - * stay at its version with it (LOCKSTEP). + * package.json with a library moved from one version to another. * @param {string} text - package.json. * @param {string} pkg * @param {string} from @@ -650,13 +649,7 @@ function bumpPackageJson(text, pkg, from, to) { // version's tag. const verRe = new RegExp(`("${esc(pkg)}":\\s*"(?:[~^]?|(?:github:|git\\+|git:)[^#"]+#v?))${esc(from)}"`); if (!verRe.test(text)) throw new Error(`package.json has no "${pkg}" at ${from}`); - let out = text.replace(verRe, `$1${to}"`); - for (const companion of LOCKSTEP[pkg] || []) { - const companionRe = new RegExp(`("${esc(companion)}":\\s*")[^"]+"`); - if (!companionRe.test(out)) throw new Error(`package.json has no "${companion}", which moves with ${pkg}`); - out = out.replace(companionRe, `$1${to}"`); - } - return out; + return text.replace(verRe, `$1${to}"`); } function applyUpdate(opts, cur, result, work) { @@ -694,8 +687,8 @@ function applyUpdate(opts, cur, result, work) { fs.copyFileSync(path.join(work, 'merged', f.file), path.join(edit, f.file)); } if (result.files.every((f) => f.landed)) { - // Dependabot takes the library back, and what moves with it. - const handedBack = dropDependabotIgnores([pkg, ...(LOCKSTEP[pkg] || [])]); + // Dependabot takes the library back. + const handedBack = dropDependabotIgnores([pkg]); console.log(`Every change has landed in ${pkg} ${to}: the patch is dropped` + (handedBack.length ? `, and Dependabot updates ${handedBack.join(' and ')} again (.github/dependabot.yml)` : '') + `. Remove any \`patched: true\` marks for ${pkg} in tools/sync-vendor.mjs.`);