Skip to content

chore(deps): upgrade eslint and @eslint/js to v10 (major)#215

Merged
Koosha-Owji merged 9 commits into
mainfrom
chore/upgrade-eslint-v10
Apr 28, 2026
Merged

chore(deps): upgrade eslint and @eslint/js to v10 (major)#215
Koosha-Owji merged 9 commits into
mainfrom
chore/upgrade-eslint-v10

Conversation

@dtoxvanilla1991
Copy link
Copy Markdown
Contributor

@dtoxvanilla1991 dtoxvanilla1991 commented Apr 21, 2026

Summary

Upgrades ESLint and @eslint/js from v9 to v10, replacing the Renovate PR #198 which had a merge conflict and an incompatibility with typescript-eslint@8.46.0.

Resolves/replaces: #198


Dependency changes

Package Before After
eslint ^9.9.1 → resolves 9.37.0 ^10.0.0 → resolves 10.2.1
@eslint/js ^9.9.1 → resolves 9.37.0 ^10.0.0 → resolves 10.0.1
typescript-eslint 8.46.0 (locked) 8.59.0 (updated)

Why typescript-eslint needed upgrading too

The Renovate PR (#198) locked eslint@10.0.0 - before the FlatESLint named export was removed in eslint@10.0.1. @typescript-eslint/utils@8.46.0 imports FlatESLint from ESLint directly, causing a runtime crash (TypeError: Class extends value undefined) with ESLint ≥ 10.0.1.

typescript-eslint@8.59.0 is the fixed release that no longer depends on the removed export and explicitly declares eslint: ^10.0.0 as a valid peer dependency. The project's existing constraint (^8.3.0) already allows this upgrade.


ESLint v10 migration fixes

ESLint v10 updated eslint:recommended with two new rules that fired on existing code. All violations are fixed in this PR:

preserve-caught-error (4 fixes)

Errors rethrown in catch blocks now require the original error to be passed as cause. Added { cause: e } to rethrown errors in:

  • lib/utils/generateAuthUrl.ts
  • lib/utils/generatePortalUrl.ts
  • lib/utils/navigateToKinde.ts
  • lib/utils/token/accountApi/callAccountApi.ts

no-useless-assignment (2 fixes)

Initial assignments whose value is immediately overwritten before being read are now flagged. Removed dead assignments in:

  • lib/utils/generateAuthUrl.ts - let codeChallenge = "" immediately overwritten in both if/else branches
  • lib/utils/token/accountApi/callAccountApi.ts - let items = [] immediately overwritten by the first API call result

Other ESLint v10 breaking changes - not applicable here

Breaking change Impact
eslintrc support removed ✅ Already using flat config (eslint.config.js)
eslint-env comments now errors ✅ No such comments in codebase
Deprecated SourceCode / rule context methods removed ✅ We don't author ESLint plugins
no-shadow-restricted-names reports globalThis by default ✅ No violations found
Node.js ^20.19.0 || ^22.13.0 || >=24 required ✅ CI uses Node 20.x (latest LTS ≥ 20.19.0)

Test results

  • pnpm lint - passes (0 errors)
  • pnpm test --run - 616 tests pass, 20 skipped (no regressions)

- Bump eslint ^9.9.1 → ^10.0.0 (resolves 10.2.1)
- Bump @eslint/js ^9.9.1 → ^10.0.0 (resolves 10.0.1)
- Upgrade typescript-eslint 8.46.0 → 8.59.0 (required for ESLint v10.0.1+ compatibility)

ESLint v10 removed the FlatESLint export that @typescript-eslint/utils@8.46.0
depended on; upgrading to typescript-eslint@8.59.0 (which declares eslint
^10.0.0 as a valid peer) fixes the runtime crash.

ESLint v10 updated eslint:recommended with two new rules that fired on
existing code — fixed all violations:

- preserve-caught-error: added { cause: e } to 4 rethrown errors in
  generateAuthUrl.ts, generatePortalUrl.ts, navigateToKinde.ts,
  callAccountApi.ts
- no-useless-assignment: removed dead initial assignments in
  generateAuthUrl.ts (codeChallenge = "") and callAccountApi.ts (items = [])

All 616 tests pass. Lint is clean.

Closes/replaces: #198
@dtoxvanilla1991 dtoxvanilla1991 requested review from a team as code owners April 21, 2026 20:07
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 61381fb8-225c-43a2-8868-b26c7bf89e69

📥 Commits

Reviewing files that changed from the base of the PR and between 317150a and 7f23dc1.

⛔ Files ignored due to path filters (2)
  • package.json is excluded by !**/*.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !**/*.yaml
📒 Files selected for processing (4)
  • lib/sessionManager/stores/memory.test.ts
  • lib/utils/generateAuthUrl.test.ts
  • lib/utils/generateAuthUrl.ts
  • lib/utils/token/accountApi/callAccountApi.test.ts
✅ Files skipped from review due to trivial changes (2)
  • lib/utils/token/accountApi/callAccountApi.test.ts
  • lib/utils/generateAuthUrl.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/sessionManager/stores/memory.test.ts

Walkthrough

Error-handling changes: multiple utilities now rethrow errors attaching the original exception as the cause. Tests added/updated to assert preserved causes. Small internal TypeScript initializations adjusted and test timer handling made deterministic.

Changes

Cohort / File(s) Summary
Error rethrow with cause
lib/utils/generateAuthUrl.ts, lib/utils/generatePortalUrl.ts, lib/utils/navigateToKinde.ts, lib/utils/token/accountApi/callAccountApi.ts
Rethrow errors using new Error(message, { cause: error }) to preserve original exceptions for reauth-state decoding, URL parsing, popup auth failures, and fetch/network failures.
Tests validating error causes
lib/utils/navigateToKinde.test.ts, lib/utils/token/accountApi/callAccountApi.test.ts, lib/utils/generateAuthUrl.test.ts
Added/updated tests to simulate listener-registration and network failures and to assert thrown errors include the original errors as cause and expected messages/regex.
Timer handling in tests
lib/sessionManager/stores/memory.test.ts
Switched to Vitest fake timers (vi.useFakeTimers() + vi.runAllTimersAsync()) and added afterEach timer restore for deterministic mixed sync/async listener test behavior.
Minor internal adjustments
lib/utils/generateAuthUrl.ts, lib/utils/token/accountApi/callAccountApi.ts
Tightened codeChallenge typing/init and changed paginated items initialization to use the first API response instead of an empty-array sentinel.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive Title claims to upgrade ESLint to v10, but the code changes actually address ESLint v10 migration fixes (error handling, dead code removal) without visible dependency version updates in provided summaries. Verify that package.json changes show eslint and @eslint/js upgraded from v9 to v10; if only migration fixes are present, update title to reflect actual changeset.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed Description comprehensively explains ESLint v9-to-v10 upgrade rationale, dependency changes, migration fixes applied, and test results, all directly related to the changeset.
Linked Issues check ✅ Passed PR addresses issue #198 objectives: upgrades ESLint/typescript-eslint versions, fixes v10 breaking changes (preserve-caught-error, no-useless-assignment rules), verifies Node.js compatibility, and passes all tests.
Out of Scope Changes check ✅ Passed All changes directly address ESLint v10 migration requirements: dependency updates, error-handling fixes for new rules, dead-assignment removals, and test updates. No unrelated changes detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/upgrade-eslint-v10

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@dtoxvanilla1991 dtoxvanilla1991 self-assigned this Apr 21, 2026
- callAccountApi: test fetch network error path (catch block with { cause })
- navigateToKinde: test popup auth failure when addEventListener throws
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
lib/utils/navigateToKinde.ts (1)

157-161: Minor: error concatenation is now redundant with cause.

Since the original error is attached via { cause: error }, interpolating it into the message ("Popup authentication failed: " + error) duplicates the information and produces output like Popup authentication failed: Error: Listener registration failed. Consider dropping the concatenation to keep the message clean:

♻️ Proposed tweak
-    throw new Error("Popup authentication failed: " + error, { cause: error });
+    throw new Error("Popup authentication failed", { cause: error });

Note: the existing test asserts toContain("Popup authentication failed"), so it would still pass.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/utils/navigateToKinde.ts` around lines 157 - 161, In the catch block
around waitForMessage in navigateToKinde.ts, remove the concatenation of the
original error into the message and instead create the Error with a clean
message and attach the original as the cause (e.g., throw new Error("Popup
authentication failed", { cause: error })); update the throw in that catch
around waitForMessage so the message is concise while preserving the original
error via the cause property.
lib/utils/token/accountApi/callAccountApi.ts (1)

33-37: Minor: interpolated ${error} duplicates info now carried by cause.

With cause: error attached, stringifying error into the message yields messages like Failed to fetch from …: Error: Network failure. The test at callAccountApi.test.ts:96-99 only asserts toContain("Failed to fetch from …"), so trimming the interpolation would be safe and a bit cleaner:

♻️ Optional cleanup
-    throw new Error(`Failed to fetch from ${domain.value}/${route}: ${error}`, {
-      cause: error,
-    });
+    throw new Error(`Failed to fetch from ${domain.value}/${route}`, {
+      cause: error,
+    });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/utils/token/accountApi/callAccountApi.ts` around lines 33 - 37, In the
catch block inside callAccountApi (in callAccountApi.ts) remove the interpolated
`${error}` from the thrown Error message and keep the existing cause: error so
the Error message reads only "Failed to fetch from ${domain.value}/${route}"
while preserving the original error via the cause option (i.e., update the throw
in the catch of callAccountApi to omit the stringified error but still pass
cause: error).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@lib/utils/navigateToKinde.ts`:
- Around line 157-161: In the catch block around waitForMessage in
navigateToKinde.ts, remove the concatenation of the original error into the
message and instead create the Error with a clean message and attach the
original as the cause (e.g., throw new Error("Popup authentication failed", {
cause: error })); update the throw in that catch around waitForMessage so the
message is concise while preserving the original error via the cause property.

In `@lib/utils/token/accountApi/callAccountApi.ts`:
- Around line 33-37: In the catch block inside callAccountApi (in
callAccountApi.ts) remove the interpolated `${error}` from the thrown Error
message and keep the existing cause: error so the Error message reads only
"Failed to fetch from ${domain.value}/${route}" while preserving the original
error via the cause option (i.e., update the throw in the catch of
callAccountApi to omit the stringified error but still pass cause: error).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 03a29b38-c22a-4479-827d-1a9ddeca922c

📥 Commits

Reviewing files that changed from the base of the PR and between 111f47d and 387ff7d.

⛔ Files ignored due to path filters (2)
  • package.json is excluded by !**/*.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !**/*.yaml
📒 Files selected for processing (6)
  • lib/utils/generateAuthUrl.ts
  • lib/utils/generatePortalUrl.ts
  • lib/utils/navigateToKinde.test.ts
  • lib/utils/navigateToKinde.ts
  • lib/utils/token/accountApi/callAccountApi.test.ts
  • lib/utils/token/accountApi/callAccountApi.ts

The async listener waits 5ms, but scheduleNotification uses setTimeout(0)
which can take several ms on loaded CI runners. Combined, the original 10ms
wait was insufficient. Increased to 50ms to match the safety margin used
in the adjacent async listener test (10ms internal + 20ms wait = 2x + buffer).
Per CodeRabbit review: don't interpolate error into the message when
the original error is already preserved via the cause property.

- navigateToKinde.ts: 'Popup authentication failed: ' + error -> 'Popup authentication failed'
- callAccountApi.ts: 'Failed to fetch from ...route: ${error}' -> 'Failed to fetch from ...route'
Comment thread lib/sessionManager/stores/memory.test.ts Outdated
Comment thread lib/utils/generateAuthUrl.ts Outdated
Comment thread lib/sessionManager/stores/memory.test.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
lib/sessionManager/stores/memory.test.ts (1)

262-269: Restore real timers safely on failure paths.

If an assertion or awaited operation between Line 262 and Line 269 throws, vi.useRealTimers() is never reached and fake timers leak into subsequent tests in this file — which all rely on real setTimeout (e.g., await new Promise((resolve) => setTimeout(resolve, 0)) at Lines 286, 295, 325, 345, 372, 394, 411, 415, 419). That can produce confusing cascading failures or hangs on CI.

Prefer scoping the restoration in afterEach (or a try/finally) so it always runs.

♻️ Proposed fix using afterEach
   beforeEach(() => {
     sessionManager = new MemoryStorage();
   });

+  afterEach(() => {
+    vi.useRealTimers();
+  });
+

And remove the inline vi.useRealTimers() at Line 269:

     vi.useFakeTimers();
     sessionManager.subscribe(syncListener);
     sessionManager.subscribe(asyncListener);

     await sessionManager.setSessionItem(StorageKeys.idToken, "mixedTest");

     await vi.runAllTimersAsync();
-    vi.useRealTimers();

     expect(syncCalled).toBe(true);
     expect(asyncCalled).toBe(true);

Note: afterEach will need to be added to the imports from vitest.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/sessionManager/stores/memory.test.ts` around lines 262 - 269, The test
enables fake timers with vi.useFakeTimers() around sessionManager.subscribe(...)
and await sessionManager.setSessionItem(...), but vi.useRealTimers() is called
inline and can be skipped on failures; ensure timers are always restored by
moving vi.useRealTimers() into a guaranteed cleanup (either add an afterEach
import from vitest that calls vi.useRealTimers(), or wrap the fake-timer section
in a try/finally that calls vi.useRealTimers()); update the test that uses
vi.useFakeTimers() (the block around sessionManager.setSessionItem and
vi.runAllTimersAsync) to rely on the global afterEach or the try/finally so
subsequent tests using real setTimeout behave correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@lib/sessionManager/stores/memory.test.ts`:
- Around line 262-269: The test enables fake timers with vi.useFakeTimers()
around sessionManager.subscribe(...) and await
sessionManager.setSessionItem(...), but vi.useRealTimers() is called inline and
can be skipped on failures; ensure timers are always restored by moving
vi.useRealTimers() into a guaranteed cleanup (either add an afterEach import
from vitest that calls vi.useRealTimers(), or wrap the fake-timer section in a
try/finally that calls vi.useRealTimers()); update the test that uses
vi.useFakeTimers() (the block around sessionManager.setSessionItem and
vi.runAllTimersAsync) to rely on the global afterEach or the try/finally so
subsequent tests using real setTimeout behave correctly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 67dcfc85-e2e3-42af-90c9-9ca074d76bf6

📥 Commits

Reviewing files that changed from the base of the PR and between 387ff7d and 317150a.

⛔ Files ignored due to path filters (2)
  • package.json is excluded by !**/*.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !**/*.yaml
📒 Files selected for processing (3)
  • lib/sessionManager/stores/memory.test.ts
  • lib/utils/navigateToKinde.ts
  • lib/utils/token/accountApi/callAccountApi.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/utils/navigateToKinde.ts
  • lib/utils/token/accountApi/callAccountApi.ts

@dtoxvanilla1991
Copy link
Copy Markdown
Contributor Author

@coderabbitai I have addressed your nitpick as well.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 24, 2026

Tip

For best results, initiate chat on the files or code changes.

@dtoxvanilla1991 Thanks for addressing the nitpick! 🎉


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

Comment thread lib/utils/token/accountApi/callAccountApi.test.ts Outdated
@Koosha-Owji Koosha-Owji merged commit 4feba30 into main Apr 28, 2026
8 checks passed
@Koosha-Owji Koosha-Owji deleted the chore/upgrade-eslint-v10 branch April 28, 2026 04:36
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.

4 participants