chore(deps): upgrade all dependencies (2026-08-03) - #135
devin-ai-integration[bot] wants to merge 34 commits into
Conversation
Also removes obsolete patches/react-virtualized+9.22.5.patch: the import it commented out was removed upstream in react-virtualized 9.22.6. Co-Authored-By: Phil Bedford <phil.bedford@cognition.ai>
Skips @types/lodash 4.17.25 (kept at 4.14.181): the newer types change intersectionWith fp comparator inference and break tsc in scripts/seedDataUtils.ts. Reformats 4 files per prettier 3.9.6. Co-Authored-By: Phil Bedford <phil.bedford@cognition.ai>
…ht-error rule Co-Authored-By: Phil Bedford <phil.bedford@cognition.ai>
v5 exposes named exports; migrates default NumberFormat import to the NumericFormat named export and renames isNumericString -> valueIsNumericString. Co-Authored-By: Phil Bedford <phil.bedford@cognition.ai>
Uses the named createProxyMiddleware export with pathFilter and drops the removed logLevel option, so the CI proxy server (start:ci) works with v4. Co-Authored-By: Phil Bedford <phil.bedford@cognition.ai>
v7 removes the default matchers export; switches setup-tests to the @testing-library/jest-dom/vitest entrypoint that auto-extends expect. Co-Authored-By: Phil Bedford <phil.bedford@cognition.ai>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Frontend verification — post-upgrade demo (PASS)Exercised the upgraded app end-to-end as seeded user @Heath93: sign-in loads clean → login succeeds (bcryptjs v3 verifies the v2 seed hash) → Everyone / Friends / Mine feeds each load → created a $50 payment to Kristian Bradtke, balance $1,509.53 → $1,459.53 (exercises the react-number-format v5 migration) → console shows only benign Vite/DevTools info + pre-existing XState v4 deprecation warnings (no errors). |
| createProxyMiddleware({ | ||
| pathFilter: ["/login", "/callback", "/logout", "/checkAuth", "graphql"], |
There was a problem hiding this comment.
📝 Info: pathFilter entry "graphql" lacks a leading slash and never matches
The pathFilter list carries over the pre-existing "graphql" entry (all other entries start with /). http-proxy-middleware matches plain string filters with a path.indexOf(filter) === 0 prefix check against the URL pathname, so /graphql never matches graphql — the same was true in 0.19, so this is pre-existing rather than a regression. Practically it is harmless today because the frontend calls the GraphQL endpoint through an absolute http://localhost:${backendPort}/graphql URL (src/machines/bankAccountsMachine.ts:51), but if any code ever relies on the proxy for GraphQL, this entry is dead. Worth normalizing to "/graphql" while the file is being touched.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Good catch, but this is pre-existing (the "graphql" entry was already there in the 0.19 config) and, as you note, harmless because the app calls GraphQL via an absolute URL. Leaving it unchanged to keep this PR a pure dependency-upgrade with no behavior changes beyond what the upgrades mechanically require.
| "@babel/plugin-proposal-private-property-in-object": "7.21.11", | ||
| "@babel/preset-env": "^7.28.0", | ||
| "@cypress/code-coverage": "^3.14.5", | ||
| "@babel/preset-env": "^8.0.2", |
There was a problem hiding this comment.
📝 Info: Babel major bump leaves one Babel 7 plugin behind
@babel/core, @babel/preset-env, @babel/plugin-syntax-flow and @babel/plugin-transform-react-jsx all moved to 8.x, but @babel/plugin-proposal-private-property-in-object stays pinned at 7.21.11 (line 56). Babel 8 removed/renamed the proposal-* plugins (the equivalent is @babel/plugin-transform-private-property-in-object) and the 7.x plugin declares a peer of @babel/core@^7, so Yarn 1 will emit a peer-dependency warning. Nothing in this repo has a Babel config that loads the plugin (no .babelrc/babel.config.*), so there is no runtime impact today — but the leftover pin makes the "upgraded together as a coupled unit" claim incomplete, and the dependency is likely vestigial CRA cruft that could just be dropped.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Correct — @babel/plugin-proposal-private-property-in-object was left at 7.x intentionally. No Babel config in the repo loads it (it's vestigial CRA cruft), so it's inert; bumping/removing it is out of scope for a dependency-upgrade PR and would risk touching build behavior. The peer warning is cosmetic. Noting it here rather than changing it.
| } catch (err: any) { | ||
| /* istanbul ignore next */ | ||
| throw new Error(err); | ||
| throw new Error(err, { cause: err }); |
There was a problem hiding this comment.
📝 Info: Rethrown error message becomes stringified object
new Error(err, { cause: err }) passes an Error object as the message argument, so the resulting message is String(err) (e.g. "Error: ...") rather than the underlying message. This is pre-existing behavior (the old code was new Error(err)), and adding cause satisfies the new eslint preserve-caught-error rule, but new Error(err?.message ?? String(err), { cause: err }) would produce a cleaner message while keeping the rule satisfied.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Agreed this is pre-existing behavior — the { cause: err } was added only to satisfy eslint 10's preserve-caught-error. Keeping the message argument unchanged to avoid altering runtime behavior in a deps PR; your err?.message ?? String(err) suggestion is a reasonable standalone cleanup.
| "@okta/okta-auth-js": "^8.0.1", | ||
| "@okta/okta-react": "^6.11.0", |
There was a problem hiding this comment.
🔍 okta-react 6.x peer range may not cover okta-auth-js 8
@okta/okta-react stays on 6.x while @okta/okta-auth-js jumps to ^8.0.1. okta-react 6.x declares a peer dependency on okta-auth-js ^5 || ^6 || ^7; Yarn 1 only warns on peer mismatches, so install/build/type gates would not catch an incompatibility. The Okta auth flow is behind VITE_OKTA and is not exercised by the unit tests that were run, so it is untested in this PR. Worth verifying the Okta login e2e spec (cypress/tests/ui-auth-providers/okta.spec.ts) before relying on this combination.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Noted — okta-react stays at 6.x (its 7.x is a larger migration) while okta-auth-js went to ^8, so there's a peer-range mismatch that yarn only warns on. The Okta flow is behind VITE_OKTA and isn't exercised by the unit tests or the manual demo, so I've flagged it as untested in the PR body. Flagging for the maintainers to verify cypress/tests/ui-auth-providers/okta.spec.ts before relying on this combo; happy to pin okta-auth-js back to ^7 if you'd prefer to avoid the mismatch.
| "webpack": "5", | ||
| "xstate": "4.38.3", | ||
| "yup": "0.32.11" | ||
| "yup": "1.7.1" |
There was a problem hiding this comment.
🔍 yup 1.x validation-message behavior is only covered by e2e tests
yup 0.32 → 1.7 is a major with behavior changes around casting/typeError messages, and the six form schemas (src/components/SignInForm.tsx, SignUpForm.tsx, UserSettingsForm.tsx, BankAccountForm.tsx, CommentForm.tsx, TransactionCreateStepTwo.tsx) drive user-visible helper text that Cypress e2e specs assert on. yarn test:unit:ci does not cover those assertions, so the validation-message assertions in the e2e suite are the real gate for this bump.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Right — the yup 0.32→1.7 major is validated by build/types/unit here, but the user-visible helper-text assertions live in the Cypress e2e specs, which weren't run in this PR. Documented as such; the e2e suite is the real gate for the validation-message behavior.
Co-Authored-By: Phil Bedford <phil.bedford@cognition.ai>
| req.logout(() => { | ||
| req.session!.destroy(() => { | ||
| res.redirect("/"); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
📝 Info: Logout now sends exactly one response; ordering with passport 0.7 session regeneration is sound
The previous code redirected twice (once from the req.logout callback and once from the session-destroy callback), which under passport 0.6+/0.7 async logout produced an ERR_HTTP_HEADERS_SENT. Nesting destroy inside the logout callback fixes that. Worth noting the sequencing: passport 0.6+ logout regenerates the session (creating a new store record) before invoking the callback, and the subsequent destroy then removes that freshly created record, so no orphaned session is left behind. The logout error argument is intentionally ignored; any store error will be silently swallowed and the client still gets a redirect.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Thanks — that matches the intent: single response, and destroying after logout's session regeneration leaves no orphaned record. The logout error is intentionally ignored (best-effort cleanup; client always gets redirected), consistent with the prior handler.
| }); | ||
| }} | ||
| thousandSeparator | ||
| isNumericString | ||
| valueIsNumericString | ||
| prefix="$" | ||
| /> |
There was a problem hiding this comment.
📝 Info: react-number-format v5 change in onValueChange semantics
In v5, onValueChange also fires for programmatic (prop-driven) value changes, distinguished via the second sourceInfo argument, whereas v4 largely fired on user input. Here the callback unconditionally calls Formik's onChange, so a prop-driven update could feed back into Formik state. In practice the value flows one way (Formik → field.value → NumericFormat) and the manual walkthrough in the PR exercised payment creation, so this is unlikely to loop, but if amount-field flakiness shows up in e2e runs this is the first place to look. Also note {...other} is spread into the synthetic target object passed to onChange, which is odd but unchanged from before.
(Refers to lines 50-64)
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Agreed — value flow is one-way (Formik → field.value → NumericFormat), so the prop-driven onValueChange in v5 shouldn't loop, and the manual walkthrough confirmed payment creation works. The {...other} spread into the synthetic target is unchanged from the v4 code; left as-is to keep this a mechanical migration. Noted as the first place to look if e2e amount-field flakiness appears.
Summary
Upgrades all safely-upgradable outdated dependencies in the Cypress Real World App, branched from and targeting
develop. Commits are separated by batch: one commit for all patch bumps, one for all minor bumps, and one commit per major package so any regression is attributable and revertable.All validation gates pass at HEAD on Node 22.20.0 (the CI runtime):
yarn lint,yarn types,yarn build,yarn test:unit:ci. The upgraded app was verified end-to-end in the browser (login → all three feeds → create payment → console check) — see the demo at the bottom.A handful of major upgrades were skipped because they require non-mechanical refactors (MUI v4→v5 rename+styling engine, react-router v5→v6/v7, lowdb ESM, express 5, xstate 5, etc.) or break the current Node/Vite/test setup. Every skip is documented below with the exact reason. No tests were modified to pass.
A few majors needed mechanical code fixes (committed separately from the bump):
react-number-formatv4→v5: default export removed → migratedTransactionCreateStepTwoto the namedNumericFormatimport +valueIsNumericString.http-proxy-middleware0.19→4: default-callable API removed →src/setupProxy.jsnow uses the namedcreateProxyMiddleware({ pathFilter, ... })and drops the removedlogLevel.passport0.5→0.7:req.logoutbecame async/callback-based → reworkedbackend/auth.tsPOST /logoutto destroy the session inside the logout callback and send exactly oneres.redirect("/")(the old code would now fire two responses and throwERR_HTTP_HEADERS_SENT).eslint9→10: newpreserve-caught-errorrule → attached{ cause: err }to a rethrow inbackend/graphql/resolvers/Query.ts.@testing-library/jest-dom5→7: default/matchersexport removed →src/setup-tests.jsuses the@testing-library/jest-dom/vitestentrypoint (auto-extendsexpect).Version pinning convention (mix of exact and caret) was preserved per package.
Upgrade summary
Patch batch (
chore(deps): upgrade patch dependencies)Minor batch (
chore(deps): upgrade minor dependencies)Major batch (one commit each)
husky installinpostinstallprints a deprecation warning but exits 0preserve-caught-errorfix inQuery.tsNumericFormatmigration inTransactionCreateStepTwo.tsxsetupProxy.jsmigration@babel/core,@babel/preset-env,@babel/plugin-*)setup-tests.jsmigrationSkipped packages (with reason)
@material-ui/*/ MUI@material-ui/*→@mui/*) plus styling-engine migration — a large refactor, not mechanical. Per task guidance, not half-migrated.react-router/react-router-domSwitch→Routes,useHistory→useNavigate, render props); non-mechanical across many routes.lowdbexpress(+@types/express)xstate(+@xstate/react)react/react-dom(+types)express-jwtbackend/helpers.ts.express-validatorsanitizeQueryremoved and validator/callback types changed — non-mechanical.jwks-rsaexpress-jwttypings.vitevite-plugin-istanbulfails to load (ESM/require) under the new major.vitestyarn installresolution failure.@faker-js/fakerfaker.random/faker.name/faker.internet.userNameused by the seed scripts.@types/lodashscripts/seedDataUtils.ts(intersectionWith). Kept at 4.14.181.detect-portdebuglog) incompatible with the Vite browser build.jsdomSecurity
Direct-dependency upgrades of security-relevant packages were applied (
axios0.28→1.19,bcryptjs2→3,uuid8→14,yup,@okta/*).yarn auditstill reports 14 advisories (11 moderate / 3 high), all in transitive chains of skipped majors / dev tooling (e.g.@okta/jwt-verifier > njwt > uuid, and dev-only chains); resolving them requires the skipped major migrations above and is intentionally out of scope. No advisories were force-fixed (npm audit fix --forcewas not used).Validation (Node 22.20.0, matching CI
cypress/browsers:22.20.0)yarn lintyarn types(tsc --noEmit)yarn buildyarn test:unit:ciBaseline on
developwas green for all of the above, so this PR maintains "no worse than baseline".Frontend verification (demo)
Re-seeded via
yarn db:seed:dev, startedyarn dev(Vite :3000 + Express :3001), and exercised the app as seeded user @Heath93:A screen recording of the full walkthrough is attached to the session and posted as a PR comment.
Link to Devin session: https://app.devin.ai/sessions/5613b071ad6f43a7aef12fd080f543ec
Requested by: @dr-phil
Devin Review