-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquery.ts
92 lines (80 loc) · 2.21 KB
/
query.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { Params } from '@feathersjs/feathers';
import { merge, omit } from 'lodash';
import { Ref, isRef, reactive, watch } from 'vue';
import { Model } from './model';
interface QueryOptions {
model: typeof Model;
method?: 'find' | 'get';
params?: Params | Ref<Params>,
hooks?: any;
}
interface QueryResult<T = any> {
items?: T[] | T;
paginationData?: Record<any, any>;
servicePath?: string;
[key: string]: any;
}
const unwrap = <T>(params: T | Ref<T>): T =>
isRef(params) ? params.value : params;
export async function useQuery<M extends Model>(options: QueryOptions) {
const { model, method, params, hooks } = merge({
method: 'find',
params: {},
hooks: (record: any, context?: any) => ({ record, context })
}, options);
if (!model) {
throw new Error('No model provided for useQuery()');
}
async function useHook(item: any, context: any) {
if (hooks) {
if (typeof hooks === 'function') {
await hooks(item, context);
}
if (Array.isArray(hooks)) {
for (const hook of hooks) {
if (typeof hook === 'function') {
await hook(item, context);
}
}
}
}
}
const computes = reactive<QueryResult<M>>({
servicePath: model.servicePath,
model: model,
class: typeof model
});
async function fetch(getterParams: any) {
if (method && method.toLowerCase() === 'get') {
const { id, params: paramsGet } = getterParams;
const response = await model.get(id, paramsGet);
await useHook(response, { model, method, params });
computes.items = response;
} else {
const response = await model.find(getterParams);
if (Array.isArray(response)) {
for (const item of response) {
await useHook(item, { model, method, params });
}
computes.items = response;
} else {
for (const item of response.data) {
await useHook(item, { model, method, params });
}
computes.items = response.data;
computes.paginationData = omit(response, 'data');
}
}
computes.servicePath = model.servicePath;
computes.model = model;
computes.class = typeof model;
}
watch(() => unwrap(params), async (value) => {
if (value !== undefined) {
await fetch(unwrap(params));
}
});
await fetch(unwrap(params))
return computes;
}
export default useQuery;