vue-api-kit 1.4.2 → 1.5.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.
- package/README.md +82 -3
- package/dist/core/types.d.ts +4 -1
- package/dist/index.js +133 -115
- package/package.json +1 -1
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,6 +83,7 @@ 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
89
|
onBeforeRequest?: (config: InternalAxiosRequestConfig<any>) => Promise<any> | void | any;
|
|
@@ -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,214 @@
|
|
|
1
|
-
import { ZodError as
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
4
|
-
import { AxiosError as
|
|
5
|
-
import { nextTick as
|
|
6
|
-
import { debounce as
|
|
7
|
-
function
|
|
8
|
-
const
|
|
1
|
+
import { ZodError as L } from "zod";
|
|
2
|
+
import * as T 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 Z } from "vue";
|
|
6
|
+
import { debounce as _ } from "lodash-es";
|
|
7
|
+
function z(r) {
|
|
8
|
+
const h = k.create({
|
|
9
9
|
baseURL: r.baseURL,
|
|
10
|
-
headers:
|
|
11
|
-
"Content-Type": "application/json",
|
|
12
|
-
Accept: "application/json",
|
|
13
|
-
...r.headers
|
|
14
|
-
},
|
|
10
|
+
...r.headers && { headers: r.headers },
|
|
15
11
|
withCredentials: r.withCredentials ?? !1
|
|
16
12
|
});
|
|
17
|
-
|
|
13
|
+
let P = !1, q = null;
|
|
14
|
+
r.onBeforeRequest && h.interceptors.request.use(
|
|
18
15
|
async (e) => {
|
|
19
16
|
try {
|
|
20
17
|
return await r.onBeforeRequest(e) || e;
|
|
21
|
-
} catch (
|
|
22
|
-
return Promise.reject(
|
|
18
|
+
} catch (s) {
|
|
19
|
+
return Promise.reject(s);
|
|
23
20
|
}
|
|
24
21
|
},
|
|
25
22
|
(e) => Promise.reject(e)
|
|
26
|
-
), r.onStartRequest &&
|
|
23
|
+
), r.onStartRequest && h.interceptors.request.use(
|
|
27
24
|
async (e) => {
|
|
28
25
|
try {
|
|
29
26
|
return await r.onStartRequest(), e;
|
|
30
|
-
} catch (
|
|
31
|
-
return Promise.reject(
|
|
27
|
+
} catch (s) {
|
|
28
|
+
return Promise.reject(s);
|
|
32
29
|
}
|
|
33
30
|
},
|
|
34
31
|
(e) => Promise.reject(e)
|
|
35
|
-
), r.onFinishRequest &&
|
|
32
|
+
), r.onFinishRequest && h.interceptors.response.use(
|
|
36
33
|
(e) => (r.onFinishRequest(), e),
|
|
37
|
-
(e) => Promise.reject(e)
|
|
38
|
-
),
|
|
34
|
+
(e) => (r.onFinishRequest(), Promise.reject(e))
|
|
35
|
+
), h.interceptors.request.use((e) => {
|
|
39
36
|
if (!e.url) return e;
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
for (const [t, v] of Object.entries(
|
|
37
|
+
const s = (a) => {
|
|
38
|
+
if (a)
|
|
39
|
+
for (const [t, v] of Object.entries(a)) {
|
|
43
40
|
const l = `{${t}}`;
|
|
44
41
|
e.url.includes(l) && (e.url = e.url.replace(
|
|
45
42
|
l,
|
|
46
43
|
encodeURIComponent(String(v))
|
|
47
|
-
), delete
|
|
44
|
+
), delete a[t]);
|
|
48
45
|
}
|
|
49
46
|
};
|
|
50
|
-
return e.method !== "get" && e.data?.params &&
|
|
51
|
-
}),
|
|
47
|
+
return e.method !== "get" && e.data?.params && s(e.data.params), s(e.params), e;
|
|
48
|
+
}), r.csrfRefreshEndpoint && h.interceptors.response.use(
|
|
52
49
|
(e) => e,
|
|
53
|
-
(e) =>
|
|
50
|
+
async (e) => {
|
|
51
|
+
const s = e.config;
|
|
52
|
+
if (s.url === r.csrfRefreshEndpoint)
|
|
53
|
+
return Promise.reject(e);
|
|
54
|
+
if (e.response && (e.response.status === 403 || e.response.status === 419) && !s._retry) {
|
|
55
|
+
s._retry = !0;
|
|
56
|
+
try {
|
|
57
|
+
return P && q ? await q : (P = !0, q = h.get(r.csrfRefreshEndpoint, {
|
|
58
|
+
// Mark this request to prevent retry
|
|
59
|
+
_skipRetry: !0
|
|
60
|
+
}).then(() => {
|
|
61
|
+
P = !1, q = null;
|
|
62
|
+
}), await q), h(s);
|
|
63
|
+
} catch (a) {
|
|
64
|
+
return P = !1, q = null, Promise.reject(a);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return Promise.reject(e);
|
|
68
|
+
}
|
|
69
|
+
), h.interceptors.response.use(
|
|
70
|
+
(e) => e,
|
|
71
|
+
(e) => (x(() => {
|
|
54
72
|
e.code;
|
|
55
73
|
}), Promise.reject(e))
|
|
56
74
|
);
|
|
57
|
-
const
|
|
58
|
-
for (const e in
|
|
59
|
-
const
|
|
60
|
-
|
|
75
|
+
const C = r.queries ?? {}, M = {};
|
|
76
|
+
for (const e in C) {
|
|
77
|
+
const s = C[e];
|
|
78
|
+
s && (M[e] = (a) => {
|
|
61
79
|
let t;
|
|
62
|
-
|
|
63
|
-
const v = m(), l = m(),
|
|
64
|
-
let
|
|
80
|
+
a && typeof a == "object" && ("loadOnMount" in a || "debounce" in a || "onResult" in a || "onError" in a || "data" in a ? t = a : t = { params: a });
|
|
81
|
+
const v = m(), l = m(), R = m(), g = m(!1), y = m(!1), A = m(!0);
|
|
82
|
+
let b = new AbortController();
|
|
65
83
|
const u = () => {
|
|
66
|
-
|
|
67
|
-
},
|
|
68
|
-
|
|
84
|
+
b?.abort(), b = new AbortController();
|
|
85
|
+
}, c = async () => {
|
|
86
|
+
g.value && u(), g.value = !0, l.value = void 0;
|
|
69
87
|
try {
|
|
70
|
-
|
|
71
|
-
let
|
|
72
|
-
|
|
88
|
+
s.params && t?.params && s.params.parse(t.params);
|
|
89
|
+
let o = t?.data;
|
|
90
|
+
s.data && o && s.data.parse(o);
|
|
73
91
|
const f = {
|
|
74
|
-
method:
|
|
75
|
-
url:
|
|
92
|
+
method: s.method ?? "GET",
|
|
93
|
+
url: s.path,
|
|
76
94
|
params: t?.params,
|
|
77
|
-
signal:
|
|
95
|
+
signal: b.signal
|
|
78
96
|
};
|
|
79
|
-
|
|
80
|
-
const n = await
|
|
81
|
-
v.value =
|
|
82
|
-
} catch (
|
|
83
|
-
if (
|
|
84
|
-
if (
|
|
85
|
-
const f =
|
|
86
|
-
l.value = f, t?.onError?.(
|
|
97
|
+
s.method === "POST" && o && (f.data = o);
|
|
98
|
+
const n = await h.request(f), i = s.response ? s.response.parse(n.data) : n.data;
|
|
99
|
+
v.value = i, t?.onResult?.(i);
|
|
100
|
+
} catch (o) {
|
|
101
|
+
if (o instanceof S) {
|
|
102
|
+
if (o.code !== "ERR_CANCELED") {
|
|
103
|
+
const f = o.response?.data?.message || o.message || "An error occurred", n = o.response?.status, i = o.code, p = o.response?.data;
|
|
104
|
+
l.value = f, t?.onError?.(o), r.onErrorRequest?.({ message: f, status: n, code: i, data: p });
|
|
87
105
|
}
|
|
88
|
-
} else if (
|
|
89
|
-
|
|
90
|
-
const n = `Validation error: ${
|
|
91
|
-
(
|
|
106
|
+
} else if (o instanceof L) {
|
|
107
|
+
R.value = o.issues || [];
|
|
108
|
+
const n = `Validation error: ${R.value.map(
|
|
109
|
+
(i) => `${i.path.join(".")}: ${i.message}`
|
|
92
110
|
).join(", ")}`;
|
|
93
|
-
l.value = n, t?.onError?.(
|
|
111
|
+
l.value = n, t?.onError?.(o), t?.onZodError?.(R.value), r.onErrorRequest?.({ message: n, code: "VALIDATION_ERROR" }), r.onZodError && r.onZodError(R.value);
|
|
94
112
|
} else {
|
|
95
|
-
const f =
|
|
113
|
+
const f = o.message || "An error occurred";
|
|
96
114
|
l.value = f, t?.onError?.(f), r.onErrorRequest?.({ message: f });
|
|
97
115
|
}
|
|
98
116
|
} finally {
|
|
99
|
-
|
|
117
|
+
g.value = !1, y.value = !0;
|
|
100
118
|
}
|
|
101
|
-
},
|
|
119
|
+
}, E = t?.debounce ? _(c, t.debounce) : c;
|
|
102
120
|
let d = null;
|
|
103
|
-
return (t?.params || t?.data) && (
|
|
121
|
+
return (t?.params || t?.data) && (F(() => {
|
|
104
122
|
d && d(), d = N(
|
|
105
123
|
() => JSON.stringify({ params: t.params, data: t.data }),
|
|
106
124
|
() => {
|
|
107
|
-
|
|
125
|
+
E();
|
|
108
126
|
},
|
|
109
127
|
{ immediate: !1 }
|
|
110
128
|
);
|
|
111
|
-
}),
|
|
112
|
-
d && d(),
|
|
113
|
-
})), (t?.loadOnMount === void 0 || t.loadOnMount) && !y.value && (A.value ? (A.value = !1,
|
|
129
|
+
}), Z(() => {
|
|
130
|
+
d && d(), b?.abort();
|
|
131
|
+
})), (t?.loadOnMount === void 0 || t.loadOnMount) && !y.value && (A.value ? (A.value = !1, c()) : E()), { result: v, errorMessage: l, zodErrors: R, isLoading: g, isDone: y, refetch: c };
|
|
114
132
|
});
|
|
115
133
|
}
|
|
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
|
-
|
|
134
|
+
const D = r.mutations ?? {}, w = {};
|
|
135
|
+
for (const e in D) {
|
|
136
|
+
const s = D[e];
|
|
137
|
+
s && (w[e] = (a) => {
|
|
138
|
+
const t = m(), v = m(), l = m(), R = m(!1), g = m(!1), y = m(0);
|
|
139
|
+
return { result: t, errorMessage: v, zodErrors: l, isLoading: R, isDone: g, uploadProgress: y, mutate: async (b) => {
|
|
140
|
+
if (!R.value) {
|
|
141
|
+
R.value = !0, v.value = void 0, y.value = 0;
|
|
124
142
|
try {
|
|
125
|
-
const { data: u, params:
|
|
126
|
-
let
|
|
127
|
-
if (
|
|
143
|
+
const { data: u = {}, params: c } = b ?? {};
|
|
144
|
+
let E = u ?? {}, d = {};
|
|
145
|
+
if (s.isMultipart) {
|
|
128
146
|
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:
|
|
147
|
+
for (const [i, p] of Object.entries(u))
|
|
148
|
+
p instanceof File || p instanceof Blob ? n.append(i, p) : Array.isArray(p) ? p.forEach((j) => {
|
|
149
|
+
j instanceof File || j instanceof Blob ? n.append(i, j) : n.append(i, JSON.stringify(j));
|
|
150
|
+
}) : typeof p == "object" && p !== null ? n.append(i, JSON.stringify(p)) : n.append(i, String(p));
|
|
151
|
+
E = n, d["Content-Type"] = "multipart/form-data";
|
|
152
|
+
} else s.data && s.data.parse(u);
|
|
153
|
+
s.params && c && s.params.parse(c);
|
|
154
|
+
const o = await h.request({
|
|
155
|
+
method: s.method,
|
|
156
|
+
url: s.path,
|
|
157
|
+
data: E,
|
|
158
|
+
params: c,
|
|
141
159
|
headers: d,
|
|
142
160
|
onUploadProgress: (n) => {
|
|
143
161
|
if (n.total) {
|
|
144
|
-
const
|
|
145
|
-
y.value =
|
|
162
|
+
const i = Math.round(n.loaded * 100 / n.total);
|
|
163
|
+
y.value = i, a?.onUploadProgress?.(i);
|
|
146
164
|
}
|
|
147
165
|
}
|
|
148
|
-
}), f =
|
|
149
|
-
t.value = f,
|
|
166
|
+
}), f = s.response ? s.response.parse(o.data) : o.data;
|
|
167
|
+
t.value = f, a?.onResult?.(f);
|
|
150
168
|
} catch (u) {
|
|
151
|
-
if (u instanceof
|
|
152
|
-
const
|
|
153
|
-
v.value =
|
|
154
|
-
} else if (u instanceof
|
|
169
|
+
if (u instanceof S) {
|
|
170
|
+
const c = u.response?.data?.message || u.message || "An error occurred", E = u.response?.status, d = u.code;
|
|
171
|
+
v.value = c, a?.onError?.(u), r.onErrorRequest?.({ message: c, status: E, code: d });
|
|
172
|
+
} else if (u instanceof L) {
|
|
155
173
|
l.value = u.issues || [];
|
|
156
|
-
const
|
|
174
|
+
const E = `Validation error: ${l.value.map(
|
|
157
175
|
(d) => `${d.path.join(".")}: ${d.message}`
|
|
158
176
|
).join(", ")}`;
|
|
159
|
-
v.value =
|
|
177
|
+
v.value = E, a?.onError?.(u), a?.onZodError?.(l.value), r.onErrorRequest?.({ message: E, code: "VALIDATION_ERROR" }), r.onZodError && r.onZodError(l.value);
|
|
160
178
|
} else {
|
|
161
|
-
const
|
|
162
|
-
v.value =
|
|
179
|
+
const c = u.message || "An error occurred";
|
|
180
|
+
v.value = c, a?.onError?.(u), r.onErrorRequest?.({ message: c });
|
|
163
181
|
}
|
|
164
182
|
} finally {
|
|
165
|
-
|
|
183
|
+
R.value = !1, g.value = !0;
|
|
166
184
|
}
|
|
167
185
|
}
|
|
168
186
|
} };
|
|
169
187
|
});
|
|
170
188
|
}
|
|
171
189
|
return {
|
|
172
|
-
query:
|
|
173
|
-
mutation:
|
|
190
|
+
query: M,
|
|
191
|
+
mutation: w
|
|
174
192
|
};
|
|
175
193
|
}
|
|
176
|
-
function
|
|
194
|
+
function V(r) {
|
|
177
195
|
return r;
|
|
178
196
|
}
|
|
179
|
-
function
|
|
197
|
+
function J(r) {
|
|
180
198
|
return r;
|
|
181
199
|
}
|
|
182
|
-
function
|
|
200
|
+
function Q(...r) {
|
|
183
201
|
return Object.assign({}, ...r);
|
|
184
202
|
}
|
|
185
|
-
function
|
|
203
|
+
function W(...r) {
|
|
186
204
|
return Object.assign({}, ...r);
|
|
187
205
|
}
|
|
188
206
|
export {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
207
|
+
K as AxiosError,
|
|
208
|
+
z as createApiClient,
|
|
209
|
+
J as defineMutation,
|
|
210
|
+
V as defineQuery,
|
|
211
|
+
W as mergeMutations,
|
|
212
|
+
Q as mergeQueries,
|
|
213
|
+
T as z
|
|
196
214
|
};
|
package/package.json
CHANGED