Skip to content

build(deps): resolve every dependabot advisory fixable without a major bump - #217

Merged
timurbazhirov merged 1 commit into
devfrom
claude/deps-audit-consolidated
Aug 14, 2026
Merged

build(deps): resolve every dependabot advisory fixable without a major bump#217
timurbazhirov merged 1 commit into
devfrom
claude/deps-audit-consolidated

Conversation

@timurbazhirov

@timurbazhirov timurbazhirov commented Aug 13, 2026

Copy link
Copy Markdown
Member

Rebased onto dev now that #216 and #214 have landed, and re-derived from scratch — the previous version of this branch targeted #216's branch and pinned versions that have since been overtaken by their own advisories (tar-fs@^3.0.9, form-data@^4.0.5 and vite@^6.4.2 are all inside the current ranges).

Scope also widened. It previously covered the seven PRs open at the time; this covers every advisory in the tree that has a fix reachable without a semver-major bump.

Result

before after
critical 5 4
high 25 10
moderate 13 5
low 18 17
total 61 36

Twenty-five packages resolved, none newly flagged.

Closes the seven originally targeted: #191, #192, #193, #194, #196, #197, #198 — and additionally resolves what #187 (sha.js), #189 (brace-expansion), #169 (prismjs), #171 (esbuild/vite), #172 and #180 (@babel/*) were after.

How each version was chosen

Not by hand. For every advisory npm reported as fixable, a script took the lowest release that is (a) outside the advisory range and (b) still inside the major that every installed copy already sits in — so no dependent is forced across a major it never declared.

Where a package is installed at two majors at once, each gets its own entry:

package resolved
form-data 3.0.5 and 4.0.6
js-yaml 3.15.1 and 4.3.1
tar-fs 2.1.5 and 3.1.3
ws 7.5.13 and 8.21.3
brace-expansion 1.1.18 and 2.1.4
minimatch 3.1.5 and 9.0.9
picomatch 2.3.2 and 4.0.5

That scoping is the whole point. A blanket js-yaml: ^4 moves eslint, @eslint/eslintrc and @istanbuljs/load-nyc-config — all of which ask for ^3.13.1 — onto the major that removed safeLoad. A blanket tar-fs: ^3 moves prebuild-install, which is what fetches sharp's prebuilt binary, and is the exact step whose flakiness 19527bd retries around.

Three entries are deliberately absent

  • esbuild needs none. vite@6.4.3 declares esbuild ^0.25.0 itself, so bumping vite carries it — which matters, because forcing ^0.25.0 onto vite 6.0.7's declared ^0.24.2 would cross a 0.x boundary npm treats as breaking.
  • ip-address is reached the same way: socks@2.8.7 declares ip-address ^10.0.1, and the override only lifts it past the advisory floor.
  • vite is the one direct dependency in the set, so it moves in devDependencies rather than through an override: 6.0.7 → 6.4.3.

yaml needed its declared specs as selectors (yaml@^1.10.0, yaml@^1.10.2) rather than a bare yaml@^1, which npm silently did not match. It is scoped so vite's own yaml ^2.4.2 stays untouched.

npm audit fix still cannot run here at all — it tries to resolve @mat3ra/code@*, which has no matching version — so overrides remains the mechanism.

What is left, and why

All 36 remaining need a semver-major bump:

  • dompurify, and the @toast-ui/editor / @toast-ui/react-editor pair it drags. The advisory covers every 2.x and @toast-ui/editor declares ^2.3.3, so this is a major bump inside @mat3ra/cove's tree rather than ours.
  • @jest/core / jest-cli — jest 27 → 28+.
  • The gl, looks-same (which also replaces the sharp line), vite-plugin-node-polyfills and @mat3ra/* chains.

Each is real breakage risk and deserves its own PR rather than being smuggled into a dependency-hygiene commit.

A lockfile trap worth recording

The lockfile is updated incrementally, not regenerated. A clean regeneration on this linux-x64 container silently dropped every non-linux optional binary — 25 @esbuild/*, 24 @rollup/rollup-* and fsevents — because npm rebuilds the lock from the installed tree, which only holds the current platform's. That would have broken macOS and Windows installs while looking perfectly fine in CI. All 26 esbuild and 25 rollup platform entries are present here and bumped in step.

Sixty collateral lockfile changes, all accounted for: those platform binaries, two rollup targets upstream renamed (loongarch64loong64, powerpc64leppc64), jsbn dropped by ip-address 10, and regenerator-runtime no longer needed by @babel/runtime 7.29.

Verification

Run against the real installed tree from a clean npm ci, not just the lockfile:

  • npm run lint 0 errors; tsc --noEmit clean
  • npm run build clean. Bundle 5,479 kB → 5,532 kB (+1%, newer esbuild/rollup codegen); the built bundle parses and still carries its feature markers
  • 461 passing / 32 suites / 0 failing — the same count as the branch point. The visual-regression suites are inside that number, so a renderer-affecting change in the build toolchain would have surfaced as a pixel diff.

…r bump

Rebased onto `dev` now that #216 and #214 have landed. The earlier version of
this branch targeted #216's branch and pinned versions that have since been
overtaken by their own advisories — `tar-fs@^3.0.9`, `form-data@^4.0.5` and
`vite@^6.4.2` are all inside the current ranges. Everything below is re-derived
against `dev`'s actual installed tree.

Baseline on `dev`: 61 advisories (5 critical, 25 high). Of those, 29 packages
had a fix reachable without a semver-major bump; the rest need jest 27 -> 30,
`gl`, `looks-same` (which also replaces the `sharp` line) or `@mat3ra/*` majors,
which is separate work with real breakage risk.

Result: **61 -> 36** advisories. Critical 5 -> 4, high 25 -> 10, moderate
13 -> 5. Twenty-five packages resolved, none newly flagged.

## How each version was chosen

Not by hand. For every advisory npm reported as fixable, the lowest release
was taken that is (a) outside the advisory range and (b) still inside the major
that every installed copy already sits in — so no dependent is forced across a
major it did not declare. Where a package is installed at two majors at once,
each gets its own entry: `form-data` 3.0.5 *and* 4.0.6, `js-yaml` 3.15.1 *and*
4.3.1, `tar-fs` 2.1.5 *and* 3.1.3, `ws` 7.5.13 *and* 8.21.3, plus
`brace-expansion`, `minimatch` and `picomatch`.

That scoping is the whole point. A blanket `js-yaml: ^4` moves `eslint`,
`@eslint/eslintrc` and `@istanbuljs/load-nyc-config` — all of which ask for
`^3.13.1` — onto the major that removed `safeLoad`. A blanket `tar-fs: ^3`
moves `prebuild-install`, which is what fetches sharp's prebuilt binary and is
the exact step whose flakiness `19527bd` retries around.

Three entries are deliberately absent:

- **esbuild** needs none. `vite@6.4.3` declares `esbuild ^0.25.0` itself, so
  bumping vite carries it — which matters, because forcing `^0.25.0` onto
  vite 6.0.7's declared `^0.24.2` would cross a 0.x boundary npm treats as
  breaking.
- **ip-address** is reached the same way: `socks@2.8.7` declares
  `ip-address ^10.0.1`, and the override only lifts it past the advisory floor.
- **vite** itself is the one direct dependency here, so it moves in
  `devDependencies` rather than through an override.

`yaml` needed its declared specs as selectors (`yaml@^1.10.0`, `yaml@^1.10.2`)
rather than a bare `yaml@^1`, which npm did not match. It is scoped so vite's
own `yaml ^2.4.2` is untouched.

## What is left, and why

- `dompurify` (and the `@toast-ui/editor` / `@toast-ui/react-editor` pair it
  drags) — the advisory covers every 2.x, and `@toast-ui/editor` declares
  `^2.3.3`, so this is a major bump inside `@mat3ra/cove`'s tree, not ours.
- `@jest/core` / `jest-cli` — jest 27 to 28+.
- The `gl`, `looks-same`, `vite-plugin-node-polyfills` and `@mat3ra/*` chains,
  all semver-major.

## Verification

The lockfile was updated **incrementally** rather than regenerated. A clean
regeneration on this linux-x64 container silently dropped every non-linux
optional binary — 25 `@esbuild/*`, 24 `@rollup/rollup-*` and `fsevents` — which
would have broken macOS and Windows installs. All 26 esbuild and 25 rollup
platform entries are present and bumped in step.

Sixty collateral lockfile changes, all accounted for: the platform binaries
above, two rollup targets that upstream *renamed* (`loongarch64` -> `loong64`,
`powerpc64le` -> `ppc64`), `jsbn` dropped by ip-address 10, and
`regenerator-runtime` no longer needed by `@babel/runtime` 7.29.

Run against the real installed tree from a clean `npm ci`, not just the
lockfile:

- `npm run lint` 0 errors, `tsc --noEmit` clean
- `npm run build` clean; bundle 5,479 kB -> 5,532 kB (+1%, newer esbuild and
  rollup codegen), and the built bundle parses and still carries its feature
  markers
- **461 passing / 32 suites / 0 failing** — the same count as the branch point.
  The visual-regression suites are inside that number, so a renderer-affecting
  change would have surfaced as a pixel diff.
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