@raphiniert/ra-data-postgrest 2.4.0 → 2.5.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/esm/index.js CHANGED
@@ -11,7 +11,7 @@ var __assign = (this && this.__assign) || function () {
11
11
  };
12
12
  import { getPrimaryKey, parseFilters, getOrderBy, dataWithVirtualId, dataWithoutVirtualId, removePrimaryKey, getQuery, encodeId, } from './urlBuilder';
13
13
  import qs from 'qs';
14
- import isEqual from 'lodash/isEqual';
14
+ import { isDeepStrictEqual as isEqual } from 'node:util';
15
15
  export var defaultPrimaryKeys = new Map();
16
16
  export var defaultSchema = function () { return ''; };
17
17
  var useCustomSchema = function (schema, metaSchema, method) {
@@ -76,13 +76,17 @@ export default (function (config) { return ({
76
76
  };
77
77
  var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs.stringify(query));
78
78
  return config.httpClient(url, options).then(function (_a) {
79
+ var _b, _c, _d;
79
80
  var headers = _a.headers, json = _a.json;
80
81
  if (!headers.has('content-range')) {
81
82
  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?");
82
83
  }
84
+ var data = json.map(function (obj) { return dataWithVirtualId(obj, primaryKey); });
85
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
83
86
  return {
84
- data: json.map(function (obj) { return dataWithVirtualId(obj, primaryKey); }),
87
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
85
88
  total: parseInt(headers.get('content-range').split('/').pop(), 10),
89
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
86
90
  };
87
91
  });
88
92
  },
@@ -99,10 +103,14 @@ export default (function (config) { return ({
99
103
  headers: new Headers(__assign(__assign({ accept: 'application/vnd.pgrst.object+json' }, (((_b = params.meta) === null || _b === void 0 ? void 0 : _b.headers) || {})), useCustomSchema(config.schema, metaSchema, 'GET'))),
100
104
  })
101
105
  .then(function (_a) {
106
+ var _b, _c, _d;
102
107
  var json = _a.json;
103
- return ({
104
- data: dataWithVirtualId(json, primaryKey),
105
- });
108
+ var data = dataWithVirtualId(json, primaryKey);
109
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
110
+ return {
111
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
112
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
113
+ };
106
114
  });
107
115
  },
108
116
  getMany: function (resource, params) {
@@ -121,10 +129,16 @@ export default (function (config) { return ({
121
129
  headers: new Headers(__assign({}, useCustomSchema(config.schema, metaSchema, 'GET'))),
122
130
  })
123
131
  .then(function (_a) {
132
+ var _b, _c, _d;
124
133
  var json = _a.json;
125
- return ({
126
- data: json.map(function (data) { return dataWithVirtualId(data, primaryKey); }),
134
+ var data = json.map(function (data) {
135
+ return dataWithVirtualId(data, primaryKey);
127
136
  });
137
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
138
+ return {
139
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
140
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
141
+ };
128
142
  });
129
143
  },
130
144
  getManyReference: function (resource, params) {
@@ -147,13 +161,17 @@ export default (function (config) { return ({
147
161
  };
148
162
  var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs.stringify(query));
149
163
  return config.httpClient(url, options).then(function (_a) {
164
+ var _b, _c, _d;
150
165
  var headers = _a.headers, json = _a.json;
151
166
  if (!headers.has('content-range')) {
152
167
  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?");
153
168
  }
169
+ var data = json.map(function (data) { return dataWithVirtualId(data, primaryKey); });
170
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
154
171
  return {
155
- data: json.map(function (data) { return dataWithVirtualId(data, primaryKey); }),
172
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
156
173
  total: parseInt(headers.get('content-range').split('/').pop(), 10),
174
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
157
175
  };
158
176
  });
159
177
  },
@@ -177,10 +195,14 @@ export default (function (config) { return ({
177
195
  body: body,
178
196
  })
179
197
  .then(function (_a) {
198
+ var _b, _c, _d;
180
199
  var json = _a.json;
181
- return ({
182
- data: dataWithVirtualId(json, primaryKey),
183
- });
200
+ var data = dataWithVirtualId(json, primaryKey);
201
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
202
+ return {
203
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
204
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
205
+ };
184
206
  });
185
207
  },
186
208
  updateMany: function (resource, params) {
@@ -221,10 +243,14 @@ export default (function (config) { return ({
221
243
  body: JSON.stringify(dataWithoutVirtualId(params.data, primaryKey)),
222
244
  })
223
245
  .then(function (_a) {
246
+ var _b, _c, _d;
224
247
  var json = _a.json;
225
- return ({
226
- data: __assign(__assign({}, json), { id: encodeId(json, primaryKey) }),
227
- });
248
+ var data = __assign(__assign({}, json), { id: encodeId(json, primaryKey) });
249
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
250
+ return {
251
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
252
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
253
+ };
228
254
  });
229
255
  },
230
256
  delete: function (resource, params) {
@@ -241,10 +267,14 @@ export default (function (config) { return ({
241
267
  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, 'DELETE'))),
242
268
  })
243
269
  .then(function (_a) {
270
+ var _b, _c, _d;
244
271
  var json = _a.json;
245
- return ({
246
- data: dataWithVirtualId(json, primaryKey),
247
- });
272
+ var data = dataWithVirtualId(json, primaryKey);
273
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
274
+ return {
275
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
276
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
277
+ };
248
278
  });
249
279
  },
250
280
  deleteMany: function (resource, params) {
@@ -277,3 +307,73 @@ var getChanges = function (data, previousData) {
277
307
  }, {});
278
308
  return changes;
279
309
  };
310
+ /**
311
+ * Extract embeds from Postgrest responses
312
+ *
313
+ * When calling Postgrest database.getOne('posts', 123, { embed: 'tags' }),
314
+ * the Postgrest response adds a `tags` key to the response, containing the
315
+ * related tags. Something like:
316
+ *
317
+ * { id: 123, title: 'React-query in details', tags: [{ id: 1, name: 'react' }, { id: 1, name: 'query' }] }
318
+ *
319
+ * We want to copy all the embeds in a data object, that will later
320
+ * be included into the response meta.prefetched key.
321
+ *
322
+ * @example getPrefetchedData({ id: 123, title: 'React-query in details', tags: [{ id: 1, name: 'react' }, { id: 1, name: 'query' }] }, ['tags'])
323
+ * // {
324
+ * // tags: [{ id: 1, name: 'react' }, { id: 1, name: 'query' }]
325
+ * // }
326
+ */
327
+ var getPrefetchedData = function (data, prefetchParam) {
328
+ if (!prefetchParam)
329
+ return undefined;
330
+ var prefetched = {};
331
+ var dataArray = Array.isArray(data) ? data : [data];
332
+ prefetchParam.forEach(function (resource) {
333
+ dataArray.forEach(function (record) {
334
+ if (!prefetched[resource]) {
335
+ prefetched[resource] = [];
336
+ }
337
+ var prefetchedData = Array.isArray(record[resource])
338
+ ? record[resource]
339
+ : [record[resource]];
340
+ prefetchedData.forEach(function (prefetchedRecord) {
341
+ if (prefetched[resource].some(function (r) { return r.id === prefetchedRecord.id; })) {
342
+ // do not add the record if it's already there
343
+ return;
344
+ }
345
+ prefetched[resource].push(prefetchedRecord);
346
+ });
347
+ });
348
+ });
349
+ return prefetched;
350
+ };
351
+ /**
352
+ * Remove embeds from Postgrest responses
353
+ *
354
+ * When calling Postgrest database.getOne('posts', 123, { embed: 'tags' }),
355
+ * the Postgrest response adds a `post` key to the response, containing the
356
+ * related post. Something like:
357
+ *
358
+ * { id: 123, title: 'React-query in details', tags: [{ id: 1, name: 'react' }, { id: 1, name: 'query' }] }
359
+ *
360
+ * We want to remove all the embeds from the response.
361
+ *
362
+ * @example removePrefetchedData({ id: 123, title: 'React-query in details', tags: [{ id: 1, name: 'react' }, { id: 1, name: 'query' }] }, 'tags')
363
+ * // { id: 123, title: 'React-query in details' }
364
+ */
365
+ var removePrefetchedData = function (data, prefetchParam) {
366
+ if (!prefetchParam)
367
+ return data;
368
+ var dataArray = Array.isArray(data) ? data : [data];
369
+ var newDataArray = dataArray.map(function (record) {
370
+ var newRecord = {};
371
+ for (var key in record) {
372
+ if (!prefetchParam.includes(key)) {
373
+ newRecord[key] = record[key];
374
+ }
375
+ }
376
+ return newRecord;
377
+ });
378
+ return Array.isArray(data) ? newDataArray : newDataArray[0];
379
+ };
package/esm/urlBuilder.js CHANGED
@@ -154,6 +154,14 @@ export var parseFilters = function (params, defaultListOp) {
154
154
  ? meta.columns.join(',')
155
155
  : meta.columns;
156
156
  }
157
+ if ((meta === null || meta === void 0 ? void 0 : meta.embed) || (meta === null || meta === void 0 ? void 0 : meta.prefetch)) {
158
+ var columns = getColumnsParam(meta.embed, meta.prefetch);
159
+ if (columns) {
160
+ result.select = result.select
161
+ ? "".concat(result.select, ",").concat(columns.join(','))
162
+ : "*,".concat(columns.join(','));
163
+ }
164
+ }
157
165
  return result;
158
166
  };
159
167
  export var getPrimaryKey = function (resource, primaryKeys) {
@@ -256,6 +264,15 @@ export var getQuery = function (primaryKey, ids, resource, meta) {
256
264
  ? meta.columns.join(',')
257
265
  : meta.columns;
258
266
  }
267
+ if ((meta === null || meta === void 0 ? void 0 : meta.embed) || (meta === null || meta === void 0 ? void 0 : meta.prefetch)) {
268
+ var columns = getColumnsParam(meta.embed, meta.prefetch);
269
+ if (columns) {
270
+ result.select = result.select
271
+ ? "".concat(result.select, ",").concat(columns.join(','))
272
+ : // if users did not specify any columns, we must add the wildcard select to not get only the embeds/prefetch
273
+ "*,".concat(columns.join(','));
274
+ }
275
+ }
259
276
  return result;
260
277
  };
261
278
  export var getOrderBy = function (field, order, primaryKey, sortOrder) {
@@ -268,3 +285,16 @@ export var getOrderBy = function (field, order, primaryKey, sortOrder) {
268
285
  return "".concat(field, ".").concat(postgRestOrder);
269
286
  }
270
287
  };
288
+ /**
289
+ * Compute the columns parameter for the embed and prefetch query meta properties
290
+ */
291
+ var getColumnsParam = function (embed, prefetch) {
292
+ if (!embed && !prefetch)
293
+ return;
294
+ var param = new Set();
295
+ if (embed)
296
+ embed.forEach(function (resource) { return param.add("".concat(resource, "(*)")); });
297
+ if (prefetch)
298
+ prefetch.forEach(function (resource) { return param.add("".concat(resource, "(*)")); });
299
+ return Array.from(param);
300
+ };
package/lib/index.js CHANGED
@@ -17,7 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.defaultSchema = exports.defaultPrimaryKeys = void 0;
18
18
  var urlBuilder_1 = require("./urlBuilder");
19
19
  var qs_1 = __importDefault(require("qs"));
20
- var isEqual_1 = __importDefault(require("lodash/isEqual"));
20
+ var node_util_1 = require("node:util");
21
21
  exports.defaultPrimaryKeys = new Map();
22
22
  var defaultSchema = function () { return ''; };
23
23
  exports.defaultSchema = defaultSchema;
@@ -83,13 +83,17 @@ exports.default = (function (config) { return ({
83
83
  };
84
84
  var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs_1.default.stringify(query));
85
85
  return config.httpClient(url, options).then(function (_a) {
86
+ var _b, _c, _d;
86
87
  var headers = _a.headers, json = _a.json;
87
88
  if (!headers.has('content-range')) {
88
89
  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?");
89
90
  }
91
+ var data = json.map(function (obj) { return (0, urlBuilder_1.dataWithVirtualId)(obj, primaryKey); });
92
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
90
93
  return {
91
- data: json.map(function (obj) { return (0, urlBuilder_1.dataWithVirtualId)(obj, primaryKey); }),
94
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
92
95
  total: parseInt(headers.get('content-range').split('/').pop(), 10),
96
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
93
97
  };
94
98
  });
95
99
  },
@@ -106,10 +110,14 @@ exports.default = (function (config) { return ({
106
110
  headers: new Headers(__assign(__assign({ accept: 'application/vnd.pgrst.object+json' }, (((_b = params.meta) === null || _b === void 0 ? void 0 : _b.headers) || {})), useCustomSchema(config.schema, metaSchema, 'GET'))),
107
111
  })
108
112
  .then(function (_a) {
113
+ var _b, _c, _d;
109
114
  var json = _a.json;
110
- return ({
111
- data: (0, urlBuilder_1.dataWithVirtualId)(json, primaryKey),
112
- });
115
+ var data = (0, urlBuilder_1.dataWithVirtualId)(json, primaryKey);
116
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
117
+ return {
118
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
119
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
120
+ };
113
121
  });
114
122
  },
115
123
  getMany: function (resource, params) {
@@ -128,10 +136,16 @@ exports.default = (function (config) { return ({
128
136
  headers: new Headers(__assign({}, useCustomSchema(config.schema, metaSchema, 'GET'))),
129
137
  })
130
138
  .then(function (_a) {
139
+ var _b, _c, _d;
131
140
  var json = _a.json;
132
- return ({
133
- data: json.map(function (data) { return (0, urlBuilder_1.dataWithVirtualId)(data, primaryKey); }),
141
+ var data = json.map(function (data) {
142
+ return (0, urlBuilder_1.dataWithVirtualId)(data, primaryKey);
134
143
  });
144
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
145
+ return {
146
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
147
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
148
+ };
135
149
  });
136
150
  },
137
151
  getManyReference: function (resource, params) {
@@ -154,13 +168,17 @@ exports.default = (function (config) { return ({
154
168
  };
155
169
  var url = "".concat(config.apiUrl, "/").concat(resource, "?").concat(qs_1.default.stringify(query));
156
170
  return config.httpClient(url, options).then(function (_a) {
171
+ var _b, _c, _d;
157
172
  var headers = _a.headers, json = _a.json;
158
173
  if (!headers.has('content-range')) {
159
174
  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?");
160
175
  }
176
+ var data = json.map(function (data) { return (0, urlBuilder_1.dataWithVirtualId)(data, primaryKey); });
177
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
161
178
  return {
162
- data: json.map(function (data) { return (0, urlBuilder_1.dataWithVirtualId)(data, primaryKey); }),
179
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
163
180
  total: parseInt(headers.get('content-range').split('/').pop(), 10),
181
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
164
182
  };
165
183
  });
166
184
  },
@@ -184,10 +202,14 @@ exports.default = (function (config) { return ({
184
202
  body: body,
185
203
  })
186
204
  .then(function (_a) {
205
+ var _b, _c, _d;
187
206
  var json = _a.json;
188
- return ({
189
- data: (0, urlBuilder_1.dataWithVirtualId)(json, primaryKey),
190
- });
207
+ var data = (0, urlBuilder_1.dataWithVirtualId)(json, primaryKey);
208
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
209
+ return {
210
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
211
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
212
+ };
191
213
  });
192
214
  },
193
215
  updateMany: function (resource, params) {
@@ -228,10 +250,14 @@ exports.default = (function (config) { return ({
228
250
  body: JSON.stringify((0, urlBuilder_1.dataWithoutVirtualId)(params.data, primaryKey)),
229
251
  })
230
252
  .then(function (_a) {
253
+ var _b, _c, _d;
231
254
  var json = _a.json;
232
- return ({
233
- data: __assign(__assign({}, json), { id: (0, urlBuilder_1.encodeId)(json, primaryKey) }),
234
- });
255
+ var data = __assign(__assign({}, json), { id: (0, urlBuilder_1.encodeId)(json, primaryKey) });
256
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
257
+ return {
258
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
259
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
260
+ };
235
261
  });
236
262
  },
237
263
  delete: function (resource, params) {
@@ -248,10 +274,14 @@ exports.default = (function (config) { return ({
248
274
  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, 'DELETE'))),
249
275
  })
250
276
  .then(function (_a) {
277
+ var _b, _c, _d;
251
278
  var json = _a.json;
252
- return ({
253
- data: (0, urlBuilder_1.dataWithVirtualId)(json, primaryKey),
254
- });
279
+ var data = (0, urlBuilder_1.dataWithVirtualId)(json, primaryKey);
280
+ var prefetched = getPrefetchedData(data, (_b = params.meta) === null || _b === void 0 ? void 0 : _b.prefetch);
281
+ return {
282
+ data: removePrefetchedData(data, (_c = params.meta) === null || _c === void 0 ? void 0 : _c.prefetch),
283
+ meta: ((_d = params.meta) === null || _d === void 0 ? void 0 : _d.prefetch) ? { prefetched: prefetched } : undefined,
284
+ };
255
285
  });
256
286
  },
257
287
  deleteMany: function (resource, params) {
@@ -277,10 +307,80 @@ exports.default = (function (config) { return ({
277
307
  }); });
278
308
  var getChanges = function (data, previousData) {
279
309
  var changes = Object.keys(data).reduce(function (changes, key) {
280
- if (!(0, isEqual_1.default)(data[key], previousData[key])) {
310
+ if (!(0, node_util_1.isDeepStrictEqual)(data[key], previousData[key])) {
281
311
  changes[key] = data[key];
282
312
  }
283
313
  return changes;
284
314
  }, {});
285
315
  return changes;
286
316
  };
317
+ /**
318
+ * Extract embeds from Postgrest responses
319
+ *
320
+ * When calling Postgrest database.getOne('posts', 123, { embed: 'tags' }),
321
+ * the Postgrest response adds a `tags` key to the response, containing the
322
+ * related tags. Something like:
323
+ *
324
+ * { id: 123, title: 'React-query in details', tags: [{ id: 1, name: 'react' }, { id: 1, name: 'query' }] }
325
+ *
326
+ * We want to copy all the embeds in a data object, that will later
327
+ * be included into the response meta.prefetched key.
328
+ *
329
+ * @example getPrefetchedData({ id: 123, title: 'React-query in details', tags: [{ id: 1, name: 'react' }, { id: 1, name: 'query' }] }, ['tags'])
330
+ * // {
331
+ * // tags: [{ id: 1, name: 'react' }, { id: 1, name: 'query' }]
332
+ * // }
333
+ */
334
+ var getPrefetchedData = function (data, prefetchParam) {
335
+ if (!prefetchParam)
336
+ return undefined;
337
+ var prefetched = {};
338
+ var dataArray = Array.isArray(data) ? data : [data];
339
+ prefetchParam.forEach(function (resource) {
340
+ dataArray.forEach(function (record) {
341
+ if (!prefetched[resource]) {
342
+ prefetched[resource] = [];
343
+ }
344
+ var prefetchedData = Array.isArray(record[resource])
345
+ ? record[resource]
346
+ : [record[resource]];
347
+ prefetchedData.forEach(function (prefetchedRecord) {
348
+ if (prefetched[resource].some(function (r) { return r.id === prefetchedRecord.id; })) {
349
+ // do not add the record if it's already there
350
+ return;
351
+ }
352
+ prefetched[resource].push(prefetchedRecord);
353
+ });
354
+ });
355
+ });
356
+ return prefetched;
357
+ };
358
+ /**
359
+ * Remove embeds from Postgrest responses
360
+ *
361
+ * When calling Postgrest database.getOne('posts', 123, { embed: 'tags' }),
362
+ * the Postgrest response adds a `post` key to the response, containing the
363
+ * related post. Something like:
364
+ *
365
+ * { id: 123, title: 'React-query in details', tags: [{ id: 1, name: 'react' }, { id: 1, name: 'query' }] }
366
+ *
367
+ * We want to remove all the embeds from the response.
368
+ *
369
+ * @example removePrefetchedData({ id: 123, title: 'React-query in details', tags: [{ id: 1, name: 'react' }, { id: 1, name: 'query' }] }, 'tags')
370
+ * // { id: 123, title: 'React-query in details' }
371
+ */
372
+ var removePrefetchedData = function (data, prefetchParam) {
373
+ if (!prefetchParam)
374
+ return data;
375
+ var dataArray = Array.isArray(data) ? data : [data];
376
+ var newDataArray = dataArray.map(function (record) {
377
+ var newRecord = {};
378
+ for (var key in record) {
379
+ if (!prefetchParam.includes(key)) {
380
+ newRecord[key] = record[key];
381
+ }
382
+ }
383
+ return newRecord;
384
+ });
385
+ return Array.isArray(data) ? newDataArray : newDataArray[0];
386
+ };
package/lib/urlBuilder.js CHANGED
@@ -157,6 +157,14 @@ var parseFilters = function (params, defaultListOp) {
157
157
  ? meta.columns.join(',')
158
158
  : meta.columns;
159
159
  }
160
+ if ((meta === null || meta === void 0 ? void 0 : meta.embed) || (meta === null || meta === void 0 ? void 0 : meta.prefetch)) {
161
+ var columns = getColumnsParam(meta.embed, meta.prefetch);
162
+ if (columns) {
163
+ result.select = result.select
164
+ ? "".concat(result.select, ",").concat(columns.join(','))
165
+ : "*,".concat(columns.join(','));
166
+ }
167
+ }
160
168
  return result;
161
169
  };
162
170
  exports.parseFilters = parseFilters;
@@ -266,6 +274,15 @@ var getQuery = function (primaryKey, ids, resource, meta) {
266
274
  ? meta.columns.join(',')
267
275
  : meta.columns;
268
276
  }
277
+ if ((meta === null || meta === void 0 ? void 0 : meta.embed) || (meta === null || meta === void 0 ? void 0 : meta.prefetch)) {
278
+ var columns = getColumnsParam(meta.embed, meta.prefetch);
279
+ if (columns) {
280
+ result.select = result.select
281
+ ? "".concat(result.select, ",").concat(columns.join(','))
282
+ : // if users did not specify any columns, we must add the wildcard select to not get only the embeds/prefetch
283
+ "*,".concat(columns.join(','));
284
+ }
285
+ }
269
286
  return result;
270
287
  };
271
288
  exports.getQuery = getQuery;
@@ -280,3 +297,16 @@ var getOrderBy = function (field, order, primaryKey, sortOrder) {
280
297
  }
281
298
  };
282
299
  exports.getOrderBy = getOrderBy;
300
+ /**
301
+ * Compute the columns parameter for the embed and prefetch query meta properties
302
+ */
303
+ var getColumnsParam = function (embed, prefetch) {
304
+ if (!embed && !prefetch)
305
+ return;
306
+ var param = new Set();
307
+ if (embed)
308
+ embed.forEach(function (resource) { return param.add("".concat(resource, "(*)")); });
309
+ if (prefetch)
310
+ prefetch.forEach(function (resource) { return param.add("".concat(resource, "(*)")); });
311
+ return Array.from(param);
312
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raphiniert/ra-data-postgrest",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "postgREST data provider for react-admin",
5
5
  "main": "lib/index.js",
6
6
  "module": "esm/index.js",
@@ -29,23 +29,22 @@
29
29
  "prettier": "prettier --config ./.prettierrc.js --write --list-different \"src/**/*.{js,json,ts,tsx,css,md}\""
30
30
  },
31
31
  "devDependencies": {
32
- "@types/jest": "^29.5.12",
33
- "@types/qs": "^6.9.15",
32
+ "@types/jest": "^29.5.14",
33
+ "@types/qs": "^6.9.18",
34
34
  "cross-env": "^7.0.3",
35
- "eslint-config-prettier": "^9.1.0",
36
- "eslint-plugin-prettier": "^5.1.3",
35
+ "eslint-config-prettier": "^10.1.2",
36
+ "eslint-plugin-prettier": "^5.2.6",
37
37
  "install-peers-cli": "^2.2.0",
38
38
  "jest": "^29.7.0",
39
- "prettier": "^3.3.2",
39
+ "prettier": "^3.5.3",
40
40
  "rimraf": "^6.0.1",
41
- "ts-jest": "^29.1.5",
42
- "typescript": "^5.5.2"
41
+ "ts-jest": "^29.3.2",
42
+ "typescript": "^5.8.3"
43
43
  },
44
44
  "peerDependencies": {
45
- "ra-core": "^3.0.0 || ^4.1.0 || ^5.0.1"
45
+ "ra-core": "^5.7.3"
46
46
  },
47
47
  "dependencies": {
48
- "lodash.isequal": "^4.5.0",
49
- "qs": "^6.12.1"
48
+ "qs": "^6.14.0"
50
49
  }
51
50
  }