Skip to content

chore: bump Jest to v30 - #319

Merged
cryptodev-2s merged 6 commits into
mainfrom
migrate/pr2e-jest30
Sep 10, 2026
Merged

chore: bump Jest to v30#319
cryptodev-2s merged 6 commits into
mainfrom
migrate/pr2e-jest30

Conversation

@cryptodev-2s

@cryptodev-2s cryptodev-2s commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Stacked on #318.

Dep From To
jest ^29.2.2 ^30.4.2
@types/jest ^28.1.7 ^30.0.0
ts-jest ^29.0.3 ^29.4.11

ts-jest has to move with it: 29.0.3 peer requires jest@^29, so Jest 30 cannot land alone. 29.4.11 is what core pairs with Jest 30.

Jest 30 pulls in @parcel/watcher via jest-haste-map, which has an install script, so lavamoat needs it declared. Set to false like core does with its equivalent native packages, so the script does not run and Jest falls back to its JS file crawler. That only affects --watch.

Fixing a flaky timing test

areUint8ArraysEqual has an assertion that comparing arrays differing at the first byte takes about as long as comparing arrays differing at the last, guarding the constant time property. It took a single timing sample per side, so one garbage collection pause or descheduled CPU slice skewed the ratio.

It was already failing intermittently before this branch (1.31 against a bound of 1.1). Under Jest 30 it reached 1.60 and failed on every Node version.

The function is genuinely constant time: it walks the full length accumulating with |= and never returns early. So the true ratio is exactly 1.0 and everything above is measurement noise. Taking the fastest of seven samples per side (noise is strictly additive, so the quickest run is closest to real cost) gets the ratio to 1.0002 locally.

CI still measured ~1.14 though, so the runners carry a systematic component no estimator removes. The bound was false precision anyway: what this test guards against is the comparison regaining an early return, and if that regressed early would stop after one byte while late walked all 100,000. Reintroducing an early return locally produces a ratio of 556.

So the bound moves from 1.1 to 2, keeping 278x margin against the real failure mode while tolerating the ~1.14 shared runners produce.

And a coverage fix

Jest 30 ships a newer istanbul that accounts for ignore directives differently. In coercers.ts the catch blocks carry /* istanbul ignore next */ on the trailing throw error. That still excludes the statement, but no longer excludes the implicit else path of the if (error instanceof StructError) above it, so branch coverage fell to 99.12% and the 100% threshold failed.

Adds /* istanbul ignore else */ to the three ifs whose else path is not exercised. createNumber is deliberately left alone: its else path is covered by a real test, and ignoring it there would hide a future regression.


Note

Low Risk
Dev-only dependency and test/coverage annotation changes; no published library API or runtime logic changes.

Overview
Upgrades the test stack to Jest 30 (jest, @types/jest, and ts-jest so peer deps stay aligned), with a large lockfile refresh. Lavamoat now blocks the install script on Jest’s transitive @parcel/watcher (same pattern as other native deps), so watch mode falls back to the JS file crawler.

bytes.test.ts stabilizes the constant-time timing check for areUint8ArraysEqual: seven trials per side, min-of-samples timing, and a ratio cap relaxed from 1.1 → 2 so shared CI noise (~1.14) does not flake while still catching a reintroduced early-return (which would spike the ratio into the hundreds).

coercers.ts adds istanbul ignore else on three coercion catch paths so Jest 30’s istanbul still hits the 100% branch coverage threshold; runtime behavior is unchanged.

Reviewed by Cursor Bugbot for commit 2bab777. Bugbot is set up for automated code reviews on this repo. Configure here.

@socket-security

socket-security Bot commented Sep 4, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedjest@​29.2.2 ⏵ 30.5.110010069 +193 +1100
Updated@​types/​jest@​29.5.5 ⏵ 30.0.01001007680100
Updatedts-jest@​29.0.3 ⏵ 29.4.129710095 +292 +1100

View full report

@socket-security

socket-security Bot commented Sep 4, 2026

Copy link
Copy Markdown

Warning

MetaMask internal reviewing guidelines:

  • Do not ignore-all
  • Each alert has instructions on how to review if you don't know what it means. If lost, ask your Security Liaison or the supply-chain group
  • Copy-paste ignore lines for specific packages or a group of one kind with a note on what research you did to deem it safe.
    @SocketSecurity ignore npm/PACKAGE@VERSION
Action Severity Alert  (click "▶" to expand/collapse)
Warn Low
Potential code anomaly (AI signal): npm escalade is 63.0% likely to have a medium risk anomaly

Notes: This is a generic upward-directory traversal utility. It is not inherently malicious. Security posture hinges on the callback's implementation and proper termination guarantees. Risks include unhandled filesystem errors and potential unbounded traversal if the callback misbehaves or lacks proper termination checks.

Confidence: 0.63

Severity: 0.50

From: package.jsonnpm/ts-jest@29.4.12npm/@metamask/auto-changelog@6.2.1npm/jest@30.5.1npm/@lavamoat/allow-scripts@3.0.4npm/depcheck@1.4.7npm/@ts-bridge/cli@0.1.2npm/escalade@3.2.0

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/escalade@3.2.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Potential code anomaly (AI signal): npm escalade is 65.0% likely to have a medium risk anomaly

Notes: The code implements a standard upward-directory search utility driven by a callback. It is not inherently malicious, but its safety and determinism depend on the callback's implementation and the absence of unhandled I/O errors. Potential issues include lack of error handling, reliance on callback contract, and possible endless loops if the callback never signals an end. Use with trusted callbacks or add explicit error handling and input validation.

Confidence: 0.65

Severity: 0.60

From: package.jsonnpm/ts-jest@29.4.12npm/@metamask/auto-changelog@6.2.1npm/jest@30.5.1npm/@lavamoat/allow-scripts@3.0.4npm/depcheck@1.4.7npm/@ts-bridge/cli@0.1.2npm/escalade@3.2.0

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/escalade@3.2.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Potential code anomaly (AI signal): npm glob is 75.0% likely to have a medium risk anomaly

Notes: The analyzed code is a conventional, non-malicious implementation of glob pattern expansion and directory traversal. It reads filesystem data based on user-provided patterns but does not exhibit data exfiltration, remote communications, or code execution risks within this fragment. Overall security risk is low, with standard OS-specific handling for nocase behavior.

Confidence: 0.75

Severity: 0.60

From: package.jsonnpm/ts-jest@29.4.12npm/jest@30.5.1npm/@lavamoat/allow-scripts@3.0.4npm/glob@10.5.0

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/glob@10.5.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Potential code anomaly (AI signal): npm node-addon-api is 77.0% likely to have a medium risk anomaly

Notes: The script is a legitimate formatting helper within a Node.js project. It orchestrates clang-format via git-clang-format, supports fix and diff modes, and provides actionable feedback to the developer. While operational dependencies exist, no malicious activity or data leakage is evident based on the provided code and typical usage.

Confidence: 0.77

Severity: 0.50

From: package.jsonnpm/ts-jest@29.4.12npm/jest@30.5.1npm/node-addon-api@7.1.1

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/node-addon-api@7.1.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Potential code anomaly (AI signal): npm ts-jest is 60.0% likely to have a medium risk anomaly

Notes: No clear evidence of malware (e.g., network exfiltration, command execution, or credential theft) is present in this fragment. However, it implements a high-impact extensibility mechanism: it dynamically imports and executes a hook module specified by the TS_JEST_HOOKS environment variable and passes it full source code and transformer configuration. If the environment variable or hook file can be influenced by an attacker (common in compromised CI/dev environments), this becomes an arbitrary code execution vector during Jest/ts-jest transformation. Additionally, cache-key material and logs may expose sensitive project data if cache/log artifacts are accessible.

Confidence: 0.60

Severity: 0.55

From: package.jsonnpm/ts-jest@29.4.12

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/ts-jest@29.4.12. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Environment variable access: npm uglify-js reads UGLIFY_BUG_REPORT

Env Vars: UGLIFY_BUG_REPORT

Location: Package overview

From: package.jsonnpm/ts-jest@29.4.12npm/uglify-js@3.19.3

ℹ Read more on: This package | This alert | What is environment variable access?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should be clear about which environment variables they access, and care should be taken to ensure they only access environment variables they claim to.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/uglify-js@3.19.3. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Environment variable access: npm update-browserslist-db reads HADOOP_HOME

Env Vars: HADOOP_HOME

Location: Package overview

From: package.jsonnpm/ts-jest@29.4.12npm/jest@30.5.1npm/update-browserslist-db@1.3.2

ℹ Read more on: This package | This alert | What is environment variable access?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should be clear about which environment variables they access, and care should be taken to ensure they only access environment variables they claim to.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/update-browserslist-db@1.3.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Ignoring alerts on:

  • @jest/snapshot-utils@30.5.1
  • @parcel/watcher@2.6.0
  • baseline-browser-mapping@2.11.20
  • detect-libc@2.1.2
  • es-module-lexer@2.3.2
  • convert-source-map@2.0.0
  • glob@13.0.6
  • @jest/core@30.5.1
  • @babel/code-frame@7.29.7
  • jest-haste-map@30.5.1
  • @babel/core@7.29.7
  • @babel/helper-string-parser@7.29.7
  • @babel/helper-compilation-targets@7.29.7
  • @babel/helper-module-transforms@7.29.7
  • @babel/helpers@7.29.7
  • @babel/helper-module-imports@7.29.7

View full report

@cryptodev-2s
cryptodev-2s force-pushed the migrate/pr2e-jest30 branch 2 times, most recently from c9e655d to d0b303d Compare September 7, 2026 12:31
@cryptodev-2s
cryptodev-2s removed this pull request from stack #329 September 9, 2026 11:46
@cryptodev-2s
cryptodev-2s added this pull request to stack #331 September 9, 2026 11:47
@cryptodev-2s
cryptodev-2s force-pushed the migrate/pr2e-jest30 branch 2 times, most recently from 50dbb76 to e70e07f Compare September 9, 2026 16:32
Mrtenz
Mrtenz previously approved these changes Sep 10, 2026
@cryptodev-2s
cryptodev-2s dismissed Mrtenz’s stale review September 10, 2026 10:15

The merge-base changed after approval.

@cryptodev-2s
cryptodev-2s removed this pull request from stack #331 September 10, 2026 10:40
@cryptodev-2s
cryptodev-2s added this pull request to stack #335 September 10, 2026 10:41
@cryptodev-2s
cryptodev-2s requested a review from Mrtenz September 10, 2026 10:46
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@SocketSecurity ignore npm/@babel/code-frame@7.29.7
@SocketSecurity ignore npm/@babel/core@7.29.7
@SocketSecurity ignore npm/@babel/helper-compilation-targets@7.29.7
@SocketSecurity ignore npm/@babel/helper-module-imports@7.29.7
@SocketSecurity ignore npm/@babel/helper-module-transforms@7.29.7
@SocketSecurity ignore npm/@babel/helper-string-parser@7.29.7
@SocketSecurity ignore npm/@babel/helpers@7.29.7
@SocketSecurity ignore npm/@jest/core@30.5.1
@SocketSecurity ignore npm/@jest/snapshot-utils@30.5.1
@SocketSecurity ignore npm/@parcel/watcher@2.6.0
@SocketSecurity ignore npm/baseline-browser-mapping@2.11.20
@SocketSecurity ignore npm/convert-source-map@2.0.0
@SocketSecurity ignore npm/detect-libc@2.1.2
@SocketSecurity ignore npm/es-module-lexer@2.3.2
@SocketSecurity ignore npm/glob@13.0.6
@SocketSecurity ignore npm/jest-haste-map@30.5.1

Base automatically changed from migrate/pr2d-devdeps to main September 10, 2026 13:03
  jest         ^29.2.2  -> ^30.4.2
  @types/jest  ^28.1.7  -> ^30.0.0
  ts-jest      ^29.0.3  -> ^29.4.11

ts-jest has to move with it: 29.0.3 peer requires jest ^29, so Jest 30
cannot land alone. 29.4.11 is the version core pairs with Jest 30.

Jest 30 pulls in @parcel/watcher through jest-haste-map, which has an
install script, so lavamoat needs it declared. Set to false like core does
with its equivalent native packages, meaning the script does not run and
Jest falls back to its JS file crawler. That only affects --watch.

No source or config changes were needed. jest-it-up declares no jest peer
and still reports coverage correctly.
areUint8ArraysEqual has a test asserting that comparing arrays which differ
at the first byte takes about as long as comparing arrays which differ at
the last, guarding the constant time property. It took a single timing
sample per side, so one garbage collection pause or descheduled CPU slice
in either loop skewed the whole ratio.

It was already failing intermittently on CI before this branch, at a ratio
of 1.31 against a bound of 1.1. Under Jest 30 it went to 1.60 and failed on
every Node version, which is what forced the fix now.

Now takes seven interleaved samples per side and compares the medians. The
1.1 bound is unchanged, so the property under test is exactly as strict as
before; only the noise rejection improved. Passes 6 out of 6 locally where
it previously failed roughly 1 in 4.
Jest 30 ships a newer istanbul, which accounts for the coverage ignore
directives differently. In coercers.ts the `catch` blocks carry
`/* istanbul ignore next */` on the trailing `throw error`. That still
excludes the statement, but it no longer excludes the implicit else path of
the `if (error instanceof StructError)` above it, so branch coverage fell to
99.12% and the 100% threshold failed.

Adds `/* istanbul ignore else */` on the three `if`s whose else path is not
exercised. createNumber is deliberately left alone: its else path is covered
by a real test, and ignoring it there would hide a future regression.

No change in what is actually tested. Branch coverage is back to 100%.
Taking the median of seven samples cut the ratio from 1.60 to 1.12, but the
bound is 1.1, so CI still failed by a hair on the slower runners.

areUint8ArraysEqual is genuinely constant time: it walks the full length and
accumulates with |=, never returning early. The true ratio is therefore
exactly 1.0 and everything above it is measurement noise. That noise is
strictly additive, since scheduling, garbage collection and cache pressure
only ever make a run slower. The fastest of several samples is consequently
the best estimate of the real cost, which is the usual approach in
benchmarking.

Switching from median to minimum moves the observed ratio from 1.12 to
between 1.0002 and 1.0040 across five local runs, roughly 25x headroom
against the unchanged 1.1 bound. The test takes 0.57s.
The fastest-sample estimator gets the ratio to 1.0002 on a quiet machine but
CI still measures around 1.14, so the runners carry a systematic component
that no choice of estimator removes. Chasing it further is not worthwhile,
because the bound was false precision to begin with.

What this test guards against is the comparison regaining an early return on
the first differing byte. If that regressed, `early` would stop after one
byte while `late` still walked all 100,000, so the ratio lands in the
hundreds. Verified by reintroducing an early return locally: the ratio came
out at 556, against the new bound of 2.

So a bound of 2 keeps 278x margin against the real failure mode while
tolerating the ~1.14 that shared runners produce. The old 1.1 bound bought
no extra sensitivity to that regression, only flakiness.
@cryptodev-2s
cryptodev-2s merged commit b665d7b into main Sep 10, 2026
22 checks passed
@cryptodev-2s
cryptodev-2s deleted the migrate/pr2e-jest30 branch September 10, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants