Plantae
"Apply the same middlewares to the all http clients"
Plantae is a Request & Response API based middleware generator compatible with the various http clients.
Currently, Plantae supports the following clients:
This is especially useful for the providers of enterprise tools that have to support multiple http clients at the same time.
It's so tiny and has no dependencies!
Installation
npm install plantae
yarn add plantae
Usage
Fetch
import { createFetch } from "plantae";
import myPlugin from "../myPlugin";
export const myFetch = createFetch({
client: fetch,
plugins: [myPlugin()],
});
Ky
import { createKyHooks } from "plantae/ky";
import myPlugin from "../myPlugin";
import ky from "ky";
const hooks = createKyHooks({
client: ky,
plugins: [myPlugin()],
});
export const myKy = ky.extend({
hooks,
});
ky("https://example.com", {
hooks,
});
Axios
import { createAxiosInterceptors } from "plantae/axios";
import myPlugin from "../myPlugin";
import axios from "axios";
const myAxios = axios.create();
const { request, response } = createAxiosInterceptors({
client: myAxios,
plugins: [myPlugin()],
});
myAxios.interceptors.request.use(request.onFulfilled, request.onRejected);
myAxios.interceptors.response.use(response.onFulfilled, request.onRejected);
export { myAxios };
Plugins
Official Plugins
Plugin Example (Authorization)
import type { Plugin } from "plantae";
export default function AuthPlugin(): Plugin<{
token: string;
}> {
const context = {
token: "token",
};
return {
name: "plugin-auth",
context,
hooks: {
beforeRequest: (req) => {
req.headers.set("Authorization", context.token);
return req;
},
afterResponse: async (res, req, retry) => {
if (res.status === 401) {
const refresh = new Request("https://example.com/refresh-token");
const token = await retry(refresh).then((res) => res.text());
context.token = token;
req.headers.set("Authorization", `token ${token}`);
return retry(req);
}
return res;
},
},
};
}
Publish a Plugin
Convention
- Plugins should have a clear name with
plantae-plugin-
prefix. - Include
plantae-plugin
keywords in package.json.
TODO
- Make 100% compatibility with Request & Response API.
Currently implemented:
export type AdapterRequest = Pick<
Request,
"body" | "headers" | "method" | "url" | "signal"
>;
export type AdapterResponse = Pick<
Response,
"body" | "headers" | "ok" | "status" | "statusText" | "url"
>;```