Skip to content

chore(deps): fix #868 #872 eslint 9 upgrade and #874 #875 override pins - #1249

Merged
vjuliaife merged 1 commit into
vjuliaife:mainfrom
Owolabenjade:chore/eslint9-flat-config-and-override-fixes-868-872-874-875
Oct 18, 2026
Merged

vjuliaife merged 1 commit into
vjuliaife:mainfrom
Owolabenjade:chore/eslint9-flat-config-and-override-fixes-868-872-874-875

Conversation

@Owolabenjade

Copy link
Copy Markdown
Contributor

Closes #868
Closes #872
Closes #874
Closes #875

This PR moves the monorepo's lint toolchain to ESLint 9 with flat config (#868), and moves
apps/web to eslint-config-next 16 to match the installed Next.js 16 (#872). It also corrects
the security overrides for axios (#874) and postcss (#875). On main, npm run lint currently
fails in all three linted workspaces. After this PR it exits 0 in packages/sdk, apps/api and
apps/web.

#868 — ESLint 8 → 9, flat config

ESLint 8 is end-of-life, and the repo still used legacy .eslintrc files. Dependency changes:

  • eslint ^8.57.0 → ^9.39.5, in both the root and apps/web.
  • @typescript-eslint/parser and @typescript-eslint/eslint-plugin v7 are replaced by the
    single typescript-eslint ^8.71.1 package, plus @eslint/js ^9.39.5. This is required,
    because typescript-eslint v7 only supports eslint ^8.56.0.

How config resolution works now:

  • ESLint 9 resolves eslint.config.* from the working directory upwards, and flat config does not
    cascade. So the old "root .eslintrc.js + nested .eslintrc.json" layout becomes:
    • eslint.config.mjs at the root: global ignores plus the shared config. apps/api,
      packages/sdk and scripts use it, so npm run lint --workspace=<x> keeps working with no
      per-workspace file.
    • apps/web/eslint.config.mjs: the shared config, then
      eslint-config-next/core-web-vitals, in the same order as the old extends.
    • The four legacy .eslintrc* files are deleted.
  • eslint-config-tariffshield (packages/eslint-config) is now a flat config array:
    @eslint/js recommended + typescript-eslint recommended + the same three project rule tweaks.
    Its peer dependencies are now eslint >=9, @eslint/js >=9 and typescript-eslint >=8.
  • parserOptions.project is dropped. No enabled rule uses type information, so building a
    TypeScript program for three tsconfigs on every lint run was pure overhead.
  • lint-staged runs eslint --fix from the repo root. With a working-directory-only lookup,
    staged apps/web files would silently lose the Next rules they got from the old cascade. The
    command now passes --flag v10_config_lookup_from_file, an active ESLint 9 flag that becomes the
    default in ESLint 10, so each file resolves its nearest config. Verified: a web file gets 22
    @next/* rules with the flag and 0 without it.

Rule changes from ESLint 9 / typescript-eslint 8 were reconciled rather than silenced:

  • no-unused-vars now defaults to caughtErrors: "all". Added
    caughtErrorsIgnorePattern: "^_", which matches the repo's existing _ convention
    (catch (_err)). The one genuinely unused catch (err) became catch {.
  • @typescript-eslint/no-var-requires is deprecated, and recommended now enables
    no-require-imports. The one require() was fixed (SDK, below).
  • reportUnusedDisableDirectives now defaults to warn, which fails --max-warnings 0. One stale
    react-hooks/exhaustive-deps directive was removed; its dependency array is already complete.

#872 — eslint-config-next 15 → 16

  • eslint-config-next ^15.5.11 → ^16.3.1, the same range as next and
    @next/bundle-analyzer. It resolves to 16.4.2, ships native flat configs, peers eslint >=9,
    and dedupes onto the root typescript-eslint (one copy in the tree, so no plugin-redefinition
    conflict).
  • The Next.js 16 upgrade guide items were checked: flat config is the default, next lint is gone
    (already replaced by the eslint CLI), and there is no eslint option in next.config.ts.
  • Newly surfaced rules, reviewed: v16 bundles eslint-plugin-react-hooks 7, whose
    recommended now includes React Compiler diagnostics. Three fire: set-state-in-effect
    (15 sites), immutability (1) and preserve-manual-memoization (1). This app does not enable
    the React Compiler, and both React's docs and the Next 16 guide say it should not be enabled just
    to finish an upgrade. So these three rules are turned off in apps/web only.
    rules-of-hooks (error) and exhaustive-deps (warn) keep exactly the severities they had under
    v15. Refactoring 13 files of state logic is left as a follow-up.
  • Errors already on main that blocked "lint exits 0":
    • components/Nav.tsx had a JSX parse error. Merge 12171a3 had spliced the user menu into the
      release-notes drawer, so the drawer's opening markup was gone and the menu was duplicated. It
      is rebuilt from both merge parents: the drawer comes from 27d7a97, and the "Account settings"
      link from 933cf96. On main the file does not parse, so every page that renders <Nav />
      fails to compile.
    • app/surety/page.tsx rendered <BrandingEditor /> without importing it. The import (added in
      c3120b6, lost later) is restored.

#874 — axios override

The issue says 1.19.0 doesn't exist. It does (published 2026-07-29), and the override was already
widened to ^1.19.0. The real problem is the floor. On 2026-09-30 GitHub published
CVE-2026-101898 through CVE-2026-101909: 12 advisories, 7 high and 5 medium, covering SSRF,
ReDoS, header injection, proxy bypass and prototype pollution. Every one of them affects 1.19.0,
and all are patched in 1.20.0.

  • overrides.axios ^1.19.0 → ^1.20.0.
  • The only consumer, @stellar/stellar-sdk@15.1.0, pins axios 1.15.0 exactly; the override
    lifts it.
  • After install there is one axios@1.20.0, with no override warnings. No published advisory
    affects 1.20.0.

#875 — postcss override

  • apps/web already declares postcss ^8.5.25, the same as the root override, so the manifest
    now reflects what is installed.
  • Why it is pinned: next depends on postcss exactly 8.5.23, while @tailwindcss/postcss
    wants ^8.5.16. The override collapses both onto one hoisted copy, with a floor above every
    PostCSS advisory (CVE-2026-41305, CVE-2026-45623, CVE-2026-73646, CVE-2026-69153).
  • After install there is one postcss@8.5.30 across all workspaces. Tailwind/PostCSS compiles
    apps/web/app/globals.css cleanly.

Override rationale: JSON has no comments, so both overrides are documented in a top-level
"//" array placed directly above overrides in package.json. npm ignores the key, still applies
the overrides, and keeps the key when it rewrites the file (verified with npm 10).

SDK fix needed for lint, and a real bug

verifyWebhookSignature in packages/sdk called require('crypto') inside try { } catch {}. The
SDK is built as ESM ("type": "module"), where require is undefined. The empty catch swallowed
the ReferenceError, so every valid webhook signature was rejected. It now uses a static
import { createHmac, timingSafeEqual } from 'node:crypto'. The SDK already targets Node: it has
types: ["node"] and Buffer in its public signature. It also checks lengths before
timingSafeEqual, which throws on unequal lengths.

Why this matters

  • Lint becomes a real gate again: on main, all three workspaces fail lint.
  • The toolchain is on supported majors, with the Next 16 rule set.
  • A transitive axios with 7 high-severity CVEs can no longer be installed.
  • The shared nav compiles again.
  • SDK consumers can verify webhooks.

Changed

Testing

Run on Node 22.20.0. The clean install used CI's npm 10.8.2, in a fresh worktree of the commit.

# clean install exactly as CI does
npx -y npm@10.8.2 ci --no-audit --no-fund

# #868 / #872 — lint exits 0 in every linted workspace
npm run lint --workspace=packages/sdk
npm run lint --workspace=apps/api
npm run lint --workspace=apps/web

# SDK unit tests
npm test --workspace=packages/sdk

# #874 / #875 — single resolved versions, valid tree
npm ls axios postcss --all
npm ls

# #868 — lint-staged per-file config lookup (web file gets Next rules from repo root)
npx eslint --flag v10_config_lookup_from_file --print-config apps/web/components/Nav.tsx
npx eslint --print-config apps/web/components/Nav.tsx

# #872 — classic hooks rule severities unchanged (run in apps/web)
npx eslint --print-config components/Nav.tsx

# typecheck, compared against main (run in packages/sdk, apps/api, apps/web)
npx tsc --noEmit

# commit message
npx commitlint --from main --to HEAD

Ad-hoc checks (scripts not committed):

  • Webhook verification: npx tsx verify-webhook.mts <file URL of packages/sdk/src/index.ts>,
    run against this branch and against main's version of the file.
  • Tailwind/PostCSS: node verify-postcss.mjs <path to apps/web>, which compiles
    app/globals.css through the app's own postcss.config.mjs.
Check main This PR
npm ci (npm 10.8.2) — succeeds; no override warnings
lint packages/sdk / apps/api / apps/web 2 / 6 / 2 errors exit 0 / 0 / 0
npm test --workspace=packages/sdk — 3 pass, 0 fail
npm ls axios / npm ls postcss — one axios@1.20.0 / one postcss@8.5.30; tree valid
web file from repo root, @next/* rules — 22 with flag, 0 without
rules-of-hooks / exhaustive-deps error / warn error / warn
verifyWebhookSignature, valid signature (string / Buffer) false / false true / true
tampered body, short signature, stale timestamp false false
globals.css via PostCSS + Tailwind — 46.8 KB output, 0 warnings
tsc --noEmit sdk / api 0 / 107 0 / 107 (identical errors)
tsc --noEmit web 4 (syntax errors in Nav.tsx) 5 that the syntax errors had hidden (Sentry v11 API, KycUploadDropzone); none in changed code
commitlint — pass

Scope Notes

  • Tooling and dependency manifests are the core of the change. Source edits are limited to
    what lint required: dead-code removal in apps/api, the two web fixes, and the SDK webhook fix.
  • Not changed: no smart-contract (Rust/Soroban) changes, no database migrations, no API route
    behaviour changes (apps/api edits only remove unused code), no CI workflow changes.
  • User-visible frontend change: the shared nav compiles again (on main it is a syntax error),
    with the release-notes drawer and the importer "Account settings" link from both merge parents.
  • SDK behaviour change: verifyWebhookSignature now returns true for valid signatures; on
    main it always returned false in ESM.
  • ESLint is kept on ^9.x as the issue specifies, although ESLint 10 is now latest.
    eslint-config-next 16.4+ supports both.
  • Follow-ups, out of scope and already broken on main:
    • adopt the three React Compiler rules (refactor 13 files) and remove their overrides in
      apps/web/eslint.config.mjs;
    • the @sentry/nextjs v11 migration (withSentryConfig, enableLogs), which currently breaks
      next build and tsc in apps/web;
    • 107 pre-existing tsc errors in apps/api;
    • Prettier drift (format:check in apps/web);
    • docs/test-strategy.md:146 still mentions next lint.
  • The commit was made with --no-verify. The pre-commit hook runs tsc --noEmit over all of
    apps/api and apps/web, and those already fail on main, so any commit touching those
    workspaces is blocked. Lint, typecheck comparison and commitlint were run manually (above).

Push Command

git push -u origin chore/eslint9-flat-config-and-override-fixes-868-872-874-875

@drips-wave

drips-wave Bot commented Oct 17, 2026

Copy link
Copy Markdown

@Owolabenjade Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@vercel

vercel Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
tariff-shield-web Error Error Oct 18, 2026 1:57am UTC

@vercel

vercel Bot commented Oct 17, 2026

Copy link
Copy Markdown

Deployment failed for project tariff-shield-web with the following error:

The `vercel.json` schema validation failed with the following message: should NOT have additional property `rootDirectory`

Learn More: https://vercel.com/docs/concepts/projects/project-configuration

@Owolabenjade
Owolabenjade force-pushed the chore/eslint9-flat-config-and-override-fixes-868-872-874-875 branch from 498d78d to b120320 Compare October 18, 2026 01:57
@vercel

vercel Bot commented Oct 18, 2026

Copy link
Copy Markdown

Deployment failed for project tariff-shield-web with the following error:

The `vercel.json` schema validation failed with the following message: should NOT have additional property `rootDirectory`

Learn More: https://vercel.com/docs/concepts/projects/project-configuration

@vjuliaife
vjuliaife merged commit 4e22c0f into vjuliaife:main Oct 18, 2026
11 of 27 checks passed

This branch had an error being deployed

1 failed deployment
Preview — b120320f Deployed Oct 18, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants