@softimist/api 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/README.md +67 -0
- package/dist/index.cjs +665 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +298 -0
- package/dist/index.d.ts +298 -0
- package/dist/index.js +617 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,665 @@
|
|
|
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/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
BaseApiClient: () => BaseApiClient,
|
|
34
|
+
QueryProvider: () => QueryProvider,
|
|
35
|
+
getErrorMessage: () => getErrorMessage,
|
|
36
|
+
getQueryClient: () => getQueryClient,
|
|
37
|
+
getSuccessMessage: () => getSuccessMessage,
|
|
38
|
+
makeQueryClient: () => makeQueryClient,
|
|
39
|
+
useApi: () => useApi,
|
|
40
|
+
useApiAction: () => useApiAction,
|
|
41
|
+
useInfiniteQuery: () => import_react_query3.useInfiniteQuery,
|
|
42
|
+
useMockPaginatedApi: () => useMockPaginatedApi,
|
|
43
|
+
usePaginatedApi: () => usePaginatedApi,
|
|
44
|
+
useQuery: () => import_react_query3.useQuery
|
|
45
|
+
});
|
|
46
|
+
module.exports = __toCommonJS(index_exports);
|
|
47
|
+
|
|
48
|
+
// src/client.ts
|
|
49
|
+
var import_axios = __toESM(require("axios"), 1);
|
|
50
|
+
var BaseApiClient = class {
|
|
51
|
+
axiosInstance;
|
|
52
|
+
getAuthToken;
|
|
53
|
+
getRefreshToken;
|
|
54
|
+
setAuthToken;
|
|
55
|
+
setRefreshToken;
|
|
56
|
+
clearAuthTokens;
|
|
57
|
+
refreshTokenUrl;
|
|
58
|
+
isRefreshing = false;
|
|
59
|
+
failedQueue = [];
|
|
60
|
+
constructor(config = {}) {
|
|
61
|
+
const defaultHeaders = {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
Accept: "application/json",
|
|
64
|
+
...config.headers
|
|
65
|
+
};
|
|
66
|
+
this.axiosInstance = import_axios.default.create({
|
|
67
|
+
baseURL: config.baseURL || "",
|
|
68
|
+
timeout: config.timeout || 3e4,
|
|
69
|
+
headers: defaultHeaders
|
|
70
|
+
});
|
|
71
|
+
this.getAuthToken = config.getAuthToken;
|
|
72
|
+
this.getRefreshToken = config.getRefreshToken;
|
|
73
|
+
this.setAuthToken = config.setAuthToken;
|
|
74
|
+
this.setRefreshToken = config.setRefreshToken;
|
|
75
|
+
this.clearAuthTokens = config.clearAuthTokens;
|
|
76
|
+
this.refreshTokenUrl = config.refreshTokenUrl || `${config.baseURL || ""}/v1/auth/refresh`;
|
|
77
|
+
this.axiosInstance.interceptors.request.use(
|
|
78
|
+
(requestConfig) => {
|
|
79
|
+
if (this.getAuthToken) {
|
|
80
|
+
const token = this.getAuthToken();
|
|
81
|
+
if (token) {
|
|
82
|
+
requestConfig.headers.Authorization = `Bearer ${token}`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return requestConfig;
|
|
86
|
+
},
|
|
87
|
+
(error) => {
|
|
88
|
+
return Promise.reject(error);
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
this.axiosInstance.interceptors.response.use(
|
|
92
|
+
(response) => response,
|
|
93
|
+
async (error) => {
|
|
94
|
+
const originalRequest = error.config;
|
|
95
|
+
if (error.response?.status === 401 && !originalRequest._retry && this.getRefreshToken) {
|
|
96
|
+
if (this.isRefreshing) {
|
|
97
|
+
return new Promise((resolve, reject) => {
|
|
98
|
+
this.failedQueue.push({ resolve, reject });
|
|
99
|
+
}).then((token) => {
|
|
100
|
+
originalRequest.headers.Authorization = `Bearer ${token}`;
|
|
101
|
+
return this.axiosInstance(originalRequest);
|
|
102
|
+
}).catch((err) => {
|
|
103
|
+
return Promise.reject(err);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
originalRequest._retry = true;
|
|
107
|
+
this.isRefreshing = true;
|
|
108
|
+
try {
|
|
109
|
+
const accessToken = await this.refreshAuthToken();
|
|
110
|
+
originalRequest.headers.Authorization = `Bearer ${accessToken}`;
|
|
111
|
+
this.processQueue(null, accessToken);
|
|
112
|
+
this.isRefreshing = false;
|
|
113
|
+
return this.axiosInstance(originalRequest);
|
|
114
|
+
} catch (refreshError) {
|
|
115
|
+
this.processQueue(refreshError, null);
|
|
116
|
+
this.isRefreshing = false;
|
|
117
|
+
return Promise.reject(this.handleError(refreshError));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return Promise.reject(this.handleError(error));
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Process queued requests after token refresh
|
|
126
|
+
*/
|
|
127
|
+
processQueue(error, token = null) {
|
|
128
|
+
this.failedQueue.forEach(({ resolve, reject }) => {
|
|
129
|
+
if (error) {
|
|
130
|
+
reject(error);
|
|
131
|
+
} else {
|
|
132
|
+
resolve(token);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
this.failedQueue = [];
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Refresh authentication token
|
|
139
|
+
*/
|
|
140
|
+
async refreshAuthToken() {
|
|
141
|
+
if (!this.getRefreshToken) {
|
|
142
|
+
throw new Error("No refresh token function provided");
|
|
143
|
+
}
|
|
144
|
+
const refreshToken = this.getRefreshToken();
|
|
145
|
+
if (!refreshToken) {
|
|
146
|
+
if (this.clearAuthTokens) {
|
|
147
|
+
this.clearAuthTokens();
|
|
148
|
+
}
|
|
149
|
+
throw new Error("No refresh token available");
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
const response = await import_axios.default.post(this.refreshTokenUrl, {
|
|
153
|
+
refresh_token: refreshToken
|
|
154
|
+
}, {
|
|
155
|
+
baseURL: ""
|
|
156
|
+
// Use absolute URL or empty to avoid baseURL duplication
|
|
157
|
+
});
|
|
158
|
+
const { access_token, refresh_token } = response.data;
|
|
159
|
+
if (this.setAuthToken) {
|
|
160
|
+
this.setAuthToken(access_token);
|
|
161
|
+
}
|
|
162
|
+
if (refresh_token && this.setRefreshToken) {
|
|
163
|
+
this.setRefreshToken(refresh_token);
|
|
164
|
+
}
|
|
165
|
+
return access_token;
|
|
166
|
+
} catch (error) {
|
|
167
|
+
if (this.clearAuthTokens) {
|
|
168
|
+
this.clearAuthTokens();
|
|
169
|
+
}
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Handle request errors
|
|
175
|
+
*/
|
|
176
|
+
handleError(error) {
|
|
177
|
+
if (error.response) {
|
|
178
|
+
const message = error.response.data?.message || error.response.data?.error || error.message || "An unknown error occurred";
|
|
179
|
+
return new Error(message);
|
|
180
|
+
} else if (error.request) {
|
|
181
|
+
return new Error("Network error: No response from server");
|
|
182
|
+
} else {
|
|
183
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Make HTTP GET request
|
|
188
|
+
* Returns unwrapped server response data
|
|
189
|
+
*/
|
|
190
|
+
async get(url, config) {
|
|
191
|
+
const axiosConfig = {
|
|
192
|
+
params: config?.params,
|
|
193
|
+
headers: config?.headers,
|
|
194
|
+
...config
|
|
195
|
+
};
|
|
196
|
+
delete axiosConfig.params;
|
|
197
|
+
delete axiosConfig.headers;
|
|
198
|
+
const response = await this.axiosInstance.get(url, {
|
|
199
|
+
...axiosConfig,
|
|
200
|
+
params: config?.params,
|
|
201
|
+
headers: config?.headers
|
|
202
|
+
});
|
|
203
|
+
return response.data;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Make HTTP POST request
|
|
207
|
+
* Returns unwrapped server response data
|
|
208
|
+
*/
|
|
209
|
+
async post(url, data, config) {
|
|
210
|
+
const axiosConfig = {
|
|
211
|
+
headers: config?.headers,
|
|
212
|
+
...config
|
|
213
|
+
};
|
|
214
|
+
delete axiosConfig.headers;
|
|
215
|
+
const response = await this.axiosInstance.post(url, data, {
|
|
216
|
+
...axiosConfig,
|
|
217
|
+
headers: config?.headers
|
|
218
|
+
});
|
|
219
|
+
return response.data;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Make HTTP PATCH request
|
|
223
|
+
* Returns unwrapped server response data
|
|
224
|
+
*/
|
|
225
|
+
async patch(url, data, config) {
|
|
226
|
+
const axiosConfig = {
|
|
227
|
+
headers: config?.headers,
|
|
228
|
+
...config
|
|
229
|
+
};
|
|
230
|
+
delete axiosConfig.headers;
|
|
231
|
+
const response = await this.axiosInstance.patch(url, data, {
|
|
232
|
+
...axiosConfig,
|
|
233
|
+
headers: config?.headers
|
|
234
|
+
});
|
|
235
|
+
return response.data;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Make HTTP PUT request
|
|
239
|
+
* Returns unwrapped server response data
|
|
240
|
+
*/
|
|
241
|
+
async put(url, data, config) {
|
|
242
|
+
const axiosConfig = {
|
|
243
|
+
headers: config?.headers,
|
|
244
|
+
...config
|
|
245
|
+
};
|
|
246
|
+
delete axiosConfig.headers;
|
|
247
|
+
const response = await this.axiosInstance.put(url, data, {
|
|
248
|
+
...axiosConfig,
|
|
249
|
+
headers: config?.headers
|
|
250
|
+
});
|
|
251
|
+
return response.data;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Make HTTP DELETE request
|
|
255
|
+
* Returns unwrapped server response data
|
|
256
|
+
*/
|
|
257
|
+
async delete(url, config) {
|
|
258
|
+
const axiosConfig = {
|
|
259
|
+
headers: config?.headers,
|
|
260
|
+
...config
|
|
261
|
+
};
|
|
262
|
+
delete axiosConfig.headers;
|
|
263
|
+
const response = await this.axiosInstance.delete(url, {
|
|
264
|
+
...axiosConfig,
|
|
265
|
+
headers: config?.headers
|
|
266
|
+
});
|
|
267
|
+
return response.data;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get the underlying axios instance for advanced usage
|
|
271
|
+
*/
|
|
272
|
+
get axios() {
|
|
273
|
+
return this.axiosInstance;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Create a new client instance with a different baseURL
|
|
277
|
+
* Useful for server-side requests or different API endpoints
|
|
278
|
+
*/
|
|
279
|
+
withBaseURL(baseURL) {
|
|
280
|
+
const ConfigClass = this.constructor;
|
|
281
|
+
const headers = { ...this.axiosInstance.defaults.headers };
|
|
282
|
+
return new ConfigClass({
|
|
283
|
+
baseURL,
|
|
284
|
+
getAuthToken: this.getAuthToken,
|
|
285
|
+
getRefreshToken: this.getRefreshToken,
|
|
286
|
+
setAuthToken: this.setAuthToken,
|
|
287
|
+
setRefreshToken: this.setRefreshToken,
|
|
288
|
+
clearAuthTokens: this.clearAuthTokens,
|
|
289
|
+
refreshTokenUrl: this.refreshTokenUrl,
|
|
290
|
+
timeout: this.axiosInstance.defaults.timeout,
|
|
291
|
+
headers
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
// src/hooks.ts
|
|
297
|
+
var import_react_query2 = require("@tanstack/react-query");
|
|
298
|
+
var import_nuqs = require("nuqs");
|
|
299
|
+
var import_react = require("react");
|
|
300
|
+
var import_sonner = require("sonner");
|
|
301
|
+
|
|
302
|
+
// src/tanstack-query.tsx
|
|
303
|
+
var import_react_query = require("@tanstack/react-query");
|
|
304
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
305
|
+
function makeQueryClient() {
|
|
306
|
+
return new import_react_query.QueryClient({
|
|
307
|
+
defaultOptions: {
|
|
308
|
+
queries: {
|
|
309
|
+
refetchOnWindowFocus: false,
|
|
310
|
+
refetchOnReconnect: false
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
var browserQueryClient = void 0;
|
|
316
|
+
function getQueryClient() {
|
|
317
|
+
if (typeof window === "undefined") {
|
|
318
|
+
return makeQueryClient();
|
|
319
|
+
} else {
|
|
320
|
+
if (!browserQueryClient) browserQueryClient = makeQueryClient();
|
|
321
|
+
return browserQueryClient;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function QueryProvider({ children }) {
|
|
325
|
+
const queryClient = getQueryClient();
|
|
326
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_query.QueryClientProvider, { client: queryClient, children });
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// src/hooks.ts
|
|
330
|
+
function useApi(httpClient, url, options = {}) {
|
|
331
|
+
const { queryKey, enabled = true, ...restOptions } = options;
|
|
332
|
+
return (0, import_react_query2.useQuery)({
|
|
333
|
+
queryKey: queryKey || [url],
|
|
334
|
+
queryFn: async () => {
|
|
335
|
+
if (!url) throw new Error("URL is required");
|
|
336
|
+
return httpClient.get(url);
|
|
337
|
+
},
|
|
338
|
+
enabled: url !== null && enabled,
|
|
339
|
+
...restOptions
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
function useApiAction(httpClient, options) {
|
|
343
|
+
const { action, showToast = true, invalidateQueries, onSuccess, onError } = options;
|
|
344
|
+
const [isExecuted, setIsExecuted] = (0, import_react.useState)(false);
|
|
345
|
+
const mutation = (0, import_react_query2.useMutation)({
|
|
346
|
+
mutationFn: action,
|
|
347
|
+
onSuccess: (res) => {
|
|
348
|
+
onSuccess?.(res.data);
|
|
349
|
+
setIsExecuted(true);
|
|
350
|
+
if (showToast) {
|
|
351
|
+
import_sonner.toast.success(res.message || "Success");
|
|
352
|
+
}
|
|
353
|
+
if (invalidateQueries && invalidateQueries.length > 0) {
|
|
354
|
+
const queryClient = getQueryClient();
|
|
355
|
+
invalidateQueries.forEach((queryKey) => {
|
|
356
|
+
queryClient.invalidateQueries({ queryKey });
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
onError: (err) => {
|
|
361
|
+
onError?.(err);
|
|
362
|
+
if (showToast) {
|
|
363
|
+
import_sonner.toast.error(err.message || "An error occurred");
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
const execute = () => {
|
|
368
|
+
mutation.mutate();
|
|
369
|
+
};
|
|
370
|
+
return {
|
|
371
|
+
isLoading: mutation.isPending,
|
|
372
|
+
error: mutation.error ?? void 0,
|
|
373
|
+
data: mutation.data?.data,
|
|
374
|
+
execute,
|
|
375
|
+
isExecuted
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
var parseAsFilterArray = (0, import_nuqs.createParser)({
|
|
379
|
+
parse: (value) => {
|
|
380
|
+
return JSON.parse(value);
|
|
381
|
+
},
|
|
382
|
+
serialize: (value) => {
|
|
383
|
+
return JSON.stringify(value);
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
function usePaginationState(options) {
|
|
387
|
+
const { persist = true, params: defaultParams } = options;
|
|
388
|
+
const defaultPerPage = defaultParams?.per_page || 20;
|
|
389
|
+
const defaultPage = defaultParams?.page || 1;
|
|
390
|
+
const [perPageQuery, setPerPageQuery] = (0, import_nuqs.useQueryState)(
|
|
391
|
+
"per_page",
|
|
392
|
+
import_nuqs.parseAsInteger.withDefault(defaultPerPage)
|
|
393
|
+
);
|
|
394
|
+
const [pageQuery, setPageQuery] = (0, import_nuqs.useQueryState)("page", import_nuqs.parseAsInteger.withDefault(defaultPage));
|
|
395
|
+
const [searchQuery, setSearchQuery] = (0, import_nuqs.useQueryState)("search", import_nuqs.parseAsString.withDefault(""));
|
|
396
|
+
const [filtersQuery, setFiltersQuery] = (0, import_nuqs.useQueryState)(
|
|
397
|
+
"filters",
|
|
398
|
+
parseAsFilterArray.withDefault([])
|
|
399
|
+
);
|
|
400
|
+
const [sortQuery, setSortQuery] = (0, import_nuqs.useQueryState)("sort", import_nuqs.parseAsString.withDefault(""));
|
|
401
|
+
const [perPageState, setPerPageState] = (0, import_react.useState)(defaultPerPage);
|
|
402
|
+
const [pageState, setPageState] = (0, import_react.useState)(defaultPage);
|
|
403
|
+
const [searchState, setSearchState] = (0, import_react.useState)("");
|
|
404
|
+
const [filtersState, setFiltersState] = (0, import_react.useState)([]);
|
|
405
|
+
const [sortState, setSortState] = (0, import_react.useState)();
|
|
406
|
+
const perPage = persist ? perPageQuery : perPageState;
|
|
407
|
+
const page = persist ? pageQuery : pageState;
|
|
408
|
+
const search = persist ? searchQuery : searchState;
|
|
409
|
+
const filters = persist ? filtersQuery : filtersState;
|
|
410
|
+
const sort = persist ? sortQuery : sortState;
|
|
411
|
+
const setPerPage = (value) => {
|
|
412
|
+
if (persist) {
|
|
413
|
+
setPerPageQuery(value);
|
|
414
|
+
} else {
|
|
415
|
+
setPerPageState(value);
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
const setPage = (value) => {
|
|
419
|
+
if (persist) {
|
|
420
|
+
setPageQuery(value);
|
|
421
|
+
} else {
|
|
422
|
+
setPageState(value);
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
const setSearch = (value) => {
|
|
426
|
+
if (persist) {
|
|
427
|
+
setSearchQuery(value);
|
|
428
|
+
} else {
|
|
429
|
+
setSearchState(value);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
const setFilters = (value) => {
|
|
433
|
+
if (persist) {
|
|
434
|
+
setFiltersQuery(value);
|
|
435
|
+
} else {
|
|
436
|
+
setFiltersState(value);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
const setSort = (value) => {
|
|
440
|
+
if (persist) {
|
|
441
|
+
setSortQuery(value);
|
|
442
|
+
} else {
|
|
443
|
+
setSortState(typeof value === "function" ? value(sortState || "") : value);
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
const getParams = () => {
|
|
447
|
+
const params = new URLSearchParams();
|
|
448
|
+
if (defaultParams) {
|
|
449
|
+
Object.entries(defaultParams).forEach(([key, value]) => {
|
|
450
|
+
if (value !== void 0) {
|
|
451
|
+
params.set(key, value.toString());
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
if (perPage) params.set("per_page", perPage.toString());
|
|
456
|
+
if (page) params.set("page", page.toString());
|
|
457
|
+
if (search) params.set("search", search);
|
|
458
|
+
if (sort) {
|
|
459
|
+
const [sortBy, sortDirection] = sort.split(":");
|
|
460
|
+
if (sortBy) params.set("sort_by", sortBy);
|
|
461
|
+
if (sortDirection) params.set("sort_dir", sortDirection);
|
|
462
|
+
}
|
|
463
|
+
filters?.forEach((filter) => {
|
|
464
|
+
if (Array.isArray(filter.value)) {
|
|
465
|
+
filter.value.forEach((v) => {
|
|
466
|
+
params.append(filter.key, v.toString());
|
|
467
|
+
});
|
|
468
|
+
} else {
|
|
469
|
+
params.set(filter.key, filter.value.toString());
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
return params;
|
|
473
|
+
};
|
|
474
|
+
return {
|
|
475
|
+
perPage,
|
|
476
|
+
page,
|
|
477
|
+
search,
|
|
478
|
+
filters,
|
|
479
|
+
sort,
|
|
480
|
+
setPerPage,
|
|
481
|
+
setPage,
|
|
482
|
+
setSearch,
|
|
483
|
+
setFilters,
|
|
484
|
+
setSort,
|
|
485
|
+
getParams
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
function usePaginatedApi(httpClient, path, options = {}) {
|
|
489
|
+
const {
|
|
490
|
+
perPage,
|
|
491
|
+
page,
|
|
492
|
+
search,
|
|
493
|
+
filters,
|
|
494
|
+
sort,
|
|
495
|
+
setPerPage,
|
|
496
|
+
setPage,
|
|
497
|
+
setSearch,
|
|
498
|
+
setFilters,
|
|
499
|
+
setSort,
|
|
500
|
+
getParams
|
|
501
|
+
} = usePaginationState(options);
|
|
502
|
+
const getUrl = () => {
|
|
503
|
+
if (!path) return null;
|
|
504
|
+
const params = getParams();
|
|
505
|
+
return params.size === 0 ? path : `${path}?${params.toString()}`;
|
|
506
|
+
};
|
|
507
|
+
const url = getUrl();
|
|
508
|
+
const { data, isLoading, error, refetch, isSuccess, isFetching } = (0, import_react_query2.useQuery)({
|
|
509
|
+
queryKey: [path, options, page, perPage, search, filters, sort],
|
|
510
|
+
queryFn: async () => {
|
|
511
|
+
if (!url) throw new Error("URL is required");
|
|
512
|
+
return httpClient.get(url);
|
|
513
|
+
},
|
|
514
|
+
enabled: !!url
|
|
515
|
+
});
|
|
516
|
+
function getBulkActionUrl(action, additionalFilters) {
|
|
517
|
+
const params = getParams();
|
|
518
|
+
params.delete("page");
|
|
519
|
+
params.delete("per_page");
|
|
520
|
+
Object.entries(additionalFilters || {}).forEach(([key, value]) => {
|
|
521
|
+
if (value === void 0) {
|
|
522
|
+
params.delete(key);
|
|
523
|
+
} else if (Array.isArray(value)) {
|
|
524
|
+
value.forEach((v) => {
|
|
525
|
+
params.append(key, v);
|
|
526
|
+
});
|
|
527
|
+
} else {
|
|
528
|
+
params.set(key, value);
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
if (params.size === 0) return `${path}/${action}`;
|
|
532
|
+
return `${path}/${action}?${params.toString()}`;
|
|
533
|
+
}
|
|
534
|
+
function setFilter(key, value) {
|
|
535
|
+
if (value === void 0) {
|
|
536
|
+
removeFilter(key);
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
const index = filters.findIndex((filter) => filter.key === key);
|
|
540
|
+
if (index === -1) {
|
|
541
|
+
setFilters([...filters, { key, value }]);
|
|
542
|
+
} else {
|
|
543
|
+
setFilters([...filters.slice(0, index), { key, value }, ...filters.slice(index + 1)]);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
function removeFilter(key) {
|
|
547
|
+
setFilters(filters.filter((filter) => filter.key !== key));
|
|
548
|
+
}
|
|
549
|
+
function getFilterValue(key) {
|
|
550
|
+
return filters.find((filter) => filter.key === key)?.value;
|
|
551
|
+
}
|
|
552
|
+
function resetFilters() {
|
|
553
|
+
setFilters([]);
|
|
554
|
+
}
|
|
555
|
+
return {
|
|
556
|
+
message: data?.message || "",
|
|
557
|
+
data: data?.data || [],
|
|
558
|
+
pagination: data?.pagination,
|
|
559
|
+
isLoading,
|
|
560
|
+
isSuccess,
|
|
561
|
+
isFetching,
|
|
562
|
+
error,
|
|
563
|
+
mutate: refetch,
|
|
564
|
+
page,
|
|
565
|
+
setPage,
|
|
566
|
+
perPage,
|
|
567
|
+
setPerPage,
|
|
568
|
+
search,
|
|
569
|
+
setSearch,
|
|
570
|
+
filters,
|
|
571
|
+
setFilters,
|
|
572
|
+
setFilter,
|
|
573
|
+
removeFilter,
|
|
574
|
+
getFilterValue,
|
|
575
|
+
resetFilters,
|
|
576
|
+
getBulkActionUrl,
|
|
577
|
+
sort,
|
|
578
|
+
setSort
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
function useMockPaginatedApi(data) {
|
|
582
|
+
return {
|
|
583
|
+
data,
|
|
584
|
+
pagination: {
|
|
585
|
+
total: data.length,
|
|
586
|
+
per_page: 10,
|
|
587
|
+
current_page: 1,
|
|
588
|
+
total_pages: Math.ceil(data.length / 10),
|
|
589
|
+
from: 1,
|
|
590
|
+
to: data.length
|
|
591
|
+
},
|
|
592
|
+
message: "Data fetched successfully",
|
|
593
|
+
isLoading: false,
|
|
594
|
+
isSuccess: true,
|
|
595
|
+
isFetching: false,
|
|
596
|
+
mutate: () => {
|
|
597
|
+
},
|
|
598
|
+
page: 1,
|
|
599
|
+
setPage: () => {
|
|
600
|
+
},
|
|
601
|
+
perPage: 10,
|
|
602
|
+
setPerPage: () => {
|
|
603
|
+
},
|
|
604
|
+
search: "",
|
|
605
|
+
setSearch: () => {
|
|
606
|
+
},
|
|
607
|
+
filters: [],
|
|
608
|
+
setFilters: () => {
|
|
609
|
+
},
|
|
610
|
+
getFilterValue: () => void 0,
|
|
611
|
+
resetFilters: () => {
|
|
612
|
+
},
|
|
613
|
+
setFilter: () => {
|
|
614
|
+
},
|
|
615
|
+
removeFilter: () => {
|
|
616
|
+
},
|
|
617
|
+
sort: "",
|
|
618
|
+
setSort: () => {
|
|
619
|
+
},
|
|
620
|
+
getBulkActionUrl: () => ""
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// src/utils.ts
|
|
625
|
+
function getErrorMessage(error) {
|
|
626
|
+
const err = error;
|
|
627
|
+
const apiMessage = err?.response?.data?.message;
|
|
628
|
+
if (typeof apiMessage === "string" && apiMessage.trim() !== "") {
|
|
629
|
+
return apiMessage;
|
|
630
|
+
}
|
|
631
|
+
const apiError = err?.response?.data?.error;
|
|
632
|
+
if (typeof apiError === "string" && apiError.trim() !== "") {
|
|
633
|
+
return apiError;
|
|
634
|
+
}
|
|
635
|
+
const message = err?.message;
|
|
636
|
+
if (typeof message === "string" && message.trim() !== "") {
|
|
637
|
+
return message;
|
|
638
|
+
}
|
|
639
|
+
if (error instanceof Error && error.message.trim() !== "") {
|
|
640
|
+
return error.message;
|
|
641
|
+
}
|
|
642
|
+
return "Something went wrong";
|
|
643
|
+
}
|
|
644
|
+
function getSuccessMessage(response, defaultMessage) {
|
|
645
|
+
return response?.data?.message || defaultMessage || "Success";
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// src/index.ts
|
|
649
|
+
var import_react_query3 = require("@tanstack/react-query");
|
|
650
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
651
|
+
0 && (module.exports = {
|
|
652
|
+
BaseApiClient,
|
|
653
|
+
QueryProvider,
|
|
654
|
+
getErrorMessage,
|
|
655
|
+
getQueryClient,
|
|
656
|
+
getSuccessMessage,
|
|
657
|
+
makeQueryClient,
|
|
658
|
+
useApi,
|
|
659
|
+
useApiAction,
|
|
660
|
+
useInfiniteQuery,
|
|
661
|
+
useMockPaginatedApi,
|
|
662
|
+
usePaginatedApi,
|
|
663
|
+
useQuery
|
|
664
|
+
});
|
|
665
|
+
//# sourceMappingURL=index.cjs.map
|