interceptor-builder
v1.3.7
Published
A modern collection of reusable utility functions for JavaScript and TypeScript, designed to simplify everyday development tasks.
Maintainers
Readme
✨ Features
- 🔗 Chainable API: Easily chain multiple interceptors together.
- 🔧 Extendable: Create your own custom interceptors with ease.
- 📦 Lightweight: No external dependencies.
- ✅ Typed: Written in TypeScript for a better developer experience.
- universal: Works with any HTTP client that supports interceptors (e.g., Axios, Fetch).
📚 Table of Contents
📦 Installation
npm install interceptor-builder🚀 Getting Started
#1. Create an HTTP client instance
First, create an instance of your preferred HTTP client. In this example, we'll use Axios.
import axios from "axios";
const instance = axios.create({
baseURL: "http://localhost:5173/",
});#2. Create a custom interceptor
Next, create a custom interceptor by implementing the Interceptor interface.
import type { Interceptor, Req, Res, Instance } from "interceptor-builder";
export default class MyInterceptor implements Interceptor {
public instance: Instance;
constructor(instance: Instance) {
this.instance = instance;
}
intercept(req: Req, res: Res): Instance {
req.use(
(config) => {
console.log("Request interceptor");
return config;
},
(error) => Promise.reject(error)
);
res.use(
(response) => {
console.log("Response interceptor");
return response;
},
(error) => Promise.reject(error)
);
return this.instance;
}
}#3. Build the interceptor chain
Finally, use the InterceptorBuilder to chain your interceptors and build the final instance.
import InterceptorBuilder from "interceptor-builder";
import MyInterceptor from "./MyInterceptor";
import LoadingInterceptor from "./LoadingInterceptor";
import TokenInterceptor from "./TokenInterceptor";
const instance = axios.create({
baseURL: "http://localhost:5173/",
});
const enhancedInstance = new InterceptorBuilder(instance).use(MyInterceptor).use(LoadingInterceptor).use(TokenInterceptor).build();
export default enhancedInstance;💡 Usage Examples
Here are some examples of custom interceptors you can create.
loading.interceptor.ts
This interceptor shows a loading indicator during a request.
import type { AxiosInstance } from "axios";
import type { Interceptor, Req, Res } from "interceptor-builder";
export default class LoadingInterceptor implements Interceptor {
public instance;
constructor(instance: AxiosInstance) {
this.instance = instance;
}
private setLoading(loading: boolean) {
const event = new CustomEvent("loading", { detail: loading });
window.dispatchEvent(event);
}
intercept(request: Req, response: Res) {
request.use(
(config) => {
this.setLoading(true);
return config;
},
(error) => {
this.setLoading(false);
return Promise.reject(error);
}
);
response.use(
(res) => {
this.setLoading(false);
return res;
},
(error) => {
this.setLoading(false);
return Promise.reject(error);
}
);
return this.instance;
}
}token.interceptor.ts
This interceptor adds an authentication token to the request headers and handles token refreshing.
import type { AxiosError, AxiosInstance } from "axios";
import axios from "axios";
import type { Interceptor, Req, Res } from "interceptor-builder";
export default class TokenInterceptor implements Interceptor {
public instance;
constructor(instance: AxiosInstance) {
this.instance = instance;
}
protected clear = async () => {
localStorage.clear();
setTimeout(() => {
window.location.replace("/auth/login");
}, 50);
};
private refreshTokenApi = async () => {
try {
const { data } = await axios.get("https://dummyjson.com/auth/refresh");
localStorage.setItem("accessToken", data?.accessToken);
return data;
} catch (error) {
this.clear();
return error;
}
};
private getToken = async () => {
const token = {
accessToken: (localStorage.getItem("accessToken") as string) || "",
};
return token;
};
intercept(request: Req, response: Res) {
request.use(
async (config) => {
const token = await this.getToken();
if (token) config.headers.Authorization = `Bearer ${token.accessToken}`;
return config;
},
(error) => Promise.reject(error)
);
response.use(
(res) => res,
async (error: AxiosError) => {
try {
const status = error.response?.status;
const originalRequest = error.config as any;
if (status === 401 && !originalRequest?._retry) {
originalRequest._retry = true;
const token = await this.getToken();
if (!token.accessToken) return;
/*---refreshTokenApi---*/
const data = await this.refreshTokenApi();
if (data?.accessToken) {
originalRequest.headers["Authorization"] = `Bearer ${data?.accessToken}`;
return axios(originalRequest);
}
}
return Promise.reject(error);
} catch (error) {
return Promise.reject(error);
}
}
);
return this.instance;
}
}📖 API Reference
InterceptorBuilder
The main class for building the interceptor chain.
| Method | Description |
| :-------- | :--------------------------------------------------- |
| use() | Adds an interceptor to the chain. |
| build() | Builds the final instance with all the interceptors. |
Interceptor
The interface that all interceptors must implement.
| Property | Description |
| :------------ | :-------------------------------------------------- |
| instance | The HTTP client instance. |
| intercept() | The method where you define your interceptor logic. |
Types
The package also provides the following types:
Req: The request interceptor manager.Res: The response interceptor manager.Instance: The HTTP client instance.
🙌 Contributing
Contributions are welcome! Please feel free to submit a pull request or open an issue.
- Fork the repository.
- Create a new branch (
git checkout -b feature/your-feature). - Make your changes.
- Commit your changes (
git commit -m 'Add some feature'). - Push to the branch (
git push origin feature/your-feature). - Open a pull request.
📄 License
This package is open-source and available under the ISC License.
