@raphiniert/ra-data-postgrest 2.0.0-alpha.3 → 2.0.0-alpha.4
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 +11 -0
- package/esm/index.js +21 -27
- package/esm/urlBuilder.d.ts +4 -4
- package/esm/urlBuilder.js +61 -23
- package/lib/index.js +20 -26
- package/lib/urlBuilder.d.ts +4 -4
- package/lib/urlBuilder.js +68 -30
- package/package.json +7 -8
- package/src/index.ts +35 -42
- package/src/urlBuilder.ts +60 -25
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
Find all notable changes of this project in this file.
|
|
4
4
|
|
|
5
|
+
## v2.0.0-alpha.4 - 2023-10-23
|
|
6
|
+
### Improvements
|
|
7
|
+
- updated dependencies
|
|
8
|
+
|
|
9
|
+
### New feature
|
|
10
|
+
- [#100](https://github.com/raphiniert-com/ra-data-postgrest/pull/100) support "meta.columns" on all code paths (useful when the user does not have permissions on all the columns in which case doing select=* gives permissions errors) - @[ruslantalpa](https://github.com/ruslantalpa)
|
|
11
|
+
|
|
12
|
+
### Fixes
|
|
13
|
+
- [#50](https://github.com/raphiniert-com/ra-data-postgrest/issues/50) and [#88](https://github.com/raphiniert-com/ra-data-postgrest/issues/88) solved by [#100](https://github.com/raphiniert-com/ra-data-postgrest/pull/100) including other fixes - @[ruslantalpa](https://github.com/ruslantalpa)
|
|
14
|
+
|
|
15
|
+
|
|
5
16
|
## v2.0.0-alpha.3 - 2023-06-16
|
|
6
17
|
### Improvements
|
|
7
18
|
- updated dependencies
|
package/esm/index.js
CHANGED
|
@@ -9,7 +9,7 @@ var __assign = (this && this.__assign) || function () {
|
|
|
9
9
|
};
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
|
-
import { getPrimaryKey, parseFilters, getOrderBy,
|
|
12
|
+
import { getPrimaryKey, parseFilters, getOrderBy, dataWithVirtualId, dataWithoutVirtualId, removePrimaryKey, getQuery, encodeId, } from './urlBuilder';
|
|
13
13
|
import qs from 'qs';
|
|
14
14
|
export var defaultPrimaryKeys = new Map();
|
|
15
15
|
export var defaultSchema = function () { return ''; };
|
|
@@ -61,7 +61,7 @@ export default (function (config) { return ({
|
|
|
61
61
|
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?");
|
|
62
62
|
}
|
|
63
63
|
return {
|
|
64
|
-
data: json.map(function (obj) { return
|
|
64
|
+
data: json.map(function (obj) { return dataWithVirtualId(obj, primaryKey); }),
|
|
65
65
|
total: parseInt(headers.get('content-range').split('/').pop(), 10),
|
|
66
66
|
};
|
|
67
67
|
});
|
|
@@ -81,7 +81,7 @@ export default (function (config) { return ({
|
|
|
81
81
|
.then(function (_a) {
|
|
82
82
|
var json = _a.json;
|
|
83
83
|
return ({
|
|
84
|
-
data:
|
|
84
|
+
data: dataWithVirtualId(json, primaryKey),
|
|
85
85
|
});
|
|
86
86
|
});
|
|
87
87
|
},
|
|
@@ -100,7 +100,7 @@ export default (function (config) { return ({
|
|
|
100
100
|
.then(function (_a) {
|
|
101
101
|
var json = _a.json;
|
|
102
102
|
return ({
|
|
103
|
-
data: json.map(function (data) { return
|
|
103
|
+
data: json.map(function (data) { return dataWithVirtualId(data, primaryKey); }),
|
|
104
104
|
});
|
|
105
105
|
});
|
|
106
106
|
},
|
|
@@ -129,7 +129,7 @@ export default (function (config) { return ({
|
|
|
129
129
|
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?");
|
|
130
130
|
}
|
|
131
131
|
return {
|
|
132
|
-
data: json.map(function (data) { return
|
|
132
|
+
data: json.map(function (data) { return dataWithVirtualId(data, primaryKey); }),
|
|
133
133
|
total: parseInt(headers.get('content-range').split('/').pop(), 10),
|
|
134
134
|
};
|
|
135
135
|
});
|
|
@@ -140,10 +140,9 @@ export default (function (config) { return ({
|
|
|
140
140
|
var id = params.id, data = params.data, meta = params.meta;
|
|
141
141
|
var primaryKey = getPrimaryKey(resource, config.primaryKeys);
|
|
142
142
|
var query = getQuery(primaryKey, id, resource, meta);
|
|
143
|
-
var primaryKeyData = getKeyData(primaryKey, data);
|
|
144
143
|
var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs.stringify(query));
|
|
145
144
|
var metaSchema = (_a = params.meta) === null || _a === void 0 ? void 0 : _a.schema;
|
|
146
|
-
var body = JSON.stringify(__assign(
|
|
145
|
+
var body = JSON.stringify(__assign({}, dataWithoutVirtualId(removePrimaryKey(data, primaryKey), primaryKey)));
|
|
147
146
|
return config
|
|
148
147
|
.httpClient(url, {
|
|
149
148
|
method: 'PATCH',
|
|
@@ -152,29 +151,19 @@ export default (function (config) { return ({
|
|
|
152
151
|
})
|
|
153
152
|
.then(function (_a) {
|
|
154
153
|
var json = _a.json;
|
|
155
|
-
return ({
|
|
154
|
+
return ({
|
|
155
|
+
data: dataWithVirtualId(json, primaryKey),
|
|
156
|
+
});
|
|
156
157
|
});
|
|
157
158
|
},
|
|
158
159
|
updateMany: function (resource, params) {
|
|
159
160
|
var _a, _b;
|
|
160
161
|
if (params === void 0) { params = {}; }
|
|
161
|
-
var ids = params.ids;
|
|
162
|
+
var ids = params.ids, meta = params.meta, data = params.data;
|
|
162
163
|
var primaryKey = getPrimaryKey(resource, config.primaryKeys);
|
|
163
|
-
var
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
var primaryKeyData = {};
|
|
167
|
-
if (isCompoundKey(primaryKey)) {
|
|
168
|
-
primaryKey.forEach(function (key, index) {
|
|
169
|
-
primaryKeyData[key] = primaryKeyParams[index];
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
primaryKeyData[primaryKey[0]] = primaryKeyParams[0];
|
|
174
|
-
}
|
|
175
|
-
return __assign(__assign({}, data), primaryKeyData);
|
|
176
|
-
}));
|
|
177
|
-
var url = "".concat(config.apiUrl, "/").concat(resource);
|
|
164
|
+
var query = getQuery(primaryKey, ids, resource, meta);
|
|
165
|
+
var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs.stringify(query));
|
|
166
|
+
var body = JSON.stringify(__assign({}, dataWithoutVirtualId(removePrimaryKey(data, primaryKey), primaryKey)));
|
|
178
167
|
var metaSchema = (_a = params.meta) === null || _a === void 0 ? void 0 : _a.schema;
|
|
179
168
|
return config
|
|
180
169
|
.httpClient(url, {
|
|
@@ -192,14 +181,17 @@ export default (function (config) { return ({
|
|
|
192
181
|
create: function (resource, params) {
|
|
193
182
|
var _a, _b;
|
|
194
183
|
if (params === void 0) { params = {}; }
|
|
184
|
+
var meta = params.meta;
|
|
195
185
|
var primaryKey = getPrimaryKey(resource, config.primaryKeys);
|
|
196
|
-
var
|
|
186
|
+
var query = getQuery(primaryKey, undefined, resource, meta);
|
|
187
|
+
var queryStr = qs.stringify(query);
|
|
188
|
+
var url = "".concat(config.apiUrl, "/").concat(resource).concat(queryStr.length > 0 ? '?' : '').concat(queryStr);
|
|
197
189
|
var metaSchema = (_a = params.meta) === null || _a === void 0 ? void 0 : _a.schema;
|
|
198
190
|
return config
|
|
199
191
|
.httpClient(url, {
|
|
200
192
|
method: 'POST',
|
|
201
193
|
headers: new Headers(__assign(__assign({ Accept: 'application/vnd.pgrst.object+json', Prefer: 'return=representation', 'Content-Type': 'application/json' }, (((_b = params.meta) === null || _b === void 0 ? void 0 : _b.headers) || {})), useCustomSchema(config.schema, metaSchema, 'POST'))),
|
|
202
|
-
body: JSON.stringify(params.data),
|
|
194
|
+
body: JSON.stringify(dataWithoutVirtualId(params.data, primaryKey)),
|
|
203
195
|
})
|
|
204
196
|
.then(function (_a) {
|
|
205
197
|
var json = _a.json;
|
|
@@ -223,7 +215,9 @@ export default (function (config) { return ({
|
|
|
223
215
|
})
|
|
224
216
|
.then(function (_a) {
|
|
225
217
|
var json = _a.json;
|
|
226
|
-
return ({
|
|
218
|
+
return ({
|
|
219
|
+
data: dataWithVirtualId(json, primaryKey),
|
|
220
|
+
});
|
|
227
221
|
});
|
|
228
222
|
},
|
|
229
223
|
deleteMany: function (resource, params) {
|
package/esm/urlBuilder.d.ts
CHANGED
|
@@ -14,9 +14,9 @@ export type PrimaryKey = Array<string>;
|
|
|
14
14
|
export declare const getPrimaryKey: (resource: string, primaryKeys: Map<string, PrimaryKey>) => PrimaryKey;
|
|
15
15
|
export declare const decodeId: (id: Identifier, primaryKey: PrimaryKey) => string[] | number[];
|
|
16
16
|
export declare const encodeId: (data: any, primaryKey: PrimaryKey) => Identifier;
|
|
17
|
-
export declare const
|
|
18
|
-
export declare const
|
|
19
|
-
export declare const
|
|
20
|
-
export declare const
|
|
17
|
+
export declare const removePrimaryKey: (data: any, primaryKey: PrimaryKey) => any;
|
|
18
|
+
export declare const dataWithVirtualId: (data: any, primaryKey: PrimaryKey) => any;
|
|
19
|
+
export declare const dataWithoutVirtualId: (data: any, primaryKey: PrimaryKey) => any;
|
|
20
|
+
export declare const getQuery: (primaryKey: PrimaryKey, ids: Identifier | Array<Identifier> | undefined, resource: string, meta?: any) => any;
|
|
21
21
|
export declare const getOrderBy: (field: string, order: string, primaryKey: PrimaryKey) => string;
|
|
22
22
|
export {};
|
package/esm/urlBuilder.js
CHANGED
|
@@ -9,6 +9,17 @@ var __assign = (this && this.__assign) || function () {
|
|
|
9
9
|
};
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
13
|
+
var t = {};
|
|
14
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
15
|
+
t[p] = s[p];
|
|
16
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
17
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
18
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
19
|
+
t[p[i]] = s[p[i]];
|
|
20
|
+
}
|
|
21
|
+
return t;
|
|
22
|
+
};
|
|
12
23
|
/**
|
|
13
24
|
* List of all possible operators in PostgRest
|
|
14
25
|
* (https://postgrest.org/en/stable/api.html#operators)
|
|
@@ -42,25 +53,53 @@ var postgrestOperators = [
|
|
|
42
53
|
'or',
|
|
43
54
|
'and',
|
|
44
55
|
];
|
|
56
|
+
var isObject = function (obj) {
|
|
57
|
+
return typeof obj === 'object' && !Array.isArray(obj) && obj !== null;
|
|
58
|
+
};
|
|
59
|
+
var resolveKeys = function (filter, keys) {
|
|
60
|
+
var result = filter[keys[0]];
|
|
61
|
+
for (var i = 1; i < keys.length; ++i) {
|
|
62
|
+
result = result[keys[i]];
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
};
|
|
45
66
|
export var parseFilters = function (params, defaultListOp) {
|
|
46
67
|
var filter = params.filter, _a = params.meta, meta = _a === void 0 ? {} : _a;
|
|
47
68
|
var result = {};
|
|
48
69
|
result.filter = {};
|
|
49
70
|
Object.keys(filter).forEach(function (key) {
|
|
50
71
|
// key: the name of the object key
|
|
72
|
+
var keyArray = [key];
|
|
73
|
+
var values;
|
|
74
|
+
// in case of a nested object selection in a text field
|
|
75
|
+
// RA returns object{ object } structure which is resolved here
|
|
76
|
+
// see issue https://github.com/raphiniert-com/ra-data-postgrest/issues/58
|
|
77
|
+
if (key.split('@')[0] !== '' && isObject(filter[key])) {
|
|
78
|
+
var innerVal = filter[key];
|
|
79
|
+
do {
|
|
80
|
+
var inner = resolveKeys(filter, keyArray);
|
|
81
|
+
var innerKey = Object.keys(inner)[0];
|
|
82
|
+
keyArray.push(innerKey);
|
|
83
|
+
innerVal = inner[innerKey];
|
|
84
|
+
} while (isObject(innerVal));
|
|
85
|
+
key = keyArray.join('.');
|
|
86
|
+
values = [innerVal];
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
values = [filter[key]];
|
|
90
|
+
}
|
|
51
91
|
var splitKey = key.split('@');
|
|
52
92
|
var operation = splitKey.length == 2
|
|
53
93
|
? splitKey[1]
|
|
54
94
|
: defaultListOp;
|
|
55
|
-
var values;
|
|
56
95
|
if (['like', 'ilike'].includes(operation)) {
|
|
57
96
|
// we split the search term in words
|
|
58
|
-
values = filter
|
|
97
|
+
values = resolveKeys(filter, keyArray).trim().split(/\s+/);
|
|
59
98
|
}
|
|
60
99
|
// CASE: Logical operator
|
|
61
100
|
else if (['or', 'and'].includes(operation)) {
|
|
62
101
|
// we extract each value entries and make it dot separated string.
|
|
63
|
-
var subFilter = parseFilters({ filter: filter
|
|
102
|
+
var subFilter = parseFilters({ filter: resolveKeys(filter, keyArray) }, defaultListOp).filter;
|
|
64
103
|
// something like { "age@lt": 18 } and { "age@gt": 21 }
|
|
65
104
|
var filterExpressions_1 = [];
|
|
66
105
|
Object.entries(subFilter).forEach(function (_a) {
|
|
@@ -73,9 +112,6 @@ export var parseFilters = function (params, defaultListOp) {
|
|
|
73
112
|
// finally we flatten all as single string and enclose with bracket.
|
|
74
113
|
values = ["(".concat(filterExpressions_1.join(','), ")")];
|
|
75
114
|
}
|
|
76
|
-
else {
|
|
77
|
-
values = [filter[key]];
|
|
78
|
-
}
|
|
79
115
|
values.forEach(function (value) {
|
|
80
116
|
var op = (function () {
|
|
81
117
|
// if operator is intentionally blank, rpc syntax
|
|
@@ -89,7 +125,7 @@ export var parseFilters = function (params, defaultListOp) {
|
|
|
89
125
|
return "".concat(operation, ".{").concat(value, "}");
|
|
90
126
|
return "".concat(operation, ".").concat(value);
|
|
91
127
|
})();
|
|
92
|
-
// If resulting filter
|
|
128
|
+
// If resulting filter doesn't contain the fieldname, then add it.
|
|
93
129
|
if (result.filter[splitKey[0]] === undefined) {
|
|
94
130
|
// first operator for the key,
|
|
95
131
|
if (['and', 'or'].includes(operation)) {
|
|
@@ -141,15 +177,29 @@ export var encodeId = function (data, primaryKey) {
|
|
|
141
177
|
return data[primaryKey[0]];
|
|
142
178
|
}
|
|
143
179
|
};
|
|
144
|
-
export var
|
|
145
|
-
|
|
180
|
+
export var removePrimaryKey = function (data, primaryKey) {
|
|
181
|
+
var newData = __assign({}, data);
|
|
182
|
+
primaryKey.forEach(function (key) {
|
|
183
|
+
delete newData[key];
|
|
184
|
+
});
|
|
185
|
+
return newData;
|
|
186
|
+
};
|
|
187
|
+
export var dataWithVirtualId = function (data, primaryKey) {
|
|
188
|
+
if (primaryKey.length === 1 && primaryKey[0] === 'id') {
|
|
146
189
|
return data;
|
|
147
190
|
}
|
|
148
191
|
return Object.assign(data, {
|
|
149
192
|
id: encodeId(data, primaryKey),
|
|
150
193
|
});
|
|
151
194
|
};
|
|
152
|
-
export var
|
|
195
|
+
export var dataWithoutVirtualId = function (data, primaryKey) {
|
|
196
|
+
if (primaryKey.length === 1 && primaryKey[0] === 'id') {
|
|
197
|
+
return data;
|
|
198
|
+
}
|
|
199
|
+
var id = data.id, dataWithoutId = __rest(data, ["id"]);
|
|
200
|
+
return dataWithoutId;
|
|
201
|
+
};
|
|
202
|
+
var isCompoundKey = function (primaryKey) {
|
|
153
203
|
return primaryKey.length > 1;
|
|
154
204
|
};
|
|
155
205
|
export var getQuery = function (primaryKey, ids, resource, meta) {
|
|
@@ -178,7 +228,7 @@ export var getQuery = function (primaryKey, ids, resource, meta) {
|
|
|
178
228
|
_a);
|
|
179
229
|
}
|
|
180
230
|
}
|
|
181
|
-
else {
|
|
231
|
+
else if (ids) {
|
|
182
232
|
// if ids is one Identifier
|
|
183
233
|
var id = ids.toString();
|
|
184
234
|
var primaryKeyParams_1 = decodeId(id, primaryKey);
|
|
@@ -210,18 +260,6 @@ export var getQuery = function (primaryKey, ids, resource, meta) {
|
|
|
210
260
|
}
|
|
211
261
|
return result;
|
|
212
262
|
};
|
|
213
|
-
export var getKeyData = function (primaryKey, data) {
|
|
214
|
-
var _a;
|
|
215
|
-
if (isCompoundKey(primaryKey)) {
|
|
216
|
-
return primaryKey.reduce(function (keyData, key) {
|
|
217
|
-
var _a;
|
|
218
|
-
return (__assign(__assign({}, keyData), (_a = {}, _a[key] = data[key], _a)));
|
|
219
|
-
}, {});
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
return _a = {}, _a[primaryKey[0]] = data[primaryKey[0]], _a;
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
263
|
export var getOrderBy = function (field, order, primaryKey) {
|
|
226
264
|
if (field == 'id') {
|
|
227
265
|
return primaryKey.map(function (key) { return "".concat(key, ".").concat(order.toLowerCase()); }).join(',');
|
package/lib/index.js
CHANGED
|
@@ -68,7 +68,7 @@ exports.default = (function (config) { return ({
|
|
|
68
68
|
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?");
|
|
69
69
|
}
|
|
70
70
|
return {
|
|
71
|
-
data: json.map(function (obj) { return (0, urlBuilder_1.
|
|
71
|
+
data: json.map(function (obj) { return (0, urlBuilder_1.dataWithVirtualId)(obj, primaryKey); }),
|
|
72
72
|
total: parseInt(headers.get('content-range').split('/').pop(), 10),
|
|
73
73
|
};
|
|
74
74
|
});
|
|
@@ -88,7 +88,7 @@ exports.default = (function (config) { return ({
|
|
|
88
88
|
.then(function (_a) {
|
|
89
89
|
var json = _a.json;
|
|
90
90
|
return ({
|
|
91
|
-
data: (0, urlBuilder_1.
|
|
91
|
+
data: (0, urlBuilder_1.dataWithVirtualId)(json, primaryKey),
|
|
92
92
|
});
|
|
93
93
|
});
|
|
94
94
|
},
|
|
@@ -107,7 +107,7 @@ exports.default = (function (config) { return ({
|
|
|
107
107
|
.then(function (_a) {
|
|
108
108
|
var json = _a.json;
|
|
109
109
|
return ({
|
|
110
|
-
data: json.map(function (data) { return (0, urlBuilder_1.
|
|
110
|
+
data: json.map(function (data) { return (0, urlBuilder_1.dataWithVirtualId)(data, primaryKey); }),
|
|
111
111
|
});
|
|
112
112
|
});
|
|
113
113
|
},
|
|
@@ -136,7 +136,7 @@ exports.default = (function (config) { return ({
|
|
|
136
136
|
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?");
|
|
137
137
|
}
|
|
138
138
|
return {
|
|
139
|
-
data: json.map(function (data) { return (0, urlBuilder_1.
|
|
139
|
+
data: json.map(function (data) { return (0, urlBuilder_1.dataWithVirtualId)(data, primaryKey); }),
|
|
140
140
|
total: parseInt(headers.get('content-range').split('/').pop(), 10),
|
|
141
141
|
};
|
|
142
142
|
});
|
|
@@ -147,10 +147,9 @@ exports.default = (function (config) { return ({
|
|
|
147
147
|
var id = params.id, data = params.data, meta = params.meta;
|
|
148
148
|
var primaryKey = (0, urlBuilder_1.getPrimaryKey)(resource, config.primaryKeys);
|
|
149
149
|
var query = (0, urlBuilder_1.getQuery)(primaryKey, id, resource, meta);
|
|
150
|
-
var primaryKeyData = (0, urlBuilder_1.getKeyData)(primaryKey, data);
|
|
151
150
|
var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs_1.default.stringify(query));
|
|
152
151
|
var metaSchema = (_a = params.meta) === null || _a === void 0 ? void 0 : _a.schema;
|
|
153
|
-
var body = JSON.stringify(__assign(
|
|
152
|
+
var body = JSON.stringify(__assign({}, (0, urlBuilder_1.dataWithoutVirtualId)((0, urlBuilder_1.removePrimaryKey)(data, primaryKey), primaryKey)));
|
|
154
153
|
return config
|
|
155
154
|
.httpClient(url, {
|
|
156
155
|
method: 'PATCH',
|
|
@@ -159,29 +158,19 @@ exports.default = (function (config) { return ({
|
|
|
159
158
|
})
|
|
160
159
|
.then(function (_a) {
|
|
161
160
|
var json = _a.json;
|
|
162
|
-
return ({
|
|
161
|
+
return ({
|
|
162
|
+
data: (0, urlBuilder_1.dataWithVirtualId)(json, primaryKey),
|
|
163
|
+
});
|
|
163
164
|
});
|
|
164
165
|
},
|
|
165
166
|
updateMany: function (resource, params) {
|
|
166
167
|
var _a, _b;
|
|
167
168
|
if (params === void 0) { params = {}; }
|
|
168
|
-
var ids = params.ids;
|
|
169
|
+
var ids = params.ids, meta = params.meta, data = params.data;
|
|
169
170
|
var primaryKey = (0, urlBuilder_1.getPrimaryKey)(resource, config.primaryKeys);
|
|
170
|
-
var
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
var primaryKeyData = {};
|
|
174
|
-
if ((0, urlBuilder_1.isCompoundKey)(primaryKey)) {
|
|
175
|
-
primaryKey.forEach(function (key, index) {
|
|
176
|
-
primaryKeyData[key] = primaryKeyParams[index];
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
primaryKeyData[primaryKey[0]] = primaryKeyParams[0];
|
|
181
|
-
}
|
|
182
|
-
return __assign(__assign({}, data), primaryKeyData);
|
|
183
|
-
}));
|
|
184
|
-
var url = "".concat(config.apiUrl, "/").concat(resource);
|
|
171
|
+
var query = (0, urlBuilder_1.getQuery)(primaryKey, ids, resource, meta);
|
|
172
|
+
var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs_1.default.stringify(query));
|
|
173
|
+
var body = JSON.stringify(__assign({}, (0, urlBuilder_1.dataWithoutVirtualId)((0, urlBuilder_1.removePrimaryKey)(data, primaryKey), primaryKey)));
|
|
185
174
|
var metaSchema = (_a = params.meta) === null || _a === void 0 ? void 0 : _a.schema;
|
|
186
175
|
return config
|
|
187
176
|
.httpClient(url, {
|
|
@@ -199,14 +188,17 @@ exports.default = (function (config) { return ({
|
|
|
199
188
|
create: function (resource, params) {
|
|
200
189
|
var _a, _b;
|
|
201
190
|
if (params === void 0) { params = {}; }
|
|
191
|
+
var meta = params.meta;
|
|
202
192
|
var primaryKey = (0, urlBuilder_1.getPrimaryKey)(resource, config.primaryKeys);
|
|
203
|
-
var
|
|
193
|
+
var query = (0, urlBuilder_1.getQuery)(primaryKey, undefined, resource, meta);
|
|
194
|
+
var queryStr = qs_1.default.stringify(query);
|
|
195
|
+
var url = "".concat(config.apiUrl, "/").concat(resource).concat(queryStr.length > 0 ? '?' : '').concat(queryStr);
|
|
204
196
|
var metaSchema = (_a = params.meta) === null || _a === void 0 ? void 0 : _a.schema;
|
|
205
197
|
return config
|
|
206
198
|
.httpClient(url, {
|
|
207
199
|
method: 'POST',
|
|
208
200
|
headers: new Headers(__assign(__assign({ Accept: 'application/vnd.pgrst.object+json', Prefer: 'return=representation', 'Content-Type': 'application/json' }, (((_b = params.meta) === null || _b === void 0 ? void 0 : _b.headers) || {})), useCustomSchema(config.schema, metaSchema, 'POST'))),
|
|
209
|
-
body: JSON.stringify(params.data),
|
|
201
|
+
body: JSON.stringify((0, urlBuilder_1.dataWithoutVirtualId)(params.data, primaryKey)),
|
|
210
202
|
})
|
|
211
203
|
.then(function (_a) {
|
|
212
204
|
var json = _a.json;
|
|
@@ -230,7 +222,9 @@ exports.default = (function (config) { return ({
|
|
|
230
222
|
})
|
|
231
223
|
.then(function (_a) {
|
|
232
224
|
var json = _a.json;
|
|
233
|
-
return ({
|
|
225
|
+
return ({
|
|
226
|
+
data: (0, urlBuilder_1.dataWithVirtualId)(json, primaryKey),
|
|
227
|
+
});
|
|
234
228
|
});
|
|
235
229
|
},
|
|
236
230
|
deleteMany: function (resource, params) {
|
package/lib/urlBuilder.d.ts
CHANGED
|
@@ -14,9 +14,9 @@ export type PrimaryKey = Array<string>;
|
|
|
14
14
|
export declare const getPrimaryKey: (resource: string, primaryKeys: Map<string, PrimaryKey>) => PrimaryKey;
|
|
15
15
|
export declare const decodeId: (id: Identifier, primaryKey: PrimaryKey) => string[] | number[];
|
|
16
16
|
export declare const encodeId: (data: any, primaryKey: PrimaryKey) => Identifier;
|
|
17
|
-
export declare const
|
|
18
|
-
export declare const
|
|
19
|
-
export declare const
|
|
20
|
-
export declare const
|
|
17
|
+
export declare const removePrimaryKey: (data: any, primaryKey: PrimaryKey) => any;
|
|
18
|
+
export declare const dataWithVirtualId: (data: any, primaryKey: PrimaryKey) => any;
|
|
19
|
+
export declare const dataWithoutVirtualId: (data: any, primaryKey: PrimaryKey) => any;
|
|
20
|
+
export declare const getQuery: (primaryKey: PrimaryKey, ids: Identifier | Array<Identifier> | undefined, resource: string, meta?: any) => any;
|
|
21
21
|
export declare const getOrderBy: (field: string, order: string, primaryKey: PrimaryKey) => string;
|
|
22
22
|
export {};
|
package/lib/urlBuilder.js
CHANGED
|
@@ -10,8 +10,19 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
};
|
|
11
11
|
return __assign.apply(this, arguments);
|
|
12
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
|
+
};
|
|
13
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.getOrderBy = exports.
|
|
25
|
+
exports.getOrderBy = exports.getQuery = exports.dataWithoutVirtualId = exports.dataWithVirtualId = exports.removePrimaryKey = exports.encodeId = exports.decodeId = exports.getPrimaryKey = exports.parseFilters = void 0;
|
|
15
26
|
/**
|
|
16
27
|
* List of all possible operators in PostgRest
|
|
17
28
|
* (https://postgrest.org/en/stable/api.html#operators)
|
|
@@ -45,25 +56,53 @@ var postgrestOperators = [
|
|
|
45
56
|
'or',
|
|
46
57
|
'and',
|
|
47
58
|
];
|
|
59
|
+
var isObject = function (obj) {
|
|
60
|
+
return typeof obj === 'object' && !Array.isArray(obj) && obj !== null;
|
|
61
|
+
};
|
|
62
|
+
var resolveKeys = function (filter, keys) {
|
|
63
|
+
var result = filter[keys[0]];
|
|
64
|
+
for (var i = 1; i < keys.length; ++i) {
|
|
65
|
+
result = result[keys[i]];
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
};
|
|
48
69
|
var parseFilters = function (params, defaultListOp) {
|
|
49
70
|
var filter = params.filter, _a = params.meta, meta = _a === void 0 ? {} : _a;
|
|
50
71
|
var result = {};
|
|
51
72
|
result.filter = {};
|
|
52
73
|
Object.keys(filter).forEach(function (key) {
|
|
53
74
|
// key: the name of the object key
|
|
75
|
+
var keyArray = [key];
|
|
76
|
+
var values;
|
|
77
|
+
// in case of a nested object selection in a text field
|
|
78
|
+
// RA returns object{ object } structure which is resolved here
|
|
79
|
+
// see issue https://github.com/raphiniert-com/ra-data-postgrest/issues/58
|
|
80
|
+
if (key.split('@')[0] !== '' && isObject(filter[key])) {
|
|
81
|
+
var innerVal = filter[key];
|
|
82
|
+
do {
|
|
83
|
+
var inner = resolveKeys(filter, keyArray);
|
|
84
|
+
var innerKey = Object.keys(inner)[0];
|
|
85
|
+
keyArray.push(innerKey);
|
|
86
|
+
innerVal = inner[innerKey];
|
|
87
|
+
} while (isObject(innerVal));
|
|
88
|
+
key = keyArray.join('.');
|
|
89
|
+
values = [innerVal];
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
values = [filter[key]];
|
|
93
|
+
}
|
|
54
94
|
var splitKey = key.split('@');
|
|
55
95
|
var operation = splitKey.length == 2
|
|
56
96
|
? splitKey[1]
|
|
57
97
|
: defaultListOp;
|
|
58
|
-
var values;
|
|
59
98
|
if (['like', 'ilike'].includes(operation)) {
|
|
60
99
|
// we split the search term in words
|
|
61
|
-
values = filter
|
|
100
|
+
values = resolveKeys(filter, keyArray).trim().split(/\s+/);
|
|
62
101
|
}
|
|
63
102
|
// CASE: Logical operator
|
|
64
103
|
else if (['or', 'and'].includes(operation)) {
|
|
65
104
|
// we extract each value entries and make it dot separated string.
|
|
66
|
-
var subFilter = (0, exports.parseFilters)({ filter: filter
|
|
105
|
+
var subFilter = (0, exports.parseFilters)({ filter: resolveKeys(filter, keyArray) }, defaultListOp).filter;
|
|
67
106
|
// something like { "age@lt": 18 } and { "age@gt": 21 }
|
|
68
107
|
var filterExpressions_1 = [];
|
|
69
108
|
Object.entries(subFilter).forEach(function (_a) {
|
|
@@ -76,9 +115,6 @@ var parseFilters = function (params, defaultListOp) {
|
|
|
76
115
|
// finally we flatten all as single string and enclose with bracket.
|
|
77
116
|
values = ["(".concat(filterExpressions_1.join(','), ")")];
|
|
78
117
|
}
|
|
79
|
-
else {
|
|
80
|
-
values = [filter[key]];
|
|
81
|
-
}
|
|
82
118
|
values.forEach(function (value) {
|
|
83
119
|
var op = (function () {
|
|
84
120
|
// if operator is intentionally blank, rpc syntax
|
|
@@ -92,7 +128,7 @@ var parseFilters = function (params, defaultListOp) {
|
|
|
92
128
|
return "".concat(operation, ".{").concat(value, "}");
|
|
93
129
|
return "".concat(operation, ".").concat(value);
|
|
94
130
|
})();
|
|
95
|
-
// If resulting filter
|
|
131
|
+
// If resulting filter doesn't contain the fieldname, then add it.
|
|
96
132
|
if (result.filter[splitKey[0]] === undefined) {
|
|
97
133
|
// first operator for the key,
|
|
98
134
|
if (['and', 'or'].includes(operation)) {
|
|
@@ -131,7 +167,7 @@ var getPrimaryKey = function (resource, primaryKeys) {
|
|
|
131
167
|
};
|
|
132
168
|
exports.getPrimaryKey = getPrimaryKey;
|
|
133
169
|
var decodeId = function (id, primaryKey) {
|
|
134
|
-
if (
|
|
170
|
+
if (isCompoundKey(primaryKey)) {
|
|
135
171
|
return JSON.parse(id.toString());
|
|
136
172
|
}
|
|
137
173
|
else {
|
|
@@ -140,7 +176,7 @@ var decodeId = function (id, primaryKey) {
|
|
|
140
176
|
};
|
|
141
177
|
exports.decodeId = decodeId;
|
|
142
178
|
var encodeId = function (data, primaryKey) {
|
|
143
|
-
if (
|
|
179
|
+
if (isCompoundKey(primaryKey)) {
|
|
144
180
|
return JSON.stringify(primaryKey.map(function (key) { return data[key]; }));
|
|
145
181
|
}
|
|
146
182
|
else {
|
|
@@ -148,19 +184,34 @@ var encodeId = function (data, primaryKey) {
|
|
|
148
184
|
}
|
|
149
185
|
};
|
|
150
186
|
exports.encodeId = encodeId;
|
|
151
|
-
var
|
|
152
|
-
|
|
187
|
+
var removePrimaryKey = function (data, primaryKey) {
|
|
188
|
+
var newData = __assign({}, data);
|
|
189
|
+
primaryKey.forEach(function (key) {
|
|
190
|
+
delete newData[key];
|
|
191
|
+
});
|
|
192
|
+
return newData;
|
|
193
|
+
};
|
|
194
|
+
exports.removePrimaryKey = removePrimaryKey;
|
|
195
|
+
var dataWithVirtualId = function (data, primaryKey) {
|
|
196
|
+
if (primaryKey.length === 1 && primaryKey[0] === 'id') {
|
|
153
197
|
return data;
|
|
154
198
|
}
|
|
155
199
|
return Object.assign(data, {
|
|
156
200
|
id: (0, exports.encodeId)(data, primaryKey),
|
|
157
201
|
});
|
|
158
202
|
};
|
|
159
|
-
exports.
|
|
203
|
+
exports.dataWithVirtualId = dataWithVirtualId;
|
|
204
|
+
var dataWithoutVirtualId = function (data, primaryKey) {
|
|
205
|
+
if (primaryKey.length === 1 && primaryKey[0] === 'id') {
|
|
206
|
+
return data;
|
|
207
|
+
}
|
|
208
|
+
var id = data.id, dataWithoutId = __rest(data, ["id"]);
|
|
209
|
+
return dataWithoutId;
|
|
210
|
+
};
|
|
211
|
+
exports.dataWithoutVirtualId = dataWithoutVirtualId;
|
|
160
212
|
var isCompoundKey = function (primaryKey) {
|
|
161
213
|
return primaryKey.length > 1;
|
|
162
214
|
};
|
|
163
|
-
exports.isCompoundKey = isCompoundKey;
|
|
164
215
|
var getQuery = function (primaryKey, ids, resource, meta) {
|
|
165
216
|
var _a, _b;
|
|
166
217
|
if (meta === void 0) { meta = null; }
|
|
@@ -171,7 +222,7 @@ var getQuery = function (primaryKey, ids, resource, meta) {
|
|
|
171
222
|
console.error("PostgREST's rpc endpoints are not intended to be handled as views. Therefore, no query generation for multiple key values implemented!");
|
|
172
223
|
return;
|
|
173
224
|
}
|
|
174
|
-
if (
|
|
225
|
+
if (isCompoundKey(primaryKey)) {
|
|
175
226
|
result = {
|
|
176
227
|
or: "(".concat(ids.map(function (id) {
|
|
177
228
|
var primaryKeyParams = (0, exports.decodeId)(id, primaryKey);
|
|
@@ -187,11 +238,11 @@ var getQuery = function (primaryKey, ids, resource, meta) {
|
|
|
187
238
|
_a);
|
|
188
239
|
}
|
|
189
240
|
}
|
|
190
|
-
else {
|
|
241
|
+
else if (ids) {
|
|
191
242
|
// if ids is one Identifier
|
|
192
243
|
var id = ids.toString();
|
|
193
244
|
var primaryKeyParams_1 = (0, exports.decodeId)(id, primaryKey);
|
|
194
|
-
if (
|
|
245
|
+
if (isCompoundKey(primaryKey)) {
|
|
195
246
|
if (resource.startsWith('rpc/')) {
|
|
196
247
|
result = {};
|
|
197
248
|
primaryKey.map(function (key, i) {
|
|
@@ -220,19 +271,6 @@ var getQuery = function (primaryKey, ids, resource, meta) {
|
|
|
220
271
|
return result;
|
|
221
272
|
};
|
|
222
273
|
exports.getQuery = getQuery;
|
|
223
|
-
var getKeyData = function (primaryKey, data) {
|
|
224
|
-
var _a;
|
|
225
|
-
if ((0, exports.isCompoundKey)(primaryKey)) {
|
|
226
|
-
return primaryKey.reduce(function (keyData, key) {
|
|
227
|
-
var _a;
|
|
228
|
-
return (__assign(__assign({}, keyData), (_a = {}, _a[key] = data[key], _a)));
|
|
229
|
-
}, {});
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
return _a = {}, _a[primaryKey[0]] = data[primaryKey[0]], _a;
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
exports.getKeyData = getKeyData;
|
|
236
274
|
var getOrderBy = function (field, order, primaryKey) {
|
|
237
275
|
if (field == 'id') {
|
|
238
276
|
return primaryKey.map(function (key) { return "".concat(key, ".").concat(order.toLowerCase()); }).join(',');
|
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.4",
|
|
4
4
|
"description": "postgREST data provider for react-admin",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"src"
|
|
13
13
|
],
|
|
14
14
|
"authors": [
|
|
15
|
-
"François Zaninotto",
|
|
16
15
|
"Raphael Scheible"
|
|
17
16
|
],
|
|
18
17
|
"repository": "raphiniert-com/ra-data-postgrest",
|
|
@@ -30,16 +29,16 @@
|
|
|
30
29
|
"prettier": "prettier --config ./.prettierrc.js --write --list-different \"src/**/*.{js,json,ts,tsx,css,md}\""
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
|
-
"@types/jest": "^
|
|
32
|
+
"@types/jest": "^29.5.6",
|
|
34
33
|
"@types/qs": "^6.9.7",
|
|
35
34
|
"cross-env": "^7.0.3",
|
|
36
|
-
"eslint-config-prettier": "^
|
|
37
|
-
"eslint-plugin-prettier": "^
|
|
35
|
+
"eslint-config-prettier": "^9.0.0",
|
|
36
|
+
"eslint-plugin-prettier": "^5.0.1",
|
|
38
37
|
"install-peers-cli": "^2.2.0",
|
|
39
|
-
"jest": "^
|
|
40
|
-
"prettier": "
|
|
38
|
+
"jest": "^29.7.0",
|
|
39
|
+
"prettier": "^3.0.3",
|
|
41
40
|
"rimraf": "^5.0.0",
|
|
42
|
-
"ts-jest": "^
|
|
41
|
+
"ts-jest": "^29.1.1",
|
|
43
42
|
"typescript": "^5.0.4"
|
|
44
43
|
},
|
|
45
44
|
"peerDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
fetchUtils,
|
|
3
2
|
DataProvider,
|
|
4
3
|
GetListParams,
|
|
5
4
|
GetOneParams,
|
|
@@ -17,12 +16,11 @@ import {
|
|
|
17
16
|
getPrimaryKey,
|
|
18
17
|
parseFilters,
|
|
19
18
|
getOrderBy,
|
|
20
|
-
|
|
19
|
+
dataWithVirtualId,
|
|
20
|
+
dataWithoutVirtualId,
|
|
21
|
+
removePrimaryKey,
|
|
21
22
|
getQuery,
|
|
22
|
-
getKeyData,
|
|
23
23
|
encodeId,
|
|
24
|
-
decodeId,
|
|
25
|
-
isCompoundKey,
|
|
26
24
|
} from './urlBuilder';
|
|
27
25
|
import qs from 'qs';
|
|
28
26
|
|
|
@@ -154,7 +152,7 @@ export default (config: IDataProviderConfig): DataProvider => ({
|
|
|
154
152
|
);
|
|
155
153
|
}
|
|
156
154
|
return {
|
|
157
|
-
data: json.map(obj =>
|
|
155
|
+
data: json.map(obj => dataWithVirtualId(obj, primaryKey)),
|
|
158
156
|
total: parseInt(
|
|
159
157
|
headers.get('content-range').split('/').pop(),
|
|
160
158
|
10
|
|
@@ -181,7 +179,7 @@ export default (config: IDataProviderConfig): DataProvider => ({
|
|
|
181
179
|
}),
|
|
182
180
|
})
|
|
183
181
|
.then(({ json }) => ({
|
|
184
|
-
data:
|
|
182
|
+
data: dataWithVirtualId(json, primaryKey),
|
|
185
183
|
}));
|
|
186
184
|
},
|
|
187
185
|
|
|
@@ -201,7 +199,7 @@ export default (config: IDataProviderConfig): DataProvider => ({
|
|
|
201
199
|
}),
|
|
202
200
|
})
|
|
203
201
|
.then(({ json }) => ({
|
|
204
|
-
data: json.map(data =>
|
|
202
|
+
data: json.map(data => dataWithVirtualId(data, primaryKey)),
|
|
205
203
|
}));
|
|
206
204
|
},
|
|
207
205
|
|
|
@@ -257,7 +255,7 @@ export default (config: IDataProviderConfig): DataProvider => ({
|
|
|
257
255
|
);
|
|
258
256
|
}
|
|
259
257
|
return {
|
|
260
|
-
data: json.map(data =>
|
|
258
|
+
data: json.map(data => dataWithVirtualId(data, primaryKey)),
|
|
261
259
|
total: parseInt(
|
|
262
260
|
headers.get('content-range').split('/').pop(),
|
|
263
261
|
10
|
|
@@ -269,17 +267,15 @@ export default (config: IDataProviderConfig): DataProvider => ({
|
|
|
269
267
|
update: (resource, params: Partial<UpdateParams> = {}) => {
|
|
270
268
|
const { id, data, meta } = params;
|
|
271
269
|
const primaryKey = getPrimaryKey(resource, config.primaryKeys);
|
|
272
|
-
|
|
273
270
|
const query = getQuery(primaryKey, id, resource, meta);
|
|
274
|
-
|
|
275
|
-
const primaryKeyData = getKeyData(primaryKey, data);
|
|
276
|
-
|
|
277
271
|
const url = `${config.apiUrl}/${resource}?${qs.stringify(query)}`;
|
|
278
272
|
const metaSchema = params.meta?.schema;
|
|
279
273
|
|
|
280
274
|
const body = JSON.stringify({
|
|
281
|
-
...
|
|
282
|
-
|
|
275
|
+
...dataWithoutVirtualId(
|
|
276
|
+
removePrimaryKey(data, primaryKey),
|
|
277
|
+
primaryKey
|
|
278
|
+
),
|
|
283
279
|
});
|
|
284
280
|
|
|
285
281
|
return config
|
|
@@ -294,35 +290,23 @@ export default (config: IDataProviderConfig): DataProvider => ({
|
|
|
294
290
|
}),
|
|
295
291
|
body,
|
|
296
292
|
})
|
|
297
|
-
.then(({ json }) => ({
|
|
293
|
+
.then(({ json }) => ({
|
|
294
|
+
data: dataWithVirtualId(json, primaryKey),
|
|
295
|
+
}));
|
|
298
296
|
},
|
|
299
297
|
|
|
300
298
|
updateMany: (resource, params: Partial<UpdateManyParams> = {}) => {
|
|
301
|
-
const ids = params
|
|
299
|
+
const { ids, meta, data } = params;
|
|
302
300
|
const primaryKey = getPrimaryKey(resource, config.primaryKeys);
|
|
301
|
+
const query = getQuery(primaryKey, ids, resource, meta);
|
|
302
|
+
const url = `${config.apiUrl}/${resource}?${qs.stringify(query)}`;
|
|
303
|
+
const body = JSON.stringify({
|
|
304
|
+
...dataWithoutVirtualId(
|
|
305
|
+
removePrimaryKey(data, primaryKey),
|
|
306
|
+
primaryKey
|
|
307
|
+
),
|
|
308
|
+
});
|
|
303
309
|
|
|
304
|
-
const body = JSON.stringify(
|
|
305
|
-
params.ids.map(id => {
|
|
306
|
-
const { data } = params;
|
|
307
|
-
const primaryKeyParams = decodeId(id, primaryKey);
|
|
308
|
-
|
|
309
|
-
const primaryKeyData = {};
|
|
310
|
-
if (isCompoundKey(primaryKey)) {
|
|
311
|
-
primaryKey.forEach((key, index) => {
|
|
312
|
-
primaryKeyData[key] = primaryKeyParams[index];
|
|
313
|
-
});
|
|
314
|
-
} else {
|
|
315
|
-
primaryKeyData[primaryKey[0]] = primaryKeyParams[0];
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
return {
|
|
319
|
-
...data,
|
|
320
|
-
...primaryKeyData,
|
|
321
|
-
};
|
|
322
|
-
})
|
|
323
|
-
);
|
|
324
|
-
|
|
325
|
-
const url = `${config.apiUrl}/${resource}`;
|
|
326
310
|
const metaSchema = params.meta?.schema;
|
|
327
311
|
|
|
328
312
|
return config
|
|
@@ -342,8 +326,13 @@ export default (config: IDataProviderConfig): DataProvider => ({
|
|
|
342
326
|
},
|
|
343
327
|
|
|
344
328
|
create: (resource, params: Partial<CreateParams> = {}) => {
|
|
329
|
+
const { meta } = params;
|
|
345
330
|
const primaryKey = getPrimaryKey(resource, config.primaryKeys);
|
|
346
|
-
const
|
|
331
|
+
const query = getQuery(primaryKey, undefined, resource, meta);
|
|
332
|
+
const queryStr = qs.stringify(query);
|
|
333
|
+
const url = `${config.apiUrl}/${resource}${
|
|
334
|
+
queryStr.length > 0 ? '?' : ''
|
|
335
|
+
}${queryStr}`;
|
|
347
336
|
const metaSchema = params.meta?.schema;
|
|
348
337
|
|
|
349
338
|
return config
|
|
@@ -356,7 +345,9 @@ export default (config: IDataProviderConfig): DataProvider => ({
|
|
|
356
345
|
...(params.meta?.headers || {}),
|
|
357
346
|
...useCustomSchema(config.schema, metaSchema, 'POST'),
|
|
358
347
|
}),
|
|
359
|
-
body: JSON.stringify(
|
|
348
|
+
body: JSON.stringify(
|
|
349
|
+
dataWithoutVirtualId(params.data, primaryKey)
|
|
350
|
+
),
|
|
360
351
|
})
|
|
361
352
|
.then(({ json }) => ({
|
|
362
353
|
data: {
|
|
@@ -386,7 +377,9 @@ export default (config: IDataProviderConfig): DataProvider => ({
|
|
|
386
377
|
...useCustomSchema(config.schema, metaSchema, 'DELETE'),
|
|
387
378
|
}),
|
|
388
379
|
})
|
|
389
|
-
.then(({ json }) => ({
|
|
380
|
+
.then(({ json }) => ({
|
|
381
|
+
data: dataWithVirtualId(json, primaryKey),
|
|
382
|
+
}));
|
|
390
383
|
},
|
|
391
384
|
|
|
392
385
|
deleteMany: (resource, params: Partial<DeleteManyParams> = {}) => {
|
package/src/urlBuilder.ts
CHANGED
|
@@ -49,6 +49,18 @@ type ParsedFiltersResult = {
|
|
|
49
49
|
select: any;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
const isObject = obj =>
|
|
53
|
+
typeof obj === 'object' && !Array.isArray(obj) && obj !== null;
|
|
54
|
+
|
|
55
|
+
const resolveKeys = (filter: any, keys: Array<any>) => {
|
|
56
|
+
let result = filter[keys[0]];
|
|
57
|
+
for (let i = 1; i < keys.length; ++i) {
|
|
58
|
+
result = result[keys[i]];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
|
|
52
64
|
export type PostgRestOperator = (typeof postgrestOperators)[number];
|
|
53
65
|
|
|
54
66
|
export const parseFilters = (
|
|
@@ -62,22 +74,44 @@ export const parseFilters = (
|
|
|
62
74
|
Object.keys(filter).forEach(function (key) {
|
|
63
75
|
// key: the name of the object key
|
|
64
76
|
|
|
77
|
+
let keyArray = [key];
|
|
78
|
+
let values: Array<string>;
|
|
79
|
+
|
|
80
|
+
// in case of a nested object selection in a text field
|
|
81
|
+
// RA returns object{ object } structure which is resolved here
|
|
82
|
+
// see issue https://github.com/raphiniert-com/ra-data-postgrest/issues/58
|
|
83
|
+
if (key.split('@')[0] !== '' && isObject(filter[key])) {
|
|
84
|
+
let innerVal = filter[key];
|
|
85
|
+
|
|
86
|
+
do {
|
|
87
|
+
const inner = resolveKeys(filter, keyArray);
|
|
88
|
+
const [innerKey] = Object.keys(inner);
|
|
89
|
+
|
|
90
|
+
keyArray.push(innerKey);
|
|
91
|
+
innerVal = inner[innerKey];
|
|
92
|
+
} while (isObject(innerVal));
|
|
93
|
+
|
|
94
|
+
key = keyArray.join('.');
|
|
95
|
+
values = [innerVal];
|
|
96
|
+
} else {
|
|
97
|
+
values = [filter[key]];
|
|
98
|
+
}
|
|
99
|
+
|
|
65
100
|
const splitKey = key.split('@');
|
|
66
101
|
const operation: PostgRestOperator =
|
|
67
102
|
splitKey.length == 2
|
|
68
103
|
? (splitKey[1] as PostgRestOperator)
|
|
69
104
|
: defaultListOp;
|
|
70
105
|
|
|
71
|
-
let values: Array<string>;
|
|
72
106
|
if (['like', 'ilike'].includes(operation)) {
|
|
73
107
|
// we split the search term in words
|
|
74
|
-
values = filter
|
|
108
|
+
values = resolveKeys(filter, keyArray).trim().split(/\s+/);
|
|
75
109
|
}
|
|
76
110
|
// CASE: Logical operator
|
|
77
111
|
else if (['or', 'and'].includes(operation)) {
|
|
78
112
|
// we extract each value entries and make it dot separated string.
|
|
79
113
|
const { filter: subFilter } = parseFilters(
|
|
80
|
-
{ filter: filter
|
|
114
|
+
{ filter: resolveKeys(filter, keyArray) },
|
|
81
115
|
defaultListOp
|
|
82
116
|
);
|
|
83
117
|
|
|
@@ -91,8 +125,6 @@ export const parseFilters = (
|
|
|
91
125
|
|
|
92
126
|
// finally we flatten all as single string and enclose with bracket.
|
|
93
127
|
values = [`(${filterExpressions.join(',')})`];
|
|
94
|
-
} else {
|
|
95
|
-
values = [filter[key]];
|
|
96
128
|
}
|
|
97
129
|
|
|
98
130
|
values.forEach(value => {
|
|
@@ -108,7 +140,7 @@ export const parseFilters = (
|
|
|
108
140
|
return `${operation}.${value}`;
|
|
109
141
|
})();
|
|
110
142
|
|
|
111
|
-
// If resulting filter
|
|
143
|
+
// If resulting filter doesn't contain the fieldname, then add it.
|
|
112
144
|
if (result.filter[splitKey[0]] === undefined) {
|
|
113
145
|
// first operator for the key,
|
|
114
146
|
if (['and', 'or'].includes(operation)) {
|
|
@@ -170,8 +202,16 @@ export const encodeId = (data: any, primaryKey: PrimaryKey): Identifier => {
|
|
|
170
202
|
}
|
|
171
203
|
};
|
|
172
204
|
|
|
173
|
-
export const
|
|
174
|
-
|
|
205
|
+
export const removePrimaryKey = (data: any, primaryKey: PrimaryKey) => {
|
|
206
|
+
const newData = { ...data };
|
|
207
|
+
primaryKey.forEach(key => {
|
|
208
|
+
delete newData[key];
|
|
209
|
+
});
|
|
210
|
+
return newData;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export const dataWithVirtualId = (data: any, primaryKey: PrimaryKey) => {
|
|
214
|
+
if (primaryKey.length === 1 && primaryKey[0] === 'id') {
|
|
175
215
|
return data;
|
|
176
216
|
}
|
|
177
217
|
|
|
@@ -180,13 +220,22 @@ export const dataWithId = (data: any, primaryKey: PrimaryKey) => {
|
|
|
180
220
|
});
|
|
181
221
|
};
|
|
182
222
|
|
|
183
|
-
export const
|
|
223
|
+
export const dataWithoutVirtualId = (data: any, primaryKey: PrimaryKey) => {
|
|
224
|
+
if (primaryKey.length === 1 && primaryKey[0] === 'id') {
|
|
225
|
+
return data;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const { id, ...dataWithoutId } = data;
|
|
229
|
+
return dataWithoutId;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const isCompoundKey = (primaryKey: PrimaryKey): Boolean => {
|
|
184
233
|
return primaryKey.length > 1;
|
|
185
234
|
};
|
|
186
235
|
|
|
187
236
|
export const getQuery = (
|
|
188
237
|
primaryKey: PrimaryKey,
|
|
189
|
-
ids: Identifier | Array<Identifier
|
|
238
|
+
ids: Identifier | Array<Identifier> | undefined,
|
|
190
239
|
resource: string,
|
|
191
240
|
meta: any = null
|
|
192
241
|
): any => {
|
|
@@ -215,7 +264,7 @@ export const getQuery = (
|
|
|
215
264
|
[primaryKey[0]]: `in.(${ids.join(',')})`,
|
|
216
265
|
};
|
|
217
266
|
}
|
|
218
|
-
} else {
|
|
267
|
+
} else if (ids) {
|
|
219
268
|
// if ids is one Identifier
|
|
220
269
|
const id: Identifier = ids.toString();
|
|
221
270
|
const primaryKeyParams = decodeId(id, primaryKey);
|
|
@@ -251,20 +300,6 @@ export const getQuery = (
|
|
|
251
300
|
return result;
|
|
252
301
|
};
|
|
253
302
|
|
|
254
|
-
export const getKeyData = (primaryKey: PrimaryKey, data: object): object => {
|
|
255
|
-
if (isCompoundKey(primaryKey)) {
|
|
256
|
-
return primaryKey.reduce(
|
|
257
|
-
(keyData, key) => ({
|
|
258
|
-
...keyData,
|
|
259
|
-
[key]: data[key],
|
|
260
|
-
}),
|
|
261
|
-
{}
|
|
262
|
-
);
|
|
263
|
-
} else {
|
|
264
|
-
return { [primaryKey[0]]: data[primaryKey[0]] };
|
|
265
|
-
}
|
|
266
|
-
};
|
|
267
|
-
|
|
268
303
|
export const getOrderBy = (
|
|
269
304
|
field: string,
|
|
270
305
|
order: string,
|