vue-api-kit 1.4.1 → 1.5.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/LICENSE +21 -0
- package/README.md +82 -3
- package/dist/core/types.d.ts +7 -4
- package/dist/index.js +141 -119
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 MelvishNiz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -237,6 +237,7 @@ async function handleSubmit() {
|
|
|
237
237
|
- ✅ **File Upload**: Support for multipart/form-data in mutations
|
|
238
238
|
- ✅ **Path Parameters**: Automatic path parameter replacement
|
|
239
239
|
- ✅ **Debouncing**: Built-in request debouncing
|
|
240
|
+
- ✅ **CSRF Protection**: Automatic CSRF token refresh on 403/419 errors
|
|
240
241
|
- ✅ **Global Error Handling**: Centralized error management
|
|
241
242
|
- ✅ **Request Interceptors**: Modify requests before sending
|
|
242
243
|
- ✅ **Fully Typed**: Complete type inference for params, data, and response
|
|
@@ -252,6 +253,9 @@ const api = createApiClient({
|
|
|
252
253
|
},
|
|
253
254
|
withCredentials: true,
|
|
254
255
|
|
|
256
|
+
// CSRF Token Protection
|
|
257
|
+
csrfRefreshEndpoint: '/sanctum/csrf-cookie', // Auto-refresh CSRF token on 403/419 errors
|
|
258
|
+
|
|
255
259
|
// Global handlers
|
|
256
260
|
onBeforeRequest: async (config) => {
|
|
257
261
|
// Modify request before sending
|
|
@@ -266,7 +270,7 @@ const api = createApiClient({
|
|
|
266
270
|
},
|
|
267
271
|
|
|
268
272
|
onFinishRequest: async () => {
|
|
269
|
-
// Called when request finishes
|
|
273
|
+
// Called when request finishes (success or error)
|
|
270
274
|
console.log('Request finished');
|
|
271
275
|
},
|
|
272
276
|
|
|
@@ -392,10 +396,10 @@ import { postQueries, postMutations } from './post-api';
|
|
|
392
396
|
// Approach 1: Merge queries and mutations separately
|
|
393
397
|
export const api = createApiClient({
|
|
394
398
|
baseURL: 'https://api.example.com',
|
|
395
|
-
|
|
399
|
+
|
|
396
400
|
// Merge all queries from different modules
|
|
397
401
|
queries: mergeQueries(userQueries, postQueries),
|
|
398
|
-
|
|
402
|
+
|
|
399
403
|
// Merge all mutations from different modules
|
|
400
404
|
mutations: mergeMutations(userMutations, postMutations)
|
|
401
405
|
});
|
|
@@ -448,6 +452,81 @@ async function handleUpload(file: File) {
|
|
|
448
452
|
}
|
|
449
453
|
```
|
|
450
454
|
|
|
455
|
+
## 🔒 CSRF Token Protection
|
|
456
|
+
|
|
457
|
+
The client includes built-in CSRF token protection, perfect for Laravel Sanctum or similar CSRF-based authentication systems.
|
|
458
|
+
|
|
459
|
+
### How it works
|
|
460
|
+
|
|
461
|
+
When you set `csrfRefreshEndpoint`, the client will:
|
|
462
|
+
1. Automatically detect CSRF errors (403 or 419 status codes)
|
|
463
|
+
2. Call the CSRF refresh endpoint to get a new token
|
|
464
|
+
3. Retry the original request with the fresh token
|
|
465
|
+
4. Prevent infinite loops and race conditions
|
|
466
|
+
|
|
467
|
+
### Configuration
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
const api = createApiClient({
|
|
471
|
+
baseURL: 'https://api.example.com',
|
|
472
|
+
withCredentials: true, // Required for CSRF cookies
|
|
473
|
+
csrfRefreshEndpoint: '/sanctum/csrf-cookie', // Laravel Sanctum endpoint
|
|
474
|
+
|
|
475
|
+
queries: { /* ... */ },
|
|
476
|
+
mutations: { /* ... */ }
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Use Case: Laravel Sanctum
|
|
481
|
+
|
|
482
|
+
```typescript
|
|
483
|
+
// api.ts
|
|
484
|
+
import { createApiClient } from 'vue-api-kit';
|
|
485
|
+
import { z } from 'zod';
|
|
486
|
+
|
|
487
|
+
export const api = createApiClient({
|
|
488
|
+
baseURL: 'https://api.example.com',
|
|
489
|
+
withCredentials: true, // Send cookies with requests
|
|
490
|
+
csrfRefreshEndpoint: '/sanctum/csrf-cookie', // Laravel's CSRF endpoint
|
|
491
|
+
|
|
492
|
+
mutations: {
|
|
493
|
+
login: {
|
|
494
|
+
method: 'POST',
|
|
495
|
+
path: '/login',
|
|
496
|
+
data: z.object({
|
|
497
|
+
email: z.string().email(),
|
|
498
|
+
password: z.string()
|
|
499
|
+
}),
|
|
500
|
+
response: z.object({
|
|
501
|
+
user: z.object({
|
|
502
|
+
id: z.number(),
|
|
503
|
+
name: z.string(),
|
|
504
|
+
email: z.string()
|
|
505
|
+
})
|
|
506
|
+
})
|
|
507
|
+
},
|
|
508
|
+
createPost: {
|
|
509
|
+
method: 'POST',
|
|
510
|
+
path: '/posts',
|
|
511
|
+
data: z.object({
|
|
512
|
+
title: z.string(),
|
|
513
|
+
content: z.string()
|
|
514
|
+
})
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### Benefits
|
|
521
|
+
|
|
522
|
+
- ✅ **Automatic Recovery**: No manual token refresh needed
|
|
523
|
+
- ✅ **Seamless UX**: Users don't experience authentication errors
|
|
524
|
+
- ✅ **Race Condition Safe**: Multiple simultaneous requests share the same refresh
|
|
525
|
+
- ✅ **Infinite Loop Prevention**: Won't retry the CSRF endpoint itself
|
|
526
|
+
- ✅ **Laravel Sanctum Compatible**: Works perfectly with Laravel's SPA authentication
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
|
|
451
530
|
## 📝 License
|
|
452
531
|
|
|
453
532
|
MIT
|
package/dist/core/types.d.ts
CHANGED
|
@@ -72,6 +72,8 @@ export interface ApiMutation<TData extends ZodType<any> | undefined = ZodType<an
|
|
|
72
72
|
* const options: ApiClientOptions = {
|
|
73
73
|
* baseURL: "https://api.example.com",
|
|
74
74
|
* headers: { Authorization: "Bearer token" },
|
|
75
|
+
* withCredentials: true,
|
|
76
|
+
* csrfRefreshEndpoint: "/auth/refresh-csrf",
|
|
75
77
|
* queries: { getUsers: { path: "/users" } },
|
|
76
78
|
* mutations: { createUser: { method: "POST", path: "/users" } },
|
|
77
79
|
* onErrorRequest: (error) => console.error(error.message)
|
|
@@ -81,11 +83,12 @@ export interface ApiClientOptions<Q extends Record<string, ApiQuery> = Record<st
|
|
|
81
83
|
baseURL: string;
|
|
82
84
|
headers?: Record<string, string>;
|
|
83
85
|
withCredentials?: boolean;
|
|
86
|
+
csrfRefreshEndpoint?: string;
|
|
84
87
|
queries?: Q;
|
|
85
88
|
mutations?: M;
|
|
86
|
-
onBeforeRequest?: (config: InternalAxiosRequestConfig<any>) => Promise<any> | any;
|
|
87
|
-
onStartRequest?: () => Promise<void
|
|
88
|
-
onFinishRequest?: () => Promise<void
|
|
89
|
+
onBeforeRequest?: (config: InternalAxiosRequestConfig<any>) => Promise<any> | void | any;
|
|
90
|
+
onStartRequest?: () => Promise<void> | void | any;
|
|
91
|
+
onFinishRequest?: () => Promise<void> | void | any;
|
|
89
92
|
onErrorRequest?: (error: {
|
|
90
93
|
message: string;
|
|
91
94
|
status?: number;
|
|
@@ -177,7 +180,7 @@ export interface MutationResult<TResult, TData = any, TParams = any> {
|
|
|
177
180
|
isLoading: Ref<boolean>;
|
|
178
181
|
isDone: Ref<boolean>;
|
|
179
182
|
uploadProgress: Ref<number>;
|
|
180
|
-
mutate: (
|
|
183
|
+
mutate: (rgs?: {
|
|
181
184
|
data?: TData;
|
|
182
185
|
params?: TParams;
|
|
183
186
|
}) => Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -1,196 +1,218 @@
|
|
|
1
|
-
import { ZodError as
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
4
|
-
import { AxiosError as
|
|
5
|
-
import { nextTick as
|
|
1
|
+
import { ZodError as L } from "zod";
|
|
2
|
+
import * as $ from "zod";
|
|
3
|
+
import k, { AxiosError as S } from "axios";
|
|
4
|
+
import { AxiosError as K } from "axios";
|
|
5
|
+
import { nextTick as x, ref as m, onMounted as F, watch as N, onBeforeUnmount as T } from "vue";
|
|
6
6
|
import { debounce as Z } from "lodash-es";
|
|
7
|
-
function
|
|
8
|
-
const
|
|
9
|
-
baseURL:
|
|
7
|
+
function z(s) {
|
|
8
|
+
const h = k.create({
|
|
9
|
+
baseURL: s.baseURL,
|
|
10
10
|
headers: {
|
|
11
11
|
"Content-Type": "application/json",
|
|
12
12
|
Accept: "application/json",
|
|
13
|
-
...
|
|
13
|
+
...s.headers
|
|
14
14
|
},
|
|
15
|
-
withCredentials:
|
|
15
|
+
withCredentials: s.withCredentials ?? !1
|
|
16
16
|
});
|
|
17
|
-
|
|
17
|
+
let b = !1, q = null;
|
|
18
|
+
s.onBeforeRequest && h.interceptors.request.use(
|
|
18
19
|
async (e) => {
|
|
19
20
|
try {
|
|
20
|
-
return await
|
|
21
|
-
} catch (
|
|
22
|
-
return Promise.reject(
|
|
21
|
+
return await s.onBeforeRequest(e) || e;
|
|
22
|
+
} catch (r) {
|
|
23
|
+
return Promise.reject(r);
|
|
23
24
|
}
|
|
24
25
|
},
|
|
25
26
|
(e) => Promise.reject(e)
|
|
26
|
-
),
|
|
27
|
+
), s.onStartRequest && h.interceptors.request.use(
|
|
27
28
|
async (e) => {
|
|
28
29
|
try {
|
|
29
|
-
return await
|
|
30
|
-
} catch (
|
|
31
|
-
return Promise.reject(
|
|
30
|
+
return await s.onStartRequest(), e;
|
|
31
|
+
} catch (r) {
|
|
32
|
+
return Promise.reject(r);
|
|
32
33
|
}
|
|
33
34
|
},
|
|
34
35
|
(e) => Promise.reject(e)
|
|
35
|
-
),
|
|
36
|
-
(e) => (
|
|
37
|
-
(e) => Promise.reject(e)
|
|
38
|
-
),
|
|
36
|
+
), s.onFinishRequest && h.interceptors.response.use(
|
|
37
|
+
(e) => (s.onFinishRequest(), e),
|
|
38
|
+
(e) => (s.onFinishRequest(), Promise.reject(e))
|
|
39
|
+
), h.interceptors.request.use((e) => {
|
|
39
40
|
if (!e.url) return e;
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
for (const [t, v] of Object.entries(
|
|
41
|
+
const r = (a) => {
|
|
42
|
+
if (a)
|
|
43
|
+
for (const [t, v] of Object.entries(a)) {
|
|
43
44
|
const l = `{${t}}`;
|
|
44
45
|
e.url.includes(l) && (e.url = e.url.replace(
|
|
45
46
|
l,
|
|
46
47
|
encodeURIComponent(String(v))
|
|
47
|
-
), delete
|
|
48
|
+
), delete a[t]);
|
|
48
49
|
}
|
|
49
50
|
};
|
|
50
|
-
return e.method !== "get" && e.data?.params &&
|
|
51
|
-
}),
|
|
51
|
+
return e.method !== "get" && e.data?.params && r(e.data.params), r(e.params), e;
|
|
52
|
+
}), s.csrfRefreshEndpoint && h.interceptors.response.use(
|
|
53
|
+
(e) => e,
|
|
54
|
+
async (e) => {
|
|
55
|
+
const r = e.config;
|
|
56
|
+
if (r.url === s.csrfRefreshEndpoint)
|
|
57
|
+
return Promise.reject(e);
|
|
58
|
+
if (e.response && (e.response.status === 403 || e.response.status === 419) && !r._retry) {
|
|
59
|
+
r._retry = !0;
|
|
60
|
+
try {
|
|
61
|
+
return b && q ? await q : (b = !0, q = h.get(s.csrfRefreshEndpoint, {
|
|
62
|
+
// Mark this request to prevent retry
|
|
63
|
+
_skipRetry: !0
|
|
64
|
+
}).then(() => {
|
|
65
|
+
b = !1, q = null;
|
|
66
|
+
}), await q), h(r);
|
|
67
|
+
} catch (a) {
|
|
68
|
+
return b = !1, q = null, Promise.reject(a);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return Promise.reject(e);
|
|
72
|
+
}
|
|
73
|
+
), h.interceptors.response.use(
|
|
52
74
|
(e) => e,
|
|
53
|
-
(e) => (
|
|
75
|
+
(e) => (x(() => {
|
|
54
76
|
e.code;
|
|
55
77
|
}), Promise.reject(e))
|
|
56
78
|
);
|
|
57
|
-
const
|
|
58
|
-
for (const e in
|
|
59
|
-
const
|
|
60
|
-
|
|
79
|
+
const C = s.queries ?? {}, M = {};
|
|
80
|
+
for (const e in C) {
|
|
81
|
+
const r = C[e];
|
|
82
|
+
r && (M[e] = (a) => {
|
|
61
83
|
let t;
|
|
62
|
-
|
|
63
|
-
const v = m(), l = m(),
|
|
64
|
-
let
|
|
84
|
+
a && typeof a == "object" && ("loadOnMount" in a || "debounce" in a || "onResult" in a || "onError" in a || "data" in a ? t = a : t = { params: a });
|
|
85
|
+
const v = m(), l = m(), R = m(), g = m(!1), y = m(!1), P = m(!0);
|
|
86
|
+
let j = new AbortController();
|
|
65
87
|
const u = () => {
|
|
66
|
-
|
|
67
|
-
},
|
|
68
|
-
|
|
88
|
+
j?.abort(), j = new AbortController();
|
|
89
|
+
}, c = async () => {
|
|
90
|
+
g.value && u(), g.value = !0, l.value = void 0;
|
|
69
91
|
try {
|
|
70
|
-
|
|
71
|
-
let
|
|
72
|
-
|
|
92
|
+
r.params && t?.params && r.params.parse(t.params);
|
|
93
|
+
let o = t?.data;
|
|
94
|
+
r.data && o && r.data.parse(o);
|
|
73
95
|
const f = {
|
|
74
|
-
method:
|
|
75
|
-
url:
|
|
96
|
+
method: r.method ?? "GET",
|
|
97
|
+
url: r.path,
|
|
76
98
|
params: t?.params,
|
|
77
|
-
signal:
|
|
99
|
+
signal: j.signal
|
|
78
100
|
};
|
|
79
|
-
|
|
80
|
-
const n = await
|
|
81
|
-
v.value =
|
|
82
|
-
} catch (
|
|
83
|
-
if (
|
|
84
|
-
if (
|
|
85
|
-
const f =
|
|
86
|
-
l.value = f, t?.onError?.(
|
|
101
|
+
r.method === "POST" && o && (f.data = o);
|
|
102
|
+
const n = await h.request(f), i = r.response ? r.response.parse(n.data) : n.data;
|
|
103
|
+
v.value = i, t?.onResult?.(i);
|
|
104
|
+
} catch (o) {
|
|
105
|
+
if (o instanceof S) {
|
|
106
|
+
if (o.code !== "ERR_CANCELED") {
|
|
107
|
+
const f = o.response?.data?.message || o.message || "An error occurred", n = o.response?.status, i = o.code, p = o.response?.data;
|
|
108
|
+
l.value = f, t?.onError?.(o), s.onErrorRequest?.({ message: f, status: n, code: i, data: p });
|
|
87
109
|
}
|
|
88
|
-
} else if (
|
|
89
|
-
|
|
90
|
-
const n = `Validation error: ${
|
|
91
|
-
(
|
|
110
|
+
} else if (o instanceof L) {
|
|
111
|
+
R.value = o.issues || [];
|
|
112
|
+
const n = `Validation error: ${R.value.map(
|
|
113
|
+
(i) => `${i.path.join(".")}: ${i.message}`
|
|
92
114
|
).join(", ")}`;
|
|
93
|
-
l.value = n, t?.onError?.(
|
|
115
|
+
l.value = n, t?.onError?.(o), t?.onZodError?.(R.value), s.onErrorRequest?.({ message: n, code: "VALIDATION_ERROR" }), s.onZodError && s.onZodError(R.value);
|
|
94
116
|
} else {
|
|
95
|
-
const f =
|
|
96
|
-
l.value = f, t?.onError?.(f),
|
|
117
|
+
const f = o.message || "An error occurred";
|
|
118
|
+
l.value = f, t?.onError?.(f), s.onErrorRequest?.({ message: f });
|
|
97
119
|
}
|
|
98
120
|
} finally {
|
|
99
|
-
|
|
121
|
+
g.value = !1, y.value = !0;
|
|
100
122
|
}
|
|
101
|
-
},
|
|
123
|
+
}, E = t?.debounce ? Z(c, t.debounce) : c;
|
|
102
124
|
let d = null;
|
|
103
|
-
return (t?.params || t?.data) && (
|
|
125
|
+
return (t?.params || t?.data) && (F(() => {
|
|
104
126
|
d && d(), d = N(
|
|
105
127
|
() => JSON.stringify({ params: t.params, data: t.data }),
|
|
106
128
|
() => {
|
|
107
|
-
|
|
129
|
+
E();
|
|
108
130
|
},
|
|
109
131
|
{ immediate: !1 }
|
|
110
132
|
);
|
|
111
133
|
}), T(() => {
|
|
112
|
-
d && d(),
|
|
113
|
-
})), (t?.loadOnMount === void 0 || t.loadOnMount) && !y.value && (
|
|
134
|
+
d && d(), j?.abort();
|
|
135
|
+
})), (t?.loadOnMount === void 0 || t.loadOnMount) && !y.value && (P.value ? (P.value = !1, c()) : E()), { result: v, errorMessage: l, zodErrors: R, isLoading: g, isDone: y, refetch: c };
|
|
114
136
|
});
|
|
115
137
|
}
|
|
116
|
-
const
|
|
117
|
-
for (const e in
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
const t = m(), v = m(), l = m(),
|
|
121
|
-
return { result: t, errorMessage: v, zodErrors: l, isLoading:
|
|
122
|
-
if (!
|
|
123
|
-
|
|
138
|
+
const D = s.mutations ?? {}, w = {};
|
|
139
|
+
for (const e in D) {
|
|
140
|
+
const r = D[e];
|
|
141
|
+
r && (w[e] = (a) => {
|
|
142
|
+
const t = m(), v = m(), l = m(), R = m(!1), g = m(!1), y = m(0);
|
|
143
|
+
return { result: t, errorMessage: v, zodErrors: l, isLoading: R, isDone: g, uploadProgress: y, mutate: async (j) => {
|
|
144
|
+
if (!R.value) {
|
|
145
|
+
R.value = !0, v.value = void 0, y.value = 0;
|
|
124
146
|
try {
|
|
125
|
-
const { data: u, params:
|
|
126
|
-
let
|
|
127
|
-
if (
|
|
147
|
+
const { data: u = {}, params: c } = j ?? {};
|
|
148
|
+
let E = u ?? {}, d = {};
|
|
149
|
+
if (r.isMultipart) {
|
|
128
150
|
const n = new FormData();
|
|
129
|
-
for (const [
|
|
130
|
-
p instanceof File || p instanceof Blob ? n.append(
|
|
131
|
-
|
|
132
|
-
}) : typeof p == "object" && p !== null ? n.append(
|
|
133
|
-
|
|
134
|
-
} else
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
-
method:
|
|
138
|
-
url:
|
|
139
|
-
data:
|
|
140
|
-
params:
|
|
151
|
+
for (const [i, p] of Object.entries(u))
|
|
152
|
+
p instanceof File || p instanceof Blob ? n.append(i, p) : Array.isArray(p) ? p.forEach((A) => {
|
|
153
|
+
A instanceof File || A instanceof Blob ? n.append(i, A) : n.append(i, JSON.stringify(A));
|
|
154
|
+
}) : typeof p == "object" && p !== null ? n.append(i, JSON.stringify(p)) : n.append(i, String(p));
|
|
155
|
+
E = n, d["Content-Type"] = "multipart/form-data";
|
|
156
|
+
} else r.data && r.data.parse(u);
|
|
157
|
+
r.params && c && r.params.parse(c);
|
|
158
|
+
const o = await h.request({
|
|
159
|
+
method: r.method,
|
|
160
|
+
url: r.path,
|
|
161
|
+
data: E,
|
|
162
|
+
params: c,
|
|
141
163
|
headers: d,
|
|
142
164
|
onUploadProgress: (n) => {
|
|
143
165
|
if (n.total) {
|
|
144
|
-
const
|
|
145
|
-
y.value =
|
|
166
|
+
const i = Math.round(n.loaded * 100 / n.total);
|
|
167
|
+
y.value = i, a?.onUploadProgress?.(i);
|
|
146
168
|
}
|
|
147
169
|
}
|
|
148
|
-
}), f =
|
|
149
|
-
t.value = f,
|
|
170
|
+
}), f = r.response ? r.response.parse(o.data) : o.data;
|
|
171
|
+
t.value = f, a?.onResult?.(f);
|
|
150
172
|
} catch (u) {
|
|
151
|
-
if (u instanceof
|
|
152
|
-
const
|
|
153
|
-
v.value =
|
|
154
|
-
} else if (u instanceof
|
|
173
|
+
if (u instanceof S) {
|
|
174
|
+
const c = u.response?.data?.message || u.message || "An error occurred", E = u.response?.status, d = u.code;
|
|
175
|
+
v.value = c, a?.onError?.(u), s.onErrorRequest?.({ message: c, status: E, code: d });
|
|
176
|
+
} else if (u instanceof L) {
|
|
155
177
|
l.value = u.issues || [];
|
|
156
|
-
const
|
|
178
|
+
const E = `Validation error: ${l.value.map(
|
|
157
179
|
(d) => `${d.path.join(".")}: ${d.message}`
|
|
158
180
|
).join(", ")}`;
|
|
159
|
-
v.value =
|
|
181
|
+
v.value = E, a?.onError?.(u), a?.onZodError?.(l.value), s.onErrorRequest?.({ message: E, code: "VALIDATION_ERROR" }), s.onZodError && s.onZodError(l.value);
|
|
160
182
|
} else {
|
|
161
|
-
const
|
|
162
|
-
v.value =
|
|
183
|
+
const c = u.message || "An error occurred";
|
|
184
|
+
v.value = c, a?.onError?.(u), s.onErrorRequest?.({ message: c });
|
|
163
185
|
}
|
|
164
186
|
} finally {
|
|
165
|
-
|
|
187
|
+
R.value = !1, g.value = !0;
|
|
166
188
|
}
|
|
167
189
|
}
|
|
168
190
|
} };
|
|
169
191
|
});
|
|
170
192
|
}
|
|
171
193
|
return {
|
|
172
|
-
query:
|
|
173
|
-
mutation:
|
|
194
|
+
query: M,
|
|
195
|
+
mutation: w
|
|
174
196
|
};
|
|
175
197
|
}
|
|
176
|
-
function
|
|
177
|
-
return
|
|
198
|
+
function V(s) {
|
|
199
|
+
return s;
|
|
178
200
|
}
|
|
179
|
-
function
|
|
180
|
-
return
|
|
201
|
+
function J(s) {
|
|
202
|
+
return s;
|
|
181
203
|
}
|
|
182
|
-
function
|
|
183
|
-
return Object.assign({}, ...
|
|
204
|
+
function Q(...s) {
|
|
205
|
+
return Object.assign({}, ...s);
|
|
184
206
|
}
|
|
185
|
-
function
|
|
186
|
-
return Object.assign({}, ...
|
|
207
|
+
function W(...s) {
|
|
208
|
+
return Object.assign({}, ...s);
|
|
187
209
|
}
|
|
188
210
|
export {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
211
|
+
K as AxiosError,
|
|
212
|
+
z as createApiClient,
|
|
213
|
+
J as defineMutation,
|
|
214
|
+
V as defineQuery,
|
|
215
|
+
W as mergeMutations,
|
|
216
|
+
Q as mergeQueries,
|
|
217
|
+
$ as z
|
|
196
218
|
};
|
package/package.json
CHANGED