@ventlio/tanstack-query 0.5.12 → 0.5.13

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.
Files changed (55) hide show
  1. package/README.md +178 -150
  2. package/dist/config/bootstrapQueryRequest.d.ts +6 -0
  3. package/dist/config/useEnvironmentVariables.d.ts +4 -0
  4. package/dist/index.mjs +306 -89
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/node_modules/@tanstack/react-store/dist/esm/index.js +1 -1
  7. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/cjs/use-sync-external-store-shim/with-selector.development.js +1 -1
  8. package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +1 -0
  9. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/cjs/use-sync-external-store-shim/with-selector.production.js +1 -1
  10. package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.js.map +1 -0
  11. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/cjs/use-sync-external-store-shim.development.js +1 -1
  12. package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +1 -0
  13. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/cjs/use-sync-external-store-shim.production.js +1 -1
  14. package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js.map +1 -0
  15. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/shim/index.js +1 -1
  16. package/dist/node_modules/use-sync-external-store/shim/index.js.map +1 -0
  17. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/shim/with-selector.js +1 -1
  18. package/dist/node_modules/use-sync-external-store/shim/with-selector.js.map +1 -0
  19. package/dist/queries/useGetRequest.d.ts +12 -2
  20. package/dist/request/make-request.d.ts +12 -1
  21. package/dist/src/config/bootstrapQueryRequest.js +41 -1
  22. package/dist/src/config/bootstrapQueryRequest.js.map +1 -1
  23. package/dist/src/config/useEnvironmentVariables.js +34 -3
  24. package/dist/src/config/useEnvironmentVariables.js.map +1 -1
  25. package/dist/src/index.js +1 -1
  26. package/dist/src/queries/useDeleteRequest.js +19 -14
  27. package/dist/src/queries/useDeleteRequest.js.map +1 -1
  28. package/dist/src/queries/useGetInfiniteRequest.js +17 -12
  29. package/dist/src/queries/useGetInfiniteRequest.js.map +1 -1
  30. package/dist/src/queries/useGetRequest.js +86 -28
  31. package/dist/src/queries/useGetRequest.js.map +1 -1
  32. package/dist/src/queries/usePatchRequest.js +19 -14
  33. package/dist/src/queries/usePatchRequest.js.map +1 -1
  34. package/dist/src/queries/usePostRequest.js +18 -13
  35. package/dist/src/queries/usePostRequest.js.map +1 -1
  36. package/dist/src/request/make-request.js +75 -6
  37. package/dist/src/request/make-request.js.map +1 -1
  38. package/dist/types/index.d.ts +24 -5
  39. package/package.json +2 -2
  40. package/src/config/bootstrapQueryRequest.ts +47 -2
  41. package/src/config/useEnvironmentVariables.ts +41 -3
  42. package/src/queries/useDeleteRequest.ts +18 -20
  43. package/src/queries/useGetInfiniteRequest.ts +17 -17
  44. package/src/queries/useGetRequest.ts +109 -33
  45. package/src/queries/usePatchRequest.ts +19 -16
  46. package/src/queries/usePostRequest.ts +18 -15
  47. package/src/queries/usePutRequest.ts +16 -15
  48. package/src/request/make-request.ts +112 -15
  49. package/src/types/index.ts +38 -4
  50. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +0 -1
  51. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.js.map +0 -1
  52. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +0 -1
  53. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js.map +0 -1
  54. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/shim/index.js.map +0 -1
  55. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/shim/with-selector.js.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import 'url-search-params-polyfill';
2
- import { create } from 'zustand';
3
2
  import require$$0, { useState, useEffect, useMemo, startTransition } from 'react';
3
+ import { create } from 'zustand';
4
4
  import { useQueryClient, useQuery, useInfiniteQuery, useMutation } from '@tanstack/react-query';
5
5
  import result from 'lodash.result';
6
6
  import lodashSet from 'lodash.set';
@@ -700,9 +700,49 @@ const bootStore = new Store({
700
700
  modelConfig: undefined,
701
701
  });
702
702
 
703
+ /**
704
+ * Bootstrap the query request system with configuration options
705
+ *
706
+ * @param queryClient - TanStack Query client instance
707
+ * @param options - Configuration options
708
+ */
703
709
  const bootstrapQueryRequest = async (queryClient, options = {}) => {
704
- // set default query config
710
+ // Resume any paused mutations
705
711
  await queryClient.resumePausedMutations();
712
+ // Set default pagination configuration if not provided
713
+ if (!options.pagination) {
714
+ options.pagination = {
715
+ pageParamName: 'page',
716
+ buildPaginationUrl: (url, page) => {
717
+ const [pathname, queryString] = url.split('?');
718
+ const queryParams = new URLSearchParams(queryString);
719
+ queryParams.set('page', String(page));
720
+ return pathname + '?' + queryParams.toString();
721
+ },
722
+ extractPagination: (response) => {
723
+ // Default pagination extraction from response
724
+ if (response.data && 'pagination' in response.data) {
725
+ return response.data.pagination;
726
+ }
727
+ return undefined;
728
+ },
729
+ };
730
+ }
731
+ // Convert legacy middleware to new format if needed
732
+ if (options.middleware && !Array.isArray(options.middleware)) {
733
+ const legacyMiddleware = options.middleware;
734
+ // Create a new middleware function that adapts the legacy format
735
+ const adaptedMiddleware = async (context, next) => {
736
+ return await legacyMiddleware((opts) => next(opts), {
737
+ baseUrl: context.baseUrl,
738
+ path: context.path,
739
+ body: context.body,
740
+ });
741
+ };
742
+ // Replace with array containing the adapted middleware
743
+ options.middleware = [adaptedMiddleware];
744
+ }
745
+ // Store the configuration
706
746
  bootStore.setState(() => options);
707
747
  };
708
748
 
@@ -719,14 +759,43 @@ const useReactNativeEnv = () => {
719
759
  return { appUrl, appTimeout, isApp };
720
760
  };
721
761
 
762
+ /**
763
+ * Hook to access environment variables across different frameworks
764
+ * Supports React (CRA), Next.js, Vite, and React Native
765
+ */
722
766
  const useEnvironmentVariables = () => {
723
767
  const { appTimeout, appUrl } = useReactNativeEnv();
724
768
  const { baseUrl } = useBaseUrlStore();
725
- const url = baseUrl ?? process.env.REACT_APP_API_URL ?? process.env.NEXT_PUBLIC_API_URL ?? appUrl;
726
- const timeout = baseUrl ?? process.env.REACT_APP_API_TIMEOUT ?? process.env.NEXT_PUBLIC_API_TIMEOUT ?? appTimeout;
769
+ const { environments } = useStore(bootStore);
770
+ // Framework environment variables detection
771
+ // Order of precedence:
772
+ // 1. Runtime baseUrl (set via useBaseUrlStore)
773
+ // 2. Bootstrap config environments
774
+ // 3. Framework-specific environment variables
775
+ // 4. React Native app URL
776
+ // Get global object to check for various environment variables
777
+ const globalObj = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : {};
778
+ // Check for Vite environment variables (without using import.meta directly)
779
+ // @ts-ignore - Access potential Vite environment variables
780
+ const viteEnv = globalObj.__VITE_ENV__ || {};
781
+ const viteApiUrl = viteEnv.VITE_API_URL;
782
+ const viteApiTimeout = viteEnv.VITE_API_TIMEOUT;
783
+ // Get URL with fallbacks
784
+ const url = baseUrl ??
785
+ environments?.appBaseUrl ??
786
+ process.env.REACT_APP_API_URL ??
787
+ process.env.NEXT_PUBLIC_API_URL ??
788
+ viteApiUrl ??
789
+ appUrl;
790
+ // Get timeout with fallbacks
791
+ const timeout = environments?.appTimeout ??
792
+ process.env.REACT_APP_API_TIMEOUT ??
793
+ process.env.NEXT_PUBLIC_API_TIMEOUT ??
794
+ viteApiTimeout ??
795
+ appTimeout;
727
796
  return {
728
797
  API_URL: url,
729
- TIMEOUT: Number(timeout),
798
+ TIMEOUT: Number(timeout) || 30000, // Default timeout of 30 seconds
730
799
  };
731
800
  };
732
801
 
@@ -1017,23 +1086,92 @@ const successTransformer = (data) => {
1017
1086
  };
1018
1087
  };
1019
1088
 
1020
- async function makeRequest({ body = {}, method = HttpMethod.GET, path, isFormData, headers = {}, baseURL, timeout, appFileConfig, onUploadProgress, }) {
1089
+ /**
1090
+ * Execute a chain of middleware functions
1091
+ */
1092
+ async function executeMiddlewareChain(middlewares, context, finalHandler) {
1093
+ // Create a chain of middleware functions
1094
+ const chain = middlewares.reduceRight((next, middleware) => {
1095
+ return (options) => {
1096
+ // Update context with new options if provided
1097
+ const updatedContext = options ? { ...context, options: { ...context.options, ...options } } : context;
1098
+ return middleware(updatedContext, next);
1099
+ };
1100
+ }, finalHandler);
1101
+ // Execute the middleware chain
1102
+ return await chain(undefined);
1103
+ }
1104
+ /**
1105
+ * Make an HTTP request with middleware support
1106
+ *
1107
+ * @param requestOptions - Request options
1108
+ * @param middlewares - Optional array of middleware functions
1109
+ */
1110
+ async function makeRequest(requestOptions, middlewares) {
1111
+ const { body = {}, method = HttpMethod.GET, path, isFormData, headers = {}, baseURL, timeout, appFileConfig, onUploadProgress, } = requestOptions;
1021
1112
  // check if file is included in mobile app environment and extract all file input to avoid
1022
1113
  // it being formatted to object using axios formData builder
1023
1114
  const isApp = appFileConfig?.isApp;
1024
1115
  const appFiles = isApp ? getAppFiles(body, appFileConfig.fileSelectors) : {};
1025
1116
  // configure body
1026
- body = (isFormData ? axios.toFormData(body) : body);
1027
- // configure request header1
1028
- configureRequestHeader(isFormData, headers, isApp, appFiles, body);
1117
+ const processedBody = (isFormData ? axios.toFormData(body) : body);
1118
+ // configure request header
1119
+ configureRequestHeader(isFormData, headers, isApp, appFiles, processedBody);
1120
+ // Create the final handler that makes the actual request
1121
+ const finalHandler = async (options) => {
1122
+ const finalRequestOptions = options
1123
+ ? {
1124
+ ...requestOptions,
1125
+ body: processedBody,
1126
+ ...options,
1127
+ }
1128
+ : {
1129
+ ...requestOptions,
1130
+ body: processedBody,
1131
+ };
1132
+ return await performRequest(finalRequestOptions);
1133
+ };
1134
+ // If middleware is available, execute the middleware chain
1135
+ if (middlewares && middlewares.length > 0) {
1136
+ const context = {
1137
+ baseUrl: baseURL,
1138
+ path,
1139
+ body: body,
1140
+ method,
1141
+ headers,
1142
+ options: {
1143
+ baseURL,
1144
+ timeout,
1145
+ path,
1146
+ body: processedBody,
1147
+ method,
1148
+ isFormData,
1149
+ headers,
1150
+ appFileConfig,
1151
+ onUploadProgress,
1152
+ },
1153
+ };
1154
+ return await executeMiddlewareChain(middlewares, context, finalHandler);
1155
+ }
1156
+ // Otherwise, just make the request directly
1157
+ return await finalHandler(undefined);
1158
+ }
1159
+ /**
1160
+ * Perform the actual HTTP request
1161
+ */
1162
+ async function performRequest({ body, method, path, isFormData, headers, baseURL, timeout, appFileConfig, onUploadProgress, }) {
1029
1163
  try {
1030
1164
  const axiosRequest = axiosInstance({ baseURL, headers, timeout });
1165
+ const isApp = appFileConfig?.isApp;
1031
1166
  const axiosRequestConfig = {
1032
1167
  url: path,
1033
1168
  method,
1034
1169
  onUploadProgress,
1035
1170
  };
1036
- if (Object.keys(body).length > 0 || (isFormData && !isApp && [...body.keys()].length > 0)) {
1171
+ // Check if body exists and is not null
1172
+ if (body &&
1173
+ ((typeof body === 'object' && Object.keys(body).length > 0) ||
1174
+ (isFormData && !isApp && body instanceof FormData && Array.from(body.keys()).length > 0))) {
1037
1175
  axiosRequestConfig.data = body;
1038
1176
  }
1039
1177
  // send request
@@ -1103,7 +1241,8 @@ const useDeleteRequest = (deleteOptions) => {
1103
1241
  const { baseUrl, headers } = deleteOptions ?? {};
1104
1242
  const [requestPath, setRequestPath] = useState('');
1105
1243
  const [options, setOptions] = useState();
1106
- const { middleware } = useStore(bootStore);
1244
+ // const { middleware: middlewares } = useStore(bootStore);
1245
+ // const [middleware] = middlewares as unknown as MiddlewareFunction[];
1107
1246
  const [requestPayload, setRequestPayload] = useState();
1108
1247
  const isFutureQueriesPaused = usePauseFutureRequests((state) => state.isFutureQueriesPaused);
1109
1248
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
@@ -1118,17 +1257,22 @@ const useDeleteRequest = (deleteOptions) => {
1118
1257
  method: HttpMethod.DELETE,
1119
1258
  timeout: TIMEOUT,
1120
1259
  };
1121
- let deleteResponse;
1122
- if (middleware) {
1123
- // perform global middleware
1124
- deleteResponse = await middleware(async (middlewareOptions) => await makeRequest(middlewareOptions ? { ...requestOptions, ...middlewareOptions } : requestOptions), {
1125
- path: requestUrl,
1126
- baseUrl: baseUrl ?? API_URL,
1127
- });
1128
- }
1129
- else {
1130
- deleteResponse = await makeRequest(requestOptions);
1131
- }
1260
+ // let deleteResponse: IRequestError | IRequestSuccess<TResponse>;
1261
+ // if (middleware) {
1262
+ // // perform global middleware
1263
+ // deleteResponse = await middleware(
1264
+ // async (middlewareOptions) =>
1265
+ // await makeRequest<TResponse>(
1266
+ // middlewareOptions ? { ...requestOptions, ...middlewareOptions } : requestOptions
1267
+ // ),
1268
+ // {
1269
+ // path: requestUrl,
1270
+ // baseUrl: baseUrl ?? API_URL,
1271
+ // }
1272
+ // );
1273
+ // } else {
1274
+ const deleteResponse = await makeRequest(requestOptions);
1275
+ // }
1132
1276
  if (deleteResponse.status) {
1133
1277
  res(deleteResponse);
1134
1278
  }
@@ -1178,7 +1322,7 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
1178
1322
  const globalHeaders = useHeaderStore((state) => state.headers);
1179
1323
  const [requestPath, setRequestPath] = useState(path);
1180
1324
  const [options, setOptions] = useState(queryOptions);
1181
- const { middleware } = useStore(bootStore);
1325
+ useStore(bootStore);
1182
1326
  const [requestPayload, setRequestPayload] = useState();
1183
1327
  const isFutureQueriesPaused = usePauseFutureRequests((state) => state.isFutureQueriesPaused);
1184
1328
  let queryClient = useQueryClient();
@@ -1193,17 +1337,22 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
1193
1337
  baseURL: baseUrl ?? API_URL,
1194
1338
  timeout: TIMEOUT,
1195
1339
  };
1196
- let getResponse;
1197
- if (middleware) {
1198
- // perform global middleware
1199
- getResponse = await middleware(async (middlewareOptions) => await makeRequest(middlewareOptions ? { ...requestOptions, ...middlewareOptions } : requestOptions), {
1200
- path,
1201
- baseUrl: baseUrl ?? API_URL,
1202
- });
1203
- }
1204
- else {
1205
- getResponse = await makeRequest(requestOptions);
1206
- }
1340
+ // let getResponse: IRequestError | IRequestSuccess<TResponse>;
1341
+ // if (middleware) {
1342
+ // // perform global middleware
1343
+ // getResponse = await middleware(
1344
+ // async (middlewareOptions) =>
1345
+ // await makeRequest<TResponse>(
1346
+ // middlewareOptions ? { ...requestOptions, ...middlewareOptions } : requestOptions
1347
+ // ),
1348
+ // {
1349
+ // path,
1350
+ // baseUrl: baseUrl ?? API_URL,
1351
+ // }
1352
+ // );
1353
+ // } else {
1354
+ const getResponse = await makeRequest(requestOptions);
1355
+ // }
1207
1356
  if (getResponse.status) {
1208
1357
  res(getResponse);
1209
1358
  }
@@ -1278,18 +1427,26 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
1278
1427
  };
1279
1428
  };
1280
1429
 
1281
- const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
1430
+ /**
1431
+ * Hook for making GET requests with pagination support
1432
+ */
1433
+ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, paginationConfig, }) => {
1282
1434
  const [requestPath, setRequestPath] = useState(path);
1283
1435
  const [options, setOptions] = useState(queryOptions);
1284
1436
  const [page, setPage] = useState(1);
1285
1437
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
1286
- const { middleware } = useStore(bootStore);
1438
+ const { middleware, pagination: globalPaginationConfig } = useStore(bootStore);
1287
1439
  const globalHeaders = useHeaderStore((state) => state.headers);
1288
1440
  const [requestPayload, setRequestPayload] = useState();
1289
1441
  const isFutureQueriesPaused = usePauseFutureRequests((state) => state.isFutureQueriesPaused);
1290
1442
  let queryClient = useQueryClient();
1291
1443
  // eslint-disable-next-line react-hooks/exhaustive-deps
1292
1444
  queryClient = useMemo(() => queryClient, []);
1445
+ // Merge global and local pagination config
1446
+ const pagination = useMemo(() => ({
1447
+ ...globalPaginationConfig,
1448
+ ...paginationConfig,
1449
+ }), [globalPaginationConfig, paginationConfig]);
1293
1450
  const sendRequest = async (res, rej, queryKey) => {
1294
1451
  const [url] = queryKey;
1295
1452
  const requestUrl = (url ?? requestPath);
@@ -1299,15 +1456,23 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
1299
1456
  baseURL: baseUrl ?? API_URL,
1300
1457
  timeout: TIMEOUT,
1301
1458
  };
1459
+ // Create the final handler that makes the actual request
1460
+ const finalHandler = async (options) => {
1461
+ const finalOptions = options ? { ...requestOptions, ...options } : requestOptions;
1462
+ return await makeRequest(finalOptions);
1463
+ };
1302
1464
  let getResponse;
1303
- if (middleware) {
1304
- // perform global middleware
1305
- getResponse = await middleware(async (middlewareOptions) => await makeRequest(middlewareOptions ? { ...requestOptions, ...middlewareOptions } : requestOptions), {
1306
- path,
1465
+ // If middleware is available, execute the middleware chain
1466
+ if (middleware && Array.isArray(middleware) && middleware.length > 0) {
1467
+ const context = {
1307
1468
  baseUrl: baseUrl ?? API_URL,
1308
- });
1469
+ path: requestUrl,
1470
+ options: requestOptions,
1471
+ };
1472
+ getResponse = await executeMiddlewareChain(middleware, context, finalHandler);
1309
1473
  }
1310
1474
  else {
1475
+ // Otherwise, just make the request directly
1311
1476
  getResponse = await makeRequest(requestOptions);
1312
1477
  }
1313
1478
  if (getResponse.status) {
@@ -1337,34 +1502,72 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
1337
1502
  queryClient.setQueryData([keyTracker], [requestPath, {}]);
1338
1503
  }
1339
1504
  }, [keyTracker, requestPath, queryClient, queryOptions?.staleTime]);
1505
+ /**
1506
+ * Extract pagination data from response using configured extractor
1507
+ */
1508
+ const getPaginationData = (response) => {
1509
+ // Use the configured pagination extractor or fall back to default
1510
+ const extractPagination = pagination.extractPagination ||
1511
+ ((res) => {
1512
+ if ('pagination' in res.data) {
1513
+ return res.data.pagination;
1514
+ }
1515
+ return undefined;
1516
+ });
1517
+ return extractPagination(response);
1518
+ };
1519
+ /**
1520
+ * Navigate to the next page if available
1521
+ */
1340
1522
  const nextPage = () => {
1341
- if (query.data.data.pagination) {
1342
- const pagination = query.data.data.pagination;
1343
- if (pagination.next_page !== pagination.current_page && pagination.next_page > pagination.current_page) {
1344
- setRequestPath(constructPaginationLink(requestPath, pagination.next_page));
1345
- }
1523
+ // The linter thinks query.data is always falsy, but we know it can be defined after a successful query
1524
+ // Let's restructure to avoid the conditional
1525
+ const paginationData = query.data && getPaginationData(query.data);
1526
+ if (!paginationData)
1527
+ return;
1528
+ if (paginationData.next_page !== paginationData.current_page &&
1529
+ paginationData.next_page > paginationData.current_page) {
1530
+ setRequestPath(constructPaginationLink(requestPath, paginationData.next_page));
1346
1531
  }
1347
1532
  };
1533
+ /**
1534
+ * Navigate to the previous page if available
1535
+ */
1348
1536
  const prevPage = () => {
1349
- if (query.data.data.pagination) {
1350
- const pagination = query.data.data.pagination;
1351
- if (pagination.previous_page !== pagination.current_page && pagination.previous_page < pagination.current_page) {
1352
- setRequestPath(constructPaginationLink(requestPath, pagination.previous_page));
1353
- }
1537
+ // The linter thinks query.data is always falsy, but we know it can be defined after a successful query
1538
+ // Let's restructure to avoid the conditional
1539
+ const paginationData = query.data && getPaginationData(query.data);
1540
+ if (!paginationData)
1541
+ return;
1542
+ if (paginationData.previous_page !== paginationData.current_page &&
1543
+ paginationData.previous_page < paginationData.current_page) {
1544
+ setRequestPath(constructPaginationLink(requestPath, paginationData.previous_page));
1354
1545
  }
1355
1546
  };
1547
+ /**
1548
+ * Construct a pagination URL using the configured builder
1549
+ */
1356
1550
  const constructPaginationLink = (link, pageNumber) => {
1357
- const [pathname, queryString] = link.split('?');
1358
- const queryParams = new URLSearchParams(queryString);
1359
- const oldPage = Number(queryParams.get('page'));
1360
- queryParams.set('page', pageNumber);
1361
- link = pathname + '?' + queryParams.toString();
1362
- // only update page when pagination number changed
1363
- if (oldPage !== pageNumber) {
1364
- setPage(pageNumber);
1365
- }
1366
- return link;
1551
+ // Use the configured pagination URL builder or fall back to default
1552
+ const buildPaginationUrl = pagination.buildPaginationUrl ||
1553
+ ((url, page) => {
1554
+ const [pathname, queryString] = url.split('?');
1555
+ const queryParams = new URLSearchParams(queryString || '');
1556
+ const pageParamName = pagination.pageParamName || 'page';
1557
+ const oldPage = Number(queryParams.get(pageParamName));
1558
+ queryParams.set(pageParamName, String(page));
1559
+ const newUrl = pathname + '?' + queryParams.toString();
1560
+ // only update page when pagination number changed
1561
+ if (oldPage !== pageNumber) {
1562
+ setPage(pageNumber);
1563
+ }
1564
+ return newUrl;
1565
+ });
1566
+ return buildPaginationUrl(link, pageNumber);
1367
1567
  };
1568
+ /**
1569
+ * Navigate to a specific page
1570
+ */
1368
1571
  const gotoPage = (pageNumber) => {
1369
1572
  setRequestPath(constructPaginationLink(requestPath, pageNumber));
1370
1573
  };
@@ -1406,6 +1609,10 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
1406
1609
  gotoPage,
1407
1610
  page,
1408
1611
  queryKey: [requestPath, {}],
1612
+ // Add pagination data accessor - restructured to avoid linter error
1613
+ getPaginationData: function () {
1614
+ return query.data ? getPaginationData(query.data) : undefined;
1615
+ },
1409
1616
  };
1410
1617
  };
1411
1618
 
@@ -1415,7 +1622,7 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
1415
1622
  const globalHeaders = useHeaderStore((state) => state.headers);
1416
1623
  const [requestPayload, setRequestPayload] = useState();
1417
1624
  const isFutureMutationsPaused = usePauseFutureRequests((state) => state.isFutureMutationsPaused);
1418
- const { middleware, context } = useStore(bootStore);
1625
+ const { context } = useStore(bootStore);
1419
1626
  const sendRequest = async (res, rej, data) => {
1420
1627
  // get request headers
1421
1628
  const requestOptions = {
@@ -1427,19 +1634,24 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
1427
1634
  timeout: TIMEOUT,
1428
1635
  onUploadProgress,
1429
1636
  };
1430
- let patchResponse;
1431
- if (middleware) {
1432
- // perform global middleware
1433
- const middlewareResponse = await middleware(async (options) => await makeRequest(options ? { ...requestOptions, ...options } : requestOptions), {
1434
- path,
1435
- baseUrl: baseUrl ?? API_URL,
1436
- body: data,
1437
- });
1438
- patchResponse = middlewareResponse;
1439
- }
1440
- else {
1441
- patchResponse = await makeRequest(requestOptions);
1442
- }
1637
+ // let patchResponse: IRequestError | IRequestSuccess<TResponse>;
1638
+ // if (middleware) {
1639
+ // // perform global middleware
1640
+ // const middlewareResponse = await middleware(
1641
+ // async (options) =>
1642
+ // await makeRequest<TResponse>(
1643
+ // options ? { ...requestOptions, ...options } : requestOptions
1644
+ // ),
1645
+ // {
1646
+ // path,
1647
+ // baseUrl: baseUrl ?? API_URL,
1648
+ // body: data,
1649
+ // }
1650
+ // );
1651
+ // patchResponse = middlewareResponse;
1652
+ // } else {
1653
+ const patchResponse = await makeRequest(requestOptions);
1654
+ // }
1443
1655
  if (patchResponse.status) {
1444
1656
  // scroll to top after success
1445
1657
  if (context !== 'app') {
@@ -1483,7 +1695,7 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
1483
1695
 
1484
1696
  const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelectors, }) => {
1485
1697
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
1486
- const { middleware, context } = useStore(bootStore);
1698
+ const { context } = useStore(bootStore);
1487
1699
  const globalHeaders = useHeaderStore((state) => state.headers);
1488
1700
  const { isApp } = useReactNativeEnv();
1489
1701
  const { uploadProgressPercent, onUploadProgress } = useUploadProgress();
@@ -1508,18 +1720,23 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
1508
1720
  onUploadProgress,
1509
1721
  ...requestConfig,
1510
1722
  };
1511
- let postResponse;
1512
- if (middleware) {
1513
- // perform global middleware
1514
- postResponse = await middleware(async (options) => await makeRequest(options ? { ...requestOptions, ...options } : requestOptions), {
1515
- path,
1516
- baseUrl: baseUrl ?? API_URL,
1517
- body: data,
1518
- });
1519
- }
1520
- else {
1521
- postResponse = await makeRequest(requestOptions);
1522
- }
1723
+ // let postResponse: IRequestError | IRequestSuccess<TResponse>;
1724
+ // if (middleware) {
1725
+ // // perform global middleware
1726
+ // postResponse = await middleware(
1727
+ // async (options) =>
1728
+ // await makeRequest<TResponse>(
1729
+ // options ? { ...requestOptions, ...options } : requestOptions
1730
+ // ),
1731
+ // {
1732
+ // path,
1733
+ // baseUrl: baseUrl ?? API_URL,
1734
+ // body: data,
1735
+ // }
1736
+ // );
1737
+ // } else {
1738
+ const postResponse = await makeRequest(requestOptions);
1739
+ // }
1523
1740
  if (postResponse.status) {
1524
1741
  // scroll to top after success
1525
1742
  if (context !== 'app') {
@@ -1560,5 +1777,5 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
1560
1777
  return { post, uploadProgressPercent, ...mutation, isLoading: mutation.isPending || isFutureMutationsPaused };
1561
1778
  };
1562
1779
 
1563
- export { ContentType, HttpMethod, axiosInstance, bootstrapQueryRequest, buildFormData, errorTransformer, getDateInFuture, makeRequest, scrollToTop, successTransformer, useBaseUrlStore, useDeleteRequest, useEnvironmentVariables, useGetInfiniteRequest, useGetRequest, useHeaderStore, useKeyTrackerModel, usePatchRequest, usePauseFutureRequests, usePostRequest, useQueryHeaders, useQueryModel, useReactNativeEnv, useRefetchQuery, useUploadProgress };
1780
+ export { ContentType, HttpMethod, axiosInstance, bootstrapQueryRequest, buildFormData, errorTransformer, executeMiddlewareChain, getDateInFuture, makeRequest, scrollToTop, successTransformer, useBaseUrlStore, useDeleteRequest, useEnvironmentVariables, useGetInfiniteRequest, useGetRequest, useHeaderStore, useKeyTrackerModel, usePatchRequest, usePauseFutureRequests, usePostRequest, useQueryHeaders, useQueryModel, useReactNativeEnv, useRefetchQuery, useUploadProgress };
1564
1781
  //# sourceMappingURL=index.mjs.map