feat(client-ts): add axios dependency and refresh token interceptor#212
feat(client-ts): add axios dependency and refresh token interceptor#212BHOGALA-SRIKA wants to merge 3 commits into
Conversation
|
Thank you for your contribution! Before we can merge this PR, we need you to sign our Contributor License Agreement. I have read the CLA and agree to its terms. You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
|
Warning Review limit reached
More reviews will be available in 32 minutes and 4 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughA new ChangesAxios Auth Interceptor
Sequence DiagramsequenceDiagram
participant App
participant AxiosInstance
participant RequestInterceptor
participant ResponseInterceptor
participant AuthClient
App->>AxiosInstance: outgoing HTTP request
AxiosInstance->>RequestInterceptor: onRequest
RequestInterceptor->>AuthClient: getAccessToken()
AuthClient-->>RequestInterceptor: token (or null)
RequestInterceptor-->>AxiosInstance: Authorization: Bearer token
AxiosInstance-->>ResponseInterceptor: 401 response
alt First 401 (isRefreshing = false)
ResponseInterceptor->>ResponseInterceptor: set isRefreshing = true, _retry = true
ResponseInterceptor->>AuthClient: refresh()
AuthClient-->>ResponseInterceptor: new token
ResponseInterceptor->>ResponseInterceptor: processQueue(null, newToken)
ResponseInterceptor-->>AxiosInstance: replay original request
else Concurrent 401 (isRefreshing = true)
ResponseInterceptor->>ResponseInterceptor: push resolve/reject to failedQueue
note over ResponseInterceptor: waits until processQueue drains
end
alt refresh() throws
ResponseInterceptor->>ResponseInterceptor: processQueue(error, null)
ResponseInterceptor->>AuthClient: logout()
ResponseInterceptor-->>App: reject all queued + original requests
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
clients/ts/src/interceptor.ts (1)
9-84: ⚡ Quick winReturn interceptor IDs to enable cleanup.
The function registers interceptors but doesn't return their IDs, making it impossible to eject them later. This is useful for testing and for SPAs that need to clean up on unmount.
♻️ Proposed refactor to return cleanup function
-export function createAuthInterceptor(axiosInstance: AxiosInstance, authClient: AuthClient) { +export function createAuthInterceptor(axiosInstance: AxiosInstance, authClient: AuthClient): () => void { let isRefreshing = false; let failedQueue: FailedRequestQueueItem[] = []; // ... processQueue definition ... - // 1. Request Interceptor: Attach the current token to outgoing requests - axiosInstance.interceptors.request.use( + const requestInterceptorId = axiosInstance.interceptors.request.use( // ... existing implementation ... ); - // 2. Response Interceptor: Catch 401 errors and handle seamless token refreshes - axiosInstance.interceptors.response.use( + const responseInterceptorId = axiosInstance.interceptors.response.use( // ... existing implementation ... ); + + return () => { + axiosInstance.interceptors.request.eject(requestInterceptorId); + axiosInstance.interceptors.response.eject(responseInterceptorId); + }; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@clients/ts/src/interceptor.ts` around lines 9 - 84, The createAuthInterceptor function does not return the interceptor IDs that are generated when registering the request and response interceptors with axiosInstance. Modify the function to capture the numeric IDs returned by both axiosInstance.interceptors.request.use() and axiosInstance.interceptors.response.use() calls, and return them (either as an object or a cleanup function) so callers can later eject these interceptors using axiosInstance.interceptors.request.eject() and axiosInstance.interceptors.response.eject() methods. This enables proper cleanup for testing and single-page applications that need to remove interceptors on unmount.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@clients/ts/src/interceptor.ts`:
- Line 42: The `_retry` property being accessed on `originalRequest` does not
exist on Axios's `InternalAxiosRequestConfig` type, causing TypeScript
compilation errors. To fix this, augment the Axios request config type at the
top of the interceptor.ts file to include the `_retry` property as an optional
boolean field, which will allow TypeScript to recognize this custom property
when checking `originalRequest._retry` in the 401 error handling logic
(appearing at lines 42 and 58).
- Around line 13-22: The processQueue function does not handle the case where
both error is falsy and token is undefined, which leaves queued promises hanging
indefinitely. In the processQueue function, add an else branch after the else if
(token) condition to handle the case where neither an error nor a valid token is
provided (i.e., when token is undefined). When this occurs, reject all promises
in the failedQueue with an appropriate error indicating that the token refresh
failed or returned an invalid token, ensuring no promises remain pending.
---
Nitpick comments:
In `@clients/ts/src/interceptor.ts`:
- Around line 9-84: The createAuthInterceptor function does not return the
interceptor IDs that are generated when registering the request and response
interceptors with axiosInstance. Modify the function to capture the numeric IDs
returned by both axiosInstance.interceptors.request.use() and
axiosInstance.interceptors.response.use() calls, and return them (either as an
object or a cleanup function) so callers can later eject these interceptors
using axiosInstance.interceptors.request.eject() and
axiosInstance.interceptors.response.eject() methods. This enables proper cleanup
for testing and single-page applications that need to remove interceptors on
unmount.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: c673b7bb-52bc-493b-96a9-d16f713d63f1
⛔ Files ignored due to path filters (1)
clients/ts/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (3)
clients/ts/package.jsonclients/ts/src/index.tsclients/ts/src/interceptor.ts
|



Closes #178
Description
This PR introduces an automatic Axios refresh token interceptor to the TypeScript SDK. It intercepts outgoing requests to attach the bearer token and seamlessly catches
401 Unauthorizedresponses to trigger a token refresh viaAuthClient.refresh().Concurrent requests hitting a 401 while a refresh is already in progress are queued and replayed once the new token is acquired.
Changes
clients/ts/src/interceptor.tscontaining the interceptor logic and request queuing.clients/ts/src/index.ts.clients/ts/package.jsonandpackage-lock.jsonto includeaxiosas a dependency, as it is required for the interceptor functionality.Verification
npm run buildsuccessfully (CJS, ESM, and DTS builds all passed cleanly).npm testand verified all 20 existing unit tests continue to pass.Summary by CodeRabbit
New Features
Chores