@ventlio/tanstack-query 0.5.12 → 0.5.14
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/config/bootstrapQueryRequest.d.ts +6 -0
- package/dist/config/useEnvironmentVariables.d.ts +4 -0
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/result.d.ts +23 -0
- package/dist/index.mjs +368 -95
- package/dist/index.mjs.map +1 -1
- package/dist/node_modules/@tanstack/react-store/dist/esm/index.js +1 -1
- 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
- package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +1 -0
- 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
- package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.js.map +1 -0
- 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
- package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +1 -0
- 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
- package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js.map +1 -0
- package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/shim/index.js +1 -1
- package/dist/node_modules/use-sync-external-store/shim/index.js.map +1 -0
- package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/shim/with-selector.js +1 -1
- package/dist/node_modules/use-sync-external-store/shim/with-selector.js.map +1 -0
- package/dist/queries/useGetRequest.d.ts +12 -2
- package/dist/request/make-request.d.ts +12 -1
- package/dist/src/config/bootstrapQueryRequest.js +41 -1
- package/dist/src/config/bootstrapQueryRequest.js.map +1 -1
- package/dist/src/config/useEnvironmentVariables.js +35 -4
- package/dist/src/config/useEnvironmentVariables.js.map +1 -1
- package/dist/src/helpers/result.js +59 -0
- package/dist/src/helpers/result.js.map +1 -0
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/model/useQueryModel.js +1 -1
- package/dist/src/queries/useDeleteRequest.js +19 -14
- package/dist/src/queries/useDeleteRequest.js.map +1 -1
- package/dist/src/queries/useGetInfiniteRequest.js +17 -12
- package/dist/src/queries/useGetInfiniteRequest.js.map +1 -1
- package/dist/src/queries/useGetRequest.js +86 -28
- package/dist/src/queries/useGetRequest.js.map +1 -1
- package/dist/src/queries/usePatchRequest.js +19 -14
- package/dist/src/queries/usePatchRequest.js.map +1 -1
- package/dist/src/queries/usePostRequest.js +18 -13
- package/dist/src/queries/usePostRequest.js.map +1 -1
- package/dist/src/request/make-request.js +75 -6
- package/dist/src/request/make-request.js.map +1 -1
- package/dist/types/index.d.ts +24 -5
- package/package.json +2 -4
- package/src/config/bootstrapQueryRequest.ts +47 -2
- package/src/config/useEnvironmentVariables.ts +42 -4
- package/src/helpers/index.ts +1 -0
- package/src/helpers/result.ts +65 -0
- package/src/model/useQueryModel.ts +2 -2
- package/src/queries/useDeleteRequest.ts +18 -20
- package/src/queries/useGetInfiniteRequest.ts +17 -17
- package/src/queries/useGetRequest.ts +109 -33
- package/src/queries/usePatchRequest.ts +19 -16
- package/src/queries/usePostRequest.ts +18 -15
- package/src/queries/usePutRequest.ts +16 -15
- package/src/request/make-request.ts +112 -15
- package/src/types/index.ts +38 -4
- 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
- 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
- package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +0 -1
- package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js.map +0 -1
- package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/shim/index.js.map +0 -1
- package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/shim/with-selector.js.map +0 -1
|
@@ -1,15 +1,53 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useStore } from '@tanstack/react-store';
|
|
2
|
+
import { bootStore } from './bootStore';
|
|
2
3
|
import type { IConfig } from './config.interface';
|
|
3
4
|
import { useReactNativeEnv } from './useReactNativeEnv';
|
|
5
|
+
import { useBaseUrlStore } from '../stores/useBaseUrlStore';
|
|
4
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Hook to access environment variables across different frameworks
|
|
9
|
+
* Supports React (CRA), Next.js, Vite, and React Native
|
|
10
|
+
*/
|
|
5
11
|
export const useEnvironmentVariables = (): IConfig => {
|
|
6
12
|
const { appTimeout, appUrl } = useReactNativeEnv();
|
|
7
13
|
const { baseUrl } = useBaseUrlStore();
|
|
8
|
-
const
|
|
9
|
-
|
|
14
|
+
const { environments } = useStore(bootStore);
|
|
15
|
+
|
|
16
|
+
// Framework environment variables detection
|
|
17
|
+
// Order of precedence:
|
|
18
|
+
// 1. Runtime baseUrl (set via useBaseUrlStore)
|
|
19
|
+
// 2. Bootstrap config environments
|
|
20
|
+
// 3. Framework-specific environment variables
|
|
21
|
+
// 4. React Native app URL
|
|
22
|
+
|
|
23
|
+
// Get global object to check for various environment variables
|
|
24
|
+
const globalObj = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : {};
|
|
25
|
+
|
|
26
|
+
// Check for Vite environment variables (without using import.meta directly)
|
|
27
|
+
// @ts-ignore - Access potential Vite environment variables
|
|
28
|
+
const viteEnv = globalObj.__VITE_ENV__ || {};
|
|
29
|
+
const viteApiUrl = viteEnv.VITE_API_URL;
|
|
30
|
+
const viteApiTimeout = viteEnv.VITE_API_TIMEOUT;
|
|
31
|
+
|
|
32
|
+
// Get URL with fallbacks
|
|
33
|
+
const url =
|
|
34
|
+
baseUrl ??
|
|
35
|
+
environments?.appBaseUrl ??
|
|
36
|
+
process.env.REACT_APP_API_URL ??
|
|
37
|
+
process.env.NEXT_PUBLIC_API_URL ??
|
|
38
|
+
viteApiUrl ??
|
|
39
|
+
appUrl;
|
|
40
|
+
|
|
41
|
+
// Get timeout with fallbacks
|
|
42
|
+
const timeout =
|
|
43
|
+
environments?.appTimeout ??
|
|
44
|
+
process.env.REACT_APP_API_TIMEOUT ??
|
|
45
|
+
process.env.NEXT_PUBLIC_API_TIMEOUT ??
|
|
46
|
+
viteApiTimeout ??
|
|
47
|
+
appTimeout;
|
|
10
48
|
|
|
11
49
|
return {
|
|
12
50
|
API_URL: url as string,
|
|
13
|
-
TIMEOUT: Number(timeout),
|
|
51
|
+
TIMEOUT: Number(timeout) || 30000, // Default timeout of 30 seconds
|
|
14
52
|
};
|
|
15
53
|
};
|
package/src/helpers/index.ts
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gets the value at path of object. If the resolved value is a function,
|
|
3
|
+
* it's invoked with the this binding of its parent object and its result is returned.
|
|
4
|
+
* Similar to lodash.result functionality.
|
|
5
|
+
*
|
|
6
|
+
* @param object - The object to query
|
|
7
|
+
* @param path - The path of the property to get (supports dot notation)
|
|
8
|
+
* @param defaultValue - The value returned if the resolved value is undefined
|
|
9
|
+
* @returns The resolved value
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const obj = { a: { b: { c: 'value' } } };
|
|
13
|
+
* result(obj, 'a.b.c'); // => 'value'
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const obj = { a: { b: () => 'computed' } };
|
|
17
|
+
* result(obj, 'a.b'); // => 'computed'
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* result({}, 'a.b.c', 'default'); // => 'default'
|
|
21
|
+
*/
|
|
22
|
+
export function result<T = any>(object: any, path: string | string[], defaultValue?: T): T | undefined {
|
|
23
|
+
if (object == null) {
|
|
24
|
+
return defaultValue;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Convert path to array if it's a string
|
|
28
|
+
const pathArray = Array.isArray(path)
|
|
29
|
+
? path
|
|
30
|
+
: path
|
|
31
|
+
.split('.')
|
|
32
|
+
.flatMap((part) => part.split('[').flatMap((p) => p.split(']')))
|
|
33
|
+
.filter(Boolean);
|
|
34
|
+
|
|
35
|
+
let current = object;
|
|
36
|
+
let parent = object;
|
|
37
|
+
|
|
38
|
+
// Traverse the path
|
|
39
|
+
for (let i = 0; i < pathArray.length; i++) {
|
|
40
|
+
if (current == null) {
|
|
41
|
+
return defaultValue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
parent = current;
|
|
45
|
+
const key = pathArray[i];
|
|
46
|
+
if (key === undefined) {
|
|
47
|
+
return defaultValue;
|
|
48
|
+
}
|
|
49
|
+
current = current[key];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// If the final value is undefined, return the default value
|
|
53
|
+
if (current === undefined) {
|
|
54
|
+
return defaultValue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// If the value is a function, invoke it with the parent object as context
|
|
58
|
+
if (typeof current === 'function') {
|
|
59
|
+
return current.call(parent) as T;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return current as T;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default result;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useQueryClient } from '@tanstack/react-query';
|
|
2
2
|
import { useStore } from '@tanstack/react-store';
|
|
3
|
-
import result from 'lodash.result';
|
|
4
3
|
import { default as lodashSet } from 'lodash.set';
|
|
5
4
|
import { bootStore } from '../config/bootStore';
|
|
5
|
+
import { result } from '../helpers';
|
|
6
6
|
import type { QueryModelAddPosition, QueryModelBuilder } from './model.interface';
|
|
7
7
|
import { useKeyTrackerModel } from './useKeyTrackerModel';
|
|
8
8
|
|
|
@@ -40,7 +40,7 @@ export const useQueryModel = <T>(keyTracker: string): QueryModelBuilder<T> => {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
if (!path) {
|
|
43
|
-
return Array.isArray(data) ? data : [data];
|
|
43
|
+
return Array.isArray(data) ? data : [data as any];
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
return result<T[]>(data, path, []);
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { QueryKey, UseQueryOptions } from '@tanstack/react-query';
|
|
2
2
|
import { useQuery } from '@tanstack/react-query';
|
|
3
|
-
import { useStore } from '@tanstack/react-store';
|
|
4
3
|
import { useEffect, useState } from 'react';
|
|
5
4
|
import { useEnvironmentVariables } from '../config';
|
|
6
|
-
import { bootStore } from '../config/bootStore';
|
|
7
5
|
import type { IRequestError, IRequestSuccess } from '../request';
|
|
8
6
|
import { HttpMethod, makeRequest } from '../request';
|
|
9
7
|
import { useHeaderStore, usePauseFutureRequests } from '../stores';
|
|
@@ -14,8 +12,8 @@ export const useDeleteRequest = <TResponse>(deleteOptions?: DefaultRequestOption
|
|
|
14
12
|
const [requestPath, setRequestPath] = useState<string>('');
|
|
15
13
|
const [options, setOptions] = useState<any>();
|
|
16
14
|
|
|
17
|
-
const { middleware } = useStore(bootStore);
|
|
18
|
-
|
|
15
|
+
// const { middleware: middlewares } = useStore(bootStore);
|
|
16
|
+
// const [middleware] = middlewares as unknown as MiddlewareFunction[];
|
|
19
17
|
const [requestPayload, setRequestPayload] = useState<Record<any, any>>();
|
|
20
18
|
|
|
21
19
|
const isFutureQueriesPaused = usePauseFutureRequests((state) => state.isFutureQueriesPaused);
|
|
@@ -36,22 +34,22 @@ export const useDeleteRequest = <TResponse>(deleteOptions?: DefaultRequestOption
|
|
|
36
34
|
timeout: TIMEOUT,
|
|
37
35
|
};
|
|
38
36
|
|
|
39
|
-
let deleteResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
40
|
-
if (middleware) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
} else {
|
|
53
|
-
|
|
54
|
-
}
|
|
37
|
+
// let deleteResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
38
|
+
// if (middleware) {
|
|
39
|
+
// // perform global middleware
|
|
40
|
+
// deleteResponse = await middleware(
|
|
41
|
+
// async (middlewareOptions) =>
|
|
42
|
+
// await makeRequest<TResponse>(
|
|
43
|
+
// middlewareOptions ? { ...requestOptions, ...middlewareOptions } : requestOptions
|
|
44
|
+
// ),
|
|
45
|
+
// {
|
|
46
|
+
// path: requestUrl,
|
|
47
|
+
// baseUrl: baseUrl ?? API_URL,
|
|
48
|
+
// }
|
|
49
|
+
// );
|
|
50
|
+
// } else {
|
|
51
|
+
const deleteResponse = await makeRequest<TResponse>(requestOptions);
|
|
52
|
+
// }
|
|
55
53
|
|
|
56
54
|
if (deleteResponse.status) {
|
|
57
55
|
res(deleteResponse as IRequestSuccess<TResponse>);
|
|
@@ -37,7 +37,7 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
|
|
|
37
37
|
const [requestPath, setRequestPath] = useState<string>(path);
|
|
38
38
|
|
|
39
39
|
const [options, setOptions] = useState<any>(queryOptions);
|
|
40
|
-
|
|
40
|
+
useStore(bootStore);
|
|
41
41
|
|
|
42
42
|
const [requestPayload, setRequestPayload] = useState<Record<any, any>>();
|
|
43
43
|
|
|
@@ -68,22 +68,22 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
|
|
|
68
68
|
timeout: TIMEOUT,
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
-
let getResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
72
|
-
if (middleware) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
} else {
|
|
85
|
-
|
|
86
|
-
}
|
|
71
|
+
// let getResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
72
|
+
// if (middleware) {
|
|
73
|
+
// // perform global middleware
|
|
74
|
+
// getResponse = await middleware(
|
|
75
|
+
// async (middlewareOptions) =>
|
|
76
|
+
// await makeRequest<TResponse>(
|
|
77
|
+
// middlewareOptions ? { ...requestOptions, ...middlewareOptions } : requestOptions
|
|
78
|
+
// ),
|
|
79
|
+
// {
|
|
80
|
+
// path,
|
|
81
|
+
// baseUrl: baseUrl ?? API_URL,
|
|
82
|
+
// }
|
|
83
|
+
// );
|
|
84
|
+
// } else {
|
|
85
|
+
const getResponse = await makeRequest<TResponse>(requestOptions);
|
|
86
|
+
// }
|
|
87
87
|
|
|
88
88
|
if (getResponse.status) {
|
|
89
89
|
res(getResponse as IRequestSuccess<TResponse & { pagination: Pagination }>);
|
|
@@ -5,9 +5,14 @@ import { useEnvironmentVariables } from '../config';
|
|
|
5
5
|
import { useStore } from '@tanstack/react-store';
|
|
6
6
|
import { bootStore } from '../config/bootStore';
|
|
7
7
|
import { IRequestError, IRequestSuccess, makeRequest } from '../request';
|
|
8
|
+
import { executeMiddlewareChain } from '../request/make-request';
|
|
8
9
|
import { useHeaderStore, usePauseFutureRequests } from '../stores';
|
|
10
|
+
import type { MiddlewareContext, MiddlewareNext } from '../types';
|
|
9
11
|
import { DefaultRequestOptions, IPagination, TanstackQueryOption } from './queries.interface';
|
|
10
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Hook for making GET requests with pagination support
|
|
15
|
+
*/
|
|
11
16
|
export const useGetRequest = <TResponse extends Record<string, any>>({
|
|
12
17
|
path,
|
|
13
18
|
load = false,
|
|
@@ -15,18 +20,24 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
|
|
|
15
20
|
keyTracker,
|
|
16
21
|
baseUrl,
|
|
17
22
|
headers,
|
|
23
|
+
paginationConfig,
|
|
18
24
|
}: {
|
|
19
25
|
path: string;
|
|
20
26
|
load?: boolean;
|
|
21
27
|
queryOptions?: TanstackQueryOption<TResponse>;
|
|
22
28
|
keyTracker?: string;
|
|
29
|
+
paginationConfig?: {
|
|
30
|
+
extractPagination?: (response: IRequestSuccess<TResponse>) => IPagination | undefined;
|
|
31
|
+
buildPaginationUrl?: (url: string, page: number) => string;
|
|
32
|
+
pageParamName?: string;
|
|
33
|
+
};
|
|
23
34
|
} & DefaultRequestOptions) => {
|
|
24
35
|
const [requestPath, setRequestPath] = useState<string>(path);
|
|
25
36
|
const [options, setOptions] = useState<any>(queryOptions);
|
|
26
37
|
const [page, setPage] = useState<number>(1);
|
|
27
38
|
|
|
28
39
|
const { API_URL, TIMEOUT } = useEnvironmentVariables();
|
|
29
|
-
const { middleware } = useStore(bootStore);
|
|
40
|
+
const { middleware, pagination: globalPaginationConfig } = useStore(bootStore);
|
|
30
41
|
|
|
31
42
|
const globalHeaders = useHeaderStore((state) => state.headers);
|
|
32
43
|
|
|
@@ -39,6 +50,15 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
|
|
|
39
50
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
51
|
queryClient = useMemo(() => queryClient, []);
|
|
41
52
|
|
|
53
|
+
// Merge global and local pagination config
|
|
54
|
+
const pagination = useMemo(
|
|
55
|
+
() => ({
|
|
56
|
+
...globalPaginationConfig,
|
|
57
|
+
...paginationConfig,
|
|
58
|
+
}),
|
|
59
|
+
[globalPaginationConfig, paginationConfig]
|
|
60
|
+
);
|
|
61
|
+
|
|
42
62
|
const sendRequest = async (
|
|
43
63
|
res: (
|
|
44
64
|
value: IRequestError | IRequestSuccess<TResponse> | PromiseLike<IRequestError | IRequestSuccess<TResponse>>
|
|
@@ -56,20 +76,25 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
|
|
|
56
76
|
timeout: TIMEOUT,
|
|
57
77
|
};
|
|
58
78
|
|
|
79
|
+
// Create the final handler that makes the actual request
|
|
80
|
+
const finalHandler: MiddlewareNext<TResponse> = async (options) => {
|
|
81
|
+
const finalOptions = options ? { ...requestOptions, ...options } : requestOptions;
|
|
82
|
+
return await makeRequest<TResponse>(finalOptions);
|
|
83
|
+
};
|
|
84
|
+
|
|
59
85
|
let getResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
);
|
|
86
|
+
|
|
87
|
+
// If middleware is available, execute the middleware chain
|
|
88
|
+
if (middleware && Array.isArray(middleware) && middleware.length > 0) {
|
|
89
|
+
const context: MiddlewareContext<TResponse> = {
|
|
90
|
+
baseUrl: baseUrl ?? API_URL,
|
|
91
|
+
path: requestUrl,
|
|
92
|
+
options: requestOptions,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
getResponse = await executeMiddlewareChain<TResponse>(middleware, context, finalHandler);
|
|
72
96
|
} else {
|
|
97
|
+
// Otherwise, just make the request directly
|
|
73
98
|
getResponse = await makeRequest<TResponse>(requestOptions);
|
|
74
99
|
}
|
|
75
100
|
|
|
@@ -105,41 +130,88 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
|
|
|
105
130
|
}
|
|
106
131
|
}, [keyTracker, requestPath, queryClient, queryOptions?.staleTime]);
|
|
107
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Extract pagination data from response using configured extractor
|
|
135
|
+
*/
|
|
136
|
+
const getPaginationData = (response: IRequestSuccess<TResponse>): IPagination | undefined => {
|
|
137
|
+
// Use the configured pagination extractor or fall back to default
|
|
138
|
+
const extractPagination =
|
|
139
|
+
pagination.extractPagination ||
|
|
140
|
+
((res) => {
|
|
141
|
+
if ('pagination' in res.data) {
|
|
142
|
+
return res.data.pagination as IPagination;
|
|
143
|
+
}
|
|
144
|
+
return undefined;
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
return extractPagination(response);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Navigate to the next page if available
|
|
152
|
+
*/
|
|
108
153
|
const nextPage = () => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
154
|
+
// The linter thinks query.data is always falsy, but we know it can be defined after a successful query
|
|
155
|
+
// Let's restructure to avoid the conditional
|
|
156
|
+
const paginationData = (query as any).data && getPaginationData(query.data);
|
|
157
|
+
if (!paginationData) return;
|
|
158
|
+
|
|
159
|
+
if (
|
|
160
|
+
paginationData.next_page !== paginationData.current_page &&
|
|
161
|
+
paginationData.next_page > paginationData.current_page
|
|
162
|
+
) {
|
|
163
|
+
setRequestPath(constructPaginationLink(requestPath, paginationData.next_page));
|
|
114
164
|
}
|
|
115
165
|
};
|
|
116
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Navigate to the previous page if available
|
|
169
|
+
*/
|
|
117
170
|
const prevPage = () => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
171
|
+
// The linter thinks query.data is always falsy, but we know it can be defined after a successful query
|
|
172
|
+
// Let's restructure to avoid the conditional
|
|
173
|
+
const paginationData = (query as any).data && getPaginationData(query.data);
|
|
174
|
+
if (!paginationData) return;
|
|
175
|
+
|
|
176
|
+
if (
|
|
177
|
+
paginationData.previous_page !== paginationData.current_page &&
|
|
178
|
+
paginationData.previous_page < paginationData.current_page
|
|
179
|
+
) {
|
|
180
|
+
setRequestPath(constructPaginationLink(requestPath, paginationData.previous_page));
|
|
123
181
|
}
|
|
124
182
|
};
|
|
125
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Construct a pagination URL using the configured builder
|
|
186
|
+
*/
|
|
126
187
|
const constructPaginationLink = (link: string, pageNumber: number) => {
|
|
127
|
-
|
|
128
|
-
const
|
|
188
|
+
// Use the configured pagination URL builder or fall back to default
|
|
189
|
+
const buildPaginationUrl =
|
|
190
|
+
pagination.buildPaginationUrl ||
|
|
191
|
+
((url, page) => {
|
|
192
|
+
const [pathname, queryString] = url.split('?');
|
|
193
|
+
const queryParams = new URLSearchParams(queryString || '');
|
|
194
|
+
const pageParamName = pagination.pageParamName || 'page';
|
|
129
195
|
|
|
130
|
-
|
|
196
|
+
const oldPage = Number(queryParams.get(pageParamName));
|
|
197
|
+
queryParams.set(pageParamName, String(page));
|
|
131
198
|
|
|
132
|
-
|
|
199
|
+
const newUrl = pathname + '?' + queryParams.toString();
|
|
133
200
|
|
|
134
|
-
|
|
201
|
+
// only update page when pagination number changed
|
|
202
|
+
if (oldPage !== pageNumber) {
|
|
203
|
+
setPage(pageNumber);
|
|
204
|
+
}
|
|
135
205
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return link;
|
|
206
|
+
return newUrl;
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
return buildPaginationUrl(link, pageNumber);
|
|
141
210
|
};
|
|
142
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Navigate to a specific page
|
|
214
|
+
*/
|
|
143
215
|
const gotoPage = (pageNumber: number) => {
|
|
144
216
|
setRequestPath(constructPaginationLink(requestPath, pageNumber));
|
|
145
217
|
};
|
|
@@ -194,5 +266,9 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
|
|
|
194
266
|
gotoPage,
|
|
195
267
|
page,
|
|
196
268
|
queryKey: [requestPath, {}],
|
|
269
|
+
// Add pagination data accessor - restructured to avoid linter error
|
|
270
|
+
getPaginationData: function () {
|
|
271
|
+
return (query as any).data ? getPaginationData(query.data) : undefined;
|
|
272
|
+
},
|
|
197
273
|
};
|
|
198
274
|
};
|
|
@@ -19,7 +19,7 @@ export const usePatchRequest = <TResponse>({ path, baseUrl, headers }: { path: s
|
|
|
19
19
|
const [requestPayload, setRequestPayload] = useState<Record<any, any>>();
|
|
20
20
|
|
|
21
21
|
const isFutureMutationsPaused = usePauseFutureRequests((state) => state.isFutureMutationsPaused);
|
|
22
|
-
const {
|
|
22
|
+
const { context } = useStore(bootStore);
|
|
23
23
|
|
|
24
24
|
const sendRequest = async (res: (value: any) => void, rej: (reason?: any) => void, data: any) => {
|
|
25
25
|
// get request headers
|
|
@@ -34,22 +34,25 @@ export const usePatchRequest = <TResponse>({ path, baseUrl, headers }: { path: s
|
|
|
34
34
|
onUploadProgress,
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
let patchResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
38
|
-
if (middleware) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
// let patchResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
38
|
+
// if (middleware) {
|
|
39
|
+
// // perform global middleware
|
|
40
|
+
// const middlewareResponse = await middleware(
|
|
41
|
+
// async (options) =>
|
|
42
|
+
// await makeRequest<TResponse>(
|
|
43
|
+
// options ? { ...requestOptions, ...options } : requestOptions
|
|
44
|
+
// ),
|
|
45
|
+
// {
|
|
46
|
+
// path,
|
|
47
|
+
// baseUrl: baseUrl ?? API_URL,
|
|
48
|
+
// body: data,
|
|
49
|
+
// }
|
|
50
|
+
// );
|
|
48
51
|
|
|
49
|
-
|
|
50
|
-
} else {
|
|
51
|
-
|
|
52
|
-
}
|
|
52
|
+
// patchResponse = middlewareResponse;
|
|
53
|
+
// } else {
|
|
54
|
+
const patchResponse = await makeRequest<TResponse>(requestOptions);
|
|
55
|
+
// }
|
|
53
56
|
if (patchResponse.status) {
|
|
54
57
|
// scroll to top after success
|
|
55
58
|
if (context !== 'app') {
|
|
@@ -25,7 +25,7 @@ export const usePostRequest = <TResponse>({
|
|
|
25
25
|
} & DefaultRequestOptions) => {
|
|
26
26
|
const { API_URL, TIMEOUT } = useEnvironmentVariables();
|
|
27
27
|
|
|
28
|
-
const {
|
|
28
|
+
const { context } = useStore(bootStore);
|
|
29
29
|
|
|
30
30
|
const globalHeaders = useHeaderStore((state) => state.headers);
|
|
31
31
|
const { isApp } = useReactNativeEnv();
|
|
@@ -61,20 +61,23 @@ export const usePostRequest = <TResponse>({
|
|
|
61
61
|
...requestConfig,
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
let postResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
65
|
-
if (middleware) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
64
|
+
// let postResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
65
|
+
// if (middleware) {
|
|
66
|
+
// // perform global middleware
|
|
67
|
+
// postResponse = await middleware(
|
|
68
|
+
// async (options) =>
|
|
69
|
+
// await makeRequest<TResponse>(
|
|
70
|
+
// options ? { ...requestOptions, ...options } : requestOptions
|
|
71
|
+
// ),
|
|
72
|
+
// {
|
|
73
|
+
// path,
|
|
74
|
+
// baseUrl: baseUrl ?? API_URL,
|
|
75
|
+
// body: data,
|
|
76
|
+
// }
|
|
77
|
+
// );
|
|
78
|
+
// } else {
|
|
79
|
+
const postResponse = await makeRequest<TResponse>(requestOptions);
|
|
80
|
+
// }
|
|
78
81
|
|
|
79
82
|
if (postResponse.status) {
|
|
80
83
|
// scroll to top after success
|
|
@@ -20,7 +20,7 @@ export const usePutRequest = <TResponse>({ path, baseUrl, headers }: { path: str
|
|
|
20
20
|
|
|
21
21
|
const isFutureMutationsPaused = usePauseFutureRequests((state) => state.isFutureMutationsPaused);
|
|
22
22
|
|
|
23
|
-
const {
|
|
23
|
+
const { context } = useStore(bootStore);
|
|
24
24
|
|
|
25
25
|
const sendRequest = async (res: (value: any) => void, rej: (reason?: any) => void, data: any) => {
|
|
26
26
|
// get request headers
|
|
@@ -35,20 +35,21 @@ export const usePutRequest = <TResponse>({ path, baseUrl, headers }: { path: str
|
|
|
35
35
|
onUploadProgress,
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
let putResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
39
|
-
if (middleware) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
38
|
+
// let putResponse: IRequestError | IRequestSuccess<TResponse>;
|
|
39
|
+
// if (middleware) {
|
|
40
|
+
// // perform global middleware
|
|
41
|
+
// putResponse = await middleware(
|
|
42
|
+
// async (options) =>
|
|
43
|
+
// await makeRequest<TResponse>(options ? { ...requestOptions, ...options } : requestOptions),
|
|
44
|
+
// {
|
|
45
|
+
// path,
|
|
46
|
+
// baseUrl: baseUrl ?? API_URL,
|
|
47
|
+
// body: data,
|
|
48
|
+
// }
|
|
49
|
+
// );
|
|
50
|
+
// } else {
|
|
51
|
+
const putResponse = await makeRequest<TResponse>(requestOptions);
|
|
52
|
+
// }
|
|
52
53
|
if (putResponse.status) {
|
|
53
54
|
// scroll to top after success
|
|
54
55
|
if (context !== 'app') {
|