@ventlio/tanstack-query 0.2.6 → 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 (100) 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 +4 -2
  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 +5 -9
  12. package/dist/config/useQueryConfig.js.map +1 -1
  13. package/dist/config/useQueryHeaders.js +19 -10
  14. package/dist/config/useQueryHeaders.js.map +1 -1
  15. package/dist/config/useReactNativeEnv.d.ts +5 -0
  16. package/dist/config/useReactNativeEnv.js +13 -0
  17. package/dist/config/useReactNativeEnv.js.map +1 -0
  18. package/dist/helpers/index.d.ts +1 -0
  19. package/dist/helpers/scrollToTop.js +1 -3
  20. package/dist/helpers/scrollToTop.js.map +1 -1
  21. package/dist/helpers/timeFuncs.d.ts +1 -0
  22. package/dist/helpers/timeFuncs.js +11 -0
  23. package/dist/helpers/timeFuncs.js.map +1 -0
  24. package/dist/index.js +19 -43
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +417 -143
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/model/index.d.ts +3 -0
  29. package/dist/model/model.interface.d.ts +11 -0
  30. package/dist/model/useKeyTrackerModel.d.ts +4 -0
  31. package/dist/model/useKeyTrackerModel.js +20 -0
  32. package/dist/model/useKeyTrackerModel.js.map +1 -0
  33. package/dist/model/useQueryModel.d.ts +2 -2
  34. package/dist/model/useQueryModel.js +119 -7
  35. package/dist/model/useQueryModel.js.map +1 -1
  36. package/dist/model/useRefetchQuery.d.ts +3 -0
  37. package/dist/model/useRefetchQuery.js +16 -0
  38. package/dist/model/useRefetchQuery.js.map +1 -0
  39. package/dist/queries/queries.interface.d.ts +5 -0
  40. package/dist/queries/useDeleteRequest.d.ts +14 -5
  41. package/dist/queries/useDeleteRequest.js +37 -37
  42. package/dist/queries/useGetRequest.d.ts +4 -3
  43. package/dist/queries/useGetRequest.js +53 -37
  44. package/dist/queries/useGetRequest.js.map +1 -1
  45. package/dist/queries/usePatchRequest.d.ts +7 -7
  46. package/dist/queries/usePatchRequest.js +42 -34
  47. package/dist/queries/usePatchRequest.js.map +1 -1
  48. package/dist/queries/usePostRequest.d.ts +8 -6
  49. package/dist/queries/usePostRequest.js +47 -37
  50. package/dist/queries/usePostRequest.js.map +1 -1
  51. package/dist/request/axios-instance.d.ts +1 -1
  52. package/dist/request/axios-instance.js +3 -5
  53. package/dist/request/axios-instance.js.map +1 -1
  54. package/dist/request/buildFormData.d.ts +1 -1
  55. package/dist/request/buildFormData.js +36 -6
  56. package/dist/request/buildFormData.js.map +1 -1
  57. package/dist/request/make-request.d.ts +1 -1
  58. package/dist/request/make-request.js +55 -17
  59. package/dist/request/make-request.js.map +1 -1
  60. package/dist/request/request.enum.js +6 -6
  61. package/dist/request/request.interface.d.ts +5 -0
  62. package/dist/request/transformer.js +1 -4
  63. package/dist/request/transformer.js.map +1 -1
  64. package/dist/types/index.d.ts +14 -11
  65. package/package.json +29 -5
  66. package/src/__tests__/queries/usePostRequest.spec.ts +77 -0
  67. package/src/config/bootstrapQueryRequest.ts +19 -0
  68. package/src/config/config.interface.ts +4 -0
  69. package/src/config/index.ts +4 -2
  70. package/src/config/useEnvironmentVariables.ts +13 -0
  71. package/src/config/useQueryConfig.ts +2 -5
  72. package/src/config/useQueryHeaders.ts +23 -6
  73. package/src/config/useReactNativeEnv.ts +13 -0
  74. package/src/env.d.ts +4 -0
  75. package/src/helpers/index.ts +1 -0
  76. package/src/helpers/timeFuncs.ts +10 -0
  77. package/src/model/index.ts +3 -0
  78. package/src/model/model.interface.ts +12 -0
  79. package/src/model/useKeyTrackerModel.ts +22 -0
  80. package/src/model/useQueryModel.ts +139 -6
  81. package/src/model/useRefetchQuery.ts +19 -0
  82. package/src/queries/queries.interface.ts +6 -0
  83. package/src/queries/useDeleteRequest.ts +34 -30
  84. package/src/queries/useGetRequest.ts +55 -38
  85. package/src/queries/usePatchRequest.ts +45 -40
  86. package/src/queries/usePostRequest.ts +54 -37
  87. package/src/request/axios-instance.ts +1 -5
  88. package/src/request/buildFormData.ts +34 -4
  89. package/src/request/make-request.ts +47 -7
  90. package/src/request/request.interface.ts +5 -0
  91. package/src/request/transformer.ts +3 -12
  92. package/src/types/index.ts +16 -13
  93. package/dist/config/useQueryBaseURL.d.ts +0 -2
  94. package/dist/config/useQueryBaseURL.js +0 -19
  95. package/dist/config/useQueryBaseURL.js.map +0 -1
  96. package/dist/config/useQueryTimeout.d.ts +0 -2
  97. package/dist/config/useQueryTimeout.js +0 -19
  98. package/dist/config/useQueryTimeout.js.map +0 -1
  99. package/src/config/useQueryBaseURL.ts +0 -17
  100. package/src/config/useQueryTimeout.ts +0 -17
package/dist/index.mjs CHANGED
@@ -1,64 +1,234 @@
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
 
5
- const useQueryConfig = () => {
6
- const queryClient = useQueryClient();
7
- const { headers, baseURL, timeout } = queryClient.getQueryData([
8
- 'config',
9
- ]);
10
- return { headers, baseURL, timeout };
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
+ });
11
21
  };
12
22
 
13
- const useQueryBaseURL = () => {
14
- const { baseURL } = useQueryConfig();
23
+ const useReactNativeEnv = () => {
15
24
  const queryClient = useQueryClient();
16
- const setQueryBaseUrl = (newBaseUrl) => {
17
- queryClient.setQueryData(['config'], (config) => {
18
- config.baseURL = newBaseUrl;
19
- return config;
20
- });
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),
21
39
  };
22
- return { baseURL, setQueryBaseUrl };
23
40
  };
24
41
 
42
+ const useQueryConfig = () => {
43
+ const queryClient = useQueryClient();
44
+ const { headers = {}, options = {} } = queryClient.getQueryData(['config']) ?? {};
45
+ return { headers, options };
46
+ };
47
+
48
+ const scrollToTop = () => {
49
+ window.scrollTo({
50
+ top: 0,
51
+ behavior: 'smooth',
52
+ });
53
+ };
54
+
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
+
25
64
  const useQueryHeaders = () => {
26
- const { headers } = useQueryConfig();
27
65
  const queryClient = useQueryClient();
66
+ const getHeaders = () => {
67
+ const config = queryClient.getQueryData(['config']);
68
+ return config.headers;
69
+ };
28
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
29
77
  queryClient.setQueryData(['config'], (config) => {
30
- config.headers = newHeaders;
31
- return config;
78
+ const newConfig = { ...config, headers: newHeaders };
79
+ return newConfig;
80
+ }, {
81
+ updatedAt: getDateInFuture(2),
32
82
  });
33
83
  };
34
- return { headers, setQueryHeaders };
84
+ return { setQueryHeaders, getHeaders };
35
85
  };
36
86
 
37
- const useQueryTimeout = () => {
38
- const { timeout } = useQueryConfig();
87
+ const useKeyTrackerModel = (keyTracker) => {
39
88
  const queryClient = useQueryClient();
40
- const setQueryTimeout = (newTimeout) => {
41
- queryClient.setQueryData(['config'], (config) => {
42
- config.timeout = newTimeout;
43
- return config;
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,
44
98
  });
45
99
  };
46
- return { timeout, setQueryTimeout };
100
+ return { refetchQuery, getQueryKey };
47
101
  };
48
102
 
49
- const scrollToTop = () => {
50
- window.scrollTo({
51
- top: 0,
52
- behavior: 'smooth',
53
- });
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 };
54
217
  };
55
218
 
56
- const useQueryModel = (queryKey, filters) => {
219
+ const useRefetchQuery = async (queryKey) => {
57
220
  const queryClient = useQueryClient();
58
- return queryClient.getQueryData(queryKey, filters);
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 };
59
229
  };
60
230
 
61
- const axiosInstance = ({ baseURL, timeout, headers, }) => {
231
+ const axiosInstance = ({ baseURL, timeout, headers }) => {
62
232
  return axios.create({
63
233
  baseURL,
64
234
  timeout,
@@ -68,12 +238,44 @@ const axiosInstance = ({ baseURL, timeout, headers, }) => {
68
238
 
69
239
  const buildFormData = (body) => {
70
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
+ };
71
265
  const bodyKeys = Object.keys(body);
72
266
  bodyKeys.forEach((key) => {
73
- 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
+ }
74
277
  });
75
- body = formData;
76
- return body;
278
+ return formData;
77
279
  };
78
280
 
79
281
  var HttpMethod;
@@ -111,17 +313,41 @@ const successTransformer = (data) => {
111
313
  };
112
314
  };
113
315
 
114
- 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) : {};
115
321
  // configure body
116
- body = isFormData ? buildFormData(body) : body;
117
- // configure request header
322
+ body = (isFormData ? axios.toFormData(body) : body);
323
+ // configure request header1
118
324
  if (!isFormData) {
119
325
  headers['Content-Type'] = ContentType.APPLICATION_JSON;
120
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
+ }
121
347
  try {
122
- const axios = axiosInstance({ baseURL, headers, timeout });
348
+ const axiosRequest = axiosInstance({ baseURL, headers, timeout });
123
349
  // send request
124
- const resp = await axios({
350
+ const resp = await axiosRequest({
125
351
  url: path,
126
352
  method,
127
353
  data: body,
@@ -135,82 +361,107 @@ async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, he
135
361
  return errorTransformer({ ...jsonResp, statusCode: responseCode });
136
362
  }
137
363
  return successTransformer({
138
- data: jsonResp,
139
364
  statusCode: responseCode,
365
+ ...jsonResp,
366
+ status: resp.status,
140
367
  });
141
368
  }
142
369
  catch (error) {
370
+ const errorData = error?.response?.data;
143
371
  return errorTransformer({
144
372
  statusCode: error.status,
145
373
  message: error.message,
146
374
  code: error.status || error.statusCode,
375
+ ...errorData,
147
376
  });
148
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;
149
391
  }
150
392
 
151
- const useDeleteRequest = () => {
393
+ const useDeleteRequest = (deleteOptions) => {
394
+ const { baseUrl, headers } = deleteOptions ?? {};
152
395
  const [requestPath, updateDeletePath] = useState('');
153
396
  const [options, setOptions] = useState();
154
- const { headers, baseURL, timeout } = useQueryConfig();
155
- const query = useQuery([requestPath, {}], () => new Promise((res, rej) => {
156
- setTimeout(async () => {
157
- const postResponse = await makeRequest({
158
- path: requestPath,
159
- headers,
160
- method: HttpMethod.DELETE,
161
- baseURL,
162
- timeout,
163
- });
164
- if (postResponse.status) {
165
- res(postResponse);
166
- }
167
- else {
168
- rej(postResponse);
169
- }
170
- }, 200);
171
- }), { ...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 });
172
417
  const updatedPathAsync = async (link) => {
173
418
  return updateDeletePath(link);
174
419
  };
175
420
  const setOptionsAsync = async (fetchOptions) => {
176
421
  return setOptions(fetchOptions);
177
422
  };
178
- const destroy = async (link, deleteOptions) => {
423
+ const destroy = async (link, internalDeleteOptions) => {
179
424
  // set enabled to be true for every delete
180
- deleteOptions = deleteOptions ?? {};
181
- deleteOptions.enabled = true;
425
+ internalDeleteOptions = internalDeleteOptions ?? {};
426
+ internalDeleteOptions.enabled = true;
427
+ await setOptionsAsync(internalDeleteOptions);
182
428
  await updatedPathAsync(link);
183
- await setOptionsAsync(deleteOptions);
184
- // return query.refetch<TResponse>({
185
- // queryKey: [link, {}],
186
- // });
187
429
  return query.data;
188
430
  };
189
431
  return { destroy, ...query };
190
432
  };
191
433
 
192
- const useGetRequest = ({ path, load = false, queryOptions, }) => {
434
+ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
193
435
  const [requestPath, updatePath] = useState(path);
194
436
  const [options, setOptions] = useState(queryOptions);
195
437
  const [page, setPage] = useState(1);
196
- 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, []);
197
443
  const sendRequest = async (res, rej) => {
198
- const postResponse = await makeRequest({
199
- path: requestPath,
200
- headers,
201
- baseURL,
202
- timeout,
203
- });
204
- if (postResponse.status) {
205
- 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
+ }
206
459
  }
207
460
  else {
208
- rej(postResponse);
461
+ res(null);
209
462
  }
210
463
  };
211
- const query = useQuery([requestPath, {}], () => new Promise((res, rej) => {
212
- return sendRequest(res, rej);
213
- }), {
464
+ const query = useQuery([requestPath, {}], () => new Promise((res, rej) => sendRequest(res, rej)), {
214
465
  enabled: load,
215
466
  ...options,
216
467
  });
@@ -219,11 +470,20 @@ const useGetRequest = ({ path, load = false, queryOptions, }) => {
219
470
  updatePath(path);
220
471
  }
221
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]);
222
483
  const nextPage = () => {
223
484
  if (query.data?.data.pagination) {
224
485
  const pagination = query.data.data.pagination;
225
- if (pagination.next_page !== pagination.current_page &&
226
- pagination.next_page > pagination.current_page) {
486
+ if (pagination.next_page !== pagination.current_page && pagination.next_page > pagination.current_page) {
227
487
  updatePath(constructPaginationLink(requestPath, pagination.next_page));
228
488
  }
229
489
  }
@@ -231,17 +491,15 @@ const useGetRequest = ({ path, load = false, queryOptions, }) => {
231
491
  const prevPage = () => {
232
492
  if (query.data?.data.pagination) {
233
493
  const pagination = query.data.data.pagination;
234
- if (pagination.previous_page !== pagination.current_page &&
235
- pagination.previous_page < pagination.current_page) {
494
+ if (pagination.previous_page !== pagination.current_page && pagination.previous_page < pagination.current_page) {
236
495
  updatePath(constructPaginationLink(requestPath, pagination.previous_page));
237
496
  }
238
497
  }
239
498
  };
240
499
  const constructPaginationLink = (link, pageNumber) => {
241
- const oldParams = new URLSearchParams(link);
242
- const oldPage = Number(oldParams.get('page'));
243
- const [pathname, queryStrings] = link.split('?', 1);
244
- const queryParams = new URLSearchParams(queryStrings ?? '');
500
+ const [pathname, queryString] = link.split('?');
501
+ const queryParams = new URLSearchParams(queryString);
502
+ const oldPage = Number(queryParams.get('page'));
245
503
  queryParams.set('page', pageNumber);
246
504
  link = pathname + '?' + queryParams.toString();
247
505
  // only update page when pagination number changed
@@ -280,75 +538,91 @@ const useGetRequest = ({ path, load = false, queryOptions, }) => {
280
538
  };
281
539
  };
282
540
 
283
- const usePatchRequest = ({ path, }) => {
284
- const { headers, baseURL, timeout } = useQueryConfig();
285
- // register post mutation
286
- const mutation = useMutation((postData) => new Promise((res, rej) => {
287
- 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({
288
550
  path: path,
289
- body: postData,
551
+ body: data,
290
552
  method: HttpMethod.PATCH,
291
- headers,
292
- baseURL,
293
- timeout,
294
- }).then((postResponse) => {
295
- if (postResponse.status) {
296
- // 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') {
297
560
  scrollToTop();
298
- res(postResponse);
299
561
  }
300
- else {
301
- // scroll to top after error
302
- window.scrollTo({
303
- top: 0,
304
- behavior: 'smooth',
305
- });
306
- rej(postResponse);
562
+ res(patchResponse);
563
+ }
564
+ else {
565
+ // scroll to top after error
566
+ if (config?.options?.context !== 'app') {
567
+ scrollToTop();
307
568
  }
308
- });
569
+ rej(patchResponse);
570
+ }
571
+ };
572
+ // register post mutation
573
+ const mutation = useMutation((dataData) => new Promise((res, rej) => {
574
+ return sendRequest(res, rej, dataData);
309
575
  }));
310
- const patch = async (postData, options) => {
311
- return mutation.mutateAsync(postData, options);
576
+ const patch = async (data, options) => {
577
+ return mutation.mutateAsync(data, options);
312
578
  };
313
579
  return { patch, ...mutation };
314
580
  };
315
581
 
316
- const usePostRequest = ({ path, isFormData = false, }) => {
317
- const { headers, baseURL, timeout } = useQueryConfig();
318
- // register post mutation
319
- const mutation = useMutation(async (postData) => new Promise((res, rej) => {
320
- makeRequest({
321
- 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,
322
593
  body: postData,
323
594
  method: HttpMethod.POST,
324
595
  isFormData,
325
- headers,
326
- baseURL,
327
- timeout,
328
- }).then((postResponse) => {
329
- if (postResponse.status) {
330
- // scroll to top after success
331
- window.scrollTo({
332
- top: 0,
333
- behavior: 'smooth',
334
- });
335
- 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();
336
608
  }
337
- else {
338
- // scroll to top after error
339
- window.scrollTo({
340
- top: 0,
341
- behavior: 'smooth',
342
- });
343
- rej(postResponse);
609
+ res(postResponse);
610
+ }
611
+ else {
612
+ // scroll to top after error
613
+ if (config?.options?.context !== 'app') {
614
+ scrollToTop();
344
615
  }
345
- });
346
- }));
347
- const post = async (postData, options) => {
348
- 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);
349
623
  };
350
624
  return { post, ...mutation };
351
625
  };
352
626
 
353
- export { ContentType, HttpMethod, axiosInstance, buildFormData, errorTransformer, makeRequest, scrollToTop, successTransformer, useDeleteRequest, useGetRequest, usePatchRequest, usePostRequest, useQueryBaseURL, useQueryConfig, useQueryHeaders, useQueryModel, useQueryTimeout };
627
+ export { ContentType, HttpMethod, axiosInstance, bootstrapQueryRequest, buildFormData, errorTransformer, getDateInFuture, makeRequest, scrollToTop, successTransformer, useDeleteRequest, useEnvironmentVariables, useGetRequest, useKeyTrackerModel, usePatchRequest, usePostRequest, useQueryConfig, useQueryHeaders, useQueryModel, useReactNativeEnv, useRefetchQuery };
354
628
  //# sourceMappingURL=index.mjs.map