Address all known vulnerabilities#124
Conversation
Pattern follows the visual-editor / sdk-test-data / js-client-sdk
cleanup: bump direct deps to latest within their compatible major (or
to a known-fixed major) so audit findings clear transitively. Yarn
`resolutions` are kept to a minimum — only two remain in this round.
yarn audit: 112 paths → 0 (was 2 Critical / 59 High / 44 Moderate / 7 Low).
Direct dep bumps:
- @eppo/js-client-sdk-common 4.15.2 → ^5 — drops the uuid runtime dep
entirely (replaced upstream with crypto.randomUUID for event IDs),
clearing the uuid moderate advisory and most of the deep transitive
vulns the earlier `resolutions` block was working around.
- express ^4 → ^5 (drops vulnerable path-to-regexp 0.x and qs <6.15
transitively without needing scoped resolutions; express is a devDep
used only by the mock API server in tests, and the simple
`app.get(regexp, handler)` usage there works the same in v5)
- @microsoft/api-documenter, @microsoft/api-extractor → latest
- @types/jest 29 → 30 (paired with jest 30)
- @typescript-eslint/{eslint-plugin,parser} 5 → 8 (rule renames forced
the lint fixes below)
- eslint-config-prettier 8 → 10
- eslint-import-resolver-typescript 2 → 4
- eslint-plugin-prettier 4 → 5
- eslint-plugin-promise 6 → 7
- husky 6 → 9 (current major; old 6.x was years EOL)
- jest stays on 29 (jest-environment-jsdom isn't used here)
- lint-staged 12 → 16 (17 needs Node 22; we still target Node 20)
- prettier 2 → 3 (drops the `yaml@1.x` transitive that triggered the
yaml advisory)
- @google-cloud/storage to latest 7.x
Resolutions left in package.json (each annotated inline):
- @types/node ^20.0.0 — intentional pin to keep the dev type surface
aligned with engines.node >=20.x. Not a vuln fix; carried over from
the previous resolutions block.
- @tootallnate/once ^3.0.1 — GHSA-rj4j-rrv4-3xc4 (low). Pulled by
@google-cloud/storage → teeny-request → http-proxy-agent. The latest
@google-cloud/storage 7.19.x still ships the unpatched chain and
there's no newer release; the chain is dev-only.
Everything else from the previous round (minimatch, brace-expansion,
diff, flatted, lodash, path-to-regexp, picomatch, qs, schema-utils/ajv,
ajv-formats/ajv) was dropped — the direct dep bumps above clear them
transitively.
Source-code adjustments forced by the dep bumps:
- src/util/index.ts: unused `catch (error)` parameter → bare `catch`
(typescript-eslint v8's stricter `no-unused-vars`).
- src/sdk-data.ts and src/index.spec.ts: replace deprecated
`@typescript-eslint/no-var-requires` disable directives with
`no-require-imports`.
Verification:
- `yarn lint`, `yarn typecheck`, `yarn test` (115 tests),
`yarn tsc` (build) all pass locally.
- `yarn audit` reports 0 vulnerabilities.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5073d19 to
7dac7b2
Compare
No public API change in this branch; the @eppo/js-client-sdk-common 4 → 5 dependency bump and devDep updates are all consumer-transparent and engines.node was already >=20.x. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR focuses on eliminating dependency vulnerabilities and modernizing the repo’s tooling/runtime dependencies, while making small source tweaks required by updated lint rules.
Changes:
- Updated a large set of dependencies (including
@eppo/js-client-sdk-commonto^5,expressto^5, tooling likeprettier/eslint/@typescript-eslint/*) and refreshedyarn.lock. - Reduced the number of
resolutionsoverrides, keeping only@types/nodeand@tootallnate/once. - Updated a few lint-related call sites (e.g., bare
catch, updated ESLint disable rule name).
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
yarn.lock |
Lockfile refresh reflecting dependency/toolchain upgrades and vulnerability remediation. |
package.json |
Dependency/devDependency upgrades, version bump, and pared-down resolutions. |
src/util/index.ts |
Removes unused catch binding to satisfy updated linting rules. |
src/sdk-data.ts |
Updates ESLint disable directive for require(...) to the new rule name. |
src/index.spec.ts |
Updates ESLint disable directives where require('.') is intentionally used in tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "@types/express": "^4", | ||
| "@types/jest": "^30", | ||
| "@typescript-eslint/eslint-plugin": "^8", | ||
| "@typescript-eslint/parser": "^8", | ||
| "eslint": "^8", | ||
| "eslint-config-prettier": "^10", | ||
| "eslint-import-resolver-typescript": "^4", | ||
| "eslint-plugin-import": "^2", | ||
| "eslint-plugin-prettier": "^5", | ||
| "eslint-plugin-promise": "^7", | ||
| "express": "^5", | ||
| "husky": "^9", | ||
| "jest": "^29", | ||
| "lint-staged": "^16", | ||
| "prettier": "^3", | ||
| "testdouble": "^3", | ||
| "ts-jest": "^29", | ||
| "typescript": "^5" |
| "@google-cloud/storage": "^7", | ||
| "@microsoft/api-documenter": "^7.30.5", | ||
| "@microsoft/api-extractor": "^7.58.7", | ||
| "@types/express": "^4", | ||
| "@types/jest": "^30", | ||
| "@typescript-eslint/eslint-plugin": "^8", | ||
| "@typescript-eslint/parser": "^8", | ||
| "eslint": "^8", | ||
| "eslint-config-prettier": "^10", | ||
| "eslint-import-resolver-typescript": "^4", | ||
| "eslint-plugin-import": "^2", | ||
| "eslint-plugin-prettier": "^5", | ||
| "eslint-plugin-promise": "^7", | ||
| "express": "^5", | ||
| "husky": "^9", |
| "resolutions": { | ||
| "minimatch": "^3.1.2", | ||
| "@types/node": "^20.0.0" | ||
| "//@types/node": "Pinned to ^20 to keep the dev type surface aligned with engines.node >=20.x; newer @types/node would let consumer code use APIs that aren't actually available on Node 20", | ||
| "@types/node": "^20.0.0", | ||
| "//@tootallnate/once": "GHSA-rj4j-rrv4-3xc4 (low). Pulled deeply by @google-cloud/storage → teeny-request → http-proxy-agent. The latest @google-cloud/storage (7.19.x) still ships the unpatched chain and there's no newer release; the chain is dev-only (test fixture downloader)", | ||
| "@tootallnate/once": "^3.0.1" |
There was a problem hiding this comment.
From Claude: the published-package concern is unfounded — resolutions is not honored on installed packages. npm and yarn both deliberately ignore the resolutions field of any dependency in node_modules; only the field in the root project's package.json controls dependency resolution. So while these "//<key>" entries do get published into the package's package.json, they never affect a downstream consumer's install graph or behavior. They're essentially dead bytes for anyone who installs @eppo/node-server-sdk.
What's left after that is a developer-experience consideration: yarn does emit one warning per pseudo-comment key during yarn install here (Resolution field "//@types/node" does not end with a valid package name and will be ignored). The trade-off we picked, in line with visual-editor and sdk-test-data's vuln-cleanup PRs, is that having the GHSA reasoning inline next to each resolution is more useful for the next person who has to revisit them than the cost of two install-time warnings. Happy to convert these to comments above the block in a sibling RESOLUTIONS.md if there's a preference for that convention instead.
Two small follow-ups from PR review: - jest ^29 → ^30, matching the @types/jest ^30 already on this branch and the jest 30 baseline used by js-client-sdk's parallel PR. ts-jest stays on ^29 because no 30.x has been published; ts-jest 29.4.x declares jest 30 as a supported peer (peerDependencies.jest: ^29.0.0 || ^30.0.0). - @types/express ^4 → ^5, matching the express ^5 runtime bump from the prior commit. tsc stays clean. Verification: yarn typecheck, yarn lint, yarn test (115 tests), yarn audit all green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sameerank
left a comment
There was a problem hiding this comment.
Approving, but please consider re-adding the lower bounds on the version constraints
| "testdouble": "^3.16.4", | ||
| "ts-jest": "^29.4.6", | ||
| "typescript": "^5.4.5" | ||
| "@google-cloud/storage": "^7", |
There was a problem hiding this comment.
Unless we're intentionally allowing downgrades to older versions (I only see versions going up in the yarn.lock), why are we loosening the lower bounds on these versions, i.e. dropping the minimum minor/patch constraints?
See commit
7dac7b2for full per-package detail and verification notes. Summary:yarn audit: 112 paths → 0 (was 2 Critical / 59 High / 44 Moderate / 7 Low).schema-utils/ajvandajv-formats/ajv. After the dep bumps below, every one of those clears transitively. The two that remain inpackage.json:@types/node ^20.0.0— intentional pin to keep the dev type surface aligned withengines.node >=20.x. Not a vuln fix.@tootallnate/once ^3.0.1— GHSA-rj4j-rrv4-3xc4 (low). Pulled by@google-cloud/storage→teeny-request→http-proxy-agent. The latest@google-cloud/storage7.19.x still ships the unpatched chain and there's no newer release; the chain is dev-only (test-fixture downloader).@eppo/js-client-sdk-common 4.15.2 → ^5(drops uuid runtime dep, replaced upstream withcrypto.randomUUIDfor event IDs),express ^4 → ^5(drops vulnerable path-to-regexp 0.x and qs <6.15 transitively without needing scoped resolutions; express is a devDep used only by the mock API server in tests, where the simpleapp.get(regex, handler)usage works the same in v5),@typescript-eslint/* 5 → 8,eslint-config-prettier 8 → 10,eslint-plugin-promise 6 → 7,husky 6 → 9,lint-staged 12 → 16,prettier 2 → 3(drops theyaml@1.xtransitive that triggered the yaml advisory),@google-cloud/storageto latest 7.x.catchfor an unusedcatch (error)parameter insrc/util/index.ts, and replacing deprecatedno-var-requiresdisable directives withno-require-imports.Test plan
yarn lint,yarn typecheck,yarn test(115 tests) green on Node 20/22/24yarn auditreports 0 vulnerabilitiesyarn tsc(build) succeeds;dist/exports unchangedManual verification
Built a tiny toy node app that consumes this branch's SDK via a
file:reference and callsinit(...).getStringAssignment(...)against an Eppo Sandbox account. ResolvedMy-Flag(with attrs{accountId, sd:'dsf'}to hit the 50/50 allocation) andmegan-test-blahhfor 12 distinct subject keys, comparing against the same 12 subjects in a parallel toy browser app onjs-client-sdkPR #284's branch. All 12 subjects produced identical variation assignments across the two SDK branches, distribution 8 treatment / 4 control, assignment-logger fired correctly on both sides.🤖 Generated with Claude Code