@raphiniert/ra-data-postgrest 2.0.0-alpha.0 → 2.0.0-alpha.3
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 +137 -41
- package/IDEAS.md +46 -0
- package/README.md +120 -55
- package/esm/index.d.ts +58 -7
- package/esm/index.js +229 -221
- package/esm/urlBuilder.d.ts +7 -3
- package/esm/urlBuilder.js +87 -38
- package/lib/index.d.ts +58 -7
- package/lib/index.js +234 -221
- package/lib/urlBuilder.d.ts +7 -3
- package/lib/urlBuilder.js +87 -38
- package/package.json +11 -6
- package/src/index.ts +237 -125
- package/src/urlBuilder.ts +100 -43
package/esm/urlBuilder.js
CHANGED
|
@@ -42,8 +42,10 @@ var postgrestOperators = [
|
|
|
42
42
|
'or',
|
|
43
43
|
'and',
|
|
44
44
|
];
|
|
45
|
-
export var parseFilters = function (
|
|
45
|
+
export var parseFilters = function (params, defaultListOp) {
|
|
46
|
+
var filter = params.filter, _a = params.meta, meta = _a === void 0 ? {} : _a;
|
|
46
47
|
var result = {};
|
|
48
|
+
result.filter = {};
|
|
47
49
|
Object.keys(filter).forEach(function (key) {
|
|
48
50
|
// key: the name of the object key
|
|
49
51
|
var splitKey = key.split('@');
|
|
@@ -55,32 +57,69 @@ export var parseFilters = function (filter, defaultListOp) {
|
|
|
55
57
|
// we split the search term in words
|
|
56
58
|
values = filter[key].trim().split(/\s+/);
|
|
57
59
|
}
|
|
60
|
+
// CASE: Logical operator
|
|
61
|
+
else if (['or', 'and'].includes(operation)) {
|
|
62
|
+
// we extract each value entries and make it dot separated string.
|
|
63
|
+
var subFilter = parseFilters({ filter: filter[key] }, defaultListOp).filter;
|
|
64
|
+
// something like { "age@lt": 18 } and { "age@gt": 21 }
|
|
65
|
+
var filterExpressions_1 = [];
|
|
66
|
+
Object.entries(subFilter).forEach(function (_a) {
|
|
67
|
+
var op = _a[0], val = _a[1];
|
|
68
|
+
if (Array.isArray(val))
|
|
69
|
+
filterExpressions_1.push.apply(filterExpressions_1, val.map(function (v) { return [op, v].join('.'); }));
|
|
70
|
+
else
|
|
71
|
+
filterExpressions_1.push([op, val].join('.'));
|
|
72
|
+
});
|
|
73
|
+
// finally we flatten all as single string and enclose with bracket.
|
|
74
|
+
values = ["(".concat(filterExpressions_1.join(','), ")")];
|
|
75
|
+
}
|
|
58
76
|
else {
|
|
59
77
|
values = [filter[key]];
|
|
60
78
|
}
|
|
61
79
|
values.forEach(function (value) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
80
|
+
var op = (function () {
|
|
81
|
+
// if operator is intentionally blank, rpc syntax
|
|
82
|
+
if (operation.length === 0)
|
|
83
|
+
return "".concat(value);
|
|
84
|
+
if (operation.includes('like'))
|
|
85
|
+
return "".concat(operation, ".*").concat(value, "*");
|
|
86
|
+
if (['and', 'or'].includes(operation))
|
|
87
|
+
return "".concat(value);
|
|
88
|
+
if (['cs', 'cd'].includes(operation))
|
|
89
|
+
return "".concat(operation, ".{").concat(value, "}");
|
|
90
|
+
return "".concat(operation, ".").concat(value);
|
|
91
|
+
})();
|
|
92
|
+
// If resulting filter haven't contains the fieldname, then add it.
|
|
93
|
+
if (result.filter[splitKey[0]] === undefined) {
|
|
94
|
+
// first operator for the key,
|
|
95
|
+
if (['and', 'or'].includes(operation)) {
|
|
96
|
+
result.filter[operation] = op;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// we add it to the dict
|
|
100
|
+
result.filter[splitKey[0]] = op;
|
|
101
|
+
}
|
|
71
102
|
}
|
|
72
103
|
else {
|
|
73
104
|
if (!Array.isArray(result[splitKey[0]])) {
|
|
74
105
|
// second operator, we transform to an array
|
|
75
|
-
result[splitKey[0]] = [
|
|
106
|
+
result.filter[splitKey[0]] = [
|
|
107
|
+
result.filter[splitKey[0]],
|
|
108
|
+
op,
|
|
109
|
+
];
|
|
76
110
|
}
|
|
77
111
|
else {
|
|
78
112
|
// third and subsequent, we add to array
|
|
79
|
-
result[splitKey[0]].push(op);
|
|
113
|
+
result.filter[splitKey[0]].push(op);
|
|
80
114
|
}
|
|
81
115
|
}
|
|
82
116
|
});
|
|
83
117
|
});
|
|
118
|
+
if (meta === null || meta === void 0 ? void 0 : meta.columns) {
|
|
119
|
+
result.select = Array.isArray(meta.columns)
|
|
120
|
+
? meta.columns.join(',')
|
|
121
|
+
: meta.columns;
|
|
122
|
+
}
|
|
84
123
|
return result;
|
|
85
124
|
};
|
|
86
125
|
export var getPrimaryKey = function (resource, primaryKeys) {
|
|
@@ -113,8 +152,10 @@ export var dataWithId = function (data, primaryKey) {
|
|
|
113
152
|
export var isCompoundKey = function (primaryKey) {
|
|
114
153
|
return primaryKey.length > 1;
|
|
115
154
|
};
|
|
116
|
-
export var getQuery = function (primaryKey, ids, resource) {
|
|
117
|
-
var _a;
|
|
155
|
+
export var getQuery = function (primaryKey, ids, resource, meta) {
|
|
156
|
+
var _a, _b;
|
|
157
|
+
if (meta === void 0) { meta = null; }
|
|
158
|
+
var result = {};
|
|
118
159
|
if (Array.isArray(ids) && ids.length > 1) {
|
|
119
160
|
// no standardized query with multiple ids possible for rpc endpoints which are api-exposed database functions
|
|
120
161
|
if (resource.startsWith('rpc/')) {
|
|
@@ -122,18 +163,19 @@ export var getQuery = function (primaryKey, ids, resource) {
|
|
|
122
163
|
return;
|
|
123
164
|
}
|
|
124
165
|
if (isCompoundKey(primaryKey)) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
166
|
+
result = {
|
|
167
|
+
or: "(".concat(ids.map(function (id) {
|
|
168
|
+
var primaryKeyParams = decodeId(id, primaryKey);
|
|
169
|
+
return "and(".concat(primaryKey
|
|
170
|
+
.map(function (key, i) { return "".concat(key, ".eq.").concat(primaryKeyParams[i]); })
|
|
171
|
+
.join(','), ")");
|
|
172
|
+
}), ")"),
|
|
173
|
+
};
|
|
132
174
|
}
|
|
133
175
|
else {
|
|
134
|
-
|
|
176
|
+
result = (_a = {},
|
|
135
177
|
_a[primaryKey[0]] = "in.(".concat(ids.join(','), ")"),
|
|
136
|
-
_a)
|
|
178
|
+
_a);
|
|
137
179
|
}
|
|
138
180
|
}
|
|
139
181
|
else {
|
|
@@ -141,25 +183,32 @@ export var getQuery = function (primaryKey, ids, resource) {
|
|
|
141
183
|
var id = ids.toString();
|
|
142
184
|
var primaryKeyParams_1 = decodeId(id, primaryKey);
|
|
143
185
|
if (isCompoundKey(primaryKey)) {
|
|
144
|
-
if (resource.startsWith('rpc/'))
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
else
|
|
151
|
-
|
|
152
|
-
.map(function (key, i) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
186
|
+
if (resource.startsWith('rpc/')) {
|
|
187
|
+
result = {};
|
|
188
|
+
primaryKey.map(function (key, i) {
|
|
189
|
+
return (result[key] = "".concat(primaryKeyParams_1[i]));
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
result = {
|
|
194
|
+
and: "(".concat(primaryKey.map(function (key, i) {
|
|
195
|
+
return "".concat(key, ".eq.").concat(primaryKeyParams_1[i]);
|
|
196
|
+
}), ")"),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
156
199
|
}
|
|
157
200
|
else {
|
|
158
|
-
|
|
159
|
-
[primaryKey[0]
|
|
160
|
-
|
|
201
|
+
result = (_b = {},
|
|
202
|
+
_b[primaryKey[0]] = "eq.".concat(id),
|
|
203
|
+
_b);
|
|
161
204
|
}
|
|
162
205
|
}
|
|
206
|
+
if (meta && meta.columns) {
|
|
207
|
+
result.select = Array.isArray(meta.columns)
|
|
208
|
+
? meta.columns.join(',')
|
|
209
|
+
: meta.columns;
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
163
212
|
};
|
|
164
213
|
export var getKeyData = function (primaryKey, data) {
|
|
165
214
|
var _a;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,60 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DataProvider } from 'ra-core';
|
|
2
2
|
import { PrimaryKey, PostgRestOperator } from './urlBuilder';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Maps react-admin queries to a postgrest REST API
|
|
5
|
+
*
|
|
6
|
+
* This REST dialect uses postgrest syntax
|
|
7
|
+
*
|
|
8
|
+
* @see https://postgrest.org/en/stable/api.html#embedded-filters
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
*
|
|
12
|
+
* getList => GET http://my.api.url/posts?order=title.asc&offset=0&limit=24&filterField=eq.value
|
|
13
|
+
* getOne => GET http://my.api.url/posts?id=eq.123
|
|
14
|
+
* getMany => GET http://my.api.url/posts?id=in.(123,456,789)
|
|
15
|
+
* getManyReference => GET http://my.api.url/posts?author_id=eq.345
|
|
16
|
+
* create => POST http://my.api.url/posts
|
|
17
|
+
* update => PATCH http://my.api.url/posts?id=eq.123
|
|
18
|
+
* updateMany => PATCH http://my.api.url/posts?id=in.(123,456,789)
|
|
19
|
+
* delete => DELETE http://my.api.url/posts?id=eq.123
|
|
20
|
+
* deleteMany => DELETE http://my.api.url/posts?id=in.(123,456,789)
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
*
|
|
24
|
+
* import * as React from 'react';
|
|
25
|
+
* import { Admin, Resource, fetchUtils } from 'react-admin';
|
|
26
|
+
* import postgrestRestProvider,
|
|
27
|
+
* { IDataProviderConfig,
|
|
28
|
+
* defaultPrimaryKeys,
|
|
29
|
+
* defaultSchema } from '@raphiniert/ra-data-postgrest';
|
|
30
|
+
*
|
|
31
|
+
* import { PostList } from './posts';
|
|
32
|
+
*
|
|
33
|
+
* const config: IDataProviderConfig = {
|
|
34
|
+
* apiUrl: 'http://path.to.my.api/',
|
|
35
|
+
* httpClient: fetchUtils.fetchJson,
|
|
36
|
+
* defaultListOp: 'eq',
|
|
37
|
+
* primaryKeys: defaultPrimaryKeys,
|
|
38
|
+
* schema: defaultSchema
|
|
39
|
+
* }
|
|
40
|
+
*
|
|
41
|
+
* const App = () => (
|
|
42
|
+
* <Admin dataProvider={postgrestRestProvider(config)}>
|
|
43
|
+
* <Resource name="posts" list={PostList} />
|
|
44
|
+
* </Admin>
|
|
45
|
+
* );
|
|
46
|
+
*
|
|
47
|
+
* export default App;
|
|
48
|
+
*/
|
|
49
|
+
export type MetaOption = string | undefined;
|
|
50
|
+
export declare const defaultPrimaryKeys: Map<string, PrimaryKey>;
|
|
51
|
+
export declare const defaultSchema: () => string;
|
|
52
|
+
export interface IDataProviderConfig {
|
|
53
|
+
apiUrl: string;
|
|
54
|
+
httpClient: (string: any, Options: any) => Promise<any>;
|
|
55
|
+
defaultListOp: PostgRestOperator;
|
|
56
|
+
primaryKeys: Map<string, PrimaryKey>;
|
|
57
|
+
schema: () => string;
|
|
58
|
+
}
|
|
59
|
+
declare const _default: (config: IDataProviderConfig) => DataProvider;
|
|
9
60
|
export default _default;
|