@ventlio/tanstack-query 0.2.63 → 0.2.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/bootstrapQueryRequest.d.ts +2 -2
- package/dist/config/bootstrapQueryRequest.js +1 -1
- package/dist/config/useEnvironmentVariables.js +2 -2
- package/dist/config/useReactNativeEnv.d.ts +1 -0
- package/dist/config/useReactNativeEnv.js +5 -16
- package/dist/config/useReactNativeEnv.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +228 -30
- package/dist/index.mjs.map +1 -1
- package/dist/model/Model.d.ts +14 -0
- package/dist/model/Model.js +93 -0
- package/dist/model/Model.js.map +1 -0
- package/dist/model/index.d.ts +2 -0
- package/dist/model/model.interface.d.ts +7 -0
- package/dist/model/useQueryModel.d.ts +2 -2
- package/dist/model/useQueryModel.js +84 -2
- package/dist/model/useQueryModel.js.map +1 -1
- package/dist/queries/useDeleteRequest.js +1 -1
- package/dist/queries/usePatchRequest.js +0 -1
- package/dist/queries/usePatchRequest.js.map +1 -1
- package/dist/queries/usePostRequest.d.ts +2 -1
- package/dist/queries/usePostRequest.js +7 -2
- package/dist/queries/usePostRequest.js.map +1 -1
- package/dist/request/make-request.d.ts +1 -1
- package/dist/request/make-request.js +41 -7
- package/dist/request/make-request.js.map +1 -1
- package/dist/request/request.interface.d.ts +5 -0
- package/dist/types/index.d.ts +8 -3
- package/package.json +8 -2
- package/src/config/bootstrapQueryRequest.ts +3 -3
- package/src/config/useEnvironmentVariables.ts +2 -2
- package/src/config/useReactNativeEnv.ts +5 -20
- package/src/model/Model.ts +107 -0
- package/src/model/index.ts +2 -0
- package/src/model/model.interface.ts +10 -0
- package/src/model/useQueryModel.ts +123 -3
- package/src/queries/useDeleteRequest.ts +1 -1
- package/src/queries/usePostRequest.ts +8 -2
- package/src/request/make-request.ts +42 -6
- package/src/request/request.interface.ts +5 -0
- package/src/types/index.ts +9 -3
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { QueryClient } from '@tanstack/react-query';
|
|
2
|
-
import type {
|
|
3
|
-
export declare const bootstrapQueryRequest: (queryClient: QueryClient, options?:
|
|
2
|
+
import type { BootstrapConfig } from '../types';
|
|
3
|
+
export declare const bootstrapQueryRequest: (queryClient: QueryClient, options?: BootstrapConfig) => void;
|
|
@@ -2,8 +2,8 @@ import { useReactNativeEnv } from './useReactNativeEnv.js';
|
|
|
2
2
|
|
|
3
3
|
const useEnvironmentVariables = () => {
|
|
4
4
|
const { appTimeout, appUrl } = useReactNativeEnv();
|
|
5
|
-
const url = process.env.REACT_APP_API_URL
|
|
6
|
-
const timeout = process.env.REACT_APP_API_TIMEOUT
|
|
5
|
+
const url = process.env.REACT_APP_API_URL ?? process.env.NEXT_PUBLIC_API_URL ?? appUrl;
|
|
6
|
+
const timeout = process.env.REACT_APP_API_TIMEOUT ?? process.env.NEXT_PUBLIC_API_TIMEOUT ?? appTimeout;
|
|
7
7
|
return {
|
|
8
8
|
API_URL: url,
|
|
9
9
|
TIMEOUT: Number(timeout),
|
|
@@ -1,23 +1,12 @@
|
|
|
1
1
|
import { useQueryClient } from '@tanstack/react-query';
|
|
2
|
-
import { useState, useEffect } from 'react';
|
|
3
2
|
|
|
4
3
|
const useReactNativeEnv = () => {
|
|
5
4
|
const queryClient = useQueryClient();
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (config?.options?.context === 'app') {
|
|
12
|
-
const API_URL = config.options.environments?.appBaseUrl;
|
|
13
|
-
const API_TIMEOUT = config.options.environments?.appTimeout;
|
|
14
|
-
setAppUrl(API_URL);
|
|
15
|
-
setAppTimeout(API_TIMEOUT);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
loadReactNativeEnvIfNeeded();
|
|
19
|
-
}, [queryClient]);
|
|
20
|
-
return { appUrl, appTimeout };
|
|
5
|
+
const config = queryClient.getQueryData(['config']);
|
|
6
|
+
const appUrl = config?.options?.environments?.appBaseUrl;
|
|
7
|
+
const appTimeout = config?.options?.environments?.appTimeout;
|
|
8
|
+
const isApp = config?.options?.context === 'app';
|
|
9
|
+
return { appUrl, appTimeout, isApp };
|
|
21
10
|
};
|
|
22
11
|
|
|
23
12
|
export { useReactNativeEnv };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useReactNativeEnv.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useReactNativeEnv.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { useQueryHeaders } from './config/useQueryHeaders.js';
|
|
|
5
5
|
export { useReactNativeEnv } from './config/useReactNativeEnv.js';
|
|
6
6
|
export { scrollToTop } from './helpers/scrollToTop.js';
|
|
7
7
|
export { getDateInFuture } from './helpers/timeFuncs.js';
|
|
8
|
+
export { QueryModel } from './model/Model.js';
|
|
8
9
|
export { useKeyTrackerModel } from './model/useKeyTrackerModel.js';
|
|
9
10
|
export { useQueryModel } from './model/useQueryModel.js';
|
|
10
11
|
export { useRefetchQuery } from './model/useRefetchQuery.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
|
|
2
|
-
import
|
|
2
|
+
import result from 'lodash.result';
|
|
3
|
+
import set from 'lodash.set';
|
|
4
|
+
import { useState, useMemo, useEffect, startTransition } from 'react';
|
|
3
5
|
import axios from 'axios';
|
|
4
6
|
|
|
5
7
|
const bootstrapQueryRequest = (queryClient, options) => {
|
|
@@ -8,7 +10,7 @@ const bootstrapQueryRequest = (queryClient, options) => {
|
|
|
8
10
|
staleTime: Infinity,
|
|
9
11
|
cacheTime: Infinity,
|
|
10
12
|
});
|
|
11
|
-
// set default query
|
|
13
|
+
// set default query config
|
|
12
14
|
queryClient.setQueryData(['config'], {
|
|
13
15
|
headers: {
|
|
14
16
|
Authorization: ``,
|
|
@@ -19,27 +21,17 @@ const bootstrapQueryRequest = (queryClient, options) => {
|
|
|
19
21
|
|
|
20
22
|
const useReactNativeEnv = () => {
|
|
21
23
|
const queryClient = useQueryClient();
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (config?.options?.context === 'app') {
|
|
28
|
-
const API_URL = config.options.environments?.appBaseUrl;
|
|
29
|
-
const API_TIMEOUT = config.options.environments?.appTimeout;
|
|
30
|
-
setAppUrl(API_URL);
|
|
31
|
-
setAppTimeout(API_TIMEOUT);
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
loadReactNativeEnvIfNeeded();
|
|
35
|
-
}, [queryClient]);
|
|
36
|
-
return { appUrl, appTimeout };
|
|
24
|
+
const config = queryClient.getQueryData(['config']);
|
|
25
|
+
const appUrl = config?.options?.environments?.appBaseUrl;
|
|
26
|
+
const appTimeout = config?.options?.environments?.appTimeout;
|
|
27
|
+
const isApp = config?.options?.context === 'app';
|
|
28
|
+
return { appUrl, appTimeout, isApp };
|
|
37
29
|
};
|
|
38
30
|
|
|
39
31
|
const useEnvironmentVariables = () => {
|
|
40
32
|
const { appTimeout, appUrl } = useReactNativeEnv();
|
|
41
|
-
const url = process.env.REACT_APP_API_URL
|
|
42
|
-
const timeout = process.env.REACT_APP_API_TIMEOUT
|
|
33
|
+
const url = process.env.REACT_APP_API_URL ?? process.env.NEXT_PUBLIC_API_URL ?? appUrl;
|
|
34
|
+
const timeout = process.env.REACT_APP_API_TIMEOUT ?? process.env.NEXT_PUBLIC_API_TIMEOUT ?? appTimeout;
|
|
43
35
|
return {
|
|
44
36
|
API_URL: url,
|
|
45
37
|
TIMEOUT: Number(timeout),
|
|
@@ -91,6 +83,94 @@ const useQueryHeaders = () => {
|
|
|
91
83
|
return { setQueryHeaders, getHeaders };
|
|
92
84
|
};
|
|
93
85
|
|
|
86
|
+
class QueryModel {
|
|
87
|
+
queryKey;
|
|
88
|
+
queryClient;
|
|
89
|
+
exact;
|
|
90
|
+
constructor(queryKey, queryClient, exact = true) {
|
|
91
|
+
this.queryKey = queryKey;
|
|
92
|
+
this.queryClient = queryClient;
|
|
93
|
+
this.exact = exact;
|
|
94
|
+
}
|
|
95
|
+
findAll(path) {
|
|
96
|
+
const data = this.queryClient.getQueryData(this.queryKey, { exact: this.exact });
|
|
97
|
+
if (!data) {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
if (!path) {
|
|
101
|
+
return Array.isArray(data) ? data : [data];
|
|
102
|
+
}
|
|
103
|
+
return result(data, path, []);
|
|
104
|
+
}
|
|
105
|
+
findMany(selector, path) {
|
|
106
|
+
const data = this.findAll(path) ?? [];
|
|
107
|
+
return data.filter(selector);
|
|
108
|
+
}
|
|
109
|
+
find(id, path) {
|
|
110
|
+
const modelConfig = this.getModelConfig();
|
|
111
|
+
if (!modelConfig?.idColumn) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
const data = this.findAll(path) ?? [];
|
|
115
|
+
return data.find((record) => record[modelConfig.idColumn] === id);
|
|
116
|
+
}
|
|
117
|
+
update(id, data, path) {
|
|
118
|
+
const oldData = this.findAll(path) ?? [];
|
|
119
|
+
const modelConfig = this.getModelConfig();
|
|
120
|
+
if (!modelConfig?.idColumn) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
const idColumn = modelConfig.idColumn;
|
|
124
|
+
let updatedRecord = undefined;
|
|
125
|
+
const newData = oldData.map((record) => {
|
|
126
|
+
let dataRecord = record;
|
|
127
|
+
if (dataRecord[idColumn] === id) {
|
|
128
|
+
dataRecord = { ...dataRecord, ...data };
|
|
129
|
+
updatedRecord = dataRecord;
|
|
130
|
+
}
|
|
131
|
+
return dataRecord;
|
|
132
|
+
});
|
|
133
|
+
if (!path) {
|
|
134
|
+
this.queryClient.setQueryData(this.queryKey, newData);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const queryData = this.queryClient.getQueryData(this.queryKey, { exact: this.exact }) ?? {};
|
|
138
|
+
this.queryClient.setQueryData(this.queryKey, set(queryData, path, newData));
|
|
139
|
+
}
|
|
140
|
+
return updatedRecord;
|
|
141
|
+
}
|
|
142
|
+
remove(id, path) {
|
|
143
|
+
const oldData = this.findAll(path) ?? [];
|
|
144
|
+
const modelConfig = this.getModelConfig();
|
|
145
|
+
if (!modelConfig?.idColumn) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
const idColumn = modelConfig.idColumn;
|
|
149
|
+
let updated = false;
|
|
150
|
+
const newData = oldData.filter((record) => {
|
|
151
|
+
const dataRecord = record;
|
|
152
|
+
if (dataRecord[idColumn] === id) {
|
|
153
|
+
updated = true;
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
return true;
|
|
157
|
+
});
|
|
158
|
+
if (!path) {
|
|
159
|
+
this.queryClient.setQueryData(this.queryKey, newData);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
const queryData = this.queryClient.getQueryData(this.queryKey, { exact: this.exact }) ?? {};
|
|
163
|
+
this.queryClient.setQueryData(this.queryKey, set(queryData, path, newData));
|
|
164
|
+
}
|
|
165
|
+
return updated;
|
|
166
|
+
}
|
|
167
|
+
getModelConfig() {
|
|
168
|
+
const { options } = this.queryClient.getQueryData(['config']) ?? {};
|
|
169
|
+
const { modelConfig } = options ?? {};
|
|
170
|
+
return modelConfig;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
94
174
|
const useKeyTrackerModel = (keyTracker) => {
|
|
95
175
|
const queryClient = useQueryClient();
|
|
96
176
|
const getQueryKey = (innerKeyTracker) => {
|
|
@@ -107,9 +187,88 @@ const useKeyTrackerModel = (keyTracker) => {
|
|
|
107
187
|
return { refetchQuery, getQueryKey };
|
|
108
188
|
};
|
|
109
189
|
|
|
110
|
-
const useQueryModel = (
|
|
190
|
+
const useQueryModel = (keyTracker, exact = true) => {
|
|
111
191
|
const queryClient = useQueryClient();
|
|
112
|
-
|
|
192
|
+
const { getQueryKey } = useKeyTrackerModel(keyTracker);
|
|
193
|
+
const queryKey = getQueryKey();
|
|
194
|
+
const findAll = (path) => {
|
|
195
|
+
const data = queryClient.getQueryData(queryKey, { exact });
|
|
196
|
+
if (!data) {
|
|
197
|
+
return [];
|
|
198
|
+
}
|
|
199
|
+
if (!path) {
|
|
200
|
+
return Array.isArray(data) ? data : [data];
|
|
201
|
+
}
|
|
202
|
+
return result(data, path, []);
|
|
203
|
+
};
|
|
204
|
+
const findMany = (selector, path) => {
|
|
205
|
+
const data = findAll(path) ?? [];
|
|
206
|
+
return data.filter(selector);
|
|
207
|
+
};
|
|
208
|
+
const find = (id, path) => {
|
|
209
|
+
const modelConfig = getModelConfig();
|
|
210
|
+
if (!modelConfig?.idColumn) {
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
const data = findAll(path) ?? [];
|
|
214
|
+
return data.find((record) => record[modelConfig.idColumn] === id);
|
|
215
|
+
};
|
|
216
|
+
const getModelConfig = () => {
|
|
217
|
+
const { options } = queryClient.getQueryData(['config']) ?? {};
|
|
218
|
+
const { modelConfig } = options ?? {};
|
|
219
|
+
return modelConfig;
|
|
220
|
+
};
|
|
221
|
+
const update = (id, data, path) => {
|
|
222
|
+
const oldData = findAll(path) ?? [];
|
|
223
|
+
const modelConfig = getModelConfig();
|
|
224
|
+
if (!modelConfig?.idColumn) {
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
const idColumn = modelConfig.idColumn;
|
|
228
|
+
let updatedRecord = undefined;
|
|
229
|
+
const newData = oldData.map((record) => {
|
|
230
|
+
let dataRecord = record;
|
|
231
|
+
if (dataRecord[idColumn] === id) {
|
|
232
|
+
dataRecord = { ...dataRecord, ...data };
|
|
233
|
+
updatedRecord = dataRecord;
|
|
234
|
+
}
|
|
235
|
+
return dataRecord;
|
|
236
|
+
});
|
|
237
|
+
if (!path) {
|
|
238
|
+
queryClient.setQueryData(queryKey, newData);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
const queryData = queryClient.getQueryData(queryKey, { exact }) ?? {};
|
|
242
|
+
queryClient.setQueryData(queryKey, set(queryData, path, newData));
|
|
243
|
+
}
|
|
244
|
+
return updatedRecord;
|
|
245
|
+
};
|
|
246
|
+
const remove = (id, path) => {
|
|
247
|
+
const oldData = findAll(path) ?? [];
|
|
248
|
+
const modelConfig = getModelConfig();
|
|
249
|
+
if (!modelConfig?.idColumn) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
const idColumn = modelConfig.idColumn;
|
|
253
|
+
let updated = false;
|
|
254
|
+
const newData = oldData.filter((record) => {
|
|
255
|
+
const dataRecord = record;
|
|
256
|
+
if (dataRecord[idColumn] === id) {
|
|
257
|
+
updated = true;
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
return true;
|
|
261
|
+
});
|
|
262
|
+
if (!path) {
|
|
263
|
+
queryClient.setQueryData(queryKey, newData);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
const queryData = queryClient.getQueryData(queryKey, { exact }) ?? {};
|
|
267
|
+
queryClient.setQueryData(queryKey, set(queryData, path, newData));
|
|
268
|
+
}
|
|
269
|
+
return updated;
|
|
270
|
+
};
|
|
271
|
+
return { find, findAll, findMany, remove, update };
|
|
113
272
|
};
|
|
114
273
|
|
|
115
274
|
const useRefetchQuery = async (queryKey) => {
|
|
@@ -209,20 +368,41 @@ const successTransformer = (data) => {
|
|
|
209
368
|
};
|
|
210
369
|
};
|
|
211
370
|
|
|
212
|
-
async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, headers = {}, baseURL, timeout, }) {
|
|
371
|
+
async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, headers = {}, baseURL, timeout, appFileConfig, }) {
|
|
372
|
+
// check if file is included in mobile app environment and extract all file input to avoid
|
|
373
|
+
// it being formatted to object using axios formData builder
|
|
374
|
+
const isApp = appFileConfig?.isApp;
|
|
375
|
+
const appFiles = isApp ? getAppFiles(body, appFileConfig.fileSelectors) : {};
|
|
213
376
|
// configure body
|
|
214
|
-
body = isFormData ?
|
|
215
|
-
// configure request
|
|
377
|
+
body = (isFormData ? axios.toFormData(body) : body);
|
|
378
|
+
// configure request header1
|
|
216
379
|
if (!isFormData) {
|
|
217
380
|
headers['Content-Type'] = ContentType.APPLICATION_JSON;
|
|
218
381
|
}
|
|
219
382
|
else {
|
|
220
|
-
|
|
383
|
+
if (isApp) {
|
|
384
|
+
headers['Content-Type'] = ContentType.MULTIPART_FORM_DATA;
|
|
385
|
+
// add the app files
|
|
386
|
+
for (const fileKey in appFiles) {
|
|
387
|
+
const currentFile = appFiles[fileKey];
|
|
388
|
+
if (Array.isArray(currentFile)) {
|
|
389
|
+
for (const innerFile of currentFile) {
|
|
390
|
+
body.append(fileKey, innerFile);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
body.append(fileKey, currentFile);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
delete headers['Content-Type'];
|
|
400
|
+
}
|
|
221
401
|
}
|
|
222
402
|
try {
|
|
223
|
-
const
|
|
403
|
+
const axiosRequest = axiosInstance({ baseURL, headers, timeout });
|
|
224
404
|
// send request
|
|
225
|
-
const resp = await
|
|
405
|
+
const resp = await axiosRequest({
|
|
226
406
|
url: path,
|
|
227
407
|
method,
|
|
228
408
|
data: body,
|
|
@@ -250,6 +430,19 @@ async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, he
|
|
|
250
430
|
...errorData,
|
|
251
431
|
});
|
|
252
432
|
}
|
|
433
|
+
}
|
|
434
|
+
function getAppFiles(body, fileSelectors = []) {
|
|
435
|
+
const files = {};
|
|
436
|
+
if (body) {
|
|
437
|
+
if (fileSelectors.length > 0) {
|
|
438
|
+
//
|
|
439
|
+
for (const fileKey of fileSelectors) {
|
|
440
|
+
files[fileKey] = body[fileKey];
|
|
441
|
+
delete body[fileKey];
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return files;
|
|
253
446
|
}
|
|
254
447
|
|
|
255
448
|
const useDeleteRequest = (deleteOptions) => {
|
|
@@ -287,7 +480,7 @@ const useDeleteRequest = (deleteOptions) => {
|
|
|
287
480
|
internalDeleteOptions = internalDeleteOptions ?? {};
|
|
288
481
|
internalDeleteOptions.enabled = true;
|
|
289
482
|
await updatedPathAsync(link);
|
|
290
|
-
await setOptionsAsync(
|
|
483
|
+
await setOptionsAsync(internalDeleteOptions);
|
|
291
484
|
return query.data;
|
|
292
485
|
};
|
|
293
486
|
return { destroy, ...query };
|
|
@@ -430,10 +623,11 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
|
|
|
430
623
|
return { patch, ...mutation };
|
|
431
624
|
};
|
|
432
625
|
|
|
433
|
-
const usePostRequest = ({ path, isFormData = false, baseUrl, headers, }) => {
|
|
626
|
+
const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelectors, }) => {
|
|
434
627
|
const { API_URL, TIMEOUT } = useEnvironmentVariables();
|
|
435
628
|
const queryClient = useQueryClient();
|
|
436
629
|
const { getHeaders } = useQueryHeaders();
|
|
630
|
+
const { isApp } = useReactNativeEnv();
|
|
437
631
|
const sendRequest = async (res, rej, postData) => {
|
|
438
632
|
// get request headers
|
|
439
633
|
const globalHeaders = getHeaders();
|
|
@@ -446,6 +640,10 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, }) => {
|
|
|
446
640
|
headers: { ...globalHeaders, ...headers },
|
|
447
641
|
baseURL: baseUrl ?? API_URL,
|
|
448
642
|
timeout: TIMEOUT,
|
|
643
|
+
appFileConfig: {
|
|
644
|
+
isApp,
|
|
645
|
+
fileSelectors,
|
|
646
|
+
},
|
|
449
647
|
});
|
|
450
648
|
if (postResponse.status) {
|
|
451
649
|
// scroll to top after success
|
|
@@ -470,5 +668,5 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, }) => {
|
|
|
470
668
|
return { post, ...mutation };
|
|
471
669
|
};
|
|
472
670
|
|
|
473
|
-
export { ContentType, HttpMethod, axiosInstance, bootstrapQueryRequest, buildFormData, errorTransformer, getDateInFuture, makeRequest, scrollToTop, successTransformer, useDeleteRequest, useEnvironmentVariables, useGetRequest, useKeyTrackerModel, usePatchRequest, usePostRequest, useQueryConfig, useQueryHeaders, useQueryModel, useReactNativeEnv, useRefetchQuery };
|
|
671
|
+
export { ContentType, HttpMethod, QueryModel, axiosInstance, bootstrapQueryRequest, buildFormData, errorTransformer, getDateInFuture, makeRequest, scrollToTop, successTransformer, useDeleteRequest, useEnvironmentVariables, useGetRequest, useKeyTrackerModel, usePatchRequest, usePostRequest, useQueryConfig, useQueryHeaders, useQueryModel, useReactNativeEnv, useRefetchQuery };
|
|
474
672
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -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,14 @@
|
|
|
1
|
+
import type { QueryClient } from '@tanstack/react-query';
|
|
2
|
+
import type { QueryModelBuilder } from './model.interface';
|
|
3
|
+
export declare class QueryModel<T> implements QueryModelBuilder<T> {
|
|
4
|
+
private readonly queryKey;
|
|
5
|
+
private readonly queryClient;
|
|
6
|
+
private readonly exact;
|
|
7
|
+
constructor(queryKey: any[], queryClient: QueryClient, exact?: boolean);
|
|
8
|
+
findAll(path?: string): T[] | undefined;
|
|
9
|
+
findMany(selector: (record: T) => boolean, path?: string): T[];
|
|
10
|
+
find(id: string | number, path?: string): T | undefined;
|
|
11
|
+
update(id: string | number, data: Partial<T>, path?: string): T | undefined;
|
|
12
|
+
remove(id: number | string, path?: string): boolean;
|
|
13
|
+
private getModelConfig;
|
|
14
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import result from 'lodash.result';
|
|
2
|
+
import set from 'lodash.set';
|
|
3
|
+
|
|
4
|
+
class QueryModel {
|
|
5
|
+
queryKey;
|
|
6
|
+
queryClient;
|
|
7
|
+
exact;
|
|
8
|
+
constructor(queryKey, queryClient, exact = true) {
|
|
9
|
+
this.queryKey = queryKey;
|
|
10
|
+
this.queryClient = queryClient;
|
|
11
|
+
this.exact = exact;
|
|
12
|
+
}
|
|
13
|
+
findAll(path) {
|
|
14
|
+
const data = this.queryClient.getQueryData(this.queryKey, { exact: this.exact });
|
|
15
|
+
if (!data) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
if (!path) {
|
|
19
|
+
return Array.isArray(data) ? data : [data];
|
|
20
|
+
}
|
|
21
|
+
return result(data, path, []);
|
|
22
|
+
}
|
|
23
|
+
findMany(selector, path) {
|
|
24
|
+
const data = this.findAll(path) ?? [];
|
|
25
|
+
return data.filter(selector);
|
|
26
|
+
}
|
|
27
|
+
find(id, path) {
|
|
28
|
+
const modelConfig = this.getModelConfig();
|
|
29
|
+
if (!modelConfig?.idColumn) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const data = this.findAll(path) ?? [];
|
|
33
|
+
return data.find((record) => record[modelConfig.idColumn] === id);
|
|
34
|
+
}
|
|
35
|
+
update(id, data, path) {
|
|
36
|
+
const oldData = this.findAll(path) ?? [];
|
|
37
|
+
const modelConfig = this.getModelConfig();
|
|
38
|
+
if (!modelConfig?.idColumn) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
const idColumn = modelConfig.idColumn;
|
|
42
|
+
let updatedRecord = undefined;
|
|
43
|
+
const newData = oldData.map((record) => {
|
|
44
|
+
let dataRecord = record;
|
|
45
|
+
if (dataRecord[idColumn] === id) {
|
|
46
|
+
dataRecord = { ...dataRecord, ...data };
|
|
47
|
+
updatedRecord = dataRecord;
|
|
48
|
+
}
|
|
49
|
+
return dataRecord;
|
|
50
|
+
});
|
|
51
|
+
if (!path) {
|
|
52
|
+
this.queryClient.setQueryData(this.queryKey, newData);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const queryData = this.queryClient.getQueryData(this.queryKey, { exact: this.exact }) ?? {};
|
|
56
|
+
this.queryClient.setQueryData(this.queryKey, set(queryData, path, newData));
|
|
57
|
+
}
|
|
58
|
+
return updatedRecord;
|
|
59
|
+
}
|
|
60
|
+
remove(id, path) {
|
|
61
|
+
const oldData = this.findAll(path) ?? [];
|
|
62
|
+
const modelConfig = this.getModelConfig();
|
|
63
|
+
if (!modelConfig?.idColumn) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const idColumn = modelConfig.idColumn;
|
|
67
|
+
let updated = false;
|
|
68
|
+
const newData = oldData.filter((record) => {
|
|
69
|
+
const dataRecord = record;
|
|
70
|
+
if (dataRecord[idColumn] === id) {
|
|
71
|
+
updated = true;
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
75
|
+
});
|
|
76
|
+
if (!path) {
|
|
77
|
+
this.queryClient.setQueryData(this.queryKey, newData);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const queryData = this.queryClient.getQueryData(this.queryKey, { exact: this.exact }) ?? {};
|
|
81
|
+
this.queryClient.setQueryData(this.queryKey, set(queryData, path, newData));
|
|
82
|
+
}
|
|
83
|
+
return updated;
|
|
84
|
+
}
|
|
85
|
+
getModelConfig() {
|
|
86
|
+
const { options } = this.queryClient.getQueryData(['config']) ?? {};
|
|
87
|
+
const { modelConfig } = options ?? {};
|
|
88
|
+
return modelConfig;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export { QueryModel };
|
|
93
|
+
//# sourceMappingURL=Model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Model.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/model/index.d.ts
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface QueryModelBuilder<T> {
|
|
2
|
+
findAll: (path?: string) => T[] | undefined;
|
|
3
|
+
findMany: (selector: (record: T) => boolean, path?: string) => T[];
|
|
4
|
+
find: (id: number | string, path?: string) => T | undefined;
|
|
5
|
+
update: (id: number | string, data: Partial<T>, path?: string) => T | undefined;
|
|
6
|
+
remove: (id: number, path?: string) => boolean;
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const useQueryModel: (
|
|
1
|
+
import type { QueryModelBuilder } from './model.interface';
|
|
2
|
+
export declare const useQueryModel: <T>(keyTracker: string, exact?: boolean) => QueryModelBuilder<T>;
|
|
@@ -1,8 +1,90 @@
|
|
|
1
1
|
import { useQueryClient } from '@tanstack/react-query';
|
|
2
|
+
import result from 'lodash.result';
|
|
3
|
+
import set from 'lodash.set';
|
|
4
|
+
import { useKeyTrackerModel } from './useKeyTrackerModel.js';
|
|
2
5
|
|
|
3
|
-
const useQueryModel = (
|
|
6
|
+
const useQueryModel = (keyTracker, exact = true) => {
|
|
4
7
|
const queryClient = useQueryClient();
|
|
5
|
-
|
|
8
|
+
const { getQueryKey } = useKeyTrackerModel(keyTracker);
|
|
9
|
+
const queryKey = getQueryKey();
|
|
10
|
+
const findAll = (path) => {
|
|
11
|
+
const data = queryClient.getQueryData(queryKey, { exact });
|
|
12
|
+
if (!data) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
if (!path) {
|
|
16
|
+
return Array.isArray(data) ? data : [data];
|
|
17
|
+
}
|
|
18
|
+
return result(data, path, []);
|
|
19
|
+
};
|
|
20
|
+
const findMany = (selector, path) => {
|
|
21
|
+
const data = findAll(path) ?? [];
|
|
22
|
+
return data.filter(selector);
|
|
23
|
+
};
|
|
24
|
+
const find = (id, path) => {
|
|
25
|
+
const modelConfig = getModelConfig();
|
|
26
|
+
if (!modelConfig?.idColumn) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const data = findAll(path) ?? [];
|
|
30
|
+
return data.find((record) => record[modelConfig.idColumn] === id);
|
|
31
|
+
};
|
|
32
|
+
const getModelConfig = () => {
|
|
33
|
+
const { options } = queryClient.getQueryData(['config']) ?? {};
|
|
34
|
+
const { modelConfig } = options ?? {};
|
|
35
|
+
return modelConfig;
|
|
36
|
+
};
|
|
37
|
+
const update = (id, data, path) => {
|
|
38
|
+
const oldData = findAll(path) ?? [];
|
|
39
|
+
const modelConfig = getModelConfig();
|
|
40
|
+
if (!modelConfig?.idColumn) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
const idColumn = modelConfig.idColumn;
|
|
44
|
+
let updatedRecord = undefined;
|
|
45
|
+
const newData = oldData.map((record) => {
|
|
46
|
+
let dataRecord = record;
|
|
47
|
+
if (dataRecord[idColumn] === id) {
|
|
48
|
+
dataRecord = { ...dataRecord, ...data };
|
|
49
|
+
updatedRecord = dataRecord;
|
|
50
|
+
}
|
|
51
|
+
return dataRecord;
|
|
52
|
+
});
|
|
53
|
+
if (!path) {
|
|
54
|
+
queryClient.setQueryData(queryKey, newData);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const queryData = queryClient.getQueryData(queryKey, { exact }) ?? {};
|
|
58
|
+
queryClient.setQueryData(queryKey, set(queryData, path, newData));
|
|
59
|
+
}
|
|
60
|
+
return updatedRecord;
|
|
61
|
+
};
|
|
62
|
+
const remove = (id, path) => {
|
|
63
|
+
const oldData = findAll(path) ?? [];
|
|
64
|
+
const modelConfig = getModelConfig();
|
|
65
|
+
if (!modelConfig?.idColumn) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const idColumn = modelConfig.idColumn;
|
|
69
|
+
let updated = false;
|
|
70
|
+
const newData = oldData.filter((record) => {
|
|
71
|
+
const dataRecord = record;
|
|
72
|
+
if (dataRecord[idColumn] === id) {
|
|
73
|
+
updated = true;
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
});
|
|
78
|
+
if (!path) {
|
|
79
|
+
queryClient.setQueryData(queryKey, newData);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const queryData = queryClient.getQueryData(queryKey, { exact }) ?? {};
|
|
83
|
+
queryClient.setQueryData(queryKey, set(queryData, path, newData));
|
|
84
|
+
}
|
|
85
|
+
return updated;
|
|
86
|
+
};
|
|
87
|
+
return { find, findAll, findMany, remove, update };
|
|
6
88
|
};
|
|
7
89
|
|
|
8
90
|
export { useQueryModel };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useQueryModel.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useQueryModel.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|