@raphiniert/ra-data-postgrest 2.0.0-alpha.0 → 2.0.0-alpha.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.
- package/CHANGELOG.md +99 -41
- package/README.md +83 -51
- package/esm/index.js +62 -61
- package/esm/urlBuilder.d.ts +7 -3
- package/esm/urlBuilder.js +51 -31
- package/lib/index.js +64 -60
- package/lib/urlBuilder.d.ts +7 -3
- package/lib/urlBuilder.js +51 -31
- package/package.json +10 -6
- package/src/index.ts +74 -39
- package/src/urlBuilder.ts +62 -35
package/lib/urlBuilder.d.ts
CHANGED
|
@@ -4,15 +4,19 @@ import { Identifier } from 'ra-core';
|
|
|
4
4
|
* (https://postgrest.org/en/stable/api.html#operators)
|
|
5
5
|
*/
|
|
6
6
|
declare const postgrestOperators: readonly ["eq", "gt", "gte", "lt", "lte", "neq", "like", "ilike", "match", "imatch", "in", "is", "fts", "plfts", "phfts", "wfts", "cs", "cd", "ov", "sl", "sr", "nxr", "nxl", "adj", "not", "or", "and"];
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
type ParsedFiltersResult = {
|
|
8
|
+
filter: any;
|
|
9
|
+
select: any;
|
|
10
|
+
};
|
|
11
|
+
export type PostgRestOperator = (typeof postgrestOperators)[number];
|
|
12
|
+
export declare const parseFilters: (params: any, defaultListOp: PostgRestOperator) => Partial<ParsedFiltersResult>;
|
|
9
13
|
export type PrimaryKey = Array<string>;
|
|
10
14
|
export declare const getPrimaryKey: (resource: string, primaryKeys: Map<string, PrimaryKey>) => PrimaryKey;
|
|
11
15
|
export declare const decodeId: (id: Identifier, primaryKey: PrimaryKey) => string[] | number[];
|
|
12
16
|
export declare const encodeId: (data: any, primaryKey: PrimaryKey) => Identifier;
|
|
13
17
|
export declare const dataWithId: (data: any, primaryKey: PrimaryKey) => any;
|
|
14
18
|
export declare const isCompoundKey: (primaryKey: PrimaryKey) => Boolean;
|
|
15
|
-
export declare const getQuery: (primaryKey: PrimaryKey, ids: Identifier | Array<Identifier>, resource: string) =>
|
|
19
|
+
export declare const getQuery: (primaryKey: PrimaryKey, ids: Identifier | Array<Identifier>, resource: string, meta?: any) => any;
|
|
16
20
|
export declare const getKeyData: (primaryKey: PrimaryKey, data: object) => object;
|
|
17
21
|
export declare const getOrderBy: (field: string, order: string, primaryKey: PrimaryKey) => string;
|
|
18
22
|
export {};
|
package/lib/urlBuilder.js
CHANGED
|
@@ -45,8 +45,10 @@ var postgrestOperators = [
|
|
|
45
45
|
'or',
|
|
46
46
|
'and',
|
|
47
47
|
];
|
|
48
|
-
var parseFilters = function (
|
|
48
|
+
var parseFilters = function (params, defaultListOp) {
|
|
49
|
+
var filter = params.filter, _a = params.meta, meta = _a === void 0 ? {} : _a;
|
|
49
50
|
var result = {};
|
|
51
|
+
result.filter = {};
|
|
50
52
|
Object.keys(filter).forEach(function (key) {
|
|
51
53
|
// key: the name of the object key
|
|
52
54
|
var splitKey = key.split('@');
|
|
@@ -68,22 +70,30 @@ var parseFilters = function (filter, defaultListOp) {
|
|
|
68
70
|
: operation.length == 0
|
|
69
71
|
? "".concat(value)
|
|
70
72
|
: "".concat(operation, ".").concat(value);
|
|
71
|
-
if (result[splitKey[0]] === undefined) {
|
|
73
|
+
if (result.filter[splitKey[0]] === undefined) {
|
|
72
74
|
// first operator for the key, we add it to the dict
|
|
73
|
-
result[splitKey[0]] = op;
|
|
75
|
+
result.filter[splitKey[0]] = op;
|
|
74
76
|
}
|
|
75
77
|
else {
|
|
76
78
|
if (!Array.isArray(result[splitKey[0]])) {
|
|
77
79
|
// second operator, we transform to an array
|
|
78
|
-
result[splitKey[0]] = [
|
|
80
|
+
result.filter[splitKey[0]] = [
|
|
81
|
+
result.filter[splitKey[0]],
|
|
82
|
+
op,
|
|
83
|
+
];
|
|
79
84
|
}
|
|
80
85
|
else {
|
|
81
86
|
// third and subsequent, we add to array
|
|
82
|
-
result[splitKey[0]].push(op);
|
|
87
|
+
result.filter[splitKey[0]].push(op);
|
|
83
88
|
}
|
|
84
89
|
}
|
|
85
90
|
});
|
|
86
91
|
});
|
|
92
|
+
if (meta === null || meta === void 0 ? void 0 : meta.columns) {
|
|
93
|
+
result.select = Array.isArray(meta.columns)
|
|
94
|
+
? meta.columns.join(',')
|
|
95
|
+
: meta.columns;
|
|
96
|
+
}
|
|
87
97
|
return result;
|
|
88
98
|
};
|
|
89
99
|
exports.parseFilters = parseFilters;
|
|
@@ -122,8 +132,10 @@ var isCompoundKey = function (primaryKey) {
|
|
|
122
132
|
return primaryKey.length > 1;
|
|
123
133
|
};
|
|
124
134
|
exports.isCompoundKey = isCompoundKey;
|
|
125
|
-
var getQuery = function (primaryKey, ids, resource) {
|
|
126
|
-
var _a;
|
|
135
|
+
var getQuery = function (primaryKey, ids, resource, meta) {
|
|
136
|
+
var _a, _b;
|
|
137
|
+
if (meta === void 0) { meta = null; }
|
|
138
|
+
var result = {};
|
|
127
139
|
if (Array.isArray(ids) && ids.length > 1) {
|
|
128
140
|
// no standardized query with multiple ids possible for rpc endpoints which are api-exposed database functions
|
|
129
141
|
if (resource.startsWith('rpc/')) {
|
|
@@ -131,18 +143,19 @@ var getQuery = function (primaryKey, ids, resource) {
|
|
|
131
143
|
return;
|
|
132
144
|
}
|
|
133
145
|
if ((0, exports.isCompoundKey)(primaryKey)) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
146
|
+
result = {
|
|
147
|
+
or: "(".concat(ids.map(function (id) {
|
|
148
|
+
var primaryKeyParams = (0, exports.decodeId)(id, primaryKey);
|
|
149
|
+
return "and(".concat(primaryKey
|
|
150
|
+
.map(function (key, i) { return "".concat(key, ".eq.").concat(primaryKeyParams[i]); })
|
|
151
|
+
.join(','), ")");
|
|
152
|
+
}), ")"),
|
|
153
|
+
};
|
|
141
154
|
}
|
|
142
155
|
else {
|
|
143
|
-
|
|
156
|
+
result = (_a = {},
|
|
144
157
|
_a[primaryKey[0]] = "in.(".concat(ids.join(','), ")"),
|
|
145
|
-
_a)
|
|
158
|
+
_a);
|
|
146
159
|
}
|
|
147
160
|
}
|
|
148
161
|
else {
|
|
@@ -150,25 +163,32 @@ var getQuery = function (primaryKey, ids, resource) {
|
|
|
150
163
|
var id = ids.toString();
|
|
151
164
|
var primaryKeyParams_1 = (0, exports.decodeId)(id, primaryKey);
|
|
152
165
|
if ((0, exports.isCompoundKey)(primaryKey)) {
|
|
153
|
-
if (resource.startsWith('rpc/'))
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
else
|
|
160
|
-
|
|
161
|
-
.map(function (key, i) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
166
|
+
if (resource.startsWith('rpc/')) {
|
|
167
|
+
result = {};
|
|
168
|
+
primaryKey.map(function (key, i) {
|
|
169
|
+
return (result[key] = "".concat(primaryKeyParams_1[i]));
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
result = {
|
|
174
|
+
and: "(".concat(primaryKey.map(function (key, i) {
|
|
175
|
+
return "".concat(key, ".eq.").concat(primaryKeyParams_1[i]);
|
|
176
|
+
}), ")"),
|
|
177
|
+
};
|
|
178
|
+
}
|
|
165
179
|
}
|
|
166
180
|
else {
|
|
167
|
-
|
|
168
|
-
[primaryKey[0]
|
|
169
|
-
|
|
181
|
+
result = (_b = {},
|
|
182
|
+
_b[primaryKey[0]] = "eq.".concat(id),
|
|
183
|
+
_b);
|
|
170
184
|
}
|
|
171
185
|
}
|
|
186
|
+
if (meta && meta.columns) {
|
|
187
|
+
result.select = Array.isArray(meta.columns)
|
|
188
|
+
? meta.columns.join(',')
|
|
189
|
+
: meta.columns;
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
172
192
|
};
|
|
173
193
|
exports.getQuery = getQuery;
|
|
174
194
|
var getKeyData = function (primaryKey, data) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raphiniert/ra-data-postgrest",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.1",
|
|
4
4
|
"description": "postgREST data provider for react-admin",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"bugs": "https://github.com/raphiniert-com/ra-data-postgrest/issues",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"scripts": {
|
|
23
|
-
"
|
|
23
|
+
"coverage": "jest --coverage",
|
|
24
|
+
"test": "jest --watchAll",
|
|
24
25
|
"build": "npm run build-cjs && npm run build-esm",
|
|
25
26
|
"build-cjs": "rimraf ./lib && tsc",
|
|
26
27
|
"build-esm": "rimraf ./esm && tsc --outDir esm --module es2015",
|
|
@@ -31,16 +32,19 @@
|
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@types/jest": "^28.1.4",
|
|
33
34
|
"cross-env": "^7.0.3",
|
|
34
|
-
"eslint-config-prettier": "^8.
|
|
35
|
+
"eslint-config-prettier": "^8.8.0",
|
|
35
36
|
"eslint-plugin-prettier": "^4.2.1",
|
|
36
37
|
"install-peers-cli": "^2.2.0",
|
|
37
38
|
"jest": "^28.1.2",
|
|
38
|
-
"prettier": "~2.
|
|
39
|
-
"rimraf": "^
|
|
39
|
+
"prettier": "~2.8.7",
|
|
40
|
+
"rimraf": "^4.4.1",
|
|
40
41
|
"ts-jest": "^28.0.5",
|
|
41
|
-
"typescript": "^4.9.
|
|
42
|
+
"typescript": "^4.9.5"
|
|
42
43
|
},
|
|
43
44
|
"peerDependencies": {
|
|
44
45
|
"ra-core": "^4.1.0"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"qs": "^6.11.1"
|
|
45
49
|
}
|
|
46
50
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
fetchUtils,
|
|
3
|
+
DataProvider,
|
|
4
|
+
GetListParams,
|
|
5
|
+
GetOneParams,
|
|
6
|
+
GetManyParams,
|
|
7
|
+
GetManyReferenceParams,
|
|
8
|
+
UpdateParams,
|
|
9
|
+
UpdateManyParams,
|
|
10
|
+
CreateParams,
|
|
11
|
+
DeleteParams,
|
|
12
|
+
DeleteManyParams,
|
|
13
|
+
} from 'ra-core';
|
|
2
14
|
import {
|
|
3
15
|
PrimaryKey,
|
|
4
16
|
PostgRestOperator,
|
|
@@ -12,6 +24,8 @@ import {
|
|
|
12
24
|
decodeId,
|
|
13
25
|
isCompoundKey,
|
|
14
26
|
} from './urlBuilder';
|
|
27
|
+
import qs from 'qs';
|
|
28
|
+
|
|
15
29
|
/**
|
|
16
30
|
* Maps react-admin queries to a postgrest REST API
|
|
17
31
|
*
|
|
@@ -35,7 +49,7 @@ import {
|
|
|
35
49
|
*
|
|
36
50
|
* import * as React from 'react';
|
|
37
51
|
* import { Admin, Resource } from 'react-admin';
|
|
38
|
-
* import postgrestRestProvider from '@
|
|
52
|
+
* import postgrestRestProvider from '@raphiniert/ra-data-postgrest';
|
|
39
53
|
*
|
|
40
54
|
* import { PostList } from './posts';
|
|
41
55
|
*
|
|
@@ -56,30 +70,38 @@ export default (
|
|
|
56
70
|
defaultListOp: PostgRestOperator = 'eq',
|
|
57
71
|
primaryKeys: Map<string, PrimaryKey> = defaultPrimaryKeys
|
|
58
72
|
): DataProvider => ({
|
|
59
|
-
getList: (resource, params) => {
|
|
73
|
+
getList: (resource, params: Partial<GetListParams> = {}) => {
|
|
60
74
|
const primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
61
75
|
|
|
62
76
|
const { page, perPage } = params.pagination;
|
|
63
|
-
const { field, order } = params.sort;
|
|
64
|
-
const
|
|
77
|
+
const { field, order } = params.sort || {};
|
|
78
|
+
const { filter, select } = parseFilters(params, defaultListOp);
|
|
65
79
|
|
|
66
|
-
|
|
67
|
-
order: getOrderBy(field, order, primaryKey),
|
|
80
|
+
let query = {
|
|
68
81
|
offset: String((page - 1) * perPage),
|
|
69
82
|
limit: String(perPage),
|
|
70
83
|
// append filters
|
|
71
|
-
...
|
|
84
|
+
...filter,
|
|
72
85
|
};
|
|
73
86
|
|
|
87
|
+
if (field) {
|
|
88
|
+
query.order = getOrderBy(field, order, primaryKey);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (select) {
|
|
92
|
+
query.select = select;
|
|
93
|
+
}
|
|
94
|
+
|
|
74
95
|
// add header that Content-Range is in returned header
|
|
75
96
|
const options = {
|
|
76
97
|
headers: new Headers({
|
|
77
98
|
Accept: 'application/json',
|
|
78
99
|
Prefer: 'count=exact',
|
|
100
|
+
...(params.meta?.headers || {}),
|
|
79
101
|
}),
|
|
80
102
|
};
|
|
81
103
|
|
|
82
|
-
const url = `${apiUrl}/${resource}?${
|
|
104
|
+
const url = `${apiUrl}/${resource}?${qs.stringify(query)}`;
|
|
83
105
|
|
|
84
106
|
return httpClient(url, options).then(({ headers, json }) => {
|
|
85
107
|
if (!headers.has('content-range')) {
|
|
@@ -99,66 +121,75 @@ export default (
|
|
|
99
121
|
});
|
|
100
122
|
},
|
|
101
123
|
|
|
102
|
-
getOne: (resource, params) => {
|
|
103
|
-
const id = params
|
|
124
|
+
getOne: (resource, params: Partial<GetOneParams> = {}) => {
|
|
125
|
+
const { id, meta } = params;
|
|
104
126
|
const primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
105
127
|
|
|
106
|
-
const query = getQuery(primaryKey, id, resource);
|
|
128
|
+
const query = getQuery(primaryKey, id, resource, meta);
|
|
107
129
|
|
|
108
|
-
const url = `${apiUrl}/${resource}?${query}`;
|
|
130
|
+
const url = `${apiUrl}/${resource}?${qs.stringify(query)}`;
|
|
109
131
|
|
|
110
132
|
return httpClient(url, {
|
|
111
133
|
headers: new Headers({
|
|
112
134
|
accept: 'application/vnd.pgrst.object+json',
|
|
135
|
+
...(params.meta?.headers || {}),
|
|
113
136
|
}),
|
|
114
137
|
}).then(({ json }) => ({
|
|
115
138
|
data: dataWithId(json, primaryKey),
|
|
116
139
|
}));
|
|
117
140
|
},
|
|
118
141
|
|
|
119
|
-
getMany: (resource, params) => {
|
|
142
|
+
getMany: (resource, params: Partial<GetManyParams> = {}) => {
|
|
120
143
|
const ids = params.ids;
|
|
121
144
|
const primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
122
145
|
|
|
123
|
-
const query = getQuery(primaryKey, ids, resource);
|
|
124
|
-
|
|
125
|
-
const url = `${apiUrl}/${resource}?${query}`;
|
|
146
|
+
const query = getQuery(primaryKey, ids, resource, params.meta);
|
|
147
|
+
const url = `${apiUrl}/${resource}?${qs.stringify(query)}`;
|
|
126
148
|
|
|
127
149
|
return httpClient(url).then(({ json }) => ({
|
|
128
150
|
data: json.map(data => dataWithId(data, primaryKey)),
|
|
129
151
|
}));
|
|
130
152
|
},
|
|
131
153
|
|
|
132
|
-
getManyReference: (
|
|
154
|
+
getManyReference: (
|
|
155
|
+
resource,
|
|
156
|
+
params: Partial<GetManyReferenceParams> = {}
|
|
157
|
+
) => {
|
|
133
158
|
const { page, perPage } = params.pagination;
|
|
134
159
|
const { field, order } = params.sort;
|
|
135
|
-
|
|
160
|
+
|
|
161
|
+
const { filter, select } = parseFilters(params, defaultListOp);
|
|
136
162
|
const primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
137
163
|
|
|
138
|
-
|
|
164
|
+
let query = params.target
|
|
139
165
|
? {
|
|
140
166
|
[params.target]: `eq.${params.id}`,
|
|
141
167
|
order: getOrderBy(field, order, primaryKey),
|
|
142
168
|
offset: String((page - 1) * perPage),
|
|
143
169
|
limit: String(perPage),
|
|
144
|
-
...
|
|
170
|
+
...filter,
|
|
145
171
|
}
|
|
146
172
|
: {
|
|
147
173
|
order: getOrderBy(field, order, primaryKey),
|
|
148
174
|
offset: String((page - 1) * perPage),
|
|
149
175
|
limit: String(perPage),
|
|
150
|
-
...
|
|
176
|
+
...filter,
|
|
151
177
|
};
|
|
152
178
|
|
|
179
|
+
if (select) {
|
|
180
|
+
query.select = select;
|
|
181
|
+
}
|
|
182
|
+
|
|
153
183
|
// add header that Content-Range is in returned header
|
|
154
184
|
const options = {
|
|
155
185
|
headers: new Headers({
|
|
156
186
|
Accept: 'application/json',
|
|
157
187
|
Prefer: 'count=exact',
|
|
188
|
+
...(params.meta?.headers || {}),
|
|
158
189
|
}),
|
|
159
190
|
};
|
|
160
191
|
|
|
161
|
-
const url = `${apiUrl}/${resource}?${
|
|
192
|
+
const url = `${apiUrl}/${resource}?${qs.stringify(query)}`;
|
|
162
193
|
|
|
163
194
|
return httpClient(url, options).then(({ headers, json }) => {
|
|
164
195
|
if (!headers.has('content-range')) {
|
|
@@ -178,15 +209,15 @@ export default (
|
|
|
178
209
|
});
|
|
179
210
|
},
|
|
180
211
|
|
|
181
|
-
update: (resource, params) => {
|
|
182
|
-
const { id, data } = params;
|
|
212
|
+
update: (resource, params: Partial<UpdateParams> = {}) => {
|
|
213
|
+
const { id, data, meta } = params;
|
|
183
214
|
const primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
184
215
|
|
|
185
|
-
const query = getQuery(primaryKey, id, resource);
|
|
216
|
+
const query = getQuery(primaryKey, id, resource, meta);
|
|
186
217
|
|
|
187
218
|
const primaryKeyData = getKeyData(primaryKey, data);
|
|
188
219
|
|
|
189
|
-
const url = `${apiUrl}/${resource}?${query}`;
|
|
220
|
+
const url = `${apiUrl}/${resource}?${qs.stringify(query)}`;
|
|
190
221
|
|
|
191
222
|
const body = JSON.stringify({
|
|
192
223
|
...data,
|
|
@@ -199,12 +230,13 @@ export default (
|
|
|
199
230
|
Accept: 'application/vnd.pgrst.object+json',
|
|
200
231
|
Prefer: 'return=representation',
|
|
201
232
|
'Content-Type': 'application/json',
|
|
233
|
+
...(params.meta?.headers || {}),
|
|
202
234
|
}),
|
|
203
235
|
body,
|
|
204
236
|
}).then(({ json }) => ({ data: dataWithId(json, primaryKey) }));
|
|
205
237
|
},
|
|
206
238
|
|
|
207
|
-
updateMany: (resource, params) => {
|
|
239
|
+
updateMany: (resource, params: Partial<UpdateManyParams> = {}) => {
|
|
208
240
|
const ids = params.ids;
|
|
209
241
|
const primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
210
242
|
|
|
@@ -236,6 +268,7 @@ export default (
|
|
|
236
268
|
headers: new Headers({
|
|
237
269
|
Prefer: 'return=representation',
|
|
238
270
|
'Content-Type': 'application/json',
|
|
271
|
+
...(params.meta?.headers || {}),
|
|
239
272
|
}),
|
|
240
273
|
body,
|
|
241
274
|
}).then(({ json }) => ({
|
|
@@ -243,9 +276,8 @@ export default (
|
|
|
243
276
|
}));
|
|
244
277
|
},
|
|
245
278
|
|
|
246
|
-
create: (resource, params) => {
|
|
279
|
+
create: (resource, params: Partial<CreateParams> = {}) => {
|
|
247
280
|
const primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
248
|
-
|
|
249
281
|
const url = `${apiUrl}/${resource}`;
|
|
250
282
|
|
|
251
283
|
return httpClient(url, {
|
|
@@ -254,23 +286,24 @@ export default (
|
|
|
254
286
|
Accept: 'application/vnd.pgrst.object+json',
|
|
255
287
|
Prefer: 'return=representation',
|
|
256
288
|
'Content-Type': 'application/json',
|
|
289
|
+
...(params.meta?.headers || {}),
|
|
257
290
|
}),
|
|
258
291
|
body: JSON.stringify(params.data),
|
|
259
292
|
}).then(({ json }) => ({
|
|
260
293
|
data: {
|
|
261
|
-
...
|
|
294
|
+
...json,
|
|
262
295
|
id: encodeId(json, primaryKey),
|
|
263
296
|
},
|
|
264
297
|
}));
|
|
265
298
|
},
|
|
266
299
|
|
|
267
|
-
delete: (resource, params) => {
|
|
268
|
-
const id = params
|
|
300
|
+
delete: (resource, params: Partial<DeleteParams> = {}) => {
|
|
301
|
+
const { id, meta } = params;
|
|
269
302
|
const primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
270
303
|
|
|
271
|
-
const query = getQuery(primaryKey, id, resource);
|
|
304
|
+
const query = getQuery(primaryKey, id, resource, meta);
|
|
272
305
|
|
|
273
|
-
const url = `${apiUrl}/${resource}?${query}`;
|
|
306
|
+
const url = `${apiUrl}/${resource}?${qs.stringify(query)}`;
|
|
274
307
|
|
|
275
308
|
return httpClient(url, {
|
|
276
309
|
method: 'DELETE',
|
|
@@ -278,23 +311,25 @@ export default (
|
|
|
278
311
|
Accept: 'application/vnd.pgrst.object+json',
|
|
279
312
|
Prefer: 'return=representation',
|
|
280
313
|
'Content-Type': 'application/json',
|
|
314
|
+
...(params.meta?.headers || {}),
|
|
281
315
|
}),
|
|
282
316
|
}).then(({ json }) => ({ data: dataWithId(json, primaryKey) }));
|
|
283
317
|
},
|
|
284
318
|
|
|
285
|
-
deleteMany: (resource, params) => {
|
|
286
|
-
const ids = params
|
|
319
|
+
deleteMany: (resource, params: Partial<DeleteManyParams> = {}) => {
|
|
320
|
+
const { ids, meta } = params;
|
|
287
321
|
const primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
288
322
|
|
|
289
|
-
const query = getQuery(primaryKey, ids, resource);
|
|
323
|
+
const query = getQuery(primaryKey, ids, resource, meta);
|
|
290
324
|
|
|
291
|
-
const url = `${apiUrl}/${resource}?${query}`;
|
|
325
|
+
const url = `${apiUrl}/${resource}?${qs.stringify(query)}`;
|
|
292
326
|
|
|
293
327
|
return httpClient(url, {
|
|
294
328
|
method: 'DELETE',
|
|
295
329
|
headers: new Headers({
|
|
296
330
|
Prefer: 'return=representation',
|
|
297
331
|
'Content-Type': 'application/json',
|
|
332
|
+
...(params.meta?.headers || {}),
|
|
298
333
|
}),
|
|
299
334
|
}).then(({ json }) => ({
|
|
300
335
|
data: json.map(data => encodeId(data, primaryKey)),
|
package/src/urlBuilder.ts
CHANGED
|
@@ -44,13 +44,21 @@ const postgrestOperators = [
|
|
|
44
44
|
'and',
|
|
45
45
|
] as const;
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
type ParsedFiltersResult = {
|
|
48
|
+
filter: any;
|
|
49
|
+
select: any;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type PostgRestOperator = (typeof postgrestOperators)[number];
|
|
48
53
|
|
|
49
54
|
export const parseFilters = (
|
|
50
|
-
|
|
55
|
+
params: any,
|
|
51
56
|
defaultListOp: PostgRestOperator
|
|
52
|
-
) => {
|
|
53
|
-
|
|
57
|
+
): Partial<ParsedFiltersResult> => {
|
|
58
|
+
const { filter, meta = {} } = params;
|
|
59
|
+
|
|
60
|
+
let result: Partial<ParsedFiltersResult> = {};
|
|
61
|
+
result.filter = {};
|
|
54
62
|
Object.keys(filter).forEach(function (key) {
|
|
55
63
|
// key: the name of the object key
|
|
56
64
|
|
|
@@ -76,21 +84,30 @@ export const parseFilters = (
|
|
|
76
84
|
? `${value}`
|
|
77
85
|
: `${operation}.${value}`;
|
|
78
86
|
|
|
79
|
-
if (result[splitKey[0]] === undefined) {
|
|
87
|
+
if (result.filter[splitKey[0]] === undefined) {
|
|
80
88
|
// first operator for the key, we add it to the dict
|
|
81
|
-
result[splitKey[0]] = op;
|
|
89
|
+
result.filter[splitKey[0]] = op;
|
|
82
90
|
} else {
|
|
83
91
|
if (!Array.isArray(result[splitKey[0]])) {
|
|
84
92
|
// second operator, we transform to an array
|
|
85
|
-
result[splitKey[0]] = [
|
|
93
|
+
result.filter[splitKey[0]] = [
|
|
94
|
+
result.filter[splitKey[0]],
|
|
95
|
+
op,
|
|
96
|
+
];
|
|
86
97
|
} else {
|
|
87
98
|
// third and subsequent, we add to array
|
|
88
|
-
result[splitKey[0]].push(op);
|
|
99
|
+
result.filter[splitKey[0]].push(op);
|
|
89
100
|
}
|
|
90
101
|
}
|
|
91
102
|
});
|
|
92
103
|
});
|
|
93
104
|
|
|
105
|
+
if (meta?.columns) {
|
|
106
|
+
result.select = Array.isArray(meta.columns)
|
|
107
|
+
? meta.columns.join(',')
|
|
108
|
+
: meta.columns;
|
|
109
|
+
}
|
|
110
|
+
|
|
94
111
|
return result;
|
|
95
112
|
};
|
|
96
113
|
|
|
@@ -140,8 +157,10 @@ export const isCompoundKey = (primaryKey: PrimaryKey): Boolean => {
|
|
|
140
157
|
export const getQuery = (
|
|
141
158
|
primaryKey: PrimaryKey,
|
|
142
159
|
ids: Identifier | Array<Identifier>,
|
|
143
|
-
resource: string
|
|
144
|
-
|
|
160
|
+
resource: string,
|
|
161
|
+
meta: any = null
|
|
162
|
+
): any => {
|
|
163
|
+
let result: any = {};
|
|
145
164
|
if (Array.isArray(ids) && ids.length > 1) {
|
|
146
165
|
// no standardized query with multiple ids possible for rpc endpoints which are api-exposed database functions
|
|
147
166
|
if (resource.startsWith('rpc/')) {
|
|
@@ -153,17 +172,18 @@ export const getQuery = (
|
|
|
153
172
|
}
|
|
154
173
|
|
|
155
174
|
if (isCompoundKey(primaryKey)) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
175
|
+
result = {
|
|
176
|
+
or: `(${ids.map(id => {
|
|
177
|
+
const primaryKeyParams = decodeId(id, primaryKey);
|
|
178
|
+
return `and(${primaryKey
|
|
179
|
+
.map((key, i) => `${key}.eq.${primaryKeyParams[i]}`)
|
|
180
|
+
.join(',')})`;
|
|
181
|
+
})})`,
|
|
182
|
+
};
|
|
163
183
|
} else {
|
|
164
|
-
|
|
184
|
+
result = {
|
|
165
185
|
[primaryKey[0]]: `in.(${ids.join(',')})`,
|
|
166
|
-
}
|
|
186
|
+
};
|
|
167
187
|
}
|
|
168
188
|
} else {
|
|
169
189
|
// if ids is one Identifier
|
|
@@ -171,27 +191,34 @@ export const getQuery = (
|
|
|
171
191
|
const primaryKeyParams = decodeId(id, primaryKey);
|
|
172
192
|
|
|
173
193
|
if (isCompoundKey(primaryKey)) {
|
|
174
|
-
if (resource.startsWith('rpc/'))
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
(key
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
return `and=(${primaryKey
|
|
184
|
-
.map(
|
|
194
|
+
if (resource.startsWith('rpc/')) {
|
|
195
|
+
result = {};
|
|
196
|
+
primaryKey.map(
|
|
197
|
+
(key: string, i: any) =>
|
|
198
|
+
(result[key] = `${primaryKeyParams[i]}`)
|
|
199
|
+
);
|
|
200
|
+
} else {
|
|
201
|
+
result = {
|
|
202
|
+
and: `(${primaryKey.map(
|
|
185
203
|
(key: string, i: any) =>
|
|
186
204
|
`${key}.eq.${primaryKeyParams[i]}`
|
|
187
|
-
)
|
|
188
|
-
|
|
205
|
+
)})`,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
189
208
|
} else {
|
|
190
|
-
|
|
191
|
-
[primaryKey[0]
|
|
192
|
-
|
|
209
|
+
result = {
|
|
210
|
+
[primaryKey[0]]: `eq.${id}`,
|
|
211
|
+
};
|
|
193
212
|
}
|
|
194
213
|
}
|
|
214
|
+
|
|
215
|
+
if (meta && meta.columns) {
|
|
216
|
+
result.select = Array.isArray(meta.columns)
|
|
217
|
+
? meta.columns.join(',')
|
|
218
|
+
: meta.columns;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return result;
|
|
195
222
|
};
|
|
196
223
|
|
|
197
224
|
export const getKeyData = (primaryKey: PrimaryKey, data: object): object => {
|