@dashadmin/dash-axios-hook 1.3.73 → 1.3.74-srcfree.1

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.
@@ -0,0 +1,4 @@
1
+ import { AxiosError } from 'axios';
2
+ import { IDashAutoAdminBackendError, IDashAutoAdminDefaultBackendStructure } from '../interfaces/IDashAutoAdminBackendError';
3
+ declare const processAxiosError: (error: AxiosError<IDashAutoAdminDefaultBackendStructure>, resource?: string, method?: string) => IDashAutoAdminBackendError;
4
+ export default processAxiosError;
@@ -0,0 +1,6 @@
1
+ import { AxiosRequestConfig } from 'axios';
2
+ export declare const initAxios: (options: Partial<AxiosRequestConfig<any>>, CSRFAuth?: boolean) => import("axios").AxiosInstance;
3
+ declare const useAxios: (options?: Partial<AxiosRequestConfig<any>>) => import("axios").AxiosInstance;
4
+ export declare const createAxiosInstance: (options?: Partial<AxiosRequestConfig<any>>) => import("axios").AxiosInstance;
5
+ export default useAxios;
6
+ export { useAxios };
@@ -0,0 +1,14 @@
1
+ export interface IUseAxiosGetWithStore {
2
+ method?: string;
3
+ url: string;
4
+ payload?: any;
5
+ storeKey: string;
6
+ dataPath?: string;
7
+ }
8
+ declare const useAxiosGetWithStore: (options: IUseAxiosGetWithStore) => {
9
+ request: (ops: IUseAxiosGetWithStore) => Promise<void>;
10
+ results: any;
11
+ error: any;
12
+ loaded: boolean;
13
+ };
14
+ export default useAxiosGetWithStore;
@@ -1,4 +1,4 @@
1
1
  export { default as useAxios, createAxiosInstance } from "./hooks/useAxios";
2
2
  export { default as useAxiosGetWithStore } from "./hooks/useAxiosWithStore";
3
- export type { IDashAutoAdminBackendError,IDashAutoAdminDefaultBackendStructure } from "./interfaces/IDashAutoAdminBackendError";
3
+ export type { IDashAutoAdminBackendError, IDashAutoAdminDefaultBackendStructure } from "./interfaces/IDashAutoAdminBackendError";
4
4
  export { default as processAxiosError } from "./hooks/processAxiosErrorFunction";
@@ -0,0 +1,18 @@
1
+ import { AxiosError } from 'axios';
2
+ export interface IDashAutoAdminBackendError {
3
+ status: number;
4
+ body: Body;
5
+ resource: string;
6
+ originalError: AxiosError<IDashAutoAdminDefaultBackendStructure>;
7
+ message?: string;
8
+ }
9
+ export interface IDashAutoAdminDefaultBackendStructure {
10
+ message: string;
11
+ errors: {
12
+ [key: string]: string[];
13
+ };
14
+ }
15
+ interface Body {
16
+ [x: string]: any;
17
+ }
18
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dashadmin/dash-axios-hook",
3
- "version": "1.3.73",
3
+ "version": "1.3.74-srcfree.1",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "devDependencies": {
@@ -26,11 +26,11 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@mui/material": "^9.3.0",
29
- "@dashadmin/dash-constants": "1.3.73",
30
- "@dashadmin/dash-utils": "1.3.73"
29
+ "@dashadmin/dash-constants": "1.3.74-srcfree.1",
30
+ "@dashadmin/dash-utils": "1.3.74-srcfree.1"
31
31
  },
32
32
  "module": "dist/index.js",
33
- "types": "./src/index.tsx",
33
+ "types": "./dist/index.d.ts",
34
34
  "exports": {
35
35
  ".": "./dist/index.js",
36
36
  "./*": "./dist/*.js",
@@ -41,22 +41,25 @@
41
41
  "registry": "https://registry.npmjs.org"
42
42
  },
43
43
  "scripts": {
44
- "build": "tsup"
44
+ "build": "tsup && pnpm run build:types",
45
+ "build:types": "tsc -p tsconfig.json --declaration --emitDeclarationOnly --noEmit false --outDir dist --rootDir src --skipLibCheck || true"
45
46
  },
46
47
  "type": "module",
47
48
  "files": [
48
- "dist",
49
- "src"
49
+ "dist"
50
50
  ],
51
51
  "typesVersions": {
52
52
  "*": {
53
+ "dist/*": [
54
+ "dist/*"
55
+ ],
53
56
  "src/*": [
54
- "src/*",
55
- "src/*/index"
57
+ "dist/*",
58
+ "dist/*/index"
56
59
  ],
57
60
  "*": [
58
- "src/*",
59
- "src/*/index"
61
+ "dist/*",
62
+ "dist/*/index"
60
63
  ]
61
64
  }
62
65
  }
@@ -1,73 +0,0 @@
1
- import { AxiosError } from 'axios';
2
- import { IDashAutoAdminBackendError,IDashAutoAdminDefaultBackendStructure } from '../interfaces/IDashAutoAdminBackendError';
3
-
4
-
5
- const processAxiosError = (error:AxiosError<IDashAutoAdminDefaultBackendStructure>,resource?:string,method:string='update') => {
6
-
7
- if(!resource) resource = ""
8
- // Map method to Spanish action words
9
- const methodMap = {
10
- 'update': 'Actualizar',
11
- 'create': 'Crear',
12
- 'delete': 'Eliminar'
13
- };
14
-
15
- // Extract error details
16
- const errorMessage = error.response?.data?.message || error.message || 'Error al '+ (methodMap[method] || method) +' el recurso';
17
- // Get HTTP status or fallback to 500
18
- const status = error.response?.status || 500;
19
-
20
- // If validation errors exist, format them for React Admin
21
- let body = {
22
- errors: {}
23
- };
24
-
25
- if (error.response?.data?.errors) {
26
-
27
-
28
- // Format Laravel validation errors for React Admin
29
- const validationErrors = error.response.data.errors;
30
- Object.keys(validationErrors).forEach(field => {
31
- if (typeof validationErrors[field] === 'string') {
32
- body.errors[field] = validationErrors[field];
33
- } else if (Array.isArray(validationErrors[field])) {
34
- body.errors[field] = validationErrors[field].join(', ');
35
- } else if (typeof validationErrors[field] === 'object') {
36
- body.errors[field] = validationErrors[field];
37
- }
38
- });
39
-
40
- // Add global validation error if exists
41
- if (errorMessage) {
42
- body.errors["root"] = {
43
- serverError: errorMessage
44
- };
45
- }
46
- }
47
-
48
- // Create an enhanced error object that React Admin can understand
49
- const enhancedError = {
50
- message: errorMessage,
51
- status: status,
52
- body: body,
53
- resource: resource,
54
- originalError: error,
55
- name: 'Error'
56
- } as IDashAutoAdminBackendError;
57
-
58
- // Log for debugging
59
- console.error('Update error:', {
60
- resource,
61
- errorMessage,
62
- status,
63
- validationErrors: body.errors,
64
- originalError: error
65
- });
66
-
67
-
68
-
69
- return enhancedError;
70
-
71
- }
72
-
73
- export default processAxiosError;
@@ -1,260 +0,0 @@
1
- import axios, { Axios, AxiosError, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
2
-
3
- import {DASHAdminSystemConstants} from 'dash-constants'
4
-
5
- import { dashStorage } from 'dash-utils';
6
-
7
- import processAxiosError from './processAxiosErrorFunction';
8
- import { IDashAutoAdminDefaultBackendStructure } from '../interfaces/IDashAutoAdminBackendError';
9
-
10
- //import { getCookie } from '../utils/cookies';
11
-
12
- // Flag to prevent multiple simultaneous refresh requests
13
- let isRefreshing = false;
14
- // Queue of requests waiting for token refresh
15
- let failedQueue: Array<{
16
- resolve: (value?: unknown) => void;
17
- reject: (reason?: any) => void;
18
- }> = [];
19
-
20
- const processQueue = (error: any, token: string | null = null) => {
21
- failedQueue.forEach(prom => {
22
- if (error) {
23
- prom.reject(error);
24
- } else {
25
- prom.resolve(token);
26
- }
27
- });
28
- failedQueue = [];
29
- };
30
-
31
- // Function to refresh the token
32
- const refreshAccessToken = async (axiosInstance: any): Promise<string | null> => {
33
- const refreshToken = dashStorage.getItem('refreshToken');
34
-
35
- if (!refreshToken) {
36
- console.log('[Axios] No refresh token available');
37
- return null;
38
- }
39
-
40
- try {
41
- console.log('[Axios] Attempting to refresh access token...');
42
-
43
- // Create a new axios instance without interceptors to avoid infinite loops
44
- const refreshAxios = axios.create({
45
- baseURL: DASHAdminSystemConstants.system.ADMIN_API_URL,
46
- headers: {
47
- 'Content-Type': 'application/json',
48
- 'Accept': 'application/json',
49
- },
50
- });
51
-
52
- const response = await refreshAxios.post('/auth/refresh', {
53
- refresh_token: refreshToken,
54
- });
55
-
56
- if (response.status === 200 && response.data.token) {
57
- const newToken = response.data.token;
58
- const newRefreshToken = response.data.refresh_token;
59
-
60
- // Store new tokens
61
- dashStorage.setItem('token', newToken);
62
- if (newRefreshToken) {
63
- dashStorage.setItem('refreshToken', newRefreshToken);
64
- }
65
-
66
- console.log('[Axios] Token refresh successful');
67
- return newToken;
68
- }
69
-
70
- return null;
71
- } catch (error) {
72
- console.error('[Axios] Token refresh failed:', error);
73
- return null;
74
- }
75
- };
76
-
77
- // Function to handle logout
78
- const handleLogout = () => {
79
- console.log('[Axios] Logging out due to authentication failure');
80
- debugger;
81
- // Clear all auth data
82
- //dashStorage.removeItem('token');
83
- //dashStorage.removeItem('refreshToken');
84
- //dashStorage.removeItem('authenticated');
85
- //dashStorage.removeItem('user');
86
- //dashStorage.removeItem('roles');
87
- dashStorage.clear();
88
- localStorage.clear();
89
- // Dispatch logout event for the app to handle
90
- window.dispatchEvent(new CustomEvent('auth:logout', {
91
- detail: { reason: 'token_refresh_failed' }
92
- }));
93
- };
94
-
95
- // Capacitor's CapacitorHttp plugin, when enabled (capacitor.config.ts's
96
- // plugins.CapacitorHttp.enabled), patches the WebView's global
97
- // XMLHttpRequest to route through its native HTTP bridge. That patched XHR
98
- // doesn't reach the OPENED state synchronously the way axios's default 'xhr'
99
- // adapter assumes - it calls setRequestHeader() immediately after open(),
100
- // which throws "Failed to execute 'setRequestHeader' on 'XMLHttpRequest':
101
- // The object's state must be OPENED" under the patch. Confirmed on an
102
- // Android build (kitchntabs-app, Capacitor 7, CapacitorHttp enabled) -
103
- // broke every axios call, login included, not just one endpoint.
104
- //
105
- // axios's 'fetch' adapter (1.7+) sidesteps this: Capacitor's fetch patch is
106
- // documented as more spec-compliant than its XHR one. Only selected when
107
- // actually running as a native Capacitor app - `window.Capacitor` is
108
- // injected into the WebView's global scope at runtime by Capacitor itself,
109
- // so this needs no @capacitor/core import (this package is consumed by
110
- // plain web apps too, which don't have that dependency at all). Web/Electron
111
- // builds keep axios's own default adapter selection, unaffected.
112
- const isCapacitorNative =
113
- typeof window !== 'undefined' &&
114
- !!(window as any).Capacitor?.isNativePlatform?.();
115
-
116
- export const initAxios = (
117
- options: Partial<AxiosRequestConfig<any>>,
118
- CSRFAuth?: boolean,
119
- ) => {
120
- const browserLanguage = typeof navigator !== 'undefined' && navigator.language ? navigator.language.split('-')[0] : 'es';
121
- const _options = {
122
- headers: {
123
- 'Content-Type': 'application/json',
124
- //'Accept-Language': browserLanguage || 'es', // fallback to 'es' if not available
125
- 'Accept-Language':'es',
126
- Accept: 'application/json',
127
- },
128
- ...(isCapacitorNative && { adapter: 'fetch' as const }),
129
- ...options,
130
- };
131
-
132
- const instance = axios.create(_options);
133
-
134
- if (CSRFAuth) {
135
- instance.defaults.withCredentials = true;
136
- instance.get('/csrf-cookie').then((response) => {
137
- console.log('sanctum', response);
138
- });
139
- }
140
-
141
- instance.interceptors.request.use(function (config) {
142
- const token = dashStorage.getItem('token');
143
- //console.log("axios Hook", axios, token);
144
- if (token !== undefined && token !== 'undefined') {
145
- config.headers.Authorization = 'Bearer ' + token;
146
- }
147
-
148
- // Inject X-Tenant-Id header when tenant impersonation is active
149
- const activeTenantId = dashStorage.getItem('active_tenant_id');
150
- if (activeTenantId) {
151
- config.headers['X-Tenant-Id'] = activeTenantId;
152
- }
153
-
154
- return config;
155
- });
156
-
157
- instance.interceptors.response.use(
158
- (response) => {
159
- //console.log("Axios Success", response);
160
- return response;
161
- },
162
- async (error: AxiosError<IDashAutoAdminDefaultBackendStructure, any>) => {
163
- const originalRequest = error.config as InternalAxiosRequestConfig & { _retry?: boolean };
164
-
165
- // Handle 401 Unauthorized errors
166
- if (error.response?.status === 401 && !originalRequest._retry) {
167
- // Skip refresh for auth endpoints to prevent infinite loops
168
- const isAuthEndpoint = originalRequest.url?.includes('/login') ||
169
- originalRequest.url?.includes('/auth/refresh') ||
170
- originalRequest.url?.includes('/logout');
171
-
172
- if (isAuthEndpoint) {
173
- return Promise.reject(error);
174
- }
175
-
176
- if (isRefreshing) {
177
- // If already refreshing, queue this request
178
- return new Promise((resolve, reject) => {
179
- failedQueue.push({ resolve, reject });
180
- }).then(token => {
181
- if (token && originalRequest.headers) {
182
- originalRequest.headers.Authorization = `Bearer ${token}`;
183
- }
184
- return instance(originalRequest);
185
- }).catch(err => {
186
- return Promise.reject(err);
187
- });
188
- }
189
-
190
- originalRequest._retry = true;
191
- isRefreshing = true;
192
-
193
- try {
194
- const newToken = await refreshAccessToken(instance);
195
-
196
- if (newToken) {
197
- // Update the authorization header
198
- if (originalRequest.headers) {
199
- originalRequest.headers.Authorization = `Bearer ${newToken}`;
200
- }
201
-
202
- // Process queued requests
203
- processQueue(null, newToken);
204
-
205
- // Retry the original request
206
- return instance(originalRequest);
207
- } else {
208
- // Refresh failed - logout user
209
- processQueue(error, null);
210
- handleLogout();
211
- return Promise.reject(error);
212
- }
213
- } catch (refreshError) {
214
- processQueue(refreshError, null);
215
- handleLogout();
216
- return Promise.reject(refreshError);
217
- } finally {
218
- isRefreshing = false;
219
- }
220
- }
221
-
222
- // Dispatch global error event for non-401 errors
223
- window.dispatchEvent(
224
- new MessageEvent('DASHGlobalError', {
225
- data: processAxiosError(error, null, "list"),
226
- origin: "AxiosInterceptor"
227
- }),
228
- );
229
-
230
- return Promise.reject(error);
231
- },
232
- );
233
-
234
- return instance;
235
- };
236
-
237
- // Hook version (for use in React components)
238
- const useAxios = (options?: Partial<AxiosRequestConfig<any>>) => {
239
- const a = initAxios({
240
- baseURL: DASHAdminSystemConstants.system.ADMIN_API_URL,
241
- ...(options && {...options})
242
- });
243
- return a;
244
- };
245
-
246
- // Non-hook version (for use in classes and regular functions)
247
- export const createAxiosInstance = (options?: Partial<AxiosRequestConfig<any>>) => {
248
- console.log('Creating Axios instance with options:', options);
249
- console.log('Base URL:', DASHAdminSystemConstants.system.ADMIN_API_URL);
250
- return initAxios({
251
- baseURL: DASHAdminSystemConstants.system.ADMIN_API_URL,
252
- ...(options && {...options})
253
- });
254
- };
255
-
256
- // Default export is the hook
257
- export default useAxios;
258
-
259
- // Named export for non-hook usage
260
- export { useAxios };
@@ -1,66 +0,0 @@
1
-
2
- import { useEffect, useState } from 'react';
3
- //import queryString from 'query-string';
4
- import { useStore } from 'react-admin';
5
- import useAxios from './useAxios';
6
-
7
- export interface IUseAxiosGetWithStore {
8
- method?: string;
9
- url: string;
10
- payload?: any;
11
- storeKey: string;
12
- dataPath?: string;
13
- }
14
-
15
- const resolveObjectPath = (object, path, defaultValue) =>
16
- path.split('.').reduce((o, p) => (o ? o[p] : defaultValue), object);
17
-
18
- const useAxiosGetWithStore = (options: IUseAxiosGetWithStore) => {
19
- const {
20
- /*method = 'GET',
21
- url,
22
- payload = null,*/
23
- storeKey,
24
- dataPath = 'data',
25
- } = options;
26
- const axios = useAxios();
27
-
28
- const [error, setError] = useState(null);
29
- const [loaded, setLoaded] = useState(false);
30
-
31
- const [results, setResults] = useStore(storeKey, null);
32
-
33
- const request = async (ops: IUseAxiosGetWithStore) => {
34
- //const payload = queryString.stringify(ops.payload, { arrayFormat: 'bracket' });
35
-
36
- try {
37
- //console.log('useAxiosGetWithStore performing query:', ops);
38
- const response = await axios({
39
- method: ops.method,
40
- url: `${ops.url}${ops.payload ? '?' + ops.payload : ''}`,
41
- });
42
-
43
- if (response.status >= 200 || response.status < 300) {
44
- setResults(resolveObjectPath(response, dataPath, null));
45
- }
46
- } catch (e:any) {
47
- setError(e);
48
- } finally {
49
- setLoaded(true);
50
- }
51
- };
52
-
53
- useEffect(() => {
54
- //console.log('useAxiosGetWithStore results:', results);
55
- if (!results) {
56
- //console.log('Therefore, performing request');
57
- request(options);
58
- } else {
59
- //console.log('returning stored results');
60
- }
61
- }, []);
62
-
63
- return { request, results, error, loaded };
64
- };
65
-
66
- export default useAxiosGetWithStore;
@@ -1,21 +0,0 @@
1
- import { AxiosError } from 'axios';
2
-
3
- export interface IDashAutoAdminBackendError {
4
- status: number;
5
- body: Body;
6
- resource: string;
7
- originalError: AxiosError<IDashAutoAdminDefaultBackendStructure>;
8
- message?: string;
9
- }
10
-
11
- export interface IDashAutoAdminDefaultBackendStructure {
12
- message: string;
13
- errors: {
14
- [key: string]: string[];
15
- };
16
- }
17
-
18
- interface Body {
19
- [x:string]: any
20
- }
21
-