@zairakai/js-http-client 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,139 @@
1
+ import {
2
+ createAuthInterceptor,
3
+ createCSRFInterceptor,
4
+ createErrorLoggerInterceptor,
5
+ createRetryInterceptor,
6
+ createTimeoutInterceptor,
7
+ createTrackingInterceptors
8
+ } from "./chunk-SSH6WKEL.js";
9
+
10
+ // src/client.ts
11
+ import axios from "axios";
12
+
13
+ // src/request-tracker.ts
14
+ var createRequestTracker = () => {
15
+ let nbrInternal = 0;
16
+ return {
17
+ get count() {
18
+ return nbrInternal;
19
+ },
20
+ set count(val) {
21
+ nbrInternal = Math.max(0, val);
22
+ },
23
+ get isActive() {
24
+ return 0 < nbrInternal;
25
+ },
26
+ increment() {
27
+ nbrInternal++;
28
+ },
29
+ decrement() {
30
+ nbrInternal = Math.max(0, nbrInternal - 1);
31
+ },
32
+ reset() {
33
+ nbrInternal = 0;
34
+ }
35
+ };
36
+ };
37
+ var globalRequestTracker = createRequestTracker();
38
+
39
+ // src/client.ts
40
+ var DEFAULT_CONFIG = {
41
+ baseURL: "",
42
+ timeout: 1e4,
43
+ withCredentials: false,
44
+ headers: {
45
+ "Content-Type": "application/json",
46
+ Accept: "application/json"
47
+ }
48
+ };
49
+ var createHttpClient = (options = {}) => {
50
+ const config = { ...DEFAULT_CONFIG, ...options };
51
+ const client = axios.create({
52
+ baseURL: config.baseURL,
53
+ timeout: config.timeout,
54
+ withCredentials: config.withCredentials,
55
+ headers: { ...DEFAULT_CONFIG.headers, ...config.headers }
56
+ });
57
+ const tracker = false !== config.trackRequests ? createRequestTracker() : null;
58
+ if (tracker) {
59
+ const trackingInterceptors = createTrackingInterceptors(tracker);
60
+ client.interceptors.request.use(trackingInterceptors.request, trackingInterceptors.requestError);
61
+ client.interceptors.response.use(trackingInterceptors.response, trackingInterceptors.responseError);
62
+ }
63
+ if (config.csrfToken) {
64
+ client.interceptors.request.use(createCSRFInterceptor(config.csrfToken));
65
+ }
66
+ if (config.authToken) {
67
+ client.interceptors.request.use(createAuthInterceptor(config.authToken, config.authType));
68
+ }
69
+ if (config.timeout !== DEFAULT_CONFIG.timeout) {
70
+ client.interceptors.request.use(createTimeoutInterceptor(config.timeout));
71
+ }
72
+ if (false !== config.enableErrorLogging) {
73
+ client.interceptors.response.use((response) => response, createErrorLoggerInterceptor(config.logger));
74
+ }
75
+ if (config.retries && 0 < config.retries) {
76
+ client.interceptors.request.use((reqConfig) => {
77
+ ;
78
+ reqConfig._axios = client;
79
+ return reqConfig;
80
+ });
81
+ client.interceptors.response.use(
82
+ (response) => response,
83
+ createRetryInterceptor(config.retries, config.retryDelay, config.shouldRetry)
84
+ );
85
+ }
86
+ if (false !== config.laravel) {
87
+ client.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
88
+ }
89
+ return {
90
+ client,
91
+ tracker,
92
+ // Convenience methods
93
+ get: (url, config2) => client.get(url, config2),
94
+ post: (url, data, config2) => client.post(url, data, config2),
95
+ put: (url, data, config2) => client.put(url, data, config2),
96
+ patch: (url, data, config2) => client.patch(url, data, config2),
97
+ delete: (url, config2) => client.delete(url, config2),
98
+ // Request status
99
+ get isLoading() {
100
+ return tracker ? tracker.isActive : false;
101
+ },
102
+ get requestCount() {
103
+ return tracker ? tracker.count : 0;
104
+ }
105
+ };
106
+ };
107
+ var createLaravelClient = (options = {}) => {
108
+ return createHttpClient({
109
+ withCredentials: true,
110
+ headers: {
111
+ "X-Requested-With": "XMLHttpRequest"
112
+ },
113
+ ...options
114
+ });
115
+ };
116
+ var createApiClient = (options = {}) => {
117
+ return createHttpClient({
118
+ withCredentials: false,
119
+ laravel: false,
120
+ ...options
121
+ });
122
+ };
123
+
124
+ // src/index.ts
125
+ import { default as default2 } from "axios";
126
+ export {
127
+ default2 as axios,
128
+ createApiClient,
129
+ createAuthInterceptor,
130
+ createCSRFInterceptor,
131
+ createErrorLoggerInterceptor,
132
+ createHttpClient,
133
+ createLaravelClient,
134
+ createRequestTracker,
135
+ createRetryInterceptor,
136
+ createTimeoutInterceptor,
137
+ createTrackingInterceptors,
138
+ globalRequestTracker
139
+ };
@@ -0,0 +1,93 @@
1
+ import { AxiosError, InternalAxiosRequestConfig, AxiosResponse } from 'axios';
2
+
3
+ /**
4
+ * Request tracking utility for monitoring ongoing HTTP requests
5
+ */
6
+ /**
7
+ * Interface for request tracker instance
8
+ */
9
+ interface RequestTracker {
10
+ /** Current number of active requests */
11
+ readonly count: number;
12
+ /** Whether there are any active requests */
13
+ readonly isActive: boolean;
14
+ /** Increment the request counter */
15
+ increment(): void;
16
+ /** Decrement the request counter */
17
+ decrement(): void;
18
+ /** Reset the counter to zero */
19
+ reset(): void;
20
+ }
21
+ /**
22
+ * Creates a request tracker instance
23
+ * @returns Request tracker with counter and methods
24
+ */
25
+ declare const createRequestTracker: () => RequestTracker;
26
+ declare const globalRequestTracker: RequestTracker;
27
+
28
+ /**
29
+ * Common interceptors for HTTP clients
30
+ */
31
+
32
+ /**
33
+ * Token source type - either a string or a function that returns a string
34
+ */
35
+ type TokenSource = string | (() => string);
36
+ /**
37
+ * Logger function type
38
+ */
39
+ type Logger = (message: string, data?: unknown) => void;
40
+ /**
41
+ * Retry condition function type
42
+ */
43
+ type ShouldRetryFunction = (error: AxiosError) => boolean;
44
+ /**
45
+ * Tracking interceptors interface
46
+ */
47
+ interface TrackingInterceptors {
48
+ request: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
49
+ requestError: (error: Error) => Promise<never>;
50
+ response: (response: AxiosResponse) => AxiosResponse;
51
+ responseError: (error: Error) => Promise<never>;
52
+ }
53
+ /**
54
+ * Creates request tracking interceptors
55
+ * @param tracker - Request tracker instance
56
+ * @returns Request and response interceptors
57
+ */
58
+ declare const createTrackingInterceptors: (tracker: RequestTracker) => TrackingInterceptors;
59
+ /**
60
+ * Creates Laravel CSRF token interceptor
61
+ * @param tokenSource - CSRF token or function that returns token
62
+ * @returns Request interceptor
63
+ */
64
+ declare const createCSRFInterceptor: (tokenSource: TokenSource) => (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
65
+ /**
66
+ * Creates authentication interceptor
67
+ * @param tokenSource - Auth token or function that returns token
68
+ * @param type - Token type ('Bearer', 'Token', etc.)
69
+ * @returns Request interceptor
70
+ */
71
+ declare const createAuthInterceptor: (tokenSource: TokenSource, type?: string) => (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
72
+ /**
73
+ * Creates error logging interceptor
74
+ * @param logger - Logging function
75
+ * @returns Response error interceptor
76
+ */
77
+ declare const createErrorLoggerInterceptor: (logger?: Logger) => (error: AxiosError) => Promise<never>;
78
+ /**
79
+ * Creates timeout interceptor
80
+ * @param timeout - Default timeout in milliseconds
81
+ * @returns Request interceptor
82
+ */
83
+ declare const createTimeoutInterceptor: (timeout: number) => (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
84
+ /**
85
+ * Creates retry interceptor
86
+ * @param retries - Number of retries
87
+ * @param delay - Delay between retries in milliseconds
88
+ * @param shouldRetry - Function to determine if request should be retried
89
+ * @returns Response error interceptor
90
+ */
91
+ declare const createRetryInterceptor: (retries?: number, delay?: number, shouldRetry?: ShouldRetryFunction) => (error: AxiosError) => Promise<any>;
92
+
93
+ export { type Logger as L, type RequestTracker as R, type ShouldRetryFunction as S, type TokenSource as T, type TrackingInterceptors as a, createCSRFInterceptor as b, createAuthInterceptor as c, createErrorLoggerInterceptor as d, createRequestTracker as e, createRetryInterceptor as f, createTimeoutInterceptor as g, createTrackingInterceptors as h, globalRequestTracker as i };
@@ -0,0 +1,93 @@
1
+ import { AxiosError, InternalAxiosRequestConfig, AxiosResponse } from 'axios';
2
+
3
+ /**
4
+ * Request tracking utility for monitoring ongoing HTTP requests
5
+ */
6
+ /**
7
+ * Interface for request tracker instance
8
+ */
9
+ interface RequestTracker {
10
+ /** Current number of active requests */
11
+ readonly count: number;
12
+ /** Whether there are any active requests */
13
+ readonly isActive: boolean;
14
+ /** Increment the request counter */
15
+ increment(): void;
16
+ /** Decrement the request counter */
17
+ decrement(): void;
18
+ /** Reset the counter to zero */
19
+ reset(): void;
20
+ }
21
+ /**
22
+ * Creates a request tracker instance
23
+ * @returns Request tracker with counter and methods
24
+ */
25
+ declare const createRequestTracker: () => RequestTracker;
26
+ declare const globalRequestTracker: RequestTracker;
27
+
28
+ /**
29
+ * Common interceptors for HTTP clients
30
+ */
31
+
32
+ /**
33
+ * Token source type - either a string or a function that returns a string
34
+ */
35
+ type TokenSource = string | (() => string);
36
+ /**
37
+ * Logger function type
38
+ */
39
+ type Logger = (message: string, data?: unknown) => void;
40
+ /**
41
+ * Retry condition function type
42
+ */
43
+ type ShouldRetryFunction = (error: AxiosError) => boolean;
44
+ /**
45
+ * Tracking interceptors interface
46
+ */
47
+ interface TrackingInterceptors {
48
+ request: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
49
+ requestError: (error: Error) => Promise<never>;
50
+ response: (response: AxiosResponse) => AxiosResponse;
51
+ responseError: (error: Error) => Promise<never>;
52
+ }
53
+ /**
54
+ * Creates request tracking interceptors
55
+ * @param tracker - Request tracker instance
56
+ * @returns Request and response interceptors
57
+ */
58
+ declare const createTrackingInterceptors: (tracker: RequestTracker) => TrackingInterceptors;
59
+ /**
60
+ * Creates Laravel CSRF token interceptor
61
+ * @param tokenSource - CSRF token or function that returns token
62
+ * @returns Request interceptor
63
+ */
64
+ declare const createCSRFInterceptor: (tokenSource: TokenSource) => (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
65
+ /**
66
+ * Creates authentication interceptor
67
+ * @param tokenSource - Auth token or function that returns token
68
+ * @param type - Token type ('Bearer', 'Token', etc.)
69
+ * @returns Request interceptor
70
+ */
71
+ declare const createAuthInterceptor: (tokenSource: TokenSource, type?: string) => (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
72
+ /**
73
+ * Creates error logging interceptor
74
+ * @param logger - Logging function
75
+ * @returns Response error interceptor
76
+ */
77
+ declare const createErrorLoggerInterceptor: (logger?: Logger) => (error: AxiosError) => Promise<never>;
78
+ /**
79
+ * Creates timeout interceptor
80
+ * @param timeout - Default timeout in milliseconds
81
+ * @returns Request interceptor
82
+ */
83
+ declare const createTimeoutInterceptor: (timeout: number) => (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
84
+ /**
85
+ * Creates retry interceptor
86
+ * @param retries - Number of retries
87
+ * @param delay - Delay between retries in milliseconds
88
+ * @param shouldRetry - Function to determine if request should be retried
89
+ * @returns Response error interceptor
90
+ */
91
+ declare const createRetryInterceptor: (retries?: number, delay?: number, shouldRetry?: ShouldRetryFunction) => (error: AxiosError) => Promise<any>;
92
+
93
+ export { type Logger as L, type RequestTracker as R, type ShouldRetryFunction as S, type TokenSource as T, type TrackingInterceptors as a, createCSRFInterceptor as b, createAuthInterceptor as c, createErrorLoggerInterceptor as d, createRequestTracker as e, createRetryInterceptor as f, createTimeoutInterceptor as g, createTrackingInterceptors as h, globalRequestTracker as i };
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/interceptors.ts
31
+ var interceptors_exports = {};
32
+ __export(interceptors_exports, {
33
+ createAuthInterceptor: () => createAuthInterceptor,
34
+ createCSRFInterceptor: () => createCSRFInterceptor,
35
+ createErrorLoggerInterceptor: () => createErrorLoggerInterceptor,
36
+ createRetryInterceptor: () => createRetryInterceptor,
37
+ createTimeoutInterceptor: () => createTimeoutInterceptor,
38
+ createTrackingInterceptors: () => createTrackingInterceptors
39
+ });
40
+ module.exports = __toCommonJS(interceptors_exports);
41
+ var import_axios = __toESM(require("axios"), 1);
42
+ var createTrackingInterceptors = (tracker) => ({
43
+ request: (config) => {
44
+ tracker.increment();
45
+ return config;
46
+ },
47
+ requestError: (error) => {
48
+ return Promise.reject(error);
49
+ },
50
+ response: (response) => {
51
+ tracker.decrement();
52
+ return response;
53
+ },
54
+ responseError: (error) => {
55
+ tracker.decrement();
56
+ return Promise.reject(error);
57
+ }
58
+ });
59
+ var createCSRFInterceptor = (tokenSource) => (config) => {
60
+ const token = "function" === typeof tokenSource ? tokenSource() : tokenSource;
61
+ if (token) {
62
+ config.headers = config.headers ?? {};
63
+ config.headers["X-CSRF-TOKEN"] = token;
64
+ }
65
+ return config;
66
+ };
67
+ var createAuthInterceptor = (tokenSource, type = "Bearer") => (config) => {
68
+ const token = "function" === typeof tokenSource ? tokenSource() : tokenSource;
69
+ if (token) {
70
+ config.headers = config.headers ?? {};
71
+ config.headers["Authorization"] = `${type} ${token}`;
72
+ }
73
+ return config;
74
+ };
75
+ var createErrorLoggerInterceptor = (logger = console.error) => (error) => {
76
+ const logData = {
77
+ message: error.message,
78
+ status: error.response?.status,
79
+ statusText: error.response?.statusText,
80
+ url: error.config?.url,
81
+ method: error.config?.method?.toUpperCase()
82
+ };
83
+ logger("HTTP Error:", logData);
84
+ return Promise.reject(error);
85
+ };
86
+ var createTimeoutInterceptor = (timeout) => (config) => {
87
+ config.timeout = timeout;
88
+ return config;
89
+ };
90
+ var createRetryInterceptor = (retries = 3, delay = 1e3, shouldRetry = () => true) => {
91
+ return async (error) => {
92
+ const config = error.config;
93
+ if (!config || (config.__retryCount ?? 0) >= retries) {
94
+ return Promise.reject(error);
95
+ }
96
+ if (!shouldRetry(error)) {
97
+ return Promise.reject(error);
98
+ }
99
+ config.__retryCount = (config.__retryCount ?? 0) + 1;
100
+ await new Promise((resolve) => setTimeout(resolve, delay));
101
+ const axiosInstance = config._axios ?? import_axios.default;
102
+ return axiosInstance.request(config);
103
+ };
104
+ };
105
+ // Annotate the CommonJS export names for ESM import in node:
106
+ 0 && (module.exports = {
107
+ createAuthInterceptor,
108
+ createCSRFInterceptor,
109
+ createErrorLoggerInterceptor,
110
+ createRetryInterceptor,
111
+ createTimeoutInterceptor,
112
+ createTrackingInterceptors
113
+ });
@@ -0,0 +1,2 @@
1
+ import 'axios';
2
+ export { L as Logger, S as ShouldRetryFunction, T as TokenSource, a as TrackingInterceptors, c as createAuthInterceptor, b as createCSRFInterceptor, d as createErrorLoggerInterceptor, f as createRetryInterceptor, g as createTimeoutInterceptor, h as createTrackingInterceptors } from './interceptors-Pv-t9Hbf.cjs';
@@ -0,0 +1,2 @@
1
+ import 'axios';
2
+ export { L as Logger, S as ShouldRetryFunction, T as TokenSource, a as TrackingInterceptors, c as createAuthInterceptor, b as createCSRFInterceptor, d as createErrorLoggerInterceptor, f as createRetryInterceptor, g as createTimeoutInterceptor, h as createTrackingInterceptors } from './interceptors-Pv-t9Hbf.js';
@@ -0,0 +1,16 @@
1
+ import {
2
+ createAuthInterceptor,
3
+ createCSRFInterceptor,
4
+ createErrorLoggerInterceptor,
5
+ createRetryInterceptor,
6
+ createTimeoutInterceptor,
7
+ createTrackingInterceptors
8
+ } from "./chunk-SSH6WKEL.js";
9
+ export {
10
+ createAuthInterceptor,
11
+ createCSRFInterceptor,
12
+ createErrorLoggerInterceptor,
13
+ createRetryInterceptor,
14
+ createTimeoutInterceptor,
15
+ createTrackingInterceptors
16
+ };
package/package.json ADDED
@@ -0,0 +1,107 @@
1
+ {
2
+ "name": "@zairakai/js-http-client",
3
+ "version": "1.0.0",
4
+ "description": "Configurable HTTP client built on axios with request tracking, Laravel CSRF support, and interceptor management",
5
+ "keywords": [
6
+ "http",
7
+ "client",
8
+ "axios",
9
+ "laravel",
10
+ "csrf",
11
+ "interceptors",
12
+ "api"
13
+ ],
14
+ "homepage": "https://gitlab.com/zairakai/npm-packages/js-http-client",
15
+ "bugs": {
16
+ "url": "https://gitlab.com/zairakai/npm-packages/js-http-client/-/issues",
17
+ "email": "contact-project+zairakai-npm-packages-js-http-client-80189938-issue-@incoming.gitlab.com"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://gitlab.com/zairakai/npm-packages/js-http-client.git"
22
+ },
23
+ "funding": [
24
+ {
25
+ "type": "patreon",
26
+ "url": "https://www.patreon.com/c/zairakai"
27
+ },
28
+ {
29
+ "type": "twitch",
30
+ "url": "https://www.twitch.tv/zairakai"
31
+ }
32
+ ],
33
+ "license": "MIT",
34
+ "author": "Stanislas Poisson <stanislas.p@the-white-rabbits.fr> (https://the-white-rabbits.fr)",
35
+ "contributors": [
36
+ {
37
+ "name": "Stanislas Poisson",
38
+ "url": "https://gitlab.com/zairakai",
39
+ "role": "Maintainer"
40
+ }
41
+ ],
42
+ "type": "module",
43
+ "exports": {
44
+ ".": {
45
+ "types": "./dist/index.d.ts",
46
+ "import": "./dist/index.js",
47
+ "require": "./dist/index.cjs"
48
+ },
49
+ "./interceptors": {
50
+ "types": "./dist/interceptors.d.ts",
51
+ "import": "./dist/interceptors.js",
52
+ "require": "./dist/interceptors.cjs"
53
+ }
54
+ },
55
+ "main": "./dist/index.cjs",
56
+ "types": "./dist/index.d.ts",
57
+ "files": [
58
+ "dist",
59
+ "src",
60
+ "LICENSE",
61
+ "README.md"
62
+ ],
63
+ "scripts": {
64
+ "build": "bash node_modules/@zairakai/js-dev-tools/scripts/build.sh",
65
+ "eslint": "bash node_modules/@zairakai/js-dev-tools/scripts/eslint.sh",
66
+ "eslint:fix": "bash node_modules/@zairakai/js-dev-tools/scripts/eslint-fix.sh",
67
+ "markdownlint": "bash node_modules/@zairakai/js-dev-tools/scripts/markdownlint.sh",
68
+ "markdownlint:fix": "bash node_modules/@zairakai/js-dev-tools/scripts/markdownlint-fix.sh",
69
+ "normalize": "make package-normalize",
70
+ "package:validate": "make package-validate",
71
+ "postinstall": "bash node_modules/@zairakai/js-dev-tools/scripts/setup-project.sh --silent || true",
72
+ "prettier": "bash node_modules/@zairakai/js-dev-tools/scripts/prettier.sh",
73
+ "prettier:fix": "bash node_modules/@zairakai/js-dev-tools/scripts/prettier-fix.sh",
74
+ "setup": "bash node_modules/@zairakai/js-dev-tools/scripts/setup-project.sh",
75
+ "test": "make test-all",
76
+ "typecheck": "tsc --noEmit",
77
+ "validate": "make quality"
78
+ },
79
+ "dependencies": {
80
+ "axios": "^1.0.0"
81
+ },
82
+ "devDependencies": {
83
+ "@types/node": "^25.0.0",
84
+ "@vitest/coverage-v8": "^4.0.0",
85
+ "@zairakai/js-dev-tools": "^1.0.0",
86
+ "knip": "^5.86.0",
87
+ "sort-package-json": "^3.6.1",
88
+ "tsup": "^8.0.0",
89
+ "typedoc": "^0.28.0",
90
+ "typescript": "^5.7.2",
91
+ "vitest": "^4.0.0"
92
+ },
93
+ "peerDependencies": {
94
+ "axios": "^1.0.0"
95
+ },
96
+ "peerDependenciesMeta": {
97
+ "axios": {
98
+ "optional": false
99
+ }
100
+ },
101
+ "engines": {
102
+ "node": ">=22.0.0"
103
+ },
104
+ "publishConfig": {
105
+ "access": "public"
106
+ }
107
+ }