-
Notifications
You must be signed in to change notification settings - Fork 134
/
Copy pathBaseCrudService.ts
142 lines (125 loc) · 4.88 KB
/
BaseCrudService.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import BaseModel from '@/models/utils/BaseModel';
import ListResult from '@/models/utils/ListResult';
import BaseService from '@/services/utils/BaseService';
import ClientResponseError from '@/ClientResponseError';
// @todo since there is no longer need of SubCrudService consider merging with CrudService in v0.9+
export default abstract class BaseCrudService<M extends BaseModel> extends BaseService {
/**
* Response data decoder.
*/
abstract decode(data: { [key: string]: any }): M
/**
* Returns a promise with all list items batch fetched at once.
*/
protected _getFullList<T = M>(basePath: string, batchSize = 100, queryParams = {}): Promise<Array<T>> {
var result: Array<T> = [];
let request = async (page: number): Promise<Array<any>> => {
return this._getList(basePath, page, batchSize, queryParams).then((list) => {
const castedList = (list as any as ListResult<T>);
const items = castedList.items;
const totalItems = castedList.totalItems;
result = result.concat(items);
if (items.length && totalItems > result.length) {
return request(page + 1);
}
return result;
});
}
return request(1);
}
/**
* Returns paginated items list.
*/
protected _getList<T = M>(basePath: string, page = 1, perPage = 30, queryParams = {}): Promise<ListResult<T>> {
queryParams = Object.assign({
'page': page,
'perPage': perPage,
}, queryParams);
return this.client.send(basePath, {
'method': 'GET',
'params': queryParams,
}).then((responseData: any) => {
const items: Array<T> = [];
if (responseData?.items) {
responseData.items = responseData.items || [];
for (const item of responseData.items) {
items.push(this.decode(item) as any as T);
}
}
return new ListResult<T>(
responseData?.page || 1,
responseData?.perPage || 0,
responseData?.totalItems || 0,
responseData?.totalPages || 0,
items,
);
});
}
/**
* Returns single item by its id.
*/
protected _getOne<T = M>(basePath: string, id: string, queryParams = {}): Promise<T> {
return this.client.send(basePath + '/' + encodeURIComponent(id), {
'method': 'GET',
'params': queryParams
}).then((responseData: any) => this.decode(responseData) as any as T);
}
/**
* Returns the first found item by a list filter.
*
* Internally it calls `_getList(basePath, 1, 1, { filter })` and returns its
* first item.
*
* For consistency with `_getOne`, this method will throw a 404
* ClientResponseError if no item was found.
*/
protected _getFirstListItem<T = M>(basePath: string, filter: string, queryParams = {}): Promise<T> {
queryParams = Object.assign({
'filter': filter,
'$cancelKey': 'one_by_filter_' + basePath + "_" + filter,
}, queryParams);
return this._getList<T>(basePath, 1, 1, queryParams)
.then((result) => {
if (!result?.items?.length) {
throw new ClientResponseError({
status: 404,
data: {
code: 404,
message: "The requested resource wasn't found.",
data: {},
},
});
}
return result.items[0];
});
}
/**
* Creates a new item.
*/
protected _create<T = M>(basePath: string, bodyParams = {}, queryParams = {}): Promise<T> {
return this.client.send(basePath, {
'method': 'POST',
'params': queryParams,
'body': bodyParams,
}).then((responseData: any) => this.decode(responseData) as any as T);
}
/**
* Updates an existing item by its id.
*/
protected _update<T = M>(basePath: string, id: string, bodyParams = {}, queryParams = {}): Promise<T> {
return this.client.send(basePath + '/' + encodeURIComponent(id), {
'method': 'PATCH',
'params': queryParams,
'body': bodyParams,
}).then((responseData: any) => this.decode(responseData) as any as T);
}
/**
* Deletes an existing item by its id.
*/
protected _delete(basePath: string, id: string, queryParams = {}): Promise<boolean> {
return this.client.send(basePath + '/' + encodeURIComponent(id), {
'method': 'DELETE',
'params': queryParams,
}).then(() => true);
}
}