npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@j45/custom-axios

v2.0.0

Published

Shared axios factory for MFE domains

Downloads

215

Readme

@j45/custom-axios

Shared axios factory for MFE domains. Handles session expiry, relogin modal, concurrent 401 queuing, WAF detection, and token attachment.


Install

yarn install @j45/custom-axios

Usage

Minimal

// src/services/custom-axios.ts
import { createJ45Axios } from "@j45/custom-axios";

const customAxios = createJ45Axios({
  baseURL: config.baseUrl ?? "",
});

export { customAxios };
export default customAxios;

With all options

import { createJ45Axios } from "@j45/custom-axios";

const customAxios = createJ45Axios({
  baseURL: config.baseUrl ?? "",
  enableWafDetection: true,
  refreshOnPaths: [
    "workflow/company",
    "transaction/statuses/counter",
  ],
});

export { customAxios };
export default customAxios;

fallbackOnUnauthorized (per-request)

For services used by usePagination or callers without a custom onError handler. Returns the fallback immediately with status: 200 on 401 so no error modal appears behind the relogin modal.

const response = await customAxios.get("/transaction/external-transfer", {
  params,
  fallbackOnUnauthorized: {
    data: [],
    pageCount: "0",
    totalPages: "0",
    count: "0",
    message: "",
  },
});
return response.data;

featureFlags (auto-persist into sessionStorage)

Pass featureFlags to have the library persist flag values from successful responses into sessionStorage. For each name, a response whose URL contains that name writes sessionStorage["<name>-flag"] = String(data?.data?.value ?? data?.value). The keys are cleared again on a dashboard/root 401.

import { createJ45Axios } from "@j45/custom-axios";

const customAxios = createJ45Axios({
  baseURL: config.baseUrl ?? "",
  featureFlags: ["new-qlola"],
});

// e.g. GET /system/key/new-qlola → sessionStorage["new-qlola-flag"]
const isNewQlola = sessionStorage.getItem("new-qlola-flag") === "true";

export default customAxios;

Adding domain-specific interceptors

createJ45Axios returns a standard axios instance — stack extra interceptors on top:

import { createJ45Axios } from "@j45/custom-axios";
import { v4 as uuidv4 } from "uuid";

const customAxios = createJ45Axios({
  baseURL: config.baseUrl ?? "",
});

customAxios.interceptors.request.use((config) => {
  if (config.url?.includes("login")) {
    config.headers["grpc-metadata-process_id"] = uuidv4();
  }
  return config;
});

export default customAxios;

Configuration

| Option | Type | Default | Description | |---|---|---|---| | baseURL | string | required | API base URL | | refreshOnPaths | string[] | [] | URL substrings where shouldRefresh: true is sent to the shell's showDialog | | featureFlags | string[] | [] | Flag names to auto-persist from responses into sessionStorage["<name>-flag"] (cleared on dashboard/root 401) | | enableWafDetection | boolean | false | Convert WAF HTML error pages to structured JSON errors | | getToken | () => string \| null | localStorage["access-token"] | Override token source |


Architecture

@j45/custom-axios/
├── config.ts                       ← default baseUrl resolved per environment
└── src/
    ├── index.ts                    ← public API
    ├── types.ts                    ← J45AxiosConfig + axios augmentation
    ├── create-axios.ts             ← factory
    ├── queue.ts                    ← per-instance queue state
    ├── interceptors/
    │   ├── request-interceptors.ts ← Bearer token attachment
    │   ├── waf-interceptors.ts     ← WAF HTML → JSON conversion
    │   └── auth-interceptors.ts    ← 401 / 499 / Another Login handling
    └── utils/
        ├── url-matchers.ts         ← pathname helpers
        └── env.ts                  ← hostname → environment baseUrl mapping

Interceptor order

Outgoing:  request-interceptors → server
Incoming:  server → waf-interceptors → auth-interceptors → caller

Per-instance isolation — each createJ45Axios() call produces an independent axios instance with its own queue. A 401 in one MFE never interferes with another.

Response branches

| Condition | Action | |---|---| | 401 on dashboard or root | Clear storage → redirect to /main-page | | 401 on login URL | Pass through | | 401 on retried request | Drain queue → reject | | 401/499 + fallbackOnUnauthorized | Return fallback, open modal in background | | 401/499 + modal already open | Queue caller, wait for token | | 401/499 first occurrence | Open modal, suspend caller | | Another Login Detected | Open modal, suspend caller | | No response | Reject with 504 |