@raphiniert/ra-data-postgrest 2.3.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  Find all notable changes of this project in this file.
4
4
 
5
+ ## v2.4.1 - 2024-09-04
6
+ ### Improvements
7
+ - updated/fixed README.md
8
+
9
+ ## v2.4.0 - 2024-09-04
10
+ ### Fixes
11
+ - [#166](https://github.com/raphiniert-com/ra-data-postgrest/pull/166) Fix update fails when nothing is changed @[fzaninotto](https://github.com/fzaninotto)
12
+ - [#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)
13
+
14
+ ### Improvements
15
+ - [#164](https://github.com/raphiniert-com/ra-data-postgrest/pull/164) Add nullslast and nullsfirst support to getList @[fzaninotto](https://github.com/fzaninotto)
16
+ - updated dependencies
17
+ - updated README.md: added section "Citation"
18
+
5
19
  ## v2.3.0 - 2024-06-28
6
20
  ### Improvements
7
21
  - [#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
@@ -13,7 +13,22 @@ PostgREST Data Provider for [react-admin](https://github.com/marmelab/react-admi
13
13
  npm install --save @raphiniert/ra-data-postgrest
14
14
  ```
15
15
 
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.
16
+ ## Citation
17
+ If you use the PostgREST Data Provider in your research or project, please consider citing the corresponding [paper](https://www.sciencedirect.com/science/article/pii/S2665963824000873). Feel free to include the following BibTeX entry in your publications:
18
+
19
+ ```bibtex
20
+ @article{SCHEIBLE2024100699,
21
+ title = {PostgREST Data Provider for React-Admin: Bootstrap the creation of user interfaces on top of PostgreSQL databases},
22
+ journal = {Software Impacts},
23
+ volume = {21},
24
+ pages = {100699},
25
+ year = {2024},
26
+ issn = {2665-9638},
27
+ doi = {https://doi.org/10.1016/j.simpa.2024.100699},
28
+ author = {Raphael Scheible}
29
+ }
30
+ ```
31
+
17
32
 
18
33
  ## REST Dialect
19
34
 
@@ -195,9 +210,12 @@ const [create, { isLoading, error }] = useCreate(
195
210
  ```
196
211
 
197
212
  ### Null sort order
213
+
198
214
  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
215
 
200
216
  ```jsx
217
+ import { PostgRestSortOrder, IDataProviderConfig } from '@raphiniert/ra-data-postgrest';
218
+
201
219
  const config: IDataProviderConfig = {
202
220
  ...
203
221
  sortOrder: PostgRestSortOrder.AscendingNullsLastDescendingNullsLast
@@ -207,8 +225,23 @@ const config: IDataProviderConfig = {
207
225
  const dataProvider = postgrestRestProvider(config);
208
226
  ```
209
227
 
228
+ This parameter impacts the `getList` and `getManyReference` calls.
229
+
210
230
  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
231
 
232
+ 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:
233
+
234
+ ```jsx
235
+ const { data, total, isLoading, error } = useGetList(
236
+ 'posts',
237
+ {
238
+ pagination: { page: 1, perPage: 10 },
239
+ sort: { field: 'published_at', order: 'DESC' },
240
+ meta: { nullslast: true }
241
+ }
242
+ );
243
+ ```
244
+
212
245
  ### Vertical filtering
213
246
  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
247
 
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.1",
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',