@ventlio/tanstack-query 0.2.5 → 0.2.7-2.1

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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +532 -2
  3. package/dist/config/bootstrapQueryRequest.d.ts +4 -0
  4. package/dist/config/bootstrapQueryRequest.js +19 -0
  5. package/dist/config/bootstrapQueryRequest.js.map +1 -0
  6. package/dist/config/config.interface.d.ts +4 -0
  7. package/dist/config/index.d.ts +6 -0
  8. package/dist/config/useEnvironmentVariables.d.ts +2 -0
  9. package/dist/config/useEnvironmentVariables.js +14 -0
  10. package/dist/config/useEnvironmentVariables.js.map +1 -0
  11. package/dist/config/useQueryConfig.js +10 -0
  12. package/dist/{queries → config}/useQueryConfig.js.map +1 -1
  13. package/dist/config/useQueryHeaders.d.ts +2 -0
  14. package/dist/config/useQueryHeaders.js +28 -0
  15. package/dist/config/useQueryHeaders.js.map +1 -0
  16. package/dist/config/useReactNativeEnv.d.ts +5 -0
  17. package/dist/config/useReactNativeEnv.js +13 -0
  18. package/dist/config/useReactNativeEnv.js.map +1 -0
  19. package/dist/helpers/index.d.ts +1 -0
  20. package/dist/helpers/scrollToTop.js +1 -3
  21. package/dist/helpers/scrollToTop.js.map +1 -1
  22. package/dist/helpers/timeFuncs.d.ts +1 -0
  23. package/dist/helpers/timeFuncs.js +11 -0
  24. package/dist/helpers/timeFuncs.js.map +1 -0
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.js +19 -35
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +434 -119
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/model/index.d.ts +4 -0
  31. package/dist/model/model.interface.d.ts +11 -0
  32. package/dist/model/useKeyTrackerModel.d.ts +4 -0
  33. package/dist/model/useKeyTrackerModel.js +20 -0
  34. package/dist/model/useKeyTrackerModel.js.map +1 -0
  35. package/dist/model/useQueryModel.d.ts +2 -0
  36. package/dist/model/useQueryModel.js +123 -0
  37. package/dist/model/useQueryModel.js.map +1 -0
  38. package/dist/model/useRefetchQuery.d.ts +3 -0
  39. package/dist/model/useRefetchQuery.js +16 -0
  40. package/dist/model/useRefetchQuery.js.map +1 -0
  41. package/dist/queries/index.d.ts +0 -1
  42. package/dist/queries/queries.interface.d.ts +5 -0
  43. package/dist/queries/useDeleteRequest.d.ts +14 -5
  44. package/dist/queries/useDeleteRequest.js +37 -37
  45. package/dist/queries/useGetRequest.d.ts +4 -3
  46. package/dist/queries/useGetRequest.js +53 -37
  47. package/dist/queries/useGetRequest.js.map +1 -1
  48. package/dist/queries/usePatchRequest.d.ts +7 -7
  49. package/dist/queries/usePatchRequest.js +42 -34
  50. package/dist/queries/usePatchRequest.js.map +1 -1
  51. package/dist/queries/usePostRequest.d.ts +8 -6
  52. package/dist/queries/usePostRequest.js +47 -37
  53. package/dist/queries/usePostRequest.js.map +1 -1
  54. package/dist/request/axios-instance.d.ts +1 -1
  55. package/dist/request/axios-instance.js +3 -5
  56. package/dist/request/axios-instance.js.map +1 -1
  57. package/dist/request/buildFormData.d.ts +1 -1
  58. package/dist/request/buildFormData.js +36 -6
  59. package/dist/request/buildFormData.js.map +1 -1
  60. package/dist/request/make-request.d.ts +1 -1
  61. package/dist/request/make-request.js +55 -17
  62. package/dist/request/make-request.js.map +1 -1
  63. package/dist/request/request.enum.js +6 -6
  64. package/dist/request/request.interface.d.ts +5 -0
  65. package/dist/request/transformer.js +1 -4
  66. package/dist/request/transformer.js.map +1 -1
  67. package/dist/types/index.d.ts +17 -2
  68. package/package.json +29 -5
  69. package/src/__tests__/queries/usePostRequest.spec.ts +77 -0
  70. package/src/config/bootstrapQueryRequest.ts +19 -0
  71. package/src/config/config.interface.ts +4 -0
  72. package/src/config/index.ts +4 -2
  73. package/src/config/useEnvironmentVariables.ts +13 -0
  74. package/src/config/useQueryConfig.ts +2 -5
  75. package/src/config/useQueryHeaders.ts +23 -6
  76. package/src/config/useReactNativeEnv.ts +13 -0
  77. package/src/env.d.ts +4 -0
  78. package/src/helpers/index.ts +1 -0
  79. package/src/helpers/timeFuncs.ts +10 -0
  80. package/src/model/index.ts +3 -0
  81. package/src/model/model.interface.ts +12 -0
  82. package/src/model/useKeyTrackerModel.ts +22 -0
  83. package/src/model/useQueryModel.ts +139 -6
  84. package/src/model/useRefetchQuery.ts +19 -0
  85. package/src/queries/queries.interface.ts +6 -0
  86. package/src/queries/useDeleteRequest.ts +34 -30
  87. package/src/queries/useGetRequest.ts +55 -38
  88. package/src/queries/usePatchRequest.ts +45 -40
  89. package/src/queries/usePostRequest.ts +54 -37
  90. package/src/request/axios-instance.ts +1 -5
  91. package/src/request/buildFormData.ts +34 -4
  92. package/src/request/make-request.ts +47 -7
  93. package/src/request/request.interface.ts +5 -0
  94. package/src/request/transformer.ts +3 -12
  95. package/src/types/index.ts +16 -13
  96. package/dist/queries/useQueryConfig.js +0 -14
  97. package/src/config/useQueryBaseURL.ts +0 -17
  98. package/src/config/useQueryTimeout.ts +0 -17
  99. /package/dist/{queries → config}/useQueryConfig.d.ts +0 -0
package/dist/index.mjs CHANGED
@@ -1,7 +1,50 @@
1
+ import 'url-search-params-polyfill';
1
2
  import { useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
2
- import { useState, useEffect, startTransition } from 'react';
3
+ import result from 'lodash.result';
4
+ import lodashSet from 'lodash.set';
5
+ import { useState, useMemo, useEffect, startTransition } from 'react';
3
6
  import axios from 'axios';
4
7
 
8
+ const bootstrapQueryRequest = (queryClient, options) => {
9
+ // make query config doesn't expire
10
+ queryClient.setQueryDefaults(['config'], {
11
+ staleTime: Infinity,
12
+ cacheTime: Infinity,
13
+ });
14
+ // set default query config
15
+ queryClient.setQueryData(['config'], {
16
+ headers: {
17
+ Authorization: ``,
18
+ },
19
+ options,
20
+ });
21
+ };
22
+
23
+ const useReactNativeEnv = () => {
24
+ const queryClient = useQueryClient();
25
+ const config = queryClient.getQueryData(['config']);
26
+ const appUrl = config?.options?.environments?.appBaseUrl;
27
+ const appTimeout = config?.options?.environments?.appTimeout;
28
+ const isApp = config?.options?.context === 'app';
29
+ return { appUrl, appTimeout, isApp };
30
+ };
31
+
32
+ const useEnvironmentVariables = () => {
33
+ const { appTimeout, appUrl } = useReactNativeEnv();
34
+ const url = process.env.REACT_APP_API_URL ?? process.env.NEXT_PUBLIC_API_URL ?? appUrl;
35
+ const timeout = process.env.REACT_APP_API_TIMEOUT ?? process.env.NEXT_PUBLIC_API_TIMEOUT ?? appTimeout;
36
+ return {
37
+ API_URL: url,
38
+ TIMEOUT: Number(timeout),
39
+ };
40
+ };
41
+
42
+ const useQueryConfig = () => {
43
+ const queryClient = useQueryClient();
44
+ const { headers = {}, options = {} } = queryClient.getQueryData(['config']) ?? {};
45
+ return { headers, options };
46
+ };
47
+
5
48
  const scrollToTop = () => {
6
49
  window.scrollTo({
7
50
  top: 0,
@@ -9,7 +52,183 @@ const scrollToTop = () => {
9
52
  });
10
53
  };
11
54
 
12
- const axiosInstance = ({ baseURL, timeout, headers, }) => {
55
+ function getDateInFuture(days) {
56
+ // Create a new Date object
57
+ const date = new Date();
58
+ // Add the specified number of days to the date
59
+ date.setDate(date.getDate() + days);
60
+ // Get the Unix timestamp of the date (in milliseconds)
61
+ return date.getTime();
62
+ }
63
+
64
+ const useQueryHeaders = () => {
65
+ const queryClient = useQueryClient();
66
+ const getHeaders = () => {
67
+ const config = queryClient.getQueryData(['config']);
68
+ return config.headers;
69
+ };
70
+ const setQueryHeaders = (newHeaders) => {
71
+ // make sure the config does not expire
72
+ queryClient.setQueryDefaults(['config'], {
73
+ staleTime: Infinity,
74
+ cacheTime: Infinity,
75
+ });
76
+ // set the config
77
+ queryClient.setQueryData(['config'], (config) => {
78
+ const newConfig = { ...config, headers: newHeaders };
79
+ return newConfig;
80
+ }, {
81
+ updatedAt: getDateInFuture(2),
82
+ });
83
+ };
84
+ return { setQueryHeaders, getHeaders };
85
+ };
86
+
87
+ const useKeyTrackerModel = (keyTracker) => {
88
+ const queryClient = useQueryClient();
89
+ const getQueryKey = (innerKeyTracker) => {
90
+ const queryKey = queryClient.getQueryData([innerKeyTracker ?? keyTracker]);
91
+ return queryKey;
92
+ };
93
+ const refetchQuery = async (innerKeyTracker) => {
94
+ const queryKey = getQueryKey(innerKeyTracker ?? keyTracker);
95
+ await queryClient.refetchQueries({
96
+ queryKey,
97
+ exact: true,
98
+ });
99
+ };
100
+ return { refetchQuery, getQueryKey };
101
+ };
102
+
103
+ const useQueryModel = (keyTracker, exact = true) => {
104
+ const queryClient = useQueryClient();
105
+ const { getQueryKey } = useKeyTrackerModel(keyTracker);
106
+ const queryKey = getQueryKey();
107
+ const add = (data, position, path) => {
108
+ let records = (findAll(path) ?? []);
109
+ if (!position || position === 'end') {
110
+ records = [...records, data];
111
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
112
+ }
113
+ else if (position === 'start') {
114
+ records = [data, ...records];
115
+ }
116
+ if (!path) {
117
+ queryClient.setQueryData(queryKey, records);
118
+ }
119
+ else {
120
+ const queryData = queryClient.getQueryData(queryKey, { exact }) ?? {};
121
+ queryClient.setQueryData(queryKey, lodashSet(queryData, path, records));
122
+ }
123
+ return data;
124
+ };
125
+ const findAll = (path) => {
126
+ const data = queryClient.getQueryData(queryKey, { exact });
127
+ if (!data) {
128
+ return [];
129
+ }
130
+ if (!path) {
131
+ return Array.isArray(data) ? data : [data];
132
+ }
133
+ return result(data, path, []);
134
+ };
135
+ const findMany = (selector, path) => {
136
+ const data = (findAll(path) ?? []);
137
+ return data.filter(selector);
138
+ };
139
+ const find = (id, path) => {
140
+ const modelConfig = getModelConfig();
141
+ if (!modelConfig?.idColumn) {
142
+ return undefined;
143
+ }
144
+ const data = (findAll(path) ?? []);
145
+ return data.find((record) => record[modelConfig.idColumn] === id);
146
+ };
147
+ const get = (path) => {
148
+ let data = queryClient.getQueryData(queryKey, { exact });
149
+ if (path) {
150
+ data = result(data, path);
151
+ }
152
+ return data;
153
+ };
154
+ const set = (newData, path) => {
155
+ if (path) {
156
+ const data = get();
157
+ newData = lodashSet(data, path, newData);
158
+ }
159
+ return queryClient.setQueryData(queryKey, newData);
160
+ };
161
+ const getModelConfig = () => {
162
+ const { options } = queryClient.getQueryData(['config']) ?? {};
163
+ const { modelConfig } = options ?? {};
164
+ return modelConfig;
165
+ };
166
+ const update = (id, data, path) => {
167
+ const oldData = (findAll(path) ?? []);
168
+ const modelConfig = getModelConfig();
169
+ if (!modelConfig?.idColumn) {
170
+ return undefined;
171
+ }
172
+ const idColumn = modelConfig.idColumn;
173
+ let updatedRecord = undefined;
174
+ const newData = oldData.map((record) => {
175
+ let dataRecord = record;
176
+ if (dataRecord[idColumn] === id) {
177
+ dataRecord = { ...dataRecord, ...data };
178
+ updatedRecord = dataRecord;
179
+ }
180
+ return dataRecord;
181
+ });
182
+ if (!path) {
183
+ queryClient.setQueryData(queryKey, newData);
184
+ }
185
+ else {
186
+ const queryData = queryClient.getQueryData(queryKey, { exact }) ?? {};
187
+ queryClient.setQueryData(queryKey, lodashSet(queryData, path, newData));
188
+ }
189
+ return updatedRecord;
190
+ };
191
+ const remove = (id, path) => {
192
+ const oldData = (findAll(path) ?? []);
193
+ const modelConfig = getModelConfig();
194
+ if (!modelConfig?.idColumn) {
195
+ return false;
196
+ }
197
+ const idColumn = modelConfig.idColumn;
198
+ let updated = false;
199
+ const newData = oldData.filter((record) => {
200
+ const dataRecord = record;
201
+ if (dataRecord[idColumn] === id) {
202
+ updated = true;
203
+ return false;
204
+ }
205
+ return true;
206
+ });
207
+ if (!path) {
208
+ queryClient.setQueryData(queryKey, newData);
209
+ }
210
+ else {
211
+ const queryData = queryClient.getQueryData(queryKey, { exact }) ?? {};
212
+ queryClient.setQueryData(queryKey, lodashSet(queryData, path, newData));
213
+ }
214
+ return updated;
215
+ };
216
+ return { find, findAll, findMany, remove, update, add, get, set };
217
+ };
218
+
219
+ const useRefetchQuery = async (queryKey) => {
220
+ const queryClient = useQueryClient();
221
+ const refetchQuery = async (innerQueryKey) => {
222
+ await queryClient.invalidateQueries({
223
+ queryKey: innerQueryKey ?? queryKey,
224
+ exact: true,
225
+ }, { throwOnError: true, cancelRefetch: true });
226
+ return queryClient.getQueriesData(innerQueryKey ?? queryKey);
227
+ };
228
+ return { refetchQuery };
229
+ };
230
+
231
+ const axiosInstance = ({ baseURL, timeout, headers }) => {
13
232
  return axios.create({
14
233
  baseURL,
15
234
  timeout,
@@ -19,12 +238,44 @@ const axiosInstance = ({ baseURL, timeout, headers, }) => {
19
238
 
20
239
  const buildFormData = (body) => {
21
240
  const formData = new FormData();
241
+ const handleArrayValue = (key, value) => {
242
+ for (const item of value) {
243
+ if (item instanceof File) {
244
+ formData.append(key, item);
245
+ }
246
+ else if (item instanceof Object) {
247
+ formData.append(key, JSON.stringify(item));
248
+ }
249
+ else {
250
+ formData.append(key, item);
251
+ }
252
+ }
253
+ };
254
+ const handleObjectValue = (key, value) => {
255
+ if (value instanceof File) {
256
+ formData.append(key, value);
257
+ }
258
+ else {
259
+ formData.append(key, JSON.stringify(value));
260
+ }
261
+ };
262
+ const handlePrimitiveValue = (key, value) => {
263
+ formData.append(key, value);
264
+ };
22
265
  const bodyKeys = Object.keys(body);
23
266
  bodyKeys.forEach((key) => {
24
- formData.append(key, body[key]);
267
+ const inputValue = body[key];
268
+ if (Array.isArray(inputValue) && inputValue.length > 0) {
269
+ handleArrayValue(key, inputValue);
270
+ }
271
+ else if (inputValue instanceof Object) {
272
+ handleObjectValue(key, inputValue);
273
+ }
274
+ else {
275
+ handlePrimitiveValue(key, inputValue);
276
+ }
25
277
  });
26
- body = formData;
27
- return body;
278
+ return formData;
28
279
  };
29
280
 
30
281
  var HttpMethod;
@@ -62,17 +313,41 @@ const successTransformer = (data) => {
62
313
  };
63
314
  };
64
315
 
65
- async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, headers = {}, baseURL, timeout, }) {
316
+ async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, headers = {}, baseURL, timeout, appFileConfig, }) {
317
+ // check if file is included in mobile app environment and extract all file input to avoid
318
+ // it being formatted to object using axios formData builder
319
+ const isApp = appFileConfig?.isApp;
320
+ const appFiles = isApp ? getAppFiles(body, appFileConfig.fileSelectors) : {};
66
321
  // configure body
67
- body = isFormData ? buildFormData(body) : body;
68
- // configure request header
322
+ body = (isFormData ? axios.toFormData(body) : body);
323
+ // configure request header1
69
324
  if (!isFormData) {
70
325
  headers['Content-Type'] = ContentType.APPLICATION_JSON;
71
326
  }
327
+ else {
328
+ if (isApp) {
329
+ headers['Content-Type'] = ContentType.MULTIPART_FORM_DATA;
330
+ // add the app files
331
+ for (const fileKey in appFiles) {
332
+ const currentFile = appFiles[fileKey];
333
+ if (Array.isArray(currentFile)) {
334
+ for (const innerFile of currentFile) {
335
+ body.append(fileKey, innerFile);
336
+ }
337
+ }
338
+ else {
339
+ body.append(fileKey, currentFile);
340
+ }
341
+ }
342
+ }
343
+ else {
344
+ delete headers['Content-Type'];
345
+ }
346
+ }
72
347
  try {
73
- const axios = axiosInstance({ baseURL, headers, timeout });
348
+ const axiosRequest = axiosInstance({ baseURL, headers, timeout });
74
349
  // send request
75
- const resp = await axios({
350
+ const resp = await axiosRequest({
76
351
  url: path,
77
352
  method,
78
353
  data: body,
@@ -86,90 +361,107 @@ async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, he
86
361
  return errorTransformer({ ...jsonResp, statusCode: responseCode });
87
362
  }
88
363
  return successTransformer({
89
- data: jsonResp,
90
364
  statusCode: responseCode,
365
+ ...jsonResp,
366
+ status: resp.status,
91
367
  });
92
368
  }
93
369
  catch (error) {
370
+ const errorData = error?.response?.data;
94
371
  return errorTransformer({
95
372
  statusCode: error.status,
96
373
  message: error.message,
97
374
  code: error.status || error.statusCode,
375
+ ...errorData,
98
376
  });
99
377
  }
378
+ }
379
+ function getAppFiles(body, fileSelectors = []) {
380
+ const files = {};
381
+ if (body) {
382
+ if (fileSelectors.length > 0) {
383
+ //
384
+ for (const fileKey of fileSelectors) {
385
+ files[fileKey] = body[fileKey];
386
+ delete body[fileKey];
387
+ }
388
+ }
389
+ }
390
+ return files;
100
391
  }
101
392
 
102
- const useQueryConfig = () => {
103
- const queryClient = useQueryClient();
104
- const { headers, baseURL, timeout } = queryClient.getQueryData([
105
- 'config',
106
- ]);
107
- return { headers, baseURL, timeout };
108
- };
109
-
110
- const useDeleteRequest = () => {
393
+ const useDeleteRequest = (deleteOptions) => {
394
+ const { baseUrl, headers } = deleteOptions ?? {};
111
395
  const [requestPath, updateDeletePath] = useState('');
112
396
  const [options, setOptions] = useState();
113
- const { headers, baseURL, timeout } = useQueryConfig();
114
- const query = useQuery([requestPath, {}], () => new Promise((res, rej) => {
115
- setTimeout(async () => {
116
- const postResponse = await makeRequest({
117
- path: requestPath,
118
- headers,
119
- method: HttpMethod.DELETE,
120
- baseURL,
121
- timeout,
122
- });
123
- if (postResponse.status) {
124
- res(postResponse);
125
- }
126
- else {
127
- rej(postResponse);
128
- }
129
- }, 200);
130
- }), { ...options });
397
+ const { API_URL, TIMEOUT } = useEnvironmentVariables();
398
+ const { getHeaders } = useQueryHeaders();
399
+ const sendRequest = async (res, rej) => {
400
+ // get request headers
401
+ const globalHeaders = getHeaders();
402
+ const postResponse = await makeRequest({
403
+ path: requestPath,
404
+ headers: { ...globalHeaders, ...headers },
405
+ method: HttpMethod.DELETE,
406
+ baseURL: baseUrl ?? API_URL,
407
+ timeout: TIMEOUT,
408
+ });
409
+ if (postResponse.status) {
410
+ res(postResponse);
411
+ }
412
+ else {
413
+ rej(postResponse);
414
+ }
415
+ };
416
+ const query = useQuery([requestPath, {}], () => new Promise((res, rej) => sendRequest(res, rej)), { enabled: false, ...options });
131
417
  const updatedPathAsync = async (link) => {
132
418
  return updateDeletePath(link);
133
419
  };
134
420
  const setOptionsAsync = async (fetchOptions) => {
135
421
  return setOptions(fetchOptions);
136
422
  };
137
- const destroy = async (link, deleteOptions) => {
423
+ const destroy = async (link, internalDeleteOptions) => {
138
424
  // set enabled to be true for every delete
139
- deleteOptions = deleteOptions ?? {};
140
- deleteOptions.enabled = true;
425
+ internalDeleteOptions = internalDeleteOptions ?? {};
426
+ internalDeleteOptions.enabled = true;
427
+ await setOptionsAsync(internalDeleteOptions);
141
428
  await updatedPathAsync(link);
142
- await setOptionsAsync(deleteOptions);
143
- // return query.refetch<TResponse>({
144
- // queryKey: [link, {}],
145
- // });
146
429
  return query.data;
147
430
  };
148
431
  return { destroy, ...query };
149
432
  };
150
433
 
151
- const useGetRequest = ({ path, load = false, queryOptions, }) => {
434
+ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
152
435
  const [requestPath, updatePath] = useState(path);
153
436
  const [options, setOptions] = useState(queryOptions);
154
437
  const [page, setPage] = useState(1);
155
- const { headers, baseURL, timeout } = useQueryConfig();
438
+ const { API_URL, TIMEOUT } = useEnvironmentVariables();
439
+ const { getHeaders } = useQueryHeaders();
440
+ let queryClient = useQueryClient();
441
+ // eslint-disable-next-line react-hooks/exhaustive-deps
442
+ queryClient = useMemo(() => queryClient, []);
156
443
  const sendRequest = async (res, rej) => {
157
- const postResponse = await makeRequest({
158
- path: requestPath,
159
- headers,
160
- baseURL,
161
- timeout,
162
- });
163
- if (postResponse.status) {
164
- res(postResponse);
444
+ if (load) {
445
+ // get request headers
446
+ const globalHeaders = getHeaders();
447
+ const getResponse = await makeRequest({
448
+ path: requestPath,
449
+ headers: { ...globalHeaders, ...headers },
450
+ baseURL: baseUrl ?? API_URL,
451
+ timeout: TIMEOUT,
452
+ });
453
+ if (getResponse.status) {
454
+ res(getResponse);
455
+ }
456
+ else {
457
+ rej(getResponse);
458
+ }
165
459
  }
166
460
  else {
167
- rej(postResponse);
461
+ res(null);
168
462
  }
169
463
  };
170
- const query = useQuery([requestPath, {}], () => new Promise((res, rej) => {
171
- return sendRequest(res, rej);
172
- }), {
464
+ const query = useQuery([requestPath, {}], () => new Promise((res, rej) => sendRequest(res, rej)), {
173
465
  enabled: load,
174
466
  ...options,
175
467
  });
@@ -178,11 +470,20 @@ const useGetRequest = ({ path, load = false, queryOptions, }) => {
178
470
  updatePath(path);
179
471
  }
180
472
  }, [path]);
473
+ useEffect(() => {
474
+ if (keyTracker) {
475
+ // set expiration time for the tracker
476
+ queryClient.setQueryDefaults([keyTracker], {
477
+ cacheTime: Infinity,
478
+ staleTime: Infinity,
479
+ });
480
+ queryClient.setQueryData([keyTracker], [requestPath, {}]);
481
+ }
482
+ }, [keyTracker, requestPath, queryClient, queryOptions?.staleTime]);
181
483
  const nextPage = () => {
182
484
  if (query.data?.data.pagination) {
183
485
  const pagination = query.data.data.pagination;
184
- if (pagination.next_page !== pagination.current_page &&
185
- pagination.next_page > pagination.current_page) {
486
+ if (pagination.next_page !== pagination.current_page && pagination.next_page > pagination.current_page) {
186
487
  updatePath(constructPaginationLink(requestPath, pagination.next_page));
187
488
  }
188
489
  }
@@ -190,17 +491,15 @@ const useGetRequest = ({ path, load = false, queryOptions, }) => {
190
491
  const prevPage = () => {
191
492
  if (query.data?.data.pagination) {
192
493
  const pagination = query.data.data.pagination;
193
- if (pagination.previous_page !== pagination.current_page &&
194
- pagination.previous_page < pagination.current_page) {
494
+ if (pagination.previous_page !== pagination.current_page && pagination.previous_page < pagination.current_page) {
195
495
  updatePath(constructPaginationLink(requestPath, pagination.previous_page));
196
496
  }
197
497
  }
198
498
  };
199
499
  const constructPaginationLink = (link, pageNumber) => {
200
- const oldParams = new URLSearchParams(link);
201
- const oldPage = Number(oldParams.get('page'));
202
- const [pathname, queryStrings] = link.split('?', 1);
203
- const queryParams = new URLSearchParams(queryStrings ?? '');
500
+ const [pathname, queryString] = link.split('?');
501
+ const queryParams = new URLSearchParams(queryString);
502
+ const oldPage = Number(queryParams.get('page'));
204
503
  queryParams.set('page', pageNumber);
205
504
  link = pathname + '?' + queryParams.toString();
206
505
  // only update page when pagination number changed
@@ -239,75 +538,91 @@ const useGetRequest = ({ path, load = false, queryOptions, }) => {
239
538
  };
240
539
  };
241
540
 
242
- const usePatchRequest = ({ path, }) => {
243
- const { headers, baseURL, timeout } = useQueryConfig();
244
- // register post mutation
245
- const mutation = useMutation((postData) => new Promise((res, rej) => {
246
- makeRequest({
541
+ const usePatchRequest = ({ path, baseUrl, headers }) => {
542
+ const { API_URL, TIMEOUT } = useEnvironmentVariables();
543
+ const { getHeaders } = useQueryHeaders();
544
+ const queryClient = useQueryClient();
545
+ const config = queryClient.getQueryData(['config']);
546
+ const sendRequest = async (res, rej, data) => {
547
+ // get request headers
548
+ const globalHeaders = getHeaders();
549
+ const patchResponse = await makeRequest({
247
550
  path: path,
248
- body: postData,
551
+ body: data,
249
552
  method: HttpMethod.PATCH,
250
- headers,
251
- baseURL,
252
- timeout,
253
- }).then((postResponse) => {
254
- if (postResponse.status) {
255
- // scroll to top after success
553
+ headers: { ...globalHeaders, ...headers },
554
+ baseURL: baseUrl ?? API_URL,
555
+ timeout: TIMEOUT,
556
+ });
557
+ if (patchResponse.status) {
558
+ // scroll to top after success
559
+ if (config?.options?.context !== 'app') {
256
560
  scrollToTop();
257
- res(postResponse);
258
561
  }
259
- else {
260
- // scroll to top after error
261
- window.scrollTo({
262
- top: 0,
263
- behavior: 'smooth',
264
- });
265
- rej(postResponse);
562
+ res(patchResponse);
563
+ }
564
+ else {
565
+ // scroll to top after error
566
+ if (config?.options?.context !== 'app') {
567
+ scrollToTop();
266
568
  }
267
- });
569
+ rej(patchResponse);
570
+ }
571
+ };
572
+ // register post mutation
573
+ const mutation = useMutation((dataData) => new Promise((res, rej) => {
574
+ return sendRequest(res, rej, dataData);
268
575
  }));
269
- const patch = async (postData, options) => {
270
- return mutation.mutateAsync(postData, options);
576
+ const patch = async (data, options) => {
577
+ return mutation.mutateAsync(data, options);
271
578
  };
272
579
  return { patch, ...mutation };
273
580
  };
274
581
 
275
- const usePostRequest = ({ path, isFormData = false, }) => {
276
- const { headers, baseURL, timeout } = useQueryConfig();
277
- // register post mutation
278
- const mutation = useMutation(async (postData) => new Promise((res, rej) => {
279
- makeRequest({
280
- path: path,
582
+ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelectors, }) => {
583
+ const { API_URL, TIMEOUT } = useEnvironmentVariables();
584
+ const queryClient = useQueryClient();
585
+ const { getHeaders } = useQueryHeaders();
586
+ const { isApp } = useReactNativeEnv();
587
+ const sendRequest = async (res, rej, postData) => {
588
+ // get request headers
589
+ const globalHeaders = getHeaders();
590
+ const config = queryClient.getQueryData(['config']);
591
+ const postResponse = await makeRequest({
592
+ path,
281
593
  body: postData,
282
594
  method: HttpMethod.POST,
283
595
  isFormData,
284
- headers,
285
- baseURL,
286
- timeout,
287
- }).then((postResponse) => {
288
- if (postResponse.status) {
289
- // scroll to top after success
290
- window.scrollTo({
291
- top: 0,
292
- behavior: 'smooth',
293
- });
294
- res(postResponse);
596
+ headers: { ...globalHeaders, ...headers },
597
+ baseURL: baseUrl ?? API_URL,
598
+ timeout: TIMEOUT,
599
+ appFileConfig: {
600
+ isApp,
601
+ fileSelectors,
602
+ },
603
+ });
604
+ if (postResponse.status) {
605
+ // scroll to top after success
606
+ if (config?.options?.context !== 'app') {
607
+ scrollToTop();
295
608
  }
296
- else {
297
- // scroll to top after error
298
- window.scrollTo({
299
- top: 0,
300
- behavior: 'smooth',
301
- });
302
- rej(postResponse);
609
+ res(postResponse);
610
+ }
611
+ else {
612
+ // scroll to top after error
613
+ if (config?.options?.context !== 'app') {
614
+ scrollToTop();
303
615
  }
304
- });
305
- }));
306
- const post = async (postData, options) => {
307
- return mutation.mutateAsync(postData, options);
616
+ rej(postResponse);
617
+ }
618
+ };
619
+ // register post mutation
620
+ const mutation = useMutation(async (postData) => new Promise((res, rej) => sendRequest(res, rej, postData)));
621
+ const post = async (data, options) => {
622
+ return mutation.mutateAsync(data, options);
308
623
  };
309
624
  return { post, ...mutation };
310
625
  };
311
626
 
312
- export { ContentType, HttpMethod, axiosInstance, buildFormData, errorTransformer, makeRequest, scrollToTop, successTransformer, useDeleteRequest, useGetRequest, usePatchRequest, usePostRequest, useQueryConfig };
627
+ export { ContentType, HttpMethod, axiosInstance, bootstrapQueryRequest, buildFormData, errorTransformer, getDateInFuture, makeRequest, scrollToTop, successTransformer, useDeleteRequest, useEnvironmentVariables, useGetRequest, useKeyTrackerModel, usePatchRequest, usePostRequest, useQueryConfig, useQueryHeaders, useQueryModel, useReactNativeEnv, useRefetchQuery };
313
628
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,4 @@
1
+ export * from './model.interface';
2
+ export * from './useKeyTrackerModel';
3
+ export * from './useQueryModel';
4
+ export * from './useRefetchQuery';