electrodb 2.5.1 → 2.6.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/src/errors.js CHANGED
@@ -187,6 +187,24 @@ const ErrorCodes = {
187
187
  name: "InvalidLimitOption",
188
188
  sym: ErrorCode,
189
189
  },
190
+ InvalidConversionKeysProvided: {
191
+ code: 2007,
192
+ section: "invalid-conversion-values-provided",
193
+ name: "InvalidConversionKeysProvided",
194
+ sym: ErrorCode,
195
+ },
196
+ InvalidConversionCursorProvided: {
197
+ code: 2008,
198
+ section: "invalid-conversion-values-provided",
199
+ name: "InvalidConversionCursorProvided",
200
+ sym: ErrorCode,
201
+ },
202
+ InvalidConversionCompositeProvided: {
203
+ code: 2009,
204
+ section: "invalid-conversion-values-provided",
205
+ name: "InvalidConversionCompositeProvided",
206
+ sym: ErrorCode,
207
+ },
190
208
  InvalidAttribute: {
191
209
  code: 3001,
192
210
  section: "invalid-attribute",
package/src/service.js CHANGED
@@ -323,17 +323,25 @@ class Service {
323
323
  continue;
324
324
  }
325
325
 
326
- const entityAlias = matchToEntityAlias({identifiers, record});
326
+ const entityAlias = matchToEntityAlias({identifiers, record, entities: this.entities, allowMatchOnKeys: config.ignoreOwnership });
327
327
 
328
328
  if (!entityAlias) {
329
329
  continue;
330
330
  }
331
+
331
332
  // pager=false because we don't want the entity trying to parse the lastEvaluatedKey
332
- let formatted = entities[entityAlias].formatResponse({Item: record}, index, {
333
- ...config,
334
- pager: false,
335
- parse: undefined
336
- });
333
+ let formatted;
334
+ if (config.hydrate) {
335
+ formatted = {
336
+ data: record // entities[entityAlias]._formatKeysToItem(index, record),
337
+ };
338
+ } else {
339
+ formatted = entities[entityAlias].formatResponse({Item: record}, index, {
340
+ ...config,
341
+ pager: false,
342
+ parse: undefined,
343
+ });
344
+ }
337
345
 
338
346
  results[entityAlias].push(formatted.data);
339
347
  }
@@ -429,6 +437,70 @@ class Service {
429
437
  entities,
430
438
  indexType,
431
439
  compositeAttributes,
440
+ hydrator: async (entity, index, items, config) => {
441
+ if (entity && entities[entity]) {
442
+ return entities[entity].hydrate(index, items, {
443
+ ...config,
444
+ parse: undefined,
445
+ hydrator: undefined,
446
+ _isCollectionQuery: false,
447
+ ignoreOwnership: config._providedIgnoreOwnership,
448
+ });
449
+ }
450
+
451
+ // let itemLookup = [];
452
+ let entityItemRefs = {};
453
+ // let entityResultRefs = {};
454
+ for (let i = 0; i < items.length; i++) {
455
+ const item = items[i];
456
+ for (let entityName in entities) {
457
+ entityItemRefs[entityName] = entityItemRefs[entityName] || [];
458
+ const entity = entities[entityName];
459
+ // if (entity.ownsKeys({ keys: item })) {
460
+ if (entity.ownsKeys(item)) {
461
+ // const entityItemRefsIndex =
462
+ entityItemRefs[entityName].push({
463
+ item,
464
+ itemSlot: i,
465
+ });
466
+ // itemLookup[i] = {
467
+ // entityName,
468
+ // entityItemRefsIndex,
469
+ // originalItem: item,
470
+ // }
471
+ }
472
+ }
473
+ }
474
+
475
+ let unprocessed = [];
476
+ let data = new Array(items.length).fill(null);
477
+ for (const entityName in entityItemRefs) {
478
+ const itemRefs = entityItemRefs[entityName];
479
+ const items = itemRefs.map(ref => ref.item);
480
+ const results = await entities[entity].hydrate(index, items, {
481
+ ...config,
482
+ parse: undefined,
483
+ hydrate: false,
484
+ hydrator: undefined,
485
+ _isCollectionQuery: false,
486
+ ignoreOwnership: config._providedIgnoreOwnership,
487
+ });
488
+ unprocessed = unprocessed.concat(results.unprocessed);
489
+ if (results.data.length !== itemRefs.length) {
490
+ throw new Error('Temporary: something wrong');
491
+ }
492
+ for (let r = 0; r < itemRefs.length; r++) {
493
+ const itemRef = itemRefs[r];
494
+ const hydrated = results.data[r];
495
+ data[itemRef.itemSlot] = hydrated;
496
+ }
497
+ }
498
+
499
+ return {
500
+ data,
501
+ unprocessed,
502
+ }
503
+ }
432
504
  };
433
505
 
434
506
  return entity.collection(name, clauses, facets, options);
package/src/update.js CHANGED
@@ -11,6 +11,7 @@ class UpdateExpression extends ExpressionState {
11
11
  subtract: new Set(),
12
12
  delete: new Set()
13
13
  };
14
+ this.seen = new Map();
14
15
  this.type = BuilderTypes.update;
15
16
  }
16
17
 
@@ -18,10 +19,29 @@ class UpdateExpression extends ExpressionState {
18
19
  this.operations[type].add(expression);
19
20
  }
20
21
 
21
- set(name, value) {
22
- const n = this.setName({}, name, name);
23
- const v = this.setValue(name, value);
24
- this.add(ItemOperations.set, `${n.prop} = ${v}`);
22
+ unadd(type, expression) {
23
+ this.operations[type].delete(expression);
24
+ }
25
+
26
+ set(name, value, operation) {
27
+ const seen = this.seen.get(name);
28
+ let n;
29
+ let v;
30
+ if (seen) {
31
+ n = seen.name;
32
+ v = seen.value;
33
+ this.unadd(ItemOperations.set, seen.expression);
34
+ } else {
35
+ n = this.setName({}, name, name);
36
+ v = this.setValue(name, value);
37
+ }
38
+ const expression = `${n.prop} = ${v}`;
39
+ this.seen.set(name, {
40
+ name: n,
41
+ value: v,
42
+ expression,
43
+ });
44
+ this.add(operation || ItemOperations.set, expression);
25
45
  }
26
46
 
27
47
  remove(name) {
package/src/util.js CHANGED
@@ -237,10 +237,15 @@ function getFirstDefined(...params) {
237
237
  return params.find(val => val !== undefined);
238
238
  }
239
239
 
240
+ function regexpEscape(str) {
241
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
242
+ }
243
+
240
244
  module.exports = {
241
245
  getUnique,
242
246
  batchItems,
243
247
  addPadding,
248
+ regexpEscape,
244
249
  removePadding,
245
250
  removeFixings,
246
251
  parseJSONPath,