@raphiniert/ra-data-postgrest 1.1.7 → 1.2.0
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 +14 -3
- package/README.md +8 -10
- package/esm/dataProvider/index.js +24 -24
- package/lib/authProvider/index.d.ts +11 -0
- package/lib/authProvider/index.js +60 -0
- package/lib/dataProvider/index.d.ts +9 -0
- package/lib/dataProvider/index.js +362 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +10 -0
- package/package.json +5 -8
- package/src/dataProvider/index.ts +11 -12
package/CHANGELOG.md
CHANGED
|
@@ -2,16 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
Find all notable changes of this project in this file.
|
|
4
4
|
|
|
5
|
+
## v1.2.0 - 2023-08-23
|
|
6
|
+
- [#33](https://github.com/raphiniert-com/ra-data-postgrest/pull/33), adding dependabot - @[promitheus7](https://github.com/promitheus7)
|
|
7
|
+
- [#30](https://github.com/raphiniert-com/ra-data-postgrest/pull/30) and [#33](https://github.com/raphiniert-com/ra-data-postgrest/pull/33), updated dependency to compatible starting from `ra-core` 4.1.x - @[corrideat](https://github.com/corrideat), @[promitheus7](https://github.com/promitheus7)
|
|
8
|
+
|
|
9
|
+
## v1.1.9 - 2023-08-23
|
|
10
|
+
- [#30](https://github.com/raphiniert-com/ra-data-postgrest/pull/30), updated ts and modified code, such that some package dependencies became unrequired - @[corrideat](https://github.com/corrideat)
|
|
11
|
+
|
|
12
|
+
## v1.1.8 - 2022-01-07
|
|
13
|
+
- required re-release as I missed to transpile all and upload the features of 1.1.7 to npm.
|
|
14
|
+
|
|
5
15
|
## v1.1.7 - 2022-01-07
|
|
6
16
|
### Fixes
|
|
7
17
|
- fixed bad behaivor with compound keys while using field named `id` [issue #27](https://github.com/raphiniert-com/ra-data-postgrest/issues/27) and [issue #19](https://github.com/raphiniert-com/ra-data-postgrest/pull/19) - @[kenfehling](https://github.com/kenfehling)
|
|
8
18
|
|
|
9
19
|
### New feature
|
|
10
|
-
- added rpc filter support, which is explained [here](https://github.com/raphiniert-com/ra-data-postgrest#special-filter-feature-rpc-functions) - @[TheRealAstroboy](https://github.com/TheRealAstroboy)
|
|
20
|
+
- [#26](https://github.com/raphiniert-com/ra-data-postgrest/pull/26), added rpc filter support, which is explained [here](https://github.com/raphiniert-com/ra-data-postgrest#special-filter-feature-rpc-functions) - @[TheRealAstroboy](https://github.com/TheRealAstroboy)
|
|
21
|
+
|
|
11
22
|
|
|
12
23
|
## v1.1.6 - 2021-01-16
|
|
13
24
|
### Fixes
|
|
14
|
-
- fixed eq. prefix for non-compound keys [issue #23](https://github.com/raphiniert-com/ra-data-postgrest/issues/23) - @[andymed-jlp](https://github.com/andymed-jlp)
|
|
25
|
+
- [#24](https://github.com/raphiniert-com/ra-data-postgrest/pull/24), fixed eq. prefix for non-compound keys [issue #23](https://github.com/raphiniert-com/ra-data-postgrest/issues/23) - @[andymed-jlp](https://github.com/andymed-jlp)
|
|
15
26
|
|
|
16
27
|
## v1.1.5 - 2021-01-16
|
|
17
28
|
### Fixes
|
|
@@ -52,7 +63,7 @@ Find all notable changes of this project in this file.
|
|
|
52
63
|
|
|
53
64
|
## v1.0.7 - 2020-08-23
|
|
54
65
|
### New feature
|
|
55
|
-
- [#14](https://github.com/raphiniert-com/ra-data-postgrest/pull/14) compound primary keys (see [README.md](https://github.com/raphiniert-com/ra-data-postgrest/blob/master/README.md#compound-primary-keys)) - @[programmarchy](https://github.com/programmarchy)
|
|
66
|
+
- [#14](https://github.com/raphiniert-com/ra-data-postgrest/pull/14), added compound primary keys (see [README.md](https://github.com/raphiniert-com/ra-data-postgrest/blob/master/README.md#compound-primary-keys)) - @[programmarchy](https://github.com/programmarchy)
|
|
56
67
|
|
|
57
68
|
### Maintenance
|
|
58
69
|
- `import React from 'react';` -> `import * as React from 'react';`
|
package/README.md
CHANGED
|
@@ -5,9 +5,11 @@ PostgREST Data Provider for [react-admin](https://github.com/marmelab/react-admi
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
npm install --save @
|
|
8
|
+
npm install --save @promitheus/ra-data-postgrest
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
**NOTE**: When using RA 3.x.x, use the data-provider 1.x.x. For RA >= 4.1.x use the data-provider starting from 1.2.x.
|
|
12
|
+
|
|
11
13
|
## REST Dialect
|
|
12
14
|
|
|
13
15
|
This Data Provider fits REST APIs using simple GET parameters for filters and sorting. This is the dialect used for instance in [PostgREST](http://postgrest.org).
|
|
@@ -42,7 +44,7 @@ Access-Control-Expose-Headers: Content-Range
|
|
|
42
44
|
// in src/App.js
|
|
43
45
|
import React from 'react';
|
|
44
46
|
import { Admin, Resource } from 'react-admin';
|
|
45
|
-
import postgrestRestProvider from '@
|
|
47
|
+
import postgrestRestProvider from '@promitheus/ra-data-postgrest';
|
|
46
48
|
|
|
47
49
|
import { PostList } from './posts';
|
|
48
50
|
|
|
@@ -63,7 +65,7 @@ That means that if you need to add custom headers to your requests, you just nee
|
|
|
63
65
|
|
|
64
66
|
```jsx
|
|
65
67
|
import { fetchUtils, Admin, Resource } from 'react-admin';
|
|
66
|
-
import postgrestRestProvider from '@
|
|
68
|
+
import postgrestRestProvider from '@promitheus/ra-data-postgrest';
|
|
67
69
|
|
|
68
70
|
const httpClient = (url, options = {}) => {
|
|
69
71
|
if (!options.headers) {
|
|
@@ -107,7 +109,7 @@ With one of the starter kits it is very easy to use the authProvider:
|
|
|
107
109
|
// in src/App.js
|
|
108
110
|
import React from 'react';
|
|
109
111
|
import { Admin, Resource } from 'react-admin';
|
|
110
|
-
import postgrestRestProvider, { authProvider } from '@
|
|
112
|
+
import postgrestRestProvider, { authProvider } from '@promitheus/ra-data-postgrest';
|
|
111
113
|
|
|
112
114
|
import { PostList } from './posts';
|
|
113
115
|
|
|
@@ -135,15 +137,11 @@ The dataProvider is designed to enable you to specify the comparator in your rea
|
|
|
135
137
|
|
|
136
138
|
One can simply append the comparator with an `@` to the source. In this example the field `post_title` would be filtered with `ilike` whereas `post_author` would be filtered using `eq` which is the default if no special comparator is specified.
|
|
137
139
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
```GET /rpc/add_them?post_author=Herbert HTTP/1.1```
|
|
142
|
-
The function parameter names match the query parameters ```&post_author=Herbert``` if you end the field with an `@` (neither default comparator nor special comparator)
|
|
140
|
+
#### RPC Functions
|
|
141
|
+
Given a RPC call as ```GET /rpc/add_them?post_author=Herbert HTTP/1.1```, the dataProvider allows you to filter such endpoints. As they are no view, but a SQL procedure, several postgREST features do not apply. I.e. no comparators such as `ilike`, `like`, `eq` are applicable. Only the raw value without comparator needs to be send to the API. In order to realize this behavior, just add an "empty" comparator to the field, i.e. end `source` with an `@` as in the example:
|
|
143
142
|
|
|
144
143
|
```jsx
|
|
145
144
|
<Filter {...props}>
|
|
146
|
-
<TextInput label="Search" source="post_title" alwaysOn />
|
|
147
145
|
<TextInput label="Search" source="post_author@" alwaysOn />
|
|
148
146
|
// some more filters
|
|
149
147
|
</Filter>
|
|
@@ -20,7 +20,6 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
20
20
|
}
|
|
21
21
|
return t;
|
|
22
22
|
};
|
|
23
|
-
import { stringify } from 'query-string';
|
|
24
23
|
import { fetchUtils } from 'ra-core';
|
|
25
24
|
/**
|
|
26
25
|
* Maps react-admin queries to a postgrest REST API
|
|
@@ -45,7 +44,7 @@ import { fetchUtils } from 'ra-core';
|
|
|
45
44
|
*
|
|
46
45
|
* import * as React from 'react';
|
|
47
46
|
* import { Admin, Resource } from 'react-admin';
|
|
48
|
-
* import postgrestRestProvider from '@
|
|
47
|
+
* import postgrestRestProvider from '@promitheus/ra-data-postgrest';
|
|
49
48
|
*
|
|
50
49
|
* import { PostList } from './posts';
|
|
51
50
|
*
|
|
@@ -72,7 +71,8 @@ function parseFilters(filter, defaultListOp) {
|
|
|
72
71
|
values = [filter[key]];
|
|
73
72
|
}
|
|
74
73
|
values.forEach(function (value) {
|
|
75
|
-
|
|
74
|
+
// if operator is intentionally blank, rpc syntax
|
|
75
|
+
var op = operation.includes('like') ? "".concat(operation, ".*").concat(value, "*") : operation.length == 0 ? "".concat(value) : "".concat(operation, ".").concat(value);
|
|
76
76
|
if (result[splitKey[0]] === undefined) {
|
|
77
77
|
// first operator for the key, we add it to the dict
|
|
78
78
|
result[splitKey[0]] = op;
|
|
@@ -122,7 +122,7 @@ var isCompoundKey = function (primaryKey) {
|
|
|
122
122
|
return primaryKey.length > 1;
|
|
123
123
|
};
|
|
124
124
|
var getQuery = function (primaryKey, ids, resource) {
|
|
125
|
-
var _a
|
|
125
|
+
var _a;
|
|
126
126
|
if (Array.isArray(ids) && ids.length > 1) {
|
|
127
127
|
// no standardized query with multiple ids possible for rpc endpoints which are api-exposed database functions
|
|
128
128
|
if (resource.startsWith('rpc/')) {
|
|
@@ -130,13 +130,13 @@ var getQuery = function (primaryKey, ids, resource) {
|
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
132
|
if (isCompoundKey(primaryKey)) {
|
|
133
|
-
return "or=(\n "
|
|
133
|
+
return "or=(\n ".concat(ids.map(function (id) {
|
|
134
134
|
var primaryKeyParams = decodeId(id, primaryKey);
|
|
135
|
-
return "and("
|
|
136
|
-
})
|
|
135
|
+
return "and(".concat(primaryKey.map(function (key, i) { return "".concat(key, ".eq.").concat(primaryKeyParams[i]); }).join(','), ")");
|
|
136
|
+
}), "\n )");
|
|
137
137
|
}
|
|
138
138
|
else {
|
|
139
|
-
return
|
|
139
|
+
return new URLSearchParams((_a = {}, _a[primaryKey[0]] = "in.(".concat(ids.join(','), ")"), _a)).toString();
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
else {
|
|
@@ -145,12 +145,12 @@ var getQuery = function (primaryKey, ids, resource) {
|
|
|
145
145
|
var primaryKeyParams_1 = decodeId(id, primaryKey);
|
|
146
146
|
if (isCompoundKey(primaryKey)) {
|
|
147
147
|
if (resource.startsWith('rpc/'))
|
|
148
|
-
return ""
|
|
148
|
+
return "".concat(primaryKey.map(function (key, i) { return "".concat(key, "=").concat(primaryKeyParams_1[i]); }).join('&'));
|
|
149
149
|
else
|
|
150
|
-
return "and=("
|
|
150
|
+
return "and=(".concat(primaryKey.map(function (key, i) { return "".concat(key, ".eq.").concat(primaryKeyParams_1[i]); }).join(','), ")");
|
|
151
151
|
}
|
|
152
152
|
else {
|
|
153
|
-
return
|
|
153
|
+
return new URLSearchParams([[primaryKey[0], "eq.".concat(id)]]).toString();
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
};
|
|
@@ -168,10 +168,10 @@ var getKeyData = function (primaryKey, data) {
|
|
|
168
168
|
};
|
|
169
169
|
var getOrderBy = function (field, order, primaryKey) {
|
|
170
170
|
if (field == 'id') {
|
|
171
|
-
return primaryKey.map(function (key) { return (key
|
|
171
|
+
return primaryKey.map(function (key) { return ("".concat(key, ".").concat(order.toLowerCase())); }).join(',');
|
|
172
172
|
}
|
|
173
173
|
else {
|
|
174
|
-
return field
|
|
174
|
+
return "".concat(field, ".").concat(order.toLowerCase());
|
|
175
175
|
}
|
|
176
176
|
};
|
|
177
177
|
var defaultPrimaryKeys = new Map();
|
|
@@ -185,7 +185,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
185
185
|
var _a = params.pagination, page = _a.page, perPage = _a.perPage;
|
|
186
186
|
var _b = params.sort, field = _b.field, order = _b.order;
|
|
187
187
|
var parsedFilter = parseFilters(params.filter, defaultListOp);
|
|
188
|
-
var query = __assign({ order: getOrderBy(field, order, primaryKey), offset: (page - 1) * perPage, limit: perPage }, parsedFilter);
|
|
188
|
+
var query = __assign({ order: getOrderBy(field, order, primaryKey), offset: String((page - 1) * perPage), limit: String(perPage) }, parsedFilter);
|
|
189
189
|
// add header that Content-Range is in returned header
|
|
190
190
|
var options = {
|
|
191
191
|
headers: new Headers({
|
|
@@ -193,7 +193,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
193
193
|
Prefer: 'count=exact'
|
|
194
194
|
})
|
|
195
195
|
};
|
|
196
|
-
var url = apiUrl
|
|
196
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(new URLSearchParams(query));
|
|
197
197
|
return httpClient(url, options).then(function (_a) {
|
|
198
198
|
var headers = _a.headers, json = _a.json;
|
|
199
199
|
if (!headers.has('content-range')) {
|
|
@@ -212,7 +212,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
212
212
|
var id = params.id;
|
|
213
213
|
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
214
214
|
var query = getQuery(primaryKey, id, resource);
|
|
215
|
-
var url = apiUrl
|
|
215
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
216
216
|
return httpClient(url, {
|
|
217
217
|
headers: new Headers({ 'accept': 'application/vnd.pgrst.object+json' }),
|
|
218
218
|
}).then(function (_a) {
|
|
@@ -226,7 +226,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
226
226
|
var ids = params.ids;
|
|
227
227
|
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
228
228
|
var query = getQuery(primaryKey, ids, resource);
|
|
229
|
-
var url = apiUrl
|
|
229
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
230
230
|
return httpClient(url).then(function (_a) {
|
|
231
231
|
var json = _a.json;
|
|
232
232
|
return ({ data: json.map(function (data) { return dataWithId(data, primaryKey); }) });
|
|
@@ -238,7 +238,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
238
238
|
var _c = params.sort, field = _c.field, order = _c.order;
|
|
239
239
|
var parsedFilter = parseFilters(params.filter, defaultListOp);
|
|
240
240
|
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
241
|
-
var query = __assign((_a = {}, _a[params.target] = "eq."
|
|
241
|
+
var query = params.target ? __assign((_a = {}, _a[params.target] = "eq.".concat(params.id), _a.order = getOrderBy(field, order, primaryKey), _a.offset = String((page - 1) * perPage), _a.limit = String(perPage), _a), parsedFilter) : __assign({ order: getOrderBy(field, order, primaryKey), offset: String((page - 1) * perPage), limit: String(perPage) }, parsedFilter);
|
|
242
242
|
// add header that Content-Range is in returned header
|
|
243
243
|
var options = {
|
|
244
244
|
headers: new Headers({
|
|
@@ -246,7 +246,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
246
246
|
Prefer: 'count=exact'
|
|
247
247
|
})
|
|
248
248
|
};
|
|
249
|
-
var url = apiUrl
|
|
249
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(new URLSearchParams(query));
|
|
250
250
|
return httpClient(url, options).then(function (_a) {
|
|
251
251
|
var headers = _a.headers, json = _a.json;
|
|
252
252
|
if (!headers.has('content-range')) {
|
|
@@ -266,7 +266,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
266
266
|
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
267
267
|
var query = getQuery(primaryKey, id, resource);
|
|
268
268
|
var primaryKeyData = getKeyData(primaryKey, data);
|
|
269
|
-
var url = apiUrl
|
|
269
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
270
270
|
var body = JSON.stringify(__assign(__assign({}, data), primaryKeyData));
|
|
271
271
|
return httpClient(url, {
|
|
272
272
|
method: 'PATCH',
|
|
@@ -290,7 +290,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
290
290
|
var primaryKeyData = getKeyData(primaryKey, data);
|
|
291
291
|
return __assign(__assign({}, data), primaryKeyData);
|
|
292
292
|
}));
|
|
293
|
-
var url = apiUrl
|
|
293
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
294
294
|
return httpClient(url, {
|
|
295
295
|
method: 'PATCH',
|
|
296
296
|
headers: new Headers({
|
|
@@ -307,7 +307,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
307
307
|
},
|
|
308
308
|
create: function (resource, params) {
|
|
309
309
|
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
310
|
-
var url = apiUrl
|
|
310
|
+
var url = "".concat(apiUrl, "/").concat(resource);
|
|
311
311
|
return httpClient(url, {
|
|
312
312
|
method: 'POST',
|
|
313
313
|
headers: new Headers({
|
|
@@ -327,7 +327,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
327
327
|
var id = params.id;
|
|
328
328
|
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
329
329
|
var query = getQuery(primaryKey, id, resource);
|
|
330
|
-
var url = apiUrl
|
|
330
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
331
331
|
return httpClient(url, {
|
|
332
332
|
method: 'DELETE',
|
|
333
333
|
headers: new Headers({
|
|
@@ -344,7 +344,7 @@ export default (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
|
344
344
|
var ids = params.ids;
|
|
345
345
|
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
346
346
|
var query = getQuery(primaryKey, ids, resource);
|
|
347
|
-
var url = apiUrl
|
|
347
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
348
348
|
return httpClient(url, {
|
|
349
349
|
method: 'DELETE',
|
|
350
350
|
headers: new Headers({
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
login: ({ username, password }: {
|
|
3
|
+
username: any;
|
|
4
|
+
password: any;
|
|
5
|
+
}) => Promise<void>;
|
|
6
|
+
logout: (params: any) => Promise<void>;
|
|
7
|
+
checkAuth: (params: any) => Promise<void>;
|
|
8
|
+
checkError: (error: any) => Promise<void>;
|
|
9
|
+
getPermissions: (params: any) => Promise<any>;
|
|
10
|
+
};
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = {
|
|
4
|
+
login: function (_a) {
|
|
5
|
+
var username = _a.username, password = _a.password;
|
|
6
|
+
var request = new Request('rest/rpc/login', {
|
|
7
|
+
method: 'POST',
|
|
8
|
+
body: JSON.stringify({ email: username, password: password }),
|
|
9
|
+
headers: new Headers({
|
|
10
|
+
'Content-Type': 'application/json',
|
|
11
|
+
'Accept': 'application/vnd.pgrst.object+json',
|
|
12
|
+
'Prefer': 'return=representation'
|
|
13
|
+
}),
|
|
14
|
+
});
|
|
15
|
+
return fetch(request)
|
|
16
|
+
.then(function (response) {
|
|
17
|
+
if (response.status < 200 || response.status >= 300) {
|
|
18
|
+
throw new Error(response.statusText);
|
|
19
|
+
}
|
|
20
|
+
return response.json();
|
|
21
|
+
})
|
|
22
|
+
.then(function (data) {
|
|
23
|
+
localStorage.setItem('me', JSON.stringify(data));
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
logout: function (params) {
|
|
27
|
+
var request = new Request('rest/rpc/logout', {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
headers: new Headers({
|
|
30
|
+
'Content-Type': 'application/json',
|
|
31
|
+
'Accept': 'application/vnd.pgrst.object+json',
|
|
32
|
+
'Prefer': 'return=representation'
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
return fetch(request)
|
|
36
|
+
.then(function (response) {
|
|
37
|
+
if (response.status < 200 || response.status >= 300) {
|
|
38
|
+
throw new Error(response.statusText);
|
|
39
|
+
}
|
|
40
|
+
return response.json();
|
|
41
|
+
})
|
|
42
|
+
.then(function (data) {
|
|
43
|
+
localStorage.removeItem('me');
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
checkAuth: function (params) { return (localStorage.getItem('me') ? Promise.resolve() : Promise.reject()); },
|
|
47
|
+
checkError: function (error) {
|
|
48
|
+
var status = error.status;
|
|
49
|
+
if (status === 401 || status === 403) {
|
|
50
|
+
localStorage.removeItem('me');
|
|
51
|
+
return Promise.reject();
|
|
52
|
+
}
|
|
53
|
+
return Promise.resolve();
|
|
54
|
+
},
|
|
55
|
+
getPermissions: function (params) {
|
|
56
|
+
var _a;
|
|
57
|
+
var role = (_a = JSON.parse(localStorage.getItem('me'))) === null || _a === void 0 ? void 0 : _a.role;
|
|
58
|
+
return role ? Promise.resolve(role) : Promise.reject();
|
|
59
|
+
},
|
|
60
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { fetchUtils, DataProvider } from 'ra-core';
|
|
2
|
+
declare type PrimaryKey = Array<string>;
|
|
3
|
+
declare const _default: (apiUrl: any, httpClient?: (url: any, options?: fetchUtils.Options) => Promise<{
|
|
4
|
+
status: number;
|
|
5
|
+
headers: Headers;
|
|
6
|
+
body: string;
|
|
7
|
+
json: any;
|
|
8
|
+
}>, defaultListOp?: string, primaryKeys?: Map<string, PrimaryKey>) => DataProvider;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
14
|
+
var t = {};
|
|
15
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
16
|
+
t[p] = s[p];
|
|
17
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
18
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
19
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
20
|
+
t[p[i]] = s[p[i]];
|
|
21
|
+
}
|
|
22
|
+
return t;
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
var ra_core_1 = require("ra-core");
|
|
26
|
+
/**
|
|
27
|
+
* Maps react-admin queries to a postgrest REST API
|
|
28
|
+
*
|
|
29
|
+
* This REST dialect uses postgrest syntax
|
|
30
|
+
*
|
|
31
|
+
* @see https://postgrest.org/en/stable/api.html#embedded-filters
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
*
|
|
35
|
+
* getList => GET http://my.api.url/posts?order=title.asc&offset=0&limit=24&filterField=eq.value
|
|
36
|
+
* getOne => GET http://my.api.url/posts?id=eq.123
|
|
37
|
+
* getMany => GET http://my.api.url/posts?id=in.(123,456,789)
|
|
38
|
+
* getManyReference => GET http://my.api.url/posts?author_id=eq.345
|
|
39
|
+
* create => POST http://my.api.url/posts
|
|
40
|
+
* update => PATCH http://my.api.url/posts?id=eq.123
|
|
41
|
+
* updateMany => PATCH http://my.api.url/posts?id=in.(123,456,789)
|
|
42
|
+
* delete => DELETE http://my.api.url/posts?id=eq.123
|
|
43
|
+
* deleteMany => DELETE http://my.api.url/posts?id=in.(123,456,789)
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
*
|
|
47
|
+
* import * as React from 'react';
|
|
48
|
+
* import { Admin, Resource } from 'react-admin';
|
|
49
|
+
* import postgrestRestProvider from '@promitheus/ra-data-postgrest';
|
|
50
|
+
*
|
|
51
|
+
* import { PostList } from './posts';
|
|
52
|
+
*
|
|
53
|
+
* const App = () => (
|
|
54
|
+
* <Admin dataProvider={postgrestRestProvider('http://path.to.my.api/')}>
|
|
55
|
+
* <Resource name="posts" list={PostList} />
|
|
56
|
+
* </Admin>
|
|
57
|
+
* );
|
|
58
|
+
*
|
|
59
|
+
* export default App;
|
|
60
|
+
*/
|
|
61
|
+
function parseFilters(filter, defaultListOp) {
|
|
62
|
+
var result = {};
|
|
63
|
+
Object.keys(filter).forEach(function (key) {
|
|
64
|
+
// key: the name of the object key
|
|
65
|
+
var splitKey = key.split('@');
|
|
66
|
+
var operation = splitKey.length == 2 ? splitKey[1] : defaultListOp;
|
|
67
|
+
var values;
|
|
68
|
+
if (operation.includes('like')) {
|
|
69
|
+
// we split the search term in words
|
|
70
|
+
values = filter[key].trim().split(' ');
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
values = [filter[key]];
|
|
74
|
+
}
|
|
75
|
+
values.forEach(function (value) {
|
|
76
|
+
// if operator is intentionally blank, rpc syntax
|
|
77
|
+
var op = operation.includes('like') ? "".concat(operation, ".*").concat(value, "*") : operation.length == 0 ? "".concat(value) : "".concat(operation, ".").concat(value);
|
|
78
|
+
if (result[splitKey[0]] === undefined) {
|
|
79
|
+
// first operator for the key, we add it to the dict
|
|
80
|
+
result[splitKey[0]] = op;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
if (!Array.isArray(result[splitKey[0]])) {
|
|
84
|
+
// second operator, we transform to an array
|
|
85
|
+
result[splitKey[0]] = [result[splitKey[0]], op];
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// third and subsequent, we add to array
|
|
89
|
+
result[splitKey[0]].push(op);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
var getPrimaryKey = function (resource, primaryKeys) {
|
|
97
|
+
return primaryKeys.get(resource) || ['id'];
|
|
98
|
+
};
|
|
99
|
+
var decodeId = function (id, primaryKey) {
|
|
100
|
+
if (isCompoundKey(primaryKey)) {
|
|
101
|
+
return JSON.parse(id.toString());
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
return [id.toString()];
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var encodeId = function (data, primaryKey) {
|
|
108
|
+
if (isCompoundKey(primaryKey)) {
|
|
109
|
+
return JSON.stringify(primaryKey.map(function (key) { return data[key]; }));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
return data[primaryKey[0]];
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
var dataWithId = function (data, primaryKey) {
|
|
116
|
+
if (primaryKey === ['id']) {
|
|
117
|
+
return data;
|
|
118
|
+
}
|
|
119
|
+
return Object.assign(data, {
|
|
120
|
+
id: encodeId(data, primaryKey)
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
var isCompoundKey = function (primaryKey) {
|
|
124
|
+
return primaryKey.length > 1;
|
|
125
|
+
};
|
|
126
|
+
var getQuery = function (primaryKey, ids, resource) {
|
|
127
|
+
var _a;
|
|
128
|
+
if (Array.isArray(ids) && ids.length > 1) {
|
|
129
|
+
// no standardized query with multiple ids possible for rpc endpoints which are api-exposed database functions
|
|
130
|
+
if (resource.startsWith('rpc/')) {
|
|
131
|
+
console.error('PostgREST\'s rpc endpoints are not intended to be handled as views. Therefore, no query generation for multiple key values implemented!');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (isCompoundKey(primaryKey)) {
|
|
135
|
+
return "or=(\n ".concat(ids.map(function (id) {
|
|
136
|
+
var primaryKeyParams = decodeId(id, primaryKey);
|
|
137
|
+
return "and(".concat(primaryKey.map(function (key, i) { return "".concat(key, ".eq.").concat(primaryKeyParams[i]); }).join(','), ")");
|
|
138
|
+
}), "\n )");
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
return new URLSearchParams((_a = {}, _a[primaryKey[0]] = "in.(".concat(ids.join(','), ")"), _a)).toString();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// if ids is one Identifier
|
|
146
|
+
var id = ids.toString();
|
|
147
|
+
var primaryKeyParams_1 = decodeId(id, primaryKey);
|
|
148
|
+
if (isCompoundKey(primaryKey)) {
|
|
149
|
+
if (resource.startsWith('rpc/'))
|
|
150
|
+
return "".concat(primaryKey.map(function (key, i) { return "".concat(key, "=").concat(primaryKeyParams_1[i]); }).join('&'));
|
|
151
|
+
else
|
|
152
|
+
return "and=(".concat(primaryKey.map(function (key, i) { return "".concat(key, ".eq.").concat(primaryKeyParams_1[i]); }).join(','), ")");
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
return new URLSearchParams([[primaryKey[0], "eq.".concat(id)]]).toString();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
var getKeyData = function (primaryKey, data) {
|
|
160
|
+
var _a;
|
|
161
|
+
if (isCompoundKey(primaryKey)) {
|
|
162
|
+
return primaryKey.reduce(function (keyData, key) {
|
|
163
|
+
var _a;
|
|
164
|
+
return (__assign(__assign({}, keyData), (_a = {}, _a[key] = data[key], _a)));
|
|
165
|
+
}, {});
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
return _a = {}, _a[primaryKey[0]] = data[primaryKey[0]], _a;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
var getOrderBy = function (field, order, primaryKey) {
|
|
172
|
+
if (field == 'id') {
|
|
173
|
+
return primaryKey.map(function (key) { return ("".concat(key, ".").concat(order.toLowerCase())); }).join(',');
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
return "".concat(field, ".").concat(order.toLowerCase());
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
var defaultPrimaryKeys = new Map();
|
|
180
|
+
exports.default = (function (apiUrl, httpClient, defaultListOp, primaryKeys) {
|
|
181
|
+
if (httpClient === void 0) { httpClient = ra_core_1.fetchUtils.fetchJson; }
|
|
182
|
+
if (defaultListOp === void 0) { defaultListOp = 'eq'; }
|
|
183
|
+
if (primaryKeys === void 0) { primaryKeys = defaultPrimaryKeys; }
|
|
184
|
+
return ({
|
|
185
|
+
getList: function (resource, params) {
|
|
186
|
+
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
187
|
+
var _a = params.pagination, page = _a.page, perPage = _a.perPage;
|
|
188
|
+
var _b = params.sort, field = _b.field, order = _b.order;
|
|
189
|
+
var parsedFilter = parseFilters(params.filter, defaultListOp);
|
|
190
|
+
var query = __assign({ order: getOrderBy(field, order, primaryKey), offset: String((page - 1) * perPage), limit: String(perPage) }, parsedFilter);
|
|
191
|
+
// add header that Content-Range is in returned header
|
|
192
|
+
var options = {
|
|
193
|
+
headers: new Headers({
|
|
194
|
+
Accept: 'application/json',
|
|
195
|
+
Prefer: 'count=exact'
|
|
196
|
+
})
|
|
197
|
+
};
|
|
198
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(new URLSearchParams(query));
|
|
199
|
+
return httpClient(url, options).then(function (_a) {
|
|
200
|
+
var headers = _a.headers, json = _a.json;
|
|
201
|
+
if (!headers.has('content-range')) {
|
|
202
|
+
throw new Error("The Content-Range header is missing in the HTTP Response. The postgREST data provider expects \n responses for lists of resources to contain this header with the total number of results to build \n the pagination. If you are using CORS, did you declare Content-Range in the Access-Control-Expose-Headers header?");
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
data: json.map(function (obj) { return dataWithId(obj, primaryKey); }),
|
|
206
|
+
total: parseInt(headers
|
|
207
|
+
.get('content-range')
|
|
208
|
+
.split('/')
|
|
209
|
+
.pop(), 10)
|
|
210
|
+
};
|
|
211
|
+
});
|
|
212
|
+
},
|
|
213
|
+
getOne: function (resource, params) {
|
|
214
|
+
var id = params.id;
|
|
215
|
+
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
216
|
+
var query = getQuery(primaryKey, id, resource);
|
|
217
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
218
|
+
return httpClient(url, {
|
|
219
|
+
headers: new Headers({ 'accept': 'application/vnd.pgrst.object+json' }),
|
|
220
|
+
}).then(function (_a) {
|
|
221
|
+
var json = _a.json;
|
|
222
|
+
return ({
|
|
223
|
+
data: dataWithId(json, primaryKey),
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
},
|
|
227
|
+
getMany: function (resource, params) {
|
|
228
|
+
var ids = params.ids;
|
|
229
|
+
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
230
|
+
var query = getQuery(primaryKey, ids, resource);
|
|
231
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
232
|
+
return httpClient(url).then(function (_a) {
|
|
233
|
+
var json = _a.json;
|
|
234
|
+
return ({ data: json.map(function (data) { return dataWithId(data, primaryKey); }) });
|
|
235
|
+
});
|
|
236
|
+
},
|
|
237
|
+
getManyReference: function (resource, params) {
|
|
238
|
+
var _a;
|
|
239
|
+
var _b = params.pagination, page = _b.page, perPage = _b.perPage;
|
|
240
|
+
var _c = params.sort, field = _c.field, order = _c.order;
|
|
241
|
+
var parsedFilter = parseFilters(params.filter, defaultListOp);
|
|
242
|
+
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
243
|
+
var query = params.target ? __assign((_a = {}, _a[params.target] = "eq.".concat(params.id), _a.order = getOrderBy(field, order, primaryKey), _a.offset = String((page - 1) * perPage), _a.limit = String(perPage), _a), parsedFilter) : __assign({ order: getOrderBy(field, order, primaryKey), offset: String((page - 1) * perPage), limit: String(perPage) }, parsedFilter);
|
|
244
|
+
// add header that Content-Range is in returned header
|
|
245
|
+
var options = {
|
|
246
|
+
headers: new Headers({
|
|
247
|
+
Accept: 'application/json',
|
|
248
|
+
Prefer: 'count=exact'
|
|
249
|
+
})
|
|
250
|
+
};
|
|
251
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(new URLSearchParams(query));
|
|
252
|
+
return httpClient(url, options).then(function (_a) {
|
|
253
|
+
var headers = _a.headers, json = _a.json;
|
|
254
|
+
if (!headers.has('content-range')) {
|
|
255
|
+
throw new Error("The Content-Range header is missing in the HTTP Response. The postgREST data provider expects \n responses for lists of resources to contain this header with the total number of results to build \n the pagination. If you are using CORS, did you declare Content-Range in the Access-Control-Expose-Headers header?");
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
data: json.map(function (data) { return dataWithId(data, primaryKey); }),
|
|
259
|
+
total: parseInt(headers
|
|
260
|
+
.get('content-range')
|
|
261
|
+
.split('/')
|
|
262
|
+
.pop(), 10),
|
|
263
|
+
};
|
|
264
|
+
});
|
|
265
|
+
},
|
|
266
|
+
update: function (resource, params) {
|
|
267
|
+
var id = params.id, data = params.data;
|
|
268
|
+
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
269
|
+
var query = getQuery(primaryKey, id, resource);
|
|
270
|
+
var primaryKeyData = getKeyData(primaryKey, data);
|
|
271
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
272
|
+
var body = JSON.stringify(__assign(__assign({}, data), primaryKeyData));
|
|
273
|
+
return httpClient(url, {
|
|
274
|
+
method: 'PATCH',
|
|
275
|
+
headers: new Headers({
|
|
276
|
+
'Accept': 'application/vnd.pgrst.object+json',
|
|
277
|
+
'Prefer': 'return=representation',
|
|
278
|
+
'Content-Type': 'application/json'
|
|
279
|
+
}),
|
|
280
|
+
body: body,
|
|
281
|
+
}).then(function (_a) {
|
|
282
|
+
var json = _a.json;
|
|
283
|
+
return ({ data: dataWithId(json, primaryKey) });
|
|
284
|
+
});
|
|
285
|
+
},
|
|
286
|
+
updateMany: function (resource, params) {
|
|
287
|
+
var ids = params.ids;
|
|
288
|
+
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
289
|
+
var query = getQuery(primaryKey, ids, resource);
|
|
290
|
+
var body = JSON.stringify(params.data.map(function (obj) {
|
|
291
|
+
var id = obj.id, data = __rest(obj, ["id"]);
|
|
292
|
+
var primaryKeyData = getKeyData(primaryKey, data);
|
|
293
|
+
return __assign(__assign({}, data), primaryKeyData);
|
|
294
|
+
}));
|
|
295
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
296
|
+
return httpClient(url, {
|
|
297
|
+
method: 'PATCH',
|
|
298
|
+
headers: new Headers({
|
|
299
|
+
'Prefer': 'return=representation',
|
|
300
|
+
'Content-Type': 'application/json',
|
|
301
|
+
}),
|
|
302
|
+
body: body,
|
|
303
|
+
}).then(function (_a) {
|
|
304
|
+
var json = _a.json;
|
|
305
|
+
return ({
|
|
306
|
+
data: json.map(function (data) { return encodeId(data, primaryKey); })
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
},
|
|
310
|
+
create: function (resource, params) {
|
|
311
|
+
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
312
|
+
var url = "".concat(apiUrl, "/").concat(resource);
|
|
313
|
+
return httpClient(url, {
|
|
314
|
+
method: 'POST',
|
|
315
|
+
headers: new Headers({
|
|
316
|
+
'Accept': 'application/vnd.pgrst.object+json',
|
|
317
|
+
'Prefer': 'return=representation',
|
|
318
|
+
'Content-Type': 'application/json'
|
|
319
|
+
}),
|
|
320
|
+
body: JSON.stringify(params.data),
|
|
321
|
+
}).then(function (_a) {
|
|
322
|
+
var json = _a.json;
|
|
323
|
+
return ({
|
|
324
|
+
data: __assign(__assign({}, params.data), { id: encodeId(json, primaryKey) })
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
},
|
|
328
|
+
delete: function (resource, params) {
|
|
329
|
+
var id = params.id;
|
|
330
|
+
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
331
|
+
var query = getQuery(primaryKey, id, resource);
|
|
332
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
333
|
+
return httpClient(url, {
|
|
334
|
+
method: 'DELETE',
|
|
335
|
+
headers: new Headers({
|
|
336
|
+
'Accept': 'application/vnd.pgrst.object+json',
|
|
337
|
+
'Prefer': 'return=representation',
|
|
338
|
+
'Content-Type': 'application/json'
|
|
339
|
+
}),
|
|
340
|
+
}).then(function (_a) {
|
|
341
|
+
var json = _a.json;
|
|
342
|
+
return ({ data: dataWithId(json, primaryKey) });
|
|
343
|
+
});
|
|
344
|
+
},
|
|
345
|
+
deleteMany: function (resource, params) {
|
|
346
|
+
var ids = params.ids;
|
|
347
|
+
var primaryKey = getPrimaryKey(resource, primaryKeys);
|
|
348
|
+
var query = getQuery(primaryKey, ids, resource);
|
|
349
|
+
var url = "".concat(apiUrl, "/").concat(resource, "?").concat(query);
|
|
350
|
+
return httpClient(url, {
|
|
351
|
+
method: 'DELETE',
|
|
352
|
+
headers: new Headers({
|
|
353
|
+
'Prefer': 'return=representation',
|
|
354
|
+
'Content-Type': 'application/json'
|
|
355
|
+
}),
|
|
356
|
+
}).then(function (_a) {
|
|
357
|
+
var json = _a.json;
|
|
358
|
+
return ({ data: json.map(function (data) { return encodeId(data, primaryKey); }) });
|
|
359
|
+
});
|
|
360
|
+
},
|
|
361
|
+
});
|
|
362
|
+
});
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.authProvider = void 0;
|
|
7
|
+
var dataProvider_1 = __importDefault(require("./dataProvider"));
|
|
8
|
+
var authProvider_1 = __importDefault(require("./authProvider"));
|
|
9
|
+
exports.authProvider = authProvider_1.default;
|
|
10
|
+
exports.default = dataProvider_1.default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raphiniert/ra-data-postgrest",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "postgREST data provider for react-admin",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
@@ -26,16 +26,13 @@
|
|
|
26
26
|
"watch": "tsc --outDir esm --module es2015 --watch",
|
|
27
27
|
"prepare": "install-peers"
|
|
28
28
|
},
|
|
29
|
-
"dependencies": {
|
|
30
|
-
"query-string": "^5.1.1"
|
|
31
|
-
},
|
|
32
29
|
"devDependencies": {
|
|
33
|
-
"cross-env": "^
|
|
30
|
+
"cross-env": "^7.0.3",
|
|
34
31
|
"install-peers-cli": "^2.2.0",
|
|
35
|
-
"rimraf": "^
|
|
36
|
-
"typescript": "^
|
|
32
|
+
"rimraf": "^3.0.2",
|
|
33
|
+
"typescript": "^4.6.4"
|
|
37
34
|
},
|
|
38
35
|
"peerDependencies": {
|
|
39
|
-
"ra-core": "^
|
|
36
|
+
"ra-core": "^4.1.0"
|
|
40
37
|
}
|
|
41
38
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { stringify } from 'query-string';
|
|
2
1
|
import { fetchUtils, DataProvider, Identifier } from 'ra-core';
|
|
3
2
|
|
|
4
3
|
/**
|
|
@@ -24,7 +23,7 @@ import { fetchUtils, DataProvider, Identifier } from 'ra-core';
|
|
|
24
23
|
*
|
|
25
24
|
* import * as React from 'react';
|
|
26
25
|
* import { Admin, Resource } from 'react-admin';
|
|
27
|
-
* import postgrestRestProvider from '@
|
|
26
|
+
* import postgrestRestProvider from '@promitheus/ra-data-postgrest';
|
|
28
27
|
*
|
|
29
28
|
* import { PostList } from './posts';
|
|
30
29
|
*
|
|
@@ -132,7 +131,7 @@ const getQuery = (primaryKey : PrimaryKey, ids: Identifier | Array<Identifier>,
|
|
|
132
131
|
}
|
|
133
132
|
)`;
|
|
134
133
|
} else {
|
|
135
|
-
return
|
|
134
|
+
return new URLSearchParams({ [primaryKey[0]]: `in.(${ids.join(',')})` }).toString();
|
|
136
135
|
}
|
|
137
136
|
} else {
|
|
138
137
|
// if ids is one Identifier
|
|
@@ -145,7 +144,7 @@ const getQuery = (primaryKey : PrimaryKey, ids: Identifier | Array<Identifier>,
|
|
|
145
144
|
else
|
|
146
145
|
return `and=(${primaryKey.map((key : string, i: any) => `${key}.eq.${primaryKeyParams[i]}`).join(',')})`;
|
|
147
146
|
} else {
|
|
148
|
-
return
|
|
147
|
+
return new URLSearchParams([[primaryKey[0], `eq.${id}`]]).toString();
|
|
149
148
|
}
|
|
150
149
|
}
|
|
151
150
|
}
|
|
@@ -184,8 +183,8 @@ export default (apiUrl, httpClient = fetchUtils.fetchJson, defaultListOp = 'eq',
|
|
|
184
183
|
|
|
185
184
|
const query = {
|
|
186
185
|
order: getOrderBy(field, order, primaryKey),
|
|
187
|
-
offset: (page - 1) * perPage,
|
|
188
|
-
limit: perPage,
|
|
186
|
+
offset: String((page - 1) * perPage),
|
|
187
|
+
limit: String(perPage),
|
|
189
188
|
// append filters
|
|
190
189
|
...parsedFilter
|
|
191
190
|
};
|
|
@@ -198,7 +197,7 @@ export default (apiUrl, httpClient = fetchUtils.fetchJson, defaultListOp = 'eq',
|
|
|
198
197
|
})
|
|
199
198
|
};
|
|
200
199
|
|
|
201
|
-
const url = `${apiUrl}/${resource}?${
|
|
200
|
+
const url = `${apiUrl}/${resource}?${new URLSearchParams(query)}`;
|
|
202
201
|
|
|
203
202
|
return httpClient(url, options).then(({ headers, json }) => {
|
|
204
203
|
if (!headers.has('content-range')) {
|
|
@@ -256,13 +255,13 @@ export default (apiUrl, httpClient = fetchUtils.fetchJson, defaultListOp = 'eq',
|
|
|
256
255
|
const query = params.target ? {
|
|
257
256
|
[params.target]: `eq.${params.id}`,
|
|
258
257
|
order: getOrderBy(field, order, primaryKey),
|
|
259
|
-
offset: (page - 1) * perPage,
|
|
260
|
-
limit: perPage,
|
|
258
|
+
offset: String((page - 1) * perPage),
|
|
259
|
+
limit: String(perPage),
|
|
261
260
|
...parsedFilter,
|
|
262
261
|
}:{
|
|
263
262
|
order: getOrderBy(field, order, primaryKey),
|
|
264
|
-
offset: (page - 1) * perPage,
|
|
265
|
-
limit: perPage,
|
|
263
|
+
offset: String((page - 1) * perPage),
|
|
264
|
+
limit: String(perPage),
|
|
266
265
|
...parsedFilter,
|
|
267
266
|
};
|
|
268
267
|
|
|
@@ -274,7 +273,7 @@ export default (apiUrl, httpClient = fetchUtils.fetchJson, defaultListOp = 'eq',
|
|
|
274
273
|
})
|
|
275
274
|
}
|
|
276
275
|
|
|
277
|
-
const url = `${apiUrl}/${resource}?${
|
|
276
|
+
const url = `${apiUrl}/${resource}?${new URLSearchParams(query)}`;
|
|
278
277
|
|
|
279
278
|
return httpClient(url, options).then(({ headers, json }) => {
|
|
280
279
|
if (!headers.has('content-range')) {
|