@raphiniert/ra-data-postgrest 2.3.0 → 2.4.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 CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  Find all notable changes of this project in this file.
4
4
 
5
+ ## v2.4.0 - 2024-09-04
6
+ ### Fixes
7
+ - [#166](https://github.com/raphiniert-com/ra-data-postgrest/pull/166) Fix update fails when nothing is changed @[fzaninotto](https://github.com/fzaninotto)
8
+ - [#165](https://github.com/raphiniert-com/ra-data-postgrest/pull/165) Fix getMany fails when called with an empty array of ids @[fzaninotto](https://github.com/fzaninotto)
9
+
10
+ ### Improvements
11
+ - [#164](https://github.com/raphiniert-com/ra-data-postgrest/pull/164) Add nullslast and nullsfirst support to getList @[fzaninotto](https://github.com/fzaninotto)
12
+ - updated dependencies
13
+ - updated README.md: added section "Citation"
14
+
5
15
  ## v2.3.0 - 2024-06-28
6
16
  ### Improvements
7
17
  - [#142](https://github.com/raphiniert-com/ra-data-postgrest/pull/142) Add support for React Admin v5 @[slax57](https://github.com/slax57)
package/README.md CHANGED
@@ -15,6 +15,22 @@ npm install --save @raphiniert/ra-data-postgrest
15
15
 
16
16
  **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.
17
17
 
18
+ ## Citation
19
+ If you use the PostgREST Data Provider in your research or project, please consider citing the (our paper)[https://www.sciencedirect.com/science/article/pii/S2665963824000873]. Feel free to include the following BibTeX entry in your publications:
20
+ ```bibtex
21
+ @article{SCHEIBLE2024100699,
22
+ title = {PostgREST Data Provider for React-Admin: Bootstrap the creation of user interfaces on top of PostgreSQL databases},
23
+ journal = {Software Impacts},
24
+ volume = {21},
25
+ pages = {100699},
26
+ year = {2024},
27
+ issn = {2665-9638},
28
+ doi = {https://doi.org/10.1016/j.simpa.2024.100699},
29
+ author = {Raphael Scheible}
30
+ }
31
+ ```
32
+
33
+
18
34
  ## REST Dialect
19
35
 
20
36
  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).
@@ -195,9 +211,12 @@ const [create, { isLoading, error }] = useCreate(
195
211
  ```
196
212
 
197
213
  ### Null sort order
214
+
198
215
  Postgrest supports specifying the position of nulls in [sort ordering](https://postgrest.org/en/v12/references/api/tables_views.html#ordering). This can be configured via an optional data provider parameter:
199
216
 
200
217
  ```jsx
218
+ import { PostgRestSortOrder, IDataProviderConfig } from '@raphiniert/ra-data-postgrest';
219
+
201
220
  const config: IDataProviderConfig = {
202
221
  ...
203
222
  sortOrder: PostgRestSortOrder.AscendingNullsLastDescendingNullsLast
@@ -207,8 +226,23 @@ const config: IDataProviderConfig = {
207
226
  const dataProvider = postgrestRestProvider(config);
208
227
  ```
209
228
 
229
+ This parameter impacts the `getList` and `getManyReference` calls.
230
+
210
231
  It is important to note that null positioning in sort will impact index utilization so in some cases you'll want to add corresponding index on the database side.
211
232
 
233
+ You can also override this parameter on a per-query basis by passing `nullsfirst: true` or `nullslast: true` in the `meta` object of the query:
234
+
235
+ ```jsx
236
+ const { data, total, isLoading, error } = useGetList(
237
+ 'posts',
238
+ {
239
+ pagination: { page: 1, perPage: 10 },
240
+ sort: { field: 'published_at', order: 'DESC' },
241
+ meta: { nullslast: true }
242
+ }
243
+ );
244
+ ```
245
+
212
246
  ### Vertical filtering
213
247
  Postgrest supports a feature of [Vertical Filtering (Columns)](https://postgrest.org/en/stable/api.html#vertical-filtering-columns). Within the react-admin hooks this feature can be used as in the following example:
214
248
 
package/esm/index.d.ts CHANGED
@@ -49,6 +49,7 @@ import { PrimaryKey, PostgRestOperator, PostgRestSortOrder } from './urlBuilder'
49
49
  export type MetaOption = string | undefined;
50
50
  export declare const defaultPrimaryKeys: Map<string, PrimaryKey>;
51
51
  export declare const defaultSchema: () => string;
52
+ export { PostgRestSortOrder };
52
53
  export interface IDataProviderConfig {
53
54
  apiUrl: string;
54
55
  httpClient: (string: any, Options: any) => Promise<any>;
package/esm/index.js CHANGED
@@ -37,23 +37,42 @@ var useCustomSchema = function (schema, metaSchema, method) {
37
37
  };
38
38
  export default (function (config) { return ({
39
39
  getList: function (resource, params) {
40
- var _a, _b;
40
+ var _a, _b, _c, _d, _e, _f;
41
41
  if (params === void 0) { params = {}; }
42
42
  var primaryKey = getPrimaryKey(resource, config.primaryKeys);
43
- var _c = params.pagination, page = _c.page, perPage = _c.perPage;
44
- var _d = params.sort || {}, field = _d.field, order = _d.order;
45
- var _e = parseFilters(params, config.defaultListOp), filter = _e.filter, select = _e.select;
43
+ var _g = params.pagination, page = _g.page, perPage = _g.perPage;
44
+ var _h = params.sort || {}, field = _h.field, order = _h.order;
45
+ var _j = parseFilters(params, config.defaultListOp), filter = _j.filter, select = _j.select;
46
46
  var metaSchema = (_a = params.meta) === null || _a === void 0 ? void 0 : _a.schema;
47
47
  var query = __assign({ offset: String((page - 1) * perPage), limit: String(perPage) }, filter);
48
48
  if (field) {
49
- query.order = getOrderBy(field, order, primaryKey);
49
+ query.order = getOrderBy(field, order, primaryKey, config.sortOrder);
50
+ if (((_b = params.meta) === null || _b === void 0 ? void 0 : _b.nullsfirst) &&
51
+ !query.order.includes('nullsfirst')) {
52
+ query.order = query.order.includes('nullslast')
53
+ ? query.order.replace('nullslast', 'nullsfirst')
54
+ : "".concat(query.order, ".nullsfirst");
55
+ }
56
+ if (((_c = params.meta) === null || _c === void 0 ? void 0 : _c.nullsfirst) === false &&
57
+ query.order.includes('nullsfirst')) {
58
+ query.order = query.order.replace('.nullsfirst', '');
59
+ }
60
+ if (((_d = params.meta) === null || _d === void 0 ? void 0 : _d.nullslast) && !query.order.includes('nullslast')) {
61
+ query.order = query.order.includes('nullsfirst')
62
+ ? query.order.replace('nullsfirst', 'nullslast')
63
+ : "".concat(query.order, ".nullslast");
64
+ }
65
+ if (((_e = params.meta) === null || _e === void 0 ? void 0 : _e.nullslast) === false &&
66
+ query.order.includes('nullslast')) {
67
+ query.order = query.order.replace('.nullslast', '');
68
+ }
50
69
  }
51
70
  if (select) {
52
71
  query.select = select;
53
72
  }
54
73
  // add header that Content-Range is in returned header
55
74
  var options = {
56
- headers: new Headers(__assign(__assign({ Accept: 'application/json', Prefer: 'count=exact' }, (((_b = params.meta) === null || _b === void 0 ? void 0 : _b.headers) || {})), useCustomSchema(config.schema, metaSchema, 'GET'))),
75
+ headers: new Headers(__assign(__assign({ Accept: 'application/json', Prefer: 'count=exact' }, (((_f = params.meta) === null || _f === void 0 ? void 0 : _f.headers) || {})), useCustomSchema(config.schema, metaSchema, 'GET'))),
57
76
  };
58
77
  var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs.stringify(query));
59
78
  return config.httpClient(url, options).then(function (_a) {
@@ -90,6 +109,9 @@ export default (function (config) { return ({
90
109
  var _a;
91
110
  if (params === void 0) { params = {}; }
92
111
  var ids = params.ids;
112
+ if (ids.length === 0) {
113
+ return Promise.resolve({ data: [] });
114
+ }
93
115
  var primaryKey = getPrimaryKey(resource, config.primaryKeys);
94
116
  var query = getQuery(primaryKey, ids, resource, params.meta);
95
117
  var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs.stringify(query));
@@ -143,6 +165,9 @@ export default (function (config) { return ({
143
165
  var query = getQuery(primaryKey, id, resource, meta);
144
166
  var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs.stringify(query));
145
167
  var changedData = getChanges(data, previousData);
168
+ if (Object.keys(changedData).length === 0) {
169
+ return Promise.resolve({ data: __assign({}, previousData) });
170
+ }
146
171
  var metaSchema = (_a = params.meta) === null || _a === void 0 ? void 0 : _a.schema;
147
172
  var body = JSON.stringify(__assign({}, dataWithoutVirtualId(removePrimaryKey(changedData, primaryKey), primaryKey)));
148
173
  return config
@@ -18,7 +18,7 @@ export declare const removePrimaryKey: (data: any, primaryKey: PrimaryKey) => an
18
18
  export declare const dataWithVirtualId: (data: any, primaryKey: PrimaryKey) => any;
19
19
  export declare const dataWithoutVirtualId: (data: any, primaryKey: PrimaryKey) => any;
20
20
  export declare const getQuery: (primaryKey: PrimaryKey, ids: Identifier | Array<Identifier> | undefined, resource: string, meta?: any) => any;
21
- export declare enum PostgRestSortOrder {
21
+ export declare const enum PostgRestSortOrder {
22
22
  AscendingNullsLastDescendingNullsFirst = "asc,desc",
23
23
  AscendingNullsLastDescendingNullsLast = "asc,desc.nullslast",
24
24
  AscendingNullsFirstDescendingNullsFirst = "asc.nullsfirst,desc",
package/esm/urlBuilder.js CHANGED
@@ -157,7 +157,7 @@ export var parseFilters = function (params, defaultListOp) {
157
157
  return result;
158
158
  };
159
159
  export var getPrimaryKey = function (resource, primaryKeys) {
160
- return primaryKeys.get(resource) || ['id'];
160
+ return (primaryKeys && primaryKeys.get(resource)) || ['id'];
161
161
  };
162
162
  export var decodeId = function (id, primaryKey) {
163
163
  if (isCompoundKey(primaryKey)) {
@@ -258,15 +258,8 @@ export var getQuery = function (primaryKey, ids, resource, meta) {
258
258
  }
259
259
  return result;
260
260
  };
261
- export var PostgRestSortOrder;
262
- (function (PostgRestSortOrder) {
263
- PostgRestSortOrder["AscendingNullsLastDescendingNullsFirst"] = "asc,desc";
264
- PostgRestSortOrder["AscendingNullsLastDescendingNullsLast"] = "asc,desc.nullslast";
265
- PostgRestSortOrder["AscendingNullsFirstDescendingNullsFirst"] = "asc.nullsfirst,desc";
266
- PostgRestSortOrder["AscendingNullsFirstDescendingNullsLast"] = "asc.nullsfirst,desc.nullslast";
267
- })(PostgRestSortOrder || (PostgRestSortOrder = {}));
268
261
  export var getOrderBy = function (field, order, primaryKey, sortOrder) {
269
- if (sortOrder === void 0) { sortOrder = PostgRestSortOrder.AscendingNullsLastDescendingNullsFirst; }
262
+ if (sortOrder === void 0) { sortOrder = "asc,desc" /* PostgRestSortOrder.AscendingNullsLastDescendingNullsFirst */; }
270
263
  var postgRestOrder = sortOrder.split(',')[order === 'ASC' ? 0 : 1];
271
264
  if (field == 'id') {
272
265
  return primaryKey.map(function (key) { return "".concat(key, ".").concat(postgRestOrder); }).join(',');
package/lib/index.d.ts CHANGED
@@ -49,6 +49,7 @@ import { PrimaryKey, PostgRestOperator, PostgRestSortOrder } from './urlBuilder'
49
49
  export type MetaOption = string | undefined;
50
50
  export declare const defaultPrimaryKeys: Map<string, PrimaryKey>;
51
51
  export declare const defaultSchema: () => string;
52
+ export { PostgRestSortOrder };
52
53
  export interface IDataProviderConfig {
53
54
  apiUrl: string;
54
55
  httpClient: (string: any, Options: any) => Promise<any>;
package/lib/index.js CHANGED
@@ -44,23 +44,42 @@ var useCustomSchema = function (schema, metaSchema, method) {
44
44
  };
45
45
  exports.default = (function (config) { return ({
46
46
  getList: function (resource, params) {
47
- var _a, _b;
47
+ var _a, _b, _c, _d, _e, _f;
48
48
  if (params === void 0) { params = {}; }
49
49
  var primaryKey = (0, urlBuilder_1.getPrimaryKey)(resource, config.primaryKeys);
50
- var _c = params.pagination, page = _c.page, perPage = _c.perPage;
51
- var _d = params.sort || {}, field = _d.field, order = _d.order;
52
- var _e = (0, urlBuilder_1.parseFilters)(params, config.defaultListOp), filter = _e.filter, select = _e.select;
50
+ var _g = params.pagination, page = _g.page, perPage = _g.perPage;
51
+ var _h = params.sort || {}, field = _h.field, order = _h.order;
52
+ var _j = (0, urlBuilder_1.parseFilters)(params, config.defaultListOp), filter = _j.filter, select = _j.select;
53
53
  var metaSchema = (_a = params.meta) === null || _a === void 0 ? void 0 : _a.schema;
54
54
  var query = __assign({ offset: String((page - 1) * perPage), limit: String(perPage) }, filter);
55
55
  if (field) {
56
- query.order = (0, urlBuilder_1.getOrderBy)(field, order, primaryKey);
56
+ query.order = (0, urlBuilder_1.getOrderBy)(field, order, primaryKey, config.sortOrder);
57
+ if (((_b = params.meta) === null || _b === void 0 ? void 0 : _b.nullsfirst) &&
58
+ !query.order.includes('nullsfirst')) {
59
+ query.order = query.order.includes('nullslast')
60
+ ? query.order.replace('nullslast', 'nullsfirst')
61
+ : "".concat(query.order, ".nullsfirst");
62
+ }
63
+ if (((_c = params.meta) === null || _c === void 0 ? void 0 : _c.nullsfirst) === false &&
64
+ query.order.includes('nullsfirst')) {
65
+ query.order = query.order.replace('.nullsfirst', '');
66
+ }
67
+ if (((_d = params.meta) === null || _d === void 0 ? void 0 : _d.nullslast) && !query.order.includes('nullslast')) {
68
+ query.order = query.order.includes('nullsfirst')
69
+ ? query.order.replace('nullsfirst', 'nullslast')
70
+ : "".concat(query.order, ".nullslast");
71
+ }
72
+ if (((_e = params.meta) === null || _e === void 0 ? void 0 : _e.nullslast) === false &&
73
+ query.order.includes('nullslast')) {
74
+ query.order = query.order.replace('.nullslast', '');
75
+ }
57
76
  }
58
77
  if (select) {
59
78
  query.select = select;
60
79
  }
61
80
  // add header that Content-Range is in returned header
62
81
  var options = {
63
- headers: new Headers(__assign(__assign({ Accept: 'application/json', Prefer: 'count=exact' }, (((_b = params.meta) === null || _b === void 0 ? void 0 : _b.headers) || {})), useCustomSchema(config.schema, metaSchema, 'GET'))),
82
+ headers: new Headers(__assign(__assign({ Accept: 'application/json', Prefer: 'count=exact' }, (((_f = params.meta) === null || _f === void 0 ? void 0 : _f.headers) || {})), useCustomSchema(config.schema, metaSchema, 'GET'))),
64
83
  };
65
84
  var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs_1.default.stringify(query));
66
85
  return config.httpClient(url, options).then(function (_a) {
@@ -97,6 +116,9 @@ exports.default = (function (config) { return ({
97
116
  var _a;
98
117
  if (params === void 0) { params = {}; }
99
118
  var ids = params.ids;
119
+ if (ids.length === 0) {
120
+ return Promise.resolve({ data: [] });
121
+ }
100
122
  var primaryKey = (0, urlBuilder_1.getPrimaryKey)(resource, config.primaryKeys);
101
123
  var query = (0, urlBuilder_1.getQuery)(primaryKey, ids, resource, params.meta);
102
124
  var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs_1.default.stringify(query));
@@ -150,6 +172,9 @@ exports.default = (function (config) { return ({
150
172
  var query = (0, urlBuilder_1.getQuery)(primaryKey, id, resource, meta);
151
173
  var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs_1.default.stringify(query));
152
174
  var changedData = getChanges(data, previousData);
175
+ if (Object.keys(changedData).length === 0) {
176
+ return Promise.resolve({ data: __assign({}, previousData) });
177
+ }
153
178
  var metaSchema = (_a = params.meta) === null || _a === void 0 ? void 0 : _a.schema;
154
179
  var body = JSON.stringify(__assign({}, (0, urlBuilder_1.dataWithoutVirtualId)((0, urlBuilder_1.removePrimaryKey)(changedData, primaryKey), primaryKey)));
155
180
  return config
@@ -18,7 +18,7 @@ export declare const removePrimaryKey: (data: any, primaryKey: PrimaryKey) => an
18
18
  export declare const dataWithVirtualId: (data: any, primaryKey: PrimaryKey) => any;
19
19
  export declare const dataWithoutVirtualId: (data: any, primaryKey: PrimaryKey) => any;
20
20
  export declare const getQuery: (primaryKey: PrimaryKey, ids: Identifier | Array<Identifier> | undefined, resource: string, meta?: any) => any;
21
- export declare enum PostgRestSortOrder {
21
+ export declare const enum PostgRestSortOrder {
22
22
  AscendingNullsLastDescendingNullsFirst = "asc,desc",
23
23
  AscendingNullsLastDescendingNullsLast = "asc,desc.nullslast",
24
24
  AscendingNullsFirstDescendingNullsFirst = "asc.nullsfirst,desc",
package/lib/urlBuilder.js CHANGED
@@ -22,7 +22,7 @@ var __rest = (this && this.__rest) || function (s, e) {
22
22
  return t;
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.getOrderBy = exports.PostgRestSortOrder = exports.getQuery = exports.dataWithoutVirtualId = exports.dataWithVirtualId = exports.removePrimaryKey = exports.encodeId = exports.decodeId = exports.getPrimaryKey = exports.parseFilters = void 0;
25
+ exports.getOrderBy = exports.getQuery = exports.dataWithoutVirtualId = exports.dataWithVirtualId = exports.removePrimaryKey = exports.encodeId = exports.decodeId = exports.getPrimaryKey = exports.parseFilters = void 0;
26
26
  /**
27
27
  * List of all possible operators in PostgRest
28
28
  * (https://postgrest.org/en/stable/api.html#operators)
@@ -161,7 +161,7 @@ var parseFilters = function (params, defaultListOp) {
161
161
  };
162
162
  exports.parseFilters = parseFilters;
163
163
  var getPrimaryKey = function (resource, primaryKeys) {
164
- return primaryKeys.get(resource) || ['id'];
164
+ return (primaryKeys && primaryKeys.get(resource)) || ['id'];
165
165
  };
166
166
  exports.getPrimaryKey = getPrimaryKey;
167
167
  var decodeId = function (id, primaryKey) {
@@ -269,15 +269,8 @@ var getQuery = function (primaryKey, ids, resource, meta) {
269
269
  return result;
270
270
  };
271
271
  exports.getQuery = getQuery;
272
- var PostgRestSortOrder;
273
- (function (PostgRestSortOrder) {
274
- PostgRestSortOrder["AscendingNullsLastDescendingNullsFirst"] = "asc,desc";
275
- PostgRestSortOrder["AscendingNullsLastDescendingNullsLast"] = "asc,desc.nullslast";
276
- PostgRestSortOrder["AscendingNullsFirstDescendingNullsFirst"] = "asc.nullsfirst,desc";
277
- PostgRestSortOrder["AscendingNullsFirstDescendingNullsLast"] = "asc.nullsfirst,desc.nullslast";
278
- })(PostgRestSortOrder || (exports.PostgRestSortOrder = PostgRestSortOrder = {}));
279
272
  var getOrderBy = function (field, order, primaryKey, sortOrder) {
280
- if (sortOrder === void 0) { sortOrder = PostgRestSortOrder.AscendingNullsLastDescendingNullsFirst; }
273
+ if (sortOrder === void 0) { sortOrder = "asc,desc" /* PostgRestSortOrder.AscendingNullsLastDescendingNullsFirst */; }
281
274
  var postgRestOrder = sortOrder.split(',')[order === 'ASC' ? 0 : 1];
282
275
  if (field == 'id') {
283
276
  return primaryKey.map(function (key) { return "".concat(key, ".").concat(postgRestOrder); }).join(',');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raphiniert/ra-data-postgrest",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "postgREST data provider for react-admin",
5
5
  "main": "lib/index.js",
6
6
  "module": "esm/index.js",
@@ -37,12 +37,12 @@
37
37
  "install-peers-cli": "^2.2.0",
38
38
  "jest": "^29.7.0",
39
39
  "prettier": "^3.3.2",
40
- "rimraf": "^5.0.7",
40
+ "rimraf": "^6.0.1",
41
41
  "ts-jest": "^29.1.5",
42
42
  "typescript": "^5.5.2"
43
43
  },
44
44
  "peerDependencies": {
45
- "ra-core": "^4.1.0 || ^5.0.1"
45
+ "ra-core": "^3.0.0 || ^4.1.0 || ^5.0.1"
46
46
  },
47
47
  "dependencies": {
48
48
  "lodash.isequal": "^4.5.0",
package/src/index.ts CHANGED
@@ -79,6 +79,8 @@ export const defaultPrimaryKeys = new Map<string, PrimaryKey>();
79
79
 
80
80
  export const defaultSchema = () => '';
81
81
 
82
+ export { PostgRestSortOrder };
83
+
82
84
  export interface IDataProviderConfig {
83
85
  apiUrl: string;
84
86
  httpClient: (string, Options) => Promise<any>;
@@ -127,7 +129,37 @@ export default (config: IDataProviderConfig): DataProvider => ({
127
129
  };
128
130
 
129
131
  if (field) {
130
- query.order = getOrderBy(field, order, primaryKey);
132
+ query.order = getOrderBy(
133
+ field,
134
+ order,
135
+ primaryKey,
136
+ config.sortOrder
137
+ );
138
+ if (
139
+ params.meta?.nullsfirst &&
140
+ !query.order.includes('nullsfirst')
141
+ ) {
142
+ query.order = query.order.includes('nullslast')
143
+ ? query.order.replace('nullslast', 'nullsfirst')
144
+ : `${query.order}.nullsfirst`;
145
+ }
146
+ if (
147
+ params.meta?.nullsfirst === false &&
148
+ query.order.includes('nullsfirst')
149
+ ) {
150
+ query.order = query.order.replace('.nullsfirst', '');
151
+ }
152
+ if (params.meta?.nullslast && !query.order.includes('nullslast')) {
153
+ query.order = query.order.includes('nullsfirst')
154
+ ? query.order.replace('nullsfirst', 'nullslast')
155
+ : `${query.order}.nullslast`;
156
+ }
157
+ if (
158
+ params.meta?.nullslast === false &&
159
+ query.order.includes('nullslast')
160
+ ) {
161
+ query.order = query.order.replace('.nullslast', '');
162
+ }
131
163
  }
132
164
 
133
165
  if (select) {
@@ -188,6 +220,9 @@ export default (config: IDataProviderConfig): DataProvider => ({
188
220
 
189
221
  getMany: (resource, params: Partial<GetManyParams> = {}) => {
190
222
  const ids = params.ids;
223
+ if (ids.length === 0) {
224
+ return Promise.resolve({ data: [] });
225
+ }
191
226
  const primaryKey = getPrimaryKey(resource, config.primaryKeys);
192
227
 
193
228
  const query = getQuery(primaryKey, ids, resource, params.meta);
@@ -273,6 +308,9 @@ export default (config: IDataProviderConfig): DataProvider => ({
273
308
  const query = getQuery(primaryKey, id, resource, meta);
274
309
  const url = `${config.apiUrl}/${resource}?${qs.stringify(query)}`;
275
310
  const changedData = getChanges(data, previousData);
311
+ if (Object.keys(changedData).length === 0) {
312
+ return Promise.resolve({ data: { ...previousData } });
313
+ }
276
314
  const metaSchema = params.meta?.schema;
277
315
 
278
316
  const body = JSON.stringify({
package/src/urlBuilder.ts CHANGED
@@ -178,7 +178,7 @@ export const getPrimaryKey = (
178
178
  resource: string,
179
179
  primaryKeys: Map<string, PrimaryKey>
180
180
  ) => {
181
- return primaryKeys.get(resource) || ['id'];
181
+ return (primaryKeys && primaryKeys.get(resource)) || ['id'];
182
182
  };
183
183
 
184
184
  export const decodeId = (
@@ -298,7 +298,7 @@ export const getQuery = (
298
298
  return result;
299
299
  };
300
300
 
301
- export enum PostgRestSortOrder {
301
+ export const enum PostgRestSortOrder {
302
302
  AscendingNullsLastDescendingNullsFirst = 'asc,desc',
303
303
  AscendingNullsLastDescendingNullsLast = 'asc,desc.nullslast',
304
304
  AscendingNullsFirstDescendingNullsFirst = 'asc.nullsfirst,desc',