@harishmano/react-enterprise-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/dist/index.js ADDED
@@ -0,0 +1,696 @@
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
+ createApiClient: () => createApiClient,
34
+ createResource: () => createResource
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+
38
+ // src/createApiClient.ts
39
+ var import_axios = __toESM(require("axios"));
40
+
41
+ // src/resource.ts
42
+ var import_react_query = require("@tanstack/react-query");
43
+
44
+ // src/utils.ts
45
+ function buildQueryParams(options, defaultParams) {
46
+ var _a;
47
+ const params = { ...defaultParams };
48
+ if (!options) return params;
49
+ if (options.pagination) {
50
+ const { page, pageSize, sortBy, sortOrder } = options.pagination;
51
+ if (page !== void 0) params.page = page;
52
+ if (pageSize !== void 0) params.pageSize = pageSize;
53
+ if (sortBy) params.sortBy = sortBy;
54
+ if (sortOrder) params.sortOrder = sortOrder;
55
+ }
56
+ if (options.search) {
57
+ params.search = options.search;
58
+ if ((_a = options.searchFields) == null ? void 0 : _a.length) {
59
+ params.searchFields = options.searchFields.join(",");
60
+ }
61
+ }
62
+ if (options.filters) {
63
+ if (Array.isArray(options.filters)) {
64
+ params.filters = JSON.stringify(options.filters);
65
+ } else {
66
+ Object.assign(params, options.filters);
67
+ }
68
+ }
69
+ return params;
70
+ }
71
+ function buildQueryKey(resource, options) {
72
+ const key = [resource];
73
+ if (options == null ? void 0 : options.pagination) key.push({ pagination: options.pagination });
74
+ if (options == null ? void 0 : options.search) key.push({ search: options.search });
75
+ if (options == null ? void 0 : options.filters) key.push({ filters: serializeFilters(options.filters) });
76
+ return key;
77
+ }
78
+ function serializeFilters(filters) {
79
+ if (!filters) return "";
80
+ return JSON.stringify(filters);
81
+ }
82
+ function triggerBrowserDownload(blob, filename, mimeType) {
83
+ const resolvedBlob = mimeType && blob.type !== mimeType ? new Blob([blob], { type: mimeType }) : blob;
84
+ const url = URL.createObjectURL(resolvedBlob);
85
+ const a = document.createElement("a");
86
+ a.href = url;
87
+ a.download = filename;
88
+ document.body.appendChild(a);
89
+ a.click();
90
+ document.body.removeChild(a);
91
+ URL.revokeObjectURL(url);
92
+ }
93
+ function sleep(ms) {
94
+ return new Promise((resolve) => setTimeout(resolve, ms));
95
+ }
96
+
97
+ // src/resource.ts
98
+ function createResource(client, name, resourceOptions = {}) {
99
+ const {
100
+ path = `/${name}`,
101
+ defaultParams,
102
+ transform,
103
+ staleTime: defaultStaleTime = 1e3 * 60,
104
+ optimistic = false
105
+ } = resourceOptions;
106
+ function applyTransform(data) {
107
+ return transform ? transform(data) : data;
108
+ }
109
+ function useList(options) {
110
+ var _a;
111
+ const params = buildQueryParams(options, defaultParams);
112
+ const queryKey = buildQueryKey(name, options);
113
+ return (0, import_react_query.useQuery)({
114
+ queryKey,
115
+ queryFn: async ({ signal }) => {
116
+ const res = await client.get(path, {
117
+ params,
118
+ signal,
119
+ ...options == null ? void 0 : options.axiosConfig
120
+ });
121
+ return applyTransform(res.data);
122
+ },
123
+ staleTime: (_a = options == null ? void 0 : options.staleTime) != null ? _a : defaultStaleTime,
124
+ placeholderData: import_react_query.keepPreviousData,
125
+ enabled: options == null ? void 0 : options.enabled,
126
+ refetchInterval: options == null ? void 0 : options.refetchInterval
127
+ });
128
+ }
129
+ function useGet(id, options) {
130
+ var _a, _b;
131
+ return (0, import_react_query.useQuery)({
132
+ queryKey: [name, id],
133
+ queryFn: async ({ signal }) => {
134
+ const res = await client.get(`${path}/${id}`, {
135
+ params: buildQueryParams(options, defaultParams),
136
+ signal,
137
+ ...options == null ? void 0 : options.axiosConfig
138
+ });
139
+ return applyTransform(res.data);
140
+ },
141
+ staleTime: (_a = options == null ? void 0 : options.staleTime) != null ? _a : defaultStaleTime,
142
+ enabled: (_b = options == null ? void 0 : options.enabled) != null ? _b : !!id,
143
+ refetchInterval: options == null ? void 0 : options.refetchInterval
144
+ });
145
+ }
146
+ function usePaginatedList(pagination, options) {
147
+ var _a;
148
+ const mergedOptions = { ...options, pagination };
149
+ const params = buildQueryParams(mergedOptions, defaultParams);
150
+ const queryKey = buildQueryKey(`${name}/paginated`, mergedOptions);
151
+ return (0, import_react_query.useQuery)({
152
+ queryKey,
153
+ queryFn: async ({ signal }) => {
154
+ const res = await client.get(path, {
155
+ params,
156
+ signal,
157
+ ...options == null ? void 0 : options.axiosConfig
158
+ });
159
+ return applyTransform(res.data);
160
+ },
161
+ staleTime: (_a = options == null ? void 0 : options.staleTime) != null ? _a : defaultStaleTime,
162
+ placeholderData: import_react_query.keepPreviousData,
163
+ enabled: options == null ? void 0 : options.enabled
164
+ });
165
+ }
166
+ function useInfiniteList(options) {
167
+ var _a;
168
+ const baseParams = buildQueryParams(options, defaultParams);
169
+ return (0, import_react_query.useInfiniteQuery)({
170
+ queryKey: [...buildQueryKey(name, options), "infinite"],
171
+ queryFn: async ({ pageParam = 1, signal }) => {
172
+ var _a2;
173
+ const res = await client.get(path, {
174
+ params: { ...baseParams, page: pageParam, pageSize: (_a2 = options == null ? void 0 : options.pageSize) != null ? _a2 : 20 },
175
+ signal,
176
+ ...options == null ? void 0 : options.axiosConfig
177
+ });
178
+ return applyTransform(res.data);
179
+ },
180
+ initialPageParam: 1,
181
+ getNextPageParam: (lastPage, allPages) => Array.isArray(lastPage) && lastPage.length > 0 ? allPages.length + 1 : void 0,
182
+ staleTime: (_a = options == null ? void 0 : options.staleTime) != null ? _a : defaultStaleTime,
183
+ enabled: options == null ? void 0 : options.enabled
184
+ });
185
+ }
186
+ function useCursorList(pagination, options) {
187
+ var _a;
188
+ const baseParams = buildQueryParams(options, defaultParams);
189
+ return (0, import_react_query.useInfiniteQuery)({
190
+ queryKey: [...buildQueryKey(name, options), "cursor", pagination],
191
+ queryFn: async ({ pageParam, signal }) => {
192
+ var _a2;
193
+ const res = await client.get(path, {
194
+ params: {
195
+ ...baseParams,
196
+ cursor: pageParam != null ? pageParam : pagination == null ? void 0 : pagination.cursor,
197
+ pageSize: (_a2 = pagination == null ? void 0 : pagination.pageSize) != null ? _a2 : 20,
198
+ sortBy: pagination == null ? void 0 : pagination.sortBy,
199
+ sortOrder: pagination == null ? void 0 : pagination.sortOrder
200
+ },
201
+ signal,
202
+ ...options == null ? void 0 : options.axiosConfig
203
+ });
204
+ return applyTransform(res.data);
205
+ },
206
+ initialPageParam: null,
207
+ getNextPageParam: (lastPage) => lastPage.hasMore ? lastPage.nextCursor : void 0,
208
+ staleTime: (_a = options == null ? void 0 : options.staleTime) != null ? _a : defaultStaleTime,
209
+ enabled: options == null ? void 0 : options.enabled
210
+ });
211
+ }
212
+ function useCreate(mutationOptions) {
213
+ const qc = (0, import_react_query.useQueryClient)();
214
+ return (0, import_react_query.useMutation)({
215
+ mutationFn: async (data) => {
216
+ const res = await client.post(path, data);
217
+ return applyTransform(res.data);
218
+ },
219
+ onMutate: optimistic ? async (newItem) => {
220
+ await qc.cancelQueries({ queryKey: [name] });
221
+ const prev = qc.getQueryData([name]);
222
+ qc.setQueryData([name], (old = []) => [
223
+ ...old,
224
+ newItem
225
+ ]);
226
+ return { prev };
227
+ } : void 0,
228
+ onError: (error, variables, context) => {
229
+ var _a;
230
+ const ctx = context;
231
+ if (optimistic && (ctx == null ? void 0 : ctx.prev)) qc.setQueryData([name], ctx.prev);
232
+ (_a = mutationOptions == null ? void 0 : mutationOptions.onError) == null ? void 0 : _a.call(mutationOptions, error, variables);
233
+ },
234
+ onSuccess: (data, variables) => {
235
+ var _a;
236
+ qc.invalidateQueries({ queryKey: [name] });
237
+ (_a = mutationOptions == null ? void 0 : mutationOptions.onSuccess) == null ? void 0 : _a.call(mutationOptions, data, variables);
238
+ },
239
+ onSettled: mutationOptions == null ? void 0 : mutationOptions.onSettled
240
+ });
241
+ }
242
+ function useUpdate(mutationOptions) {
243
+ const qc = (0, import_react_query.useQueryClient)();
244
+ return (0, import_react_query.useMutation)({
245
+ mutationFn: async ({ id, data }) => {
246
+ const res = await client.put(`${path}/${id}`, data);
247
+ return applyTransform(res.data);
248
+ },
249
+ onMutate: optimistic ? async ({ id, data }) => {
250
+ await qc.cancelQueries({ queryKey: [name, id] });
251
+ const prev = qc.getQueryData([name, id]);
252
+ qc.setQueryData([name, id], (old) => ({
253
+ ...old,
254
+ ...data
255
+ }));
256
+ return { prev };
257
+ } : void 0,
258
+ onError: (error, variables, context) => {
259
+ var _a;
260
+ const ctx = context;
261
+ if (optimistic && (ctx == null ? void 0 : ctx.prev)) qc.setQueryData([name, variables.id], ctx.prev);
262
+ (_a = mutationOptions == null ? void 0 : mutationOptions.onError) == null ? void 0 : _a.call(mutationOptions, error, variables);
263
+ },
264
+ onSuccess: (data, variables) => {
265
+ var _a;
266
+ qc.invalidateQueries({ queryKey: [name] });
267
+ qc.invalidateQueries({ queryKey: [name, variables.id] });
268
+ (_a = mutationOptions == null ? void 0 : mutationOptions.onSuccess) == null ? void 0 : _a.call(mutationOptions, data, variables);
269
+ },
270
+ onSettled: mutationOptions == null ? void 0 : mutationOptions.onSettled
271
+ });
272
+ }
273
+ function usePatch(mutationOptions) {
274
+ const qc = (0, import_react_query.useQueryClient)();
275
+ return (0, import_react_query.useMutation)({
276
+ mutationFn: async ({ id, data }) => {
277
+ const res = await client.patch(`${path}/${id}`, data);
278
+ return applyTransform(res.data);
279
+ },
280
+ onMutate: optimistic ? async ({ id, data }) => {
281
+ await qc.cancelQueries({ queryKey: [name, id] });
282
+ const prev = qc.getQueryData([name, id]);
283
+ qc.setQueryData([name, id], (old) => ({
284
+ ...old,
285
+ ...data
286
+ }));
287
+ return { prev };
288
+ } : void 0,
289
+ onError: (error, variables, context) => {
290
+ var _a;
291
+ const ctx = context;
292
+ if (optimistic && (ctx == null ? void 0 : ctx.prev)) qc.setQueryData([name, variables.id], ctx.prev);
293
+ (_a = mutationOptions == null ? void 0 : mutationOptions.onError) == null ? void 0 : _a.call(mutationOptions, error, variables);
294
+ },
295
+ onSuccess: (data, variables) => {
296
+ var _a;
297
+ qc.invalidateQueries({ queryKey: [name] });
298
+ qc.invalidateQueries({ queryKey: [name, variables.id] });
299
+ (_a = mutationOptions == null ? void 0 : mutationOptions.onSuccess) == null ? void 0 : _a.call(mutationOptions, data, variables);
300
+ },
301
+ onSettled: mutationOptions == null ? void 0 : mutationOptions.onSettled
302
+ });
303
+ }
304
+ function useDelete(mutationOptions) {
305
+ const qc = (0, import_react_query.useQueryClient)();
306
+ return (0, import_react_query.useMutation)({
307
+ mutationFn: async (id) => {
308
+ await client.delete(`${path}/${id}`);
309
+ },
310
+ onMutate: optimistic ? async (id) => {
311
+ await qc.cancelQueries({ queryKey: [name] });
312
+ const prev = qc.getQueryData([name]);
313
+ qc.setQueryData(
314
+ [name],
315
+ (old = []) => old.filter((item) => item.id !== id)
316
+ );
317
+ return { prev };
318
+ } : void 0,
319
+ onError: (error, id, context) => {
320
+ var _a;
321
+ const ctx = context;
322
+ if (optimistic && (ctx == null ? void 0 : ctx.prev)) qc.setQueryData([name], ctx.prev);
323
+ (_a = mutationOptions == null ? void 0 : mutationOptions.onError) == null ? void 0 : _a.call(mutationOptions, error, id);
324
+ },
325
+ onSuccess: (_, id) => {
326
+ var _a;
327
+ qc.invalidateQueries({ queryKey: [name] });
328
+ (_a = mutationOptions == null ? void 0 : mutationOptions.onSuccess) == null ? void 0 : _a.call(mutationOptions, void 0, id);
329
+ },
330
+ onSettled: mutationOptions == null ? void 0 : mutationOptions.onSettled
331
+ });
332
+ }
333
+ function useBulkDelete(mutationOptions) {
334
+ const qc = (0, import_react_query.useQueryClient)();
335
+ return (0, import_react_query.useMutation)({
336
+ mutationFn: async (ids) => {
337
+ await client.delete(path, { data: { ids } });
338
+ },
339
+ onSuccess: (_, ids) => {
340
+ var _a;
341
+ qc.invalidateQueries({ queryKey: [name] });
342
+ (_a = mutationOptions == null ? void 0 : mutationOptions.onSuccess) == null ? void 0 : _a.call(mutationOptions, void 0, ids);
343
+ },
344
+ onError: mutationOptions == null ? void 0 : mutationOptions.onError
345
+ });
346
+ }
347
+ function useBulkUpdate(mutationOptions) {
348
+ const qc = (0, import_react_query.useQueryClient)();
349
+ return (0, import_react_query.useMutation)({
350
+ mutationFn: async ({ ids, data }) => {
351
+ const res = await client.patch(path, { ids, ...data });
352
+ return applyTransform(res.data);
353
+ },
354
+ onSuccess: (data, variables) => {
355
+ var _a;
356
+ qc.invalidateQueries({ queryKey: [name] });
357
+ (_a = mutationOptions == null ? void 0 : mutationOptions.onSuccess) == null ? void 0 : _a.call(mutationOptions, data, variables);
358
+ },
359
+ onError: mutationOptions == null ? void 0 : mutationOptions.onError
360
+ });
361
+ }
362
+ function useUpload(uploadOptions) {
363
+ const qc = (0, import_react_query.useQueryClient)();
364
+ return (0, import_react_query.useMutation)({
365
+ mutationFn: async ({ id, file, extraFields }) => {
366
+ var _a;
367
+ const formData = new FormData();
368
+ const fieldName = (_a = uploadOptions == null ? void 0 : uploadOptions.fieldName) != null ? _a : "file";
369
+ if (Array.isArray(file)) {
370
+ file.forEach((f) => formData.append(fieldName, f));
371
+ } else {
372
+ formData.append(fieldName, file);
373
+ }
374
+ const mergedExtra = { ...uploadOptions == null ? void 0 : uploadOptions.extraFields, ...extraFields };
375
+ Object.entries(mergedExtra).forEach(([k, v]) => formData.append(k, v));
376
+ const url = id ? `${path}/${id}/upload` : `${path}/upload`;
377
+ const res = await client.post(url, formData, {
378
+ headers: { "Content-Type": "multipart/form-data" },
379
+ onUploadProgress: (e) => {
380
+ if ((uploadOptions == null ? void 0 : uploadOptions.onProgress) && e.total) {
381
+ uploadOptions.onProgress(Math.round(e.loaded * 100 / e.total));
382
+ }
383
+ }
384
+ });
385
+ return applyTransform(res.data);
386
+ },
387
+ onSuccess: () => qc.invalidateQueries({ queryKey: [name] })
388
+ });
389
+ }
390
+ function useFormData(opts) {
391
+ var _a, _b;
392
+ const qc = (0, import_react_query.useQueryClient)();
393
+ const method = (_a = opts == null ? void 0 : opts.method) != null ? _a : "post";
394
+ const url = (opts == null ? void 0 : opts.id) ? `${path}/${opts.id}` : path;
395
+ return (0, import_react_query.useMutation)({
396
+ mutationFn: async (formData) => {
397
+ const res = await client[method](url, formData, {
398
+ headers: { "Content-Type": "multipart/form-data" },
399
+ onUploadProgress: (e) => {
400
+ if ((opts == null ? void 0 : opts.onProgress) && e.total) {
401
+ opts.onProgress(Math.round(e.loaded * 100 / e.total));
402
+ }
403
+ }
404
+ });
405
+ return applyTransform(res.data);
406
+ },
407
+ onSuccess: (data, variables) => {
408
+ var _a2, _b2;
409
+ qc.invalidateQueries({ queryKey: [name] });
410
+ (_b2 = (_a2 = opts == null ? void 0 : opts.mutationOptions) == null ? void 0 : _a2.onSuccess) == null ? void 0 : _b2.call(_a2, data, variables);
411
+ },
412
+ onError: (_b = opts == null ? void 0 : opts.mutationOptions) == null ? void 0 : _b.onError
413
+ });
414
+ }
415
+ function useDownload(downloadOptions) {
416
+ return (0, import_react_query.useMutation)({
417
+ mutationFn: async ({ id, params }) => {
418
+ var _a, _b;
419
+ const url = id ? `${path}/${id}/download` : `${path}/download`;
420
+ const res = await client.get(url, {
421
+ params,
422
+ responseType: "blob",
423
+ onDownloadProgress: (e) => {
424
+ if ((downloadOptions == null ? void 0 : downloadOptions.onProgress) && e.total) {
425
+ downloadOptions.onProgress(Math.round(e.loaded * 100 / e.total));
426
+ }
427
+ }
428
+ });
429
+ if ((downloadOptions == null ? void 0 : downloadOptions.saveAs) !== false) {
430
+ const filename = (_b = (_a = downloadOptions == null ? void 0 : downloadOptions.filename) != null ? _a : extractFilename(res.headers["content-disposition"])) != null ? _b : `${name}-download`;
431
+ triggerBrowserDownload(res.data, filename, downloadOptions == null ? void 0 : downloadOptions.mimeType);
432
+ }
433
+ return res.data;
434
+ }
435
+ });
436
+ }
437
+ function useExport(opts) {
438
+ return (0, import_react_query.useMutation)({
439
+ mutationFn: async (queryOptions) => {
440
+ var _a, _b, _c;
441
+ const params = buildQueryParams(queryOptions, defaultParams);
442
+ const res = await client.get(`${path}/export`, {
443
+ params: { ...params, format: (_a = opts == null ? void 0 : opts.format) != null ? _a : "csv" },
444
+ responseType: "blob",
445
+ onDownloadProgress: (e) => {
446
+ if ((opts == null ? void 0 : opts.onProgress) && e.total) {
447
+ opts.onProgress(Math.round(e.loaded * 100 / e.total));
448
+ }
449
+ }
450
+ });
451
+ const fmt = (_b = opts == null ? void 0 : opts.format) != null ? _b : "csv";
452
+ const filename = (_c = opts == null ? void 0 : opts.filename) != null ? _c : `${name}-export.${fmt}`;
453
+ const mimeMap = {
454
+ csv: "text/csv",
455
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
456
+ pdf: "application/pdf"
457
+ };
458
+ triggerBrowserDownload(res.data, filename, mimeMap[fmt]);
459
+ return res.data;
460
+ }
461
+ });
462
+ }
463
+ function useAction(action, opts) {
464
+ var _a, _b;
465
+ const qc = (0, import_react_query.useQueryClient)();
466
+ const method = (_a = opts == null ? void 0 : opts.method) != null ? _a : "post";
467
+ const url = (opts == null ? void 0 : opts.id) ? `${path}/${opts.id}/${action}` : `${path}/${action}`;
468
+ return (0, import_react_query.useMutation)({
469
+ mutationFn: async (payload) => {
470
+ const res = await client[method](url, payload);
471
+ return applyTransform(res.data);
472
+ },
473
+ onSuccess: (data, variables) => {
474
+ var _a2, _b2;
475
+ if ((opts == null ? void 0 : opts.invalidate) !== false) {
476
+ qc.invalidateQueries({ queryKey: [name] });
477
+ }
478
+ (_b2 = (_a2 = opts == null ? void 0 : opts.mutationOptions) == null ? void 0 : _a2.onSuccess) == null ? void 0 : _b2.call(_a2, data, variables);
479
+ },
480
+ onError: (_b = opts == null ? void 0 : opts.mutationOptions) == null ? void 0 : _b.onError
481
+ });
482
+ }
483
+ function useInvalidate() {
484
+ const qc = (0, import_react_query.useQueryClient)();
485
+ return (id) => {
486
+ if (id) {
487
+ qc.invalidateQueries({ queryKey: [name, id] });
488
+ } else {
489
+ qc.invalidateQueries({ queryKey: [name] });
490
+ }
491
+ };
492
+ }
493
+ function usePrefetch() {
494
+ const qc = (0, import_react_query.useQueryClient)();
495
+ return (id) => {
496
+ if (id) {
497
+ qc.prefetchQuery({
498
+ queryKey: [name, id],
499
+ queryFn: () => client.get(`${path}/${id}`).then((r) => r.data)
500
+ });
501
+ } else {
502
+ qc.prefetchQuery({
503
+ queryKey: [name],
504
+ queryFn: () => client.get(path).then((r) => r.data)
505
+ });
506
+ }
507
+ };
508
+ }
509
+ function useSetCache() {
510
+ const qc = (0, import_react_query.useQueryClient)();
511
+ return (data, id) => {
512
+ if (id) {
513
+ qc.setQueryData([name, id], data);
514
+ } else {
515
+ qc.setQueryData([name], data);
516
+ }
517
+ };
518
+ }
519
+ return {
520
+ // ── Queries ──────────────────────────────────────────────────────────
521
+ /** Full list — with filters, search, sorting, polling */
522
+ useList,
523
+ /** Single item by ID */
524
+ useGet,
525
+ /** Page-number pagination */
526
+ usePaginatedList,
527
+ /** Offset-based infinite scroll */
528
+ useInfiniteList,
529
+ /** Cursor-based infinite scroll (for DB cursor pagination) */
530
+ useCursorList,
531
+ // ── Mutations ─────────────────────────────────────────────────────────
532
+ /** Create — POST /resource */
533
+ useCreate,
534
+ /** Full replace — PUT /resource/:id */
535
+ useUpdate,
536
+ /** Partial update — PATCH /resource/:id */
537
+ usePatch,
538
+ /** Delete — DELETE /resource/:id */
539
+ useDelete,
540
+ /** Delete many — DELETE /resource { ids: [...] } */
541
+ useBulkDelete,
542
+ /** Update many — PATCH /resource { ids: [...], ...fields } */
543
+ useBulkUpdate,
544
+ // ── File Operations ───────────────────────────────────────────────────
545
+ /** Upload file(s) with progress tracking */
546
+ useUpload,
547
+ /** Submit any FormData (mixed files + fields) */
548
+ useFormData,
549
+ /** Download blob file with progress + auto "Save As" */
550
+ useDownload,
551
+ /** Export list to CSV / XLSX / PDF */
552
+ useExport,
553
+ // ── Custom Actions ────────────────────────────────────────────────────
554
+ /** Arbitrary endpoint action (e.g. /resource/:id/approve) */
555
+ useAction,
556
+ // ── Cache Utilities ───────────────────────────────────────────────────
557
+ /** Manually invalidate cache */
558
+ useInvalidate,
559
+ /** Prefetch on hover/navigation */
560
+ usePrefetch,
561
+ /** Manually write data into cache (SSR/seed) */
562
+ useSetCache,
563
+ // ── Meta ──────────────────────────────────────────────────────────────
564
+ path,
565
+ name
566
+ };
567
+ }
568
+ function extractFilename(contentDisposition) {
569
+ if (!contentDisposition) return null;
570
+ const match = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
571
+ return match ? match[1].replace(/['"]/g, "").trim() : null;
572
+ }
573
+
574
+ // src/createApiClient.ts
575
+ function createApiClient(config) {
576
+ const {
577
+ baseURL,
578
+ getToken,
579
+ onTokenRefresh,
580
+ onAuthFailure,
581
+ onError,
582
+ headers = {},
583
+ timeout = 3e4,
584
+ retry = { count: 0, delay: 1e3, statusCodes: [429, 503] }
585
+ } = config;
586
+ const client = import_axios.default.create({
587
+ baseURL,
588
+ timeout,
589
+ headers: {
590
+ "Content-Type": "application/json",
591
+ ...headers
592
+ }
593
+ });
594
+ client.interceptors.request.use(async (req) => {
595
+ const token = await (getToken == null ? void 0 : getToken());
596
+ if (token) {
597
+ req.headers.Authorization = `Bearer ${token}`;
598
+ }
599
+ return req;
600
+ });
601
+ let isRefreshing = false;
602
+ let refreshQueue = [];
603
+ function processRefreshQueue(token, error = null) {
604
+ refreshQueue.forEach(({ resolve, reject }) => {
605
+ if (token) resolve(token);
606
+ else reject(error);
607
+ });
608
+ refreshQueue = [];
609
+ }
610
+ client.interceptors.response.use(
611
+ (res) => res,
612
+ async (error) => {
613
+ var _a, _b;
614
+ const originalRequest = error.config;
615
+ if (onError) onError(error);
616
+ if (((_a = error.response) == null ? void 0 : _a.status) === 401 && originalRequest && !originalRequest._retryCount) {
617
+ if (isRefreshing) {
618
+ return new Promise((resolve, reject) => {
619
+ refreshQueue.push({ resolve, reject });
620
+ }).then((token) => {
621
+ originalRequest.headers.Authorization = `Bearer ${token}`;
622
+ return client(originalRequest);
623
+ });
624
+ }
625
+ if (onTokenRefresh) {
626
+ isRefreshing = true;
627
+ try {
628
+ const newToken = await refreshTokenRequest(config);
629
+ onTokenRefresh(newToken);
630
+ processRefreshQueue(newToken);
631
+ isRefreshing = false;
632
+ originalRequest.headers.Authorization = `Bearer ${newToken}`;
633
+ return client(originalRequest);
634
+ } catch (refreshError) {
635
+ processRefreshQueue(null, refreshError);
636
+ isRefreshing = false;
637
+ onAuthFailure == null ? void 0 : onAuthFailure();
638
+ return Promise.reject(refreshError);
639
+ }
640
+ } else {
641
+ onAuthFailure == null ? void 0 : onAuthFailure();
642
+ }
643
+ }
644
+ if (originalRequest && shouldRetry(error, retry)) {
645
+ originalRequest._retryCount = ((_b = originalRequest._retryCount) != null ? _b : 0) + 1;
646
+ if (originalRequest._retryCount <= retry.count) {
647
+ const delay = retry.delay !== void 0 ? retry.delay * originalRequest._retryCount : 1e3;
648
+ await sleep(delay);
649
+ return client(originalRequest);
650
+ }
651
+ }
652
+ return Promise.reject(error);
653
+ }
654
+ );
655
+ return {
656
+ /** Access the raw axios instance for custom requests */
657
+ axiosInstance: client,
658
+ /** Create a resource with CRUD hooks */
659
+ resource: (name, options) => createResource(client, name, options),
660
+ /** Raw GET */
661
+ get: (url, axiosConfig) => client.get(url, axiosConfig).then((r) => r.data),
662
+ /** Raw POST */
663
+ post: (url, data, axiosConfig) => client.post(url, data, axiosConfig).then((r) => r.data),
664
+ /** Raw PUT */
665
+ put: (url, data, axiosConfig) => client.put(url, data, axiosConfig).then((r) => r.data),
666
+ /** Raw PATCH */
667
+ patch: (url, data, axiosConfig) => client.patch(url, data, axiosConfig).then((r) => r.data),
668
+ /** Raw DELETE */
669
+ delete: (url, axiosConfig) => client.delete(url, axiosConfig).then((r) => r.data)
670
+ };
671
+ }
672
+ async function refreshTokenRequest(config) {
673
+ var _a, _b, _c, _d;
674
+ const currentToken = await ((_a = config.getToken) == null ? void 0 : _a.call(config));
675
+ const res = await import_axios.default.post(
676
+ `${config.baseURL}/auth/refresh`,
677
+ {},
678
+ {
679
+ headers: currentToken ? { Authorization: `Bearer ${currentToken}` } : void 0
680
+ }
681
+ );
682
+ return (_d = (_b = res.data) == null ? void 0 : _b.token) != null ? _d : (_c = res.data) == null ? void 0 : _c.accessToken;
683
+ }
684
+ function shouldRetry(error, retry) {
685
+ if (!retry.count) return false;
686
+ if (!error.response) return true;
687
+ if (retry.statusCodes && retry.statusCodes.length > 0) {
688
+ return retry.statusCodes.includes(error.response.status);
689
+ }
690
+ return false;
691
+ }
692
+ // Annotate the CommonJS export names for ESM import in node:
693
+ 0 && (module.exports = {
694
+ createApiClient,
695
+ createResource
696
+ });