@ventlio/tanstack-query 0.2.86 → 0.2.87

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.mjs CHANGED
@@ -393,31 +393,42 @@ function getAppFiles(body, fileSelectors = []) {
393
393
 
394
394
  const useDeleteRequest = (deleteOptions) => {
395
395
  const { baseUrl, headers } = deleteOptions ?? {};
396
- const [requestPath, updateDeletePath] = useState('');
396
+ const [requestPath, setRequestPath] = useState('');
397
397
  const [options, setOptions] = useState();
398
+ const { options: queryConfigOptions } = useQueryConfig();
398
399
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
399
400
  const { getHeaders } = useQueryHeaders();
400
401
  const sendRequest = async (res, rej, queryKey) => {
401
402
  // get request headers
402
403
  const globalHeaders = getHeaders();
403
- const [url] = (queryKey ?? []);
404
- const postResponse = await makeRequest({
405
- path: url ?? requestPath,
404
+ const [url] = queryKey;
405
+ const requestUrl = (url ?? requestPath);
406
+ const requestOptions = {
407
+ path: requestUrl,
406
408
  headers: { ...globalHeaders, ...headers },
407
- method: HttpMethod.DELETE,
408
409
  baseURL: baseUrl ?? API_URL,
409
410
  timeout: TIMEOUT,
410
- });
411
- if (postResponse.status) {
412
- res(postResponse);
411
+ };
412
+ let shouldContinue = true;
413
+ if (queryConfigOptions?.queryMiddleware) {
414
+ shouldContinue = await queryConfigOptions.queryMiddleware({ queryKey, ...requestOptions });
415
+ }
416
+ if (shouldContinue) {
417
+ const postResponse = await makeRequest(requestOptions);
418
+ if (postResponse.status) {
419
+ res(postResponse);
420
+ }
421
+ else {
422
+ rej(postResponse);
423
+ }
413
424
  }
414
425
  else {
415
- rej(postResponse);
426
+ rej(null);
416
427
  }
417
428
  };
418
429
  const query = useQuery([requestPath, {}], ({ queryKey }) => new Promise((res, rej) => sendRequest(res, rej, queryKey)), { enabled: false, ...options });
419
430
  const updatedPathAsync = async (link) => {
420
- return updateDeletePath(link);
431
+ return setRequestPath(link);
421
432
  };
422
433
  const setOptionsAsync = async (fetchOptions) => {
423
434
  return setOptions(fetchOptions);
@@ -436,26 +447,37 @@ const useDeleteRequest = (deleteOptions) => {
436
447
  const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
437
448
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
438
449
  const { getHeaders } = useQueryHeaders();
439
- const [requestPath, updatePath] = useState(path);
450
+ const [requestPath, setRequestPath] = useState(path);
440
451
  const [options, setOptions] = useState(queryOptions);
452
+ const { options: queryConfigOptions } = useQueryConfig();
441
453
  let queryClient = useQueryClient();
442
454
  // eslint-disable-next-line react-hooks/exhaustive-deps
443
455
  queryClient = useMemo(() => queryClient, []);
444
- const sendRequest = async (res, rej, pageParam) => {
456
+ const sendRequest = async (res, rej, queryKey, pageParam) => {
445
457
  if (load) {
446
458
  // get request headers
447
459
  const globalHeaders = getHeaders();
448
- const getResponse = await makeRequest({
460
+ const requestOptions = {
449
461
  path: pageParam ?? requestPath,
450
462
  headers: { ...globalHeaders, ...headers },
451
463
  baseURL: baseUrl ?? API_URL,
452
464
  timeout: TIMEOUT,
453
- });
454
- if (getResponse.status) {
455
- res(getResponse);
465
+ };
466
+ let shouldContinue = true;
467
+ if (queryConfigOptions?.queryMiddleware) {
468
+ shouldContinue = await queryConfigOptions.queryMiddleware({ queryKey, ...requestOptions });
469
+ }
470
+ if (shouldContinue) {
471
+ const getResponse = await makeRequest(requestOptions);
472
+ if (getResponse.status) {
473
+ res(getResponse);
474
+ }
475
+ else {
476
+ rej(getResponse);
477
+ }
456
478
  }
457
479
  else {
458
- rej(getResponse);
480
+ rej(null);
459
481
  }
460
482
  }
461
483
  else {
@@ -473,7 +495,7 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
473
495
  queryParams.set('page', String(lastPageItem));
474
496
  return pathname + '?' + queryParams.toString();
475
497
  };
476
- const query = useInfiniteQuery([requestPath, {}], ({ pageParam = requestPath }) => new Promise((res, rej) => sendRequest(res, rej, pageParam)), {
498
+ const query = useInfiniteQuery([requestPath, {}], ({ pageParam = requestPath, queryKey }) => new Promise((res, rej) => sendRequest(res, rej, queryKey, pageParam)), {
477
499
  enabled: load,
478
500
  getNextPageParam: (lastPage) => constructPaginationLink('next_page', lastPage),
479
501
  getPreviousPageParam: (lastPage) => constructPaginationLink('previous_page', lastPage),
@@ -491,7 +513,7 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
491
513
  };
492
514
  const updatedPathAsync = async (link) => {
493
515
  startTransition(() => {
494
- updatePath(link);
516
+ setRequestPath(link);
495
517
  });
496
518
  };
497
519
  useEffect(() => {
@@ -511,11 +533,12 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
511
533
  };
512
534
 
513
535
  const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
514
- const [requestPath, updatePath] = useState(path);
536
+ const [requestPath, setRequestPath] = useState(path);
515
537
  const [options, setOptions] = useState(queryOptions);
516
538
  const [page, setPage] = useState(1);
517
539
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
518
540
  const { getHeaders } = useQueryHeaders();
541
+ const { options: queryConfigOptions } = useQueryConfig();
519
542
  let queryClient = useQueryClient();
520
543
  // eslint-disable-next-line react-hooks/exhaustive-deps
521
544
  queryClient = useMemo(() => queryClient, []);
@@ -523,18 +546,29 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
523
546
  if (load) {
524
547
  // get request headers
525
548
  const globalHeaders = getHeaders();
526
- const [url] = (queryKey ?? []);
527
- const getResponse = await makeRequest({
528
- path: url ?? requestPath,
549
+ const [url] = queryKey;
550
+ const requestUrl = (url ?? requestPath);
551
+ const requestOptions = {
552
+ path: requestUrl,
529
553
  headers: { ...globalHeaders, ...headers },
530
554
  baseURL: baseUrl ?? API_URL,
531
555
  timeout: TIMEOUT,
532
- });
533
- if (getResponse.status) {
534
- res(getResponse);
556
+ };
557
+ let shouldContinue = true;
558
+ if (queryConfigOptions?.queryMiddleware) {
559
+ shouldContinue = await queryConfigOptions.queryMiddleware({ queryKey, ...requestOptions });
560
+ }
561
+ if (shouldContinue) {
562
+ const getResponse = await makeRequest(requestOptions);
563
+ if (getResponse.status) {
564
+ res(getResponse);
565
+ }
566
+ else {
567
+ rej(getResponse);
568
+ }
535
569
  }
536
570
  else {
537
- rej(getResponse);
571
+ rej(null);
538
572
  }
539
573
  }
540
574
  else {
@@ -547,7 +581,7 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
547
581
  });
548
582
  useEffect(() => {
549
583
  if (path) {
550
- updatePath(path);
584
+ setRequestPath(path);
551
585
  }
552
586
  }, [path]);
553
587
  useEffect(() => {
@@ -564,7 +598,7 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
564
598
  if (query.data?.data.pagination) {
565
599
  const pagination = query.data.data.pagination;
566
600
  if (pagination.next_page !== pagination.current_page && pagination.next_page > pagination.current_page) {
567
- updatePath(constructPaginationLink(requestPath, pagination.next_page));
601
+ setRequestPath(constructPaginationLink(requestPath, pagination.next_page));
568
602
  }
569
603
  }
570
604
  };
@@ -572,7 +606,7 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
572
606
  if (query.data?.data.pagination) {
573
607
  const pagination = query.data.data.pagination;
574
608
  if (pagination.previous_page !== pagination.current_page && pagination.previous_page < pagination.current_page) {
575
- updatePath(constructPaginationLink(requestPath, pagination.previous_page));
609
+ setRequestPath(constructPaginationLink(requestPath, pagination.previous_page));
576
610
  }
577
611
  }
578
612
  };
@@ -589,11 +623,11 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
589
623
  return link;
590
624
  };
591
625
  const gotoPage = (pageNumber) => {
592
- updatePath(constructPaginationLink(requestPath, pageNumber));
626
+ setRequestPath(constructPaginationLink(requestPath, pageNumber));
593
627
  };
594
628
  const updatedPathAsync = async (link) => {
595
629
  startTransition(() => {
596
- updatePath(link);
630
+ setRequestPath(link);
597
631
  });
598
632
  };
599
633
  const setOptionsAsync = async (fetchOptions) => {
@@ -608,7 +642,7 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
608
642
  };
609
643
  return {
610
644
  ...query,
611
- updatePath,
645
+ setRequestPath,
612
646
  nextPage,
613
647
  prevPage,
614
648
  get,
@@ -636,7 +670,7 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
636
670
  const sendRequest = async (res, rej, data) => {
637
671
  // get request headers
638
672
  const globalHeaders = getHeaders();
639
- const patchResponse = await makeRequest({
673
+ const requestOptions = {
640
674
  path: path,
641
675
  body: data,
642
676
  method: HttpMethod.PATCH,
@@ -644,26 +678,39 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
644
678
  baseURL: baseUrl ?? API_URL,
645
679
  timeout: TIMEOUT,
646
680
  onUploadProgress,
647
- });
648
- if (patchResponse.status) {
649
- // scroll to top after success
650
- if (config.options?.context !== 'app') {
651
- scrollToTop();
681
+ };
682
+ let shouldContinue = true;
683
+ if (config.options?.mutationMiddleware) {
684
+ shouldContinue = await config.options.mutationMiddleware({
685
+ mutationKey: [path, { type: 'mutation' }],
686
+ ...requestOptions,
687
+ });
688
+ }
689
+ if (shouldContinue) {
690
+ const patchResponse = await makeRequest(requestOptions);
691
+ if (patchResponse.status) {
692
+ // scroll to top after success
693
+ if (config.options?.context !== 'app') {
694
+ scrollToTop();
695
+ }
696
+ res(patchResponse);
697
+ }
698
+ else {
699
+ // scroll to top after error
700
+ if (config.options?.context !== 'app') {
701
+ scrollToTop();
702
+ }
703
+ rej(patchResponse);
652
704
  }
653
- res(patchResponse);
654
705
  }
655
706
  else {
656
- // scroll to top after error
657
- if (config.options?.context !== 'app') {
658
- scrollToTop();
659
- }
660
- rej(patchResponse);
707
+ rej(null);
661
708
  }
662
709
  };
663
710
  // register post mutation
664
711
  const mutation = useMutation((dataData) => new Promise((res, rej) => {
665
712
  return sendRequest(res, rej, dataData);
666
- }));
713
+ }), { mutationKey: [path, { type: 'mutation' }] });
667
714
  const patch = async (data, options) => {
668
715
  return mutation.mutateAsync(data, options);
669
716
  };
@@ -681,7 +728,7 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
681
728
  const globalHeaders = getHeaders();
682
729
  const { data, requestConfig } = postData;
683
730
  delete requestConfig?.body;
684
- const postResponse = await makeRequest({
731
+ const requestOptions = {
685
732
  path,
686
733
  body: data,
687
734
  method: HttpMethod.POST,
@@ -695,20 +742,33 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
695
742
  },
696
743
  onUploadProgress,
697
744
  ...requestConfig,
698
- });
699
- if (postResponse.status) {
700
- // scroll to top after success
701
- if (config.options?.context !== 'app') {
702
- scrollToTop();
745
+ };
746
+ let shouldContinue = true;
747
+ if (config.options?.mutationMiddleware) {
748
+ shouldContinue = await config.options.mutationMiddleware({
749
+ mutationKey: [path, { type: 'mutation' }],
750
+ ...requestOptions,
751
+ });
752
+ }
753
+ if (shouldContinue) {
754
+ const postResponse = await makeRequest(requestOptions);
755
+ if (postResponse.status) {
756
+ // scroll to top after success
757
+ if (config.options?.context !== 'app') {
758
+ scrollToTop();
759
+ }
760
+ res(postResponse);
761
+ }
762
+ else {
763
+ // scroll to top after error
764
+ if (config.options?.context !== 'app') {
765
+ scrollToTop();
766
+ }
767
+ rej(postResponse);
703
768
  }
704
- res(postResponse);
705
769
  }
706
770
  else {
707
- // scroll to top after error
708
- if (config.options?.context !== 'app') {
709
- scrollToTop();
710
- }
711
- rej(postResponse);
771
+ rej(null);
712
772
  }
713
773
  };
714
774
  // register post mutation
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,38 +2,50 @@ import { useQuery } from '@tanstack/react-query';
2
2
  import { useState } from 'react';
3
3
  import 'url-search-params-polyfill';
4
4
  import { useEnvironmentVariables } from '../config/useEnvironmentVariables.js';
5
+ import { useQueryConfig } from '../config/useQueryConfig.js';
5
6
  import { useQueryHeaders } from '../config/useQueryHeaders.js';
6
7
  import 'axios';
7
8
  import { makeRequest } from '../request/make-request.js';
8
- import { HttpMethod } from '../request/request.enum.js';
9
+ import '../request/request.enum.js';
9
10
 
10
11
  const useDeleteRequest = (deleteOptions) => {
11
12
  const { baseUrl, headers } = deleteOptions ?? {};
12
- const [requestPath, updateDeletePath] = useState('');
13
+ const [requestPath, setRequestPath] = useState('');
13
14
  const [options, setOptions] = useState();
15
+ const { options: queryConfigOptions } = useQueryConfig();
14
16
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
15
17
  const { getHeaders } = useQueryHeaders();
16
18
  const sendRequest = async (res, rej, queryKey) => {
17
19
  // get request headers
18
20
  const globalHeaders = getHeaders();
19
- const [url] = (queryKey ?? []);
20
- const postResponse = await makeRequest({
21
- path: url ?? requestPath,
21
+ const [url] = queryKey;
22
+ const requestUrl = (url ?? requestPath);
23
+ const requestOptions = {
24
+ path: requestUrl,
22
25
  headers: { ...globalHeaders, ...headers },
23
- method: HttpMethod.DELETE,
24
26
  baseURL: baseUrl ?? API_URL,
25
27
  timeout: TIMEOUT,
26
- });
27
- if (postResponse.status) {
28
- res(postResponse);
28
+ };
29
+ let shouldContinue = true;
30
+ if (queryConfigOptions?.queryMiddleware) {
31
+ shouldContinue = await queryConfigOptions.queryMiddleware({ queryKey, ...requestOptions });
32
+ }
33
+ if (shouldContinue) {
34
+ const postResponse = await makeRequest(requestOptions);
35
+ if (postResponse.status) {
36
+ res(postResponse);
37
+ }
38
+ else {
39
+ rej(postResponse);
40
+ }
29
41
  }
30
42
  else {
31
- rej(postResponse);
43
+ rej(null);
32
44
  }
33
45
  };
34
46
  const query = useQuery([requestPath, {}], ({ queryKey }) => new Promise((res, rej) => sendRequest(res, rej, queryKey)), { enabled: false, ...options });
35
47
  const updatedPathAsync = async (link) => {
36
- return updateDeletePath(link);
48
+ return setRequestPath(link);
37
49
  };
38
50
  const setOptionsAsync = async (fetchOptions) => {
39
51
  return setOptions(fetchOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"useDeleteRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useDeleteRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,6 +2,7 @@ import { useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
2
2
  import { useState, useMemo, useEffect, startTransition } from 'react';
3
3
  import 'url-search-params-polyfill';
4
4
  import { useEnvironmentVariables } from '../config/useEnvironmentVariables.js';
5
+ import { useQueryConfig } from '../config/useQueryConfig.js';
5
6
  import { useQueryHeaders } from '../config/useQueryHeaders.js';
6
7
  import 'axios';
7
8
  import { makeRequest } from '../request/make-request.js';
@@ -10,26 +11,37 @@ import '../request/request.enum.js';
10
11
  const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
11
12
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
12
13
  const { getHeaders } = useQueryHeaders();
13
- const [requestPath, updatePath] = useState(path);
14
+ const [requestPath, setRequestPath] = useState(path);
14
15
  const [options, setOptions] = useState(queryOptions);
16
+ const { options: queryConfigOptions } = useQueryConfig();
15
17
  let queryClient = useQueryClient();
16
18
  // eslint-disable-next-line react-hooks/exhaustive-deps
17
19
  queryClient = useMemo(() => queryClient, []);
18
- const sendRequest = async (res, rej, pageParam) => {
20
+ const sendRequest = async (res, rej, queryKey, pageParam) => {
19
21
  if (load) {
20
22
  // get request headers
21
23
  const globalHeaders = getHeaders();
22
- const getResponse = await makeRequest({
24
+ const requestOptions = {
23
25
  path: pageParam ?? requestPath,
24
26
  headers: { ...globalHeaders, ...headers },
25
27
  baseURL: baseUrl ?? API_URL,
26
28
  timeout: TIMEOUT,
27
- });
28
- if (getResponse.status) {
29
- res(getResponse);
29
+ };
30
+ let shouldContinue = true;
31
+ if (queryConfigOptions?.queryMiddleware) {
32
+ shouldContinue = await queryConfigOptions.queryMiddleware({ queryKey, ...requestOptions });
33
+ }
34
+ if (shouldContinue) {
35
+ const getResponse = await makeRequest(requestOptions);
36
+ if (getResponse.status) {
37
+ res(getResponse);
38
+ }
39
+ else {
40
+ rej(getResponse);
41
+ }
30
42
  }
31
43
  else {
32
- rej(getResponse);
44
+ rej(null);
33
45
  }
34
46
  }
35
47
  else {
@@ -47,7 +59,7 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
47
59
  queryParams.set('page', String(lastPageItem));
48
60
  return pathname + '?' + queryParams.toString();
49
61
  };
50
- const query = useInfiniteQuery([requestPath, {}], ({ pageParam = requestPath }) => new Promise((res, rej) => sendRequest(res, rej, pageParam)), {
62
+ const query = useInfiniteQuery([requestPath, {}], ({ pageParam = requestPath, queryKey }) => new Promise((res, rej) => sendRequest(res, rej, queryKey, pageParam)), {
51
63
  enabled: load,
52
64
  getNextPageParam: (lastPage) => constructPaginationLink('next_page', lastPage),
53
65
  getPreviousPageParam: (lastPage) => constructPaginationLink('previous_page', lastPage),
@@ -65,7 +77,7 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
65
77
  };
66
78
  const updatedPathAsync = async (link) => {
67
79
  startTransition(() => {
68
- updatePath(link);
80
+ setRequestPath(link);
69
81
  });
70
82
  };
71
83
  useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"useGetInfiniteRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useGetInfiniteRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -8,7 +8,7 @@ export declare const useGetRequest: <TResponse extends Record<string, any>>({ pa
8
8
  queryOptions?: TanstackQueryOption<TResponse> | undefined;
9
9
  keyTracker?: string | undefined;
10
10
  } & DefaultRequestOptions) => {
11
- updatePath: import("react").Dispatch<import("react").SetStateAction<string>>;
11
+ setRequestPath: import("react").Dispatch<import("react").SetStateAction<string>>;
12
12
  nextPage: () => void;
13
13
  prevPage: () => void;
14
14
  get: (link: string, fetchOptions?: UseQueryOptions<IRequestSuccess<TResponse | undefined>, IRequestError, IRequestSuccess<TResponse | undefined>, any[]> | undefined) => Promise<IRequestSuccess<TResponse> | undefined>;
@@ -41,7 +41,7 @@ export declare const useGetRequest: <TResponse extends Record<string, any>>({ pa
41
41
  remove: () => void;
42
42
  fetchStatus: import("@tanstack/react-query").FetchStatus;
43
43
  } | {
44
- updatePath: import("react").Dispatch<import("react").SetStateAction<string>>;
44
+ setRequestPath: import("react").Dispatch<import("react").SetStateAction<string>>;
45
45
  nextPage: () => void;
46
46
  prevPage: () => void;
47
47
  get: (link: string, fetchOptions?: UseQueryOptions<IRequestSuccess<TResponse | undefined>, IRequestError, IRequestSuccess<TResponse | undefined>, any[]> | undefined) => Promise<IRequestSuccess<TResponse> | undefined>;
@@ -74,7 +74,7 @@ export declare const useGetRequest: <TResponse extends Record<string, any>>({ pa
74
74
  remove: () => void;
75
75
  fetchStatus: import("@tanstack/react-query").FetchStatus;
76
76
  } | {
77
- updatePath: import("react").Dispatch<import("react").SetStateAction<string>>;
77
+ setRequestPath: import("react").Dispatch<import("react").SetStateAction<string>>;
78
78
  nextPage: () => void;
79
79
  prevPage: () => void;
80
80
  get: (link: string, fetchOptions?: UseQueryOptions<IRequestSuccess<TResponse | undefined>, IRequestError, IRequestSuccess<TResponse | undefined>, any[]> | undefined) => Promise<IRequestSuccess<TResponse> | undefined>;
@@ -107,7 +107,7 @@ export declare const useGetRequest: <TResponse extends Record<string, any>>({ pa
107
107
  remove: () => void;
108
108
  fetchStatus: import("@tanstack/react-query").FetchStatus;
109
109
  } | {
110
- updatePath: import("react").Dispatch<import("react").SetStateAction<string>>;
110
+ setRequestPath: import("react").Dispatch<import("react").SetStateAction<string>>;
111
111
  nextPage: () => void;
112
112
  prevPage: () => void;
113
113
  get: (link: string, fetchOptions?: UseQueryOptions<IRequestSuccess<TResponse | undefined>, IRequestError, IRequestSuccess<TResponse | undefined>, any[]> | undefined) => Promise<IRequestSuccess<TResponse> | undefined>;
@@ -2,17 +2,19 @@ import { useQueryClient, useQuery } from '@tanstack/react-query';
2
2
  import { useState, useMemo, useEffect, startTransition } from 'react';
3
3
  import 'url-search-params-polyfill';
4
4
  import { useEnvironmentVariables } from '../config/useEnvironmentVariables.js';
5
+ import { useQueryConfig } from '../config/useQueryConfig.js';
5
6
  import { useQueryHeaders } from '../config/useQueryHeaders.js';
6
7
  import 'axios';
7
8
  import { makeRequest } from '../request/make-request.js';
8
9
  import '../request/request.enum.js';
9
10
 
10
11
  const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
11
- const [requestPath, updatePath] = useState(path);
12
+ const [requestPath, setRequestPath] = useState(path);
12
13
  const [options, setOptions] = useState(queryOptions);
13
14
  const [page, setPage] = useState(1);
14
15
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
15
16
  const { getHeaders } = useQueryHeaders();
17
+ const { options: queryConfigOptions } = useQueryConfig();
16
18
  let queryClient = useQueryClient();
17
19
  // eslint-disable-next-line react-hooks/exhaustive-deps
18
20
  queryClient = useMemo(() => queryClient, []);
@@ -20,18 +22,29 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
20
22
  if (load) {
21
23
  // get request headers
22
24
  const globalHeaders = getHeaders();
23
- const [url] = (queryKey ?? []);
24
- const getResponse = await makeRequest({
25
- path: url ?? requestPath,
25
+ const [url] = queryKey;
26
+ const requestUrl = (url ?? requestPath);
27
+ const requestOptions = {
28
+ path: requestUrl,
26
29
  headers: { ...globalHeaders, ...headers },
27
30
  baseURL: baseUrl ?? API_URL,
28
31
  timeout: TIMEOUT,
29
- });
30
- if (getResponse.status) {
31
- res(getResponse);
32
+ };
33
+ let shouldContinue = true;
34
+ if (queryConfigOptions?.queryMiddleware) {
35
+ shouldContinue = await queryConfigOptions.queryMiddleware({ queryKey, ...requestOptions });
36
+ }
37
+ if (shouldContinue) {
38
+ const getResponse = await makeRequest(requestOptions);
39
+ if (getResponse.status) {
40
+ res(getResponse);
41
+ }
42
+ else {
43
+ rej(getResponse);
44
+ }
32
45
  }
33
46
  else {
34
- rej(getResponse);
47
+ rej(null);
35
48
  }
36
49
  }
37
50
  else {
@@ -44,7 +57,7 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
44
57
  });
45
58
  useEffect(() => {
46
59
  if (path) {
47
- updatePath(path);
60
+ setRequestPath(path);
48
61
  }
49
62
  }, [path]);
50
63
  useEffect(() => {
@@ -61,7 +74,7 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
61
74
  if (query.data?.data.pagination) {
62
75
  const pagination = query.data.data.pagination;
63
76
  if (pagination.next_page !== pagination.current_page && pagination.next_page > pagination.current_page) {
64
- updatePath(constructPaginationLink(requestPath, pagination.next_page));
77
+ setRequestPath(constructPaginationLink(requestPath, pagination.next_page));
65
78
  }
66
79
  }
67
80
  };
@@ -69,7 +82,7 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
69
82
  if (query.data?.data.pagination) {
70
83
  const pagination = query.data.data.pagination;
71
84
  if (pagination.previous_page !== pagination.current_page && pagination.previous_page < pagination.current_page) {
72
- updatePath(constructPaginationLink(requestPath, pagination.previous_page));
85
+ setRequestPath(constructPaginationLink(requestPath, pagination.previous_page));
73
86
  }
74
87
  }
75
88
  };
@@ -86,11 +99,11 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
86
99
  return link;
87
100
  };
88
101
  const gotoPage = (pageNumber) => {
89
- updatePath(constructPaginationLink(requestPath, pageNumber));
102
+ setRequestPath(constructPaginationLink(requestPath, pageNumber));
90
103
  };
91
104
  const updatedPathAsync = async (link) => {
92
105
  startTransition(() => {
93
- updatePath(link);
106
+ setRequestPath(link);
94
107
  });
95
108
  };
96
109
  const setOptionsAsync = async (fetchOptions) => {
@@ -105,7 +118,7 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
105
118
  };
106
119
  return {
107
120
  ...query,
108
- updatePath,
121
+ setRequestPath,
109
122
  nextPage,
110
123
  prevPage,
111
124
  get,
@@ -1 +1 @@
1
- {"version":3,"file":"useGetRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useGetRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -17,7 +17,7 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
17
17
  const sendRequest = async (res, rej, data) => {
18
18
  // get request headers
19
19
  const globalHeaders = getHeaders();
20
- const patchResponse = await makeRequest({
20
+ const requestOptions = {
21
21
  path: path,
22
22
  body: data,
23
23
  method: HttpMethod.PATCH,
@@ -25,26 +25,39 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
25
25
  baseURL: baseUrl ?? API_URL,
26
26
  timeout: TIMEOUT,
27
27
  onUploadProgress,
28
- });
29
- if (patchResponse.status) {
30
- // scroll to top after success
31
- if (config.options?.context !== 'app') {
32
- scrollToTop();
28
+ };
29
+ let shouldContinue = true;
30
+ if (config.options?.mutationMiddleware) {
31
+ shouldContinue = await config.options.mutationMiddleware({
32
+ mutationKey: [path, { type: 'mutation' }],
33
+ ...requestOptions,
34
+ });
35
+ }
36
+ if (shouldContinue) {
37
+ const patchResponse = await makeRequest(requestOptions);
38
+ if (patchResponse.status) {
39
+ // scroll to top after success
40
+ if (config.options?.context !== 'app') {
41
+ scrollToTop();
42
+ }
43
+ res(patchResponse);
44
+ }
45
+ else {
46
+ // scroll to top after error
47
+ if (config.options?.context !== 'app') {
48
+ scrollToTop();
49
+ }
50
+ rej(patchResponse);
33
51
  }
34
- res(patchResponse);
35
52
  }
36
53
  else {
37
- // scroll to top after error
38
- if (config.options?.context !== 'app') {
39
- scrollToTop();
40
- }
41
- rej(patchResponse);
54
+ rej(null);
42
55
  }
43
56
  };
44
57
  // register post mutation
45
58
  const mutation = useMutation((dataData) => new Promise((res, rej) => {
46
59
  return sendRequest(res, rej, dataData);
47
- }));
60
+ }), { mutationKey: [path, { type: 'mutation' }] });
48
61
  const patch = async (data, options) => {
49
62
  return mutation.mutateAsync(data, options);
50
63
  };
@@ -1 +1 @@
1
- {"version":3,"file":"usePatchRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"usePatchRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -21,7 +21,7 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
21
21
  const globalHeaders = getHeaders();
22
22
  const { data, requestConfig } = postData;
23
23
  delete requestConfig?.body;
24
- const postResponse = await makeRequest({
24
+ const requestOptions = {
25
25
  path,
26
26
  body: data,
27
27
  method: HttpMethod.POST,
@@ -35,20 +35,33 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
35
35
  },
36
36
  onUploadProgress,
37
37
  ...requestConfig,
38
- });
39
- if (postResponse.status) {
40
- // scroll to top after success
41
- if (config.options?.context !== 'app') {
42
- scrollToTop();
38
+ };
39
+ let shouldContinue = true;
40
+ if (config.options?.mutationMiddleware) {
41
+ shouldContinue = await config.options.mutationMiddleware({
42
+ mutationKey: [path, { type: 'mutation' }],
43
+ ...requestOptions,
44
+ });
45
+ }
46
+ if (shouldContinue) {
47
+ const postResponse = await makeRequest(requestOptions);
48
+ if (postResponse.status) {
49
+ // scroll to top after success
50
+ if (config.options?.context !== 'app') {
51
+ scrollToTop();
52
+ }
53
+ res(postResponse);
54
+ }
55
+ else {
56
+ // scroll to top after error
57
+ if (config.options?.context !== 'app') {
58
+ scrollToTop();
59
+ }
60
+ rej(postResponse);
43
61
  }
44
- res(postResponse);
45
62
  }
46
63
  else {
47
- // scroll to top after error
48
- if (config.options?.context !== 'app') {
49
- scrollToTop();
50
- }
51
- rej(postResponse);
64
+ rej(null);
52
65
  }
53
66
  };
54
67
  // register post mutation
@@ -1 +1 @@
1
- {"version":3,"file":"usePostRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"usePostRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,6 @@
1
+ import type { QueryKey } from '@tanstack/react-query';
1
2
  import type { RawAxiosRequestHeaders } from 'axios';
3
+ import type { IMakeRequest } from '../request';
2
4
  export interface BootstrapConfig {
3
5
  environments?: {
4
6
  appBaseUrl: string;
@@ -6,8 +8,12 @@ export interface BootstrapConfig {
6
8
  };
7
9
  context?: ContextType;
8
10
  modelConfig?: BootstrapModelConfig;
9
- mutationMiddleware?: (mutateRequest?: any, mutateResponse?: any) => Promise<boolean>;
10
- queryMiddleware?: (queryRequest?: any, queryResponse?: any) => Promise<boolean>;
11
+ mutationMiddleware?: (mutateRequestConfig?: IMakeRequest & {
12
+ mutationKey: QueryKey;
13
+ }) => Promise<boolean>;
14
+ queryMiddleware?: (queryRequestConfig?: IMakeRequest & {
15
+ queryKey: QueryKey;
16
+ }) => Promise<boolean>;
11
17
  }
12
18
  export interface BootstrapModelConfig {
13
19
  idColumn: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ventlio/tanstack-query",
3
- "version": "0.2.86",
3
+ "version": "0.2.87",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "contributors": [
@@ -2,38 +2,52 @@ import type { QueryKey, UseQueryOptions } from '@tanstack/react-query';
2
2
  import { useQuery } from '@tanstack/react-query';
3
3
  import type { RawAxiosRequestHeaders } from 'axios';
4
4
  import { useState } from 'react';
5
- import { useEnvironmentVariables, useQueryHeaders } from '../config';
5
+ import { useEnvironmentVariables, useQueryConfig, useQueryHeaders } from '../config';
6
6
  import type { IRequestError, IRequestSuccess } from '../request';
7
- import { HttpMethod, makeRequest } from '../request';
7
+ import { makeRequest } from '../request';
8
8
  import type { DefaultRequestOptions } from './queries.interface';
9
9
 
10
10
  export const useDeleteRequest = <TResponse>(deleteOptions?: DefaultRequestOptions) => {
11
11
  const { baseUrl, headers } = deleteOptions ?? {};
12
- const [requestPath, updateDeletePath] = useState<string>('');
12
+ const [requestPath, setRequestPath] = useState<string>('');
13
13
  const [options, setOptions] = useState<any>();
14
14
 
15
+ const { options: queryConfigOptions } = useQueryConfig();
16
+
15
17
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
16
18
 
17
19
  const { getHeaders } = useQueryHeaders();
18
20
 
19
- const sendRequest = async (res: (value: any) => void, rej: (reason?: any) => void, queryKey?: QueryKey) => {
21
+ const sendRequest = async (res: (value: any) => void, rej: (reason?: any) => void, queryKey: QueryKey) => {
20
22
  // get request headers
21
23
  const globalHeaders: RawAxiosRequestHeaders = getHeaders();
22
24
 
23
- const [url] = (queryKey ?? []) as string[];
25
+ const [url] = queryKey;
26
+ const requestUrl = (url ?? requestPath) as string;
24
27
 
25
- const postResponse = await makeRequest<TResponse>({
26
- path: url ?? requestPath,
28
+ const requestOptions = {
29
+ path: requestUrl,
27
30
  headers: { ...globalHeaders, ...headers },
28
- method: HttpMethod.DELETE,
29
31
  baseURL: baseUrl ?? API_URL,
30
32
  timeout: TIMEOUT,
31
- });
33
+ };
34
+
35
+ let shouldContinue = true;
36
+
37
+ if (queryConfigOptions?.queryMiddleware) {
38
+ shouldContinue = await queryConfigOptions.queryMiddleware({ queryKey, ...requestOptions });
39
+ }
40
+
41
+ if (shouldContinue) {
42
+ const postResponse = await makeRequest<TResponse>(requestOptions);
32
43
 
33
- if (postResponse.status) {
34
- res(postResponse as IRequestSuccess<TResponse>);
44
+ if (postResponse.status) {
45
+ res(postResponse as IRequestSuccess<TResponse>);
46
+ } else {
47
+ rej(postResponse);
48
+ }
35
49
  } else {
36
- rej(postResponse);
50
+ rej(null);
37
51
  }
38
52
  };
39
53
 
@@ -45,7 +59,7 @@ export const useDeleteRequest = <TResponse>(deleteOptions?: DefaultRequestOption
45
59
  );
46
60
 
47
61
  const updatedPathAsync = async (link: string) => {
48
- return updateDeletePath(link);
62
+ return setRequestPath(link);
49
63
  };
50
64
 
51
65
  const setOptionsAsync = async (fetchOptions: any) => {
@@ -1,8 +1,8 @@
1
- import type { InfiniteData, UseQueryOptions } from '@tanstack/react-query';
1
+ import type { InfiniteData, QueryKey, UseQueryOptions } from '@tanstack/react-query';
2
2
  import { useInfiniteQuery, useQueryClient } from '@tanstack/react-query';
3
3
  import type { RawAxiosRequestHeaders } from 'axios';
4
4
  import { startTransition, useEffect, useMemo, useState } from 'react';
5
- import { useEnvironmentVariables, useQueryHeaders } from '../config';
5
+ import { useEnvironmentVariables, useQueryConfig, useQueryHeaders } from '../config';
6
6
 
7
7
  import type { IRequestError, IRequestSuccess } from '../request';
8
8
  import { makeRequest } from '../request';
@@ -32,9 +32,10 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
32
32
  } & DefaultRequestOptions) => {
33
33
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
34
34
  const { getHeaders } = useQueryHeaders();
35
- const [requestPath, updatePath] = useState<string>(path);
35
+ const [requestPath, setRequestPath] = useState<string>(path);
36
36
 
37
37
  const [options, setOptions] = useState<any>(queryOptions);
38
+ const { options: queryConfigOptions } = useQueryConfig();
38
39
 
39
40
  let queryClient = useQueryClient();
40
41
 
@@ -49,23 +50,36 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
49
50
  | PromiseLike<IRequestError | IRequestSuccess<TResponse & { pagination: Pagination }>>
50
51
  ) => void,
51
52
  rej: (reason?: any) => void,
53
+ queryKey: QueryKey,
52
54
  pageParam?: string
53
55
  ) => {
54
56
  if (load) {
55
57
  // get request headers
56
58
  const globalHeaders: RawAxiosRequestHeaders = getHeaders();
57
59
 
58
- const getResponse = await makeRequest<TResponse>({
60
+ const requestOptions = {
59
61
  path: pageParam ?? requestPath,
60
62
  headers: { ...globalHeaders, ...headers },
61
63
  baseURL: baseUrl ?? API_URL,
62
64
  timeout: TIMEOUT,
63
- });
65
+ };
66
+
67
+ let shouldContinue = true;
68
+
69
+ if (queryConfigOptions?.queryMiddleware) {
70
+ shouldContinue = await queryConfigOptions.queryMiddleware({ queryKey, ...requestOptions });
71
+ }
72
+
73
+ if (shouldContinue) {
74
+ const getResponse = await makeRequest<TResponse>(requestOptions);
64
75
 
65
- if (getResponse.status) {
66
- res(getResponse as IRequestSuccess<TResponse & { pagination: Pagination }>);
76
+ if (getResponse.status) {
77
+ res(getResponse as IRequestSuccess<TResponse & { pagination: Pagination }>);
78
+ } else {
79
+ rej(getResponse);
80
+ }
67
81
  } else {
68
- rej(getResponse);
82
+ rej(null);
69
83
  }
70
84
  } else {
71
85
  res(null as any);
@@ -96,9 +110,9 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
96
110
 
97
111
  const query = useInfiniteQuery<any, any, IRequestSuccess<TResponse & { pagination: Pagination }>>(
98
112
  [requestPath, {}],
99
- ({ pageParam = requestPath }) =>
113
+ ({ pageParam = requestPath, queryKey }) =>
100
114
  new Promise<IRequestSuccess<TResponse & { pagination: Pagination }> | IRequestError>((res, rej) =>
101
- sendRequest(res, rej, pageParam)
115
+ sendRequest(res, rej, queryKey, pageParam)
102
116
  ),
103
117
  {
104
118
  enabled: load,
@@ -140,7 +154,7 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
140
154
 
141
155
  const updatedPathAsync = async (link: string) => {
142
156
  startTransition(() => {
143
- updatePath(link);
157
+ setRequestPath(link);
144
158
  });
145
159
  };
146
160
 
@@ -2,7 +2,7 @@ import type { QueryKey, UseQueryOptions } from '@tanstack/react-query';
2
2
  import { useQuery, useQueryClient } from '@tanstack/react-query';
3
3
  import { startTransition, useEffect, useMemo, useState } from 'react';
4
4
  import type { RawAxiosRequestHeaders } from '../../node_modules/axios/index';
5
- import { useEnvironmentVariables, useQueryHeaders } from '../config';
5
+ import { useEnvironmentVariables, useQueryConfig, useQueryHeaders } from '../config';
6
6
 
7
7
  import type { IRequestError, IRequestSuccess } from '../request';
8
8
  import { makeRequest } from '../request';
@@ -21,12 +21,13 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
21
21
  queryOptions?: TanstackQueryOption<TResponse>;
22
22
  keyTracker?: string;
23
23
  } & DefaultRequestOptions) => {
24
- const [requestPath, updatePath] = useState<string>(path);
24
+ const [requestPath, setRequestPath] = useState<string>(path);
25
25
  const [options, setOptions] = useState<any>(queryOptions);
26
26
  const [page, setPage] = useState<number>(1);
27
27
 
28
28
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
29
29
  const { getHeaders } = useQueryHeaders();
30
+ const { options: queryConfigOptions } = useQueryConfig();
30
31
 
31
32
  let queryClient = useQueryClient();
32
33
 
@@ -38,25 +39,38 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
38
39
  value: IRequestError | IRequestSuccess<TResponse> | PromiseLike<IRequestError | IRequestSuccess<TResponse>>
39
40
  ) => void,
40
41
  rej: (reason?: any) => void,
41
- queryKey?: QueryKey
42
+ queryKey: QueryKey
42
43
  ) => {
43
44
  if (load) {
44
45
  // get request headers
45
46
  const globalHeaders: RawAxiosRequestHeaders = getHeaders();
46
47
 
47
- const [url] = (queryKey ?? []) as string[];
48
+ const [url] = queryKey;
49
+ const requestUrl = (url ?? requestPath) as string;
48
50
 
49
- const getResponse = await makeRequest<TResponse>({
50
- path: url ?? requestPath,
51
+ const requestOptions = {
52
+ path: requestUrl,
51
53
  headers: { ...globalHeaders, ...headers },
52
54
  baseURL: baseUrl ?? API_URL,
53
55
  timeout: TIMEOUT,
54
- });
56
+ };
57
+
58
+ let shouldContinue = true;
59
+
60
+ if (queryConfigOptions?.queryMiddleware) {
61
+ shouldContinue = await queryConfigOptions.queryMiddleware({ queryKey, ...requestOptions });
62
+ }
63
+
64
+ if (shouldContinue) {
65
+ const getResponse = await makeRequest<TResponse>(requestOptions);
55
66
 
56
- if (getResponse.status) {
57
- res(getResponse as IRequestSuccess<TResponse>);
67
+ if (getResponse.status) {
68
+ res(getResponse as IRequestSuccess<TResponse>);
69
+ } else {
70
+ rej(getResponse);
71
+ }
58
72
  } else {
59
- rej(getResponse);
73
+ rej(null);
60
74
  }
61
75
  } else {
62
76
  res(null as any);
@@ -75,7 +89,7 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
75
89
 
76
90
  useEffect(() => {
77
91
  if (path) {
78
- updatePath(path);
92
+ setRequestPath(path);
79
93
  }
80
94
  }, [path]);
81
95
 
@@ -95,7 +109,7 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
95
109
  if (query.data?.data.pagination) {
96
110
  const pagination: IPagination = query.data.data.pagination;
97
111
  if (pagination.next_page !== pagination.current_page && pagination.next_page > pagination.current_page) {
98
- updatePath(constructPaginationLink(requestPath, pagination.next_page));
112
+ setRequestPath(constructPaginationLink(requestPath, pagination.next_page));
99
113
  }
100
114
  }
101
115
  };
@@ -104,7 +118,7 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
104
118
  if (query.data?.data.pagination) {
105
119
  const pagination: IPagination = query.data.data.pagination;
106
120
  if (pagination.previous_page !== pagination.current_page && pagination.previous_page < pagination.current_page) {
107
- updatePath(constructPaginationLink(requestPath, pagination.previous_page));
121
+ setRequestPath(constructPaginationLink(requestPath, pagination.previous_page));
108
122
  }
109
123
  }
110
124
  };
@@ -127,12 +141,12 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
127
141
  };
128
142
 
129
143
  const gotoPage = (pageNumber: number) => {
130
- updatePath(constructPaginationLink(requestPath, pageNumber));
144
+ setRequestPath(constructPaginationLink(requestPath, pageNumber));
131
145
  };
132
146
 
133
147
  const updatedPathAsync = async (link: string) => {
134
148
  startTransition(() => {
135
- updatePath(link);
149
+ setRequestPath(link);
136
150
  });
137
151
  };
138
152
 
@@ -159,7 +173,7 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
159
173
 
160
174
  return {
161
175
  ...query,
162
- updatePath,
176
+ setRequestPath,
163
177
  nextPage,
164
178
  prevPage,
165
179
  get,
@@ -20,7 +20,7 @@ export const usePatchRequest = <TResponse>({ path, baseUrl, headers }: { path: s
20
20
  // get request headers
21
21
  const globalHeaders: RawAxiosRequestHeaders = getHeaders();
22
22
 
23
- const patchResponse = await makeRequest<TResponse>({
23
+ const requestOptions = {
24
24
  path: path,
25
25
  body: data,
26
26
  method: HttpMethod.PATCH,
@@ -28,20 +28,34 @@ export const usePatchRequest = <TResponse>({ path, baseUrl, headers }: { path: s
28
28
  baseURL: baseUrl ?? API_URL,
29
29
  timeout: TIMEOUT,
30
30
  onUploadProgress,
31
- });
31
+ };
32
32
 
33
- if (patchResponse.status) {
34
- // scroll to top after success
35
- if (config.options?.context !== 'app') {
36
- scrollToTop();
33
+ let shouldContinue = true;
34
+
35
+ if (config.options?.mutationMiddleware) {
36
+ shouldContinue = await config.options.mutationMiddleware({
37
+ mutationKey: [path, { type: 'mutation' }],
38
+ ...requestOptions,
39
+ });
40
+ }
41
+
42
+ if (shouldContinue) {
43
+ const patchResponse = await makeRequest<TResponse>(requestOptions);
44
+ if (patchResponse.status) {
45
+ // scroll to top after success
46
+ if (config.options?.context !== 'app') {
47
+ scrollToTop();
48
+ }
49
+ res(patchResponse as IRequestSuccess<TResponse>);
50
+ } else {
51
+ // scroll to top after error
52
+ if (config.options?.context !== 'app') {
53
+ scrollToTop();
54
+ }
55
+ rej(patchResponse);
37
56
  }
38
- res(patchResponse as IRequestSuccess<TResponse>);
39
57
  } else {
40
- // scroll to top after error
41
- if (config.options?.context !== 'app') {
42
- scrollToTop();
43
- }
44
- rej(patchResponse);
58
+ rej(null);
45
59
  }
46
60
  };
47
61
 
@@ -50,7 +64,8 @@ export const usePatchRequest = <TResponse>({ path, baseUrl, headers }: { path: s
50
64
  (dataData: any) =>
51
65
  new Promise<IRequestSuccess<TResponse>>((res, rej) => {
52
66
  return sendRequest(res, rej, dataData);
53
- })
67
+ }),
68
+ { mutationKey: [path, { type: 'mutation' }] }
54
69
  );
55
70
 
56
71
  const patch = async (
@@ -40,7 +40,7 @@ export const usePostRequest = <TResponse>({
40
40
 
41
41
  delete requestConfig?.body;
42
42
 
43
- const postResponse = await makeRequest<TResponse>({
43
+ const requestOptions = {
44
44
  path,
45
45
  body: data,
46
46
  method: HttpMethod.POST,
@@ -54,21 +54,36 @@ export const usePostRequest = <TResponse>({
54
54
  },
55
55
  onUploadProgress,
56
56
  ...requestConfig,
57
- });
57
+ };
58
58
 
59
- if (postResponse.status) {
60
- // scroll to top after success
59
+ let shouldContinue = true;
61
60
 
62
- if (config.options?.context !== 'app') {
63
- scrollToTop();
61
+ if (config.options?.mutationMiddleware) {
62
+ shouldContinue = await config.options.mutationMiddleware({
63
+ mutationKey: [path, { type: 'mutation' }],
64
+ ...requestOptions,
65
+ });
66
+ }
67
+
68
+ if (shouldContinue) {
69
+ const postResponse = await makeRequest<TResponse>(requestOptions);
70
+
71
+ if (postResponse.status) {
72
+ // scroll to top after success
73
+
74
+ if (config.options?.context !== 'app') {
75
+ scrollToTop();
76
+ }
77
+ res(postResponse as IRequestSuccess<TResponse>);
78
+ } else {
79
+ // scroll to top after error
80
+ if (config.options?.context !== 'app') {
81
+ scrollToTop();
82
+ }
83
+ rej(postResponse);
64
84
  }
65
- res(postResponse as IRequestSuccess<TResponse>);
66
85
  } else {
67
- // scroll to top after error
68
- if (config.options?.context !== 'app') {
69
- scrollToTop();
70
- }
71
- rej(postResponse);
86
+ rej(null);
72
87
  }
73
88
  };
74
89
 
@@ -1,4 +1,6 @@
1
+ import type { QueryKey } from '@tanstack/react-query';
1
2
  import type { RawAxiosRequestHeaders } from 'axios';
3
+ import type { IMakeRequest } from '../request';
2
4
 
3
5
  export interface BootstrapConfig {
4
6
  environments?: {
@@ -7,8 +9,8 @@ export interface BootstrapConfig {
7
9
  };
8
10
  context?: ContextType;
9
11
  modelConfig?: BootstrapModelConfig;
10
- mutationMiddleware?: (mutateRequest?: any, mutateResponse?: any) => Promise<boolean>;
11
- queryMiddleware?: (queryRequest?: any, queryResponse?: any) => Promise<boolean>;
12
+ mutationMiddleware?: (mutateRequestConfig?: IMakeRequest & { mutationKey: QueryKey }) => Promise<boolean>;
13
+ queryMiddleware?: (queryRequestConfig?: IMakeRequest & { queryKey: QueryKey }) => Promise<boolean>;
12
14
  }
13
15
 
14
16
  export interface BootstrapModelConfig {