@onehat/data 1.7.6 → 1.7.10

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.
@@ -347,6 +347,18 @@ describe('Entity', function() {
347
347
  expect(_.isEqual(result, expected)).to.be.true;
348
348
  });
349
349
 
350
+ it('getChangedValues', function() {
351
+ this.entity.foo = 2;
352
+ const result = this.entity.getChangedValues(),
353
+ expected = {
354
+ foo: {
355
+ original: 1,
356
+ current: 2,
357
+ },
358
+ };
359
+ expect(_.isEqual(result, expected)).to.be.true;
360
+ });
361
+
350
362
  it('data', function() {
351
363
  const result = this.entity.data,
352
364
  expected = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/data",
3
- "version": "1.7.6",
3
+ "version": "1.7.10",
4
4
  "description": "JS data modeling package with adapters for many storage mediums.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/Entity.js CHANGED
@@ -158,6 +158,7 @@ class Entity extends EventEmitter {
158
158
  initialize = () => {
159
159
  this.properties = this._createProperties();
160
160
  this._createMethods();
161
+ this._createStatics();
161
162
  this.reset();
162
163
  this.isInitialized = true;
163
164
  }
@@ -170,14 +171,30 @@ class Entity extends EventEmitter {
170
171
  if (this.isDestroyed) {
171
172
  throw Error('this._createMethods is no longer valid. Entity has been destroyed.');
172
173
  }
173
- const methodDefinitions = this.schema.entity.methods;
174
- if (!_.isEmpty(methodDefinitions)) {
175
- _.each(methodDefinitions, (method, name) => {
174
+ const methodsDefinitions = this.schema.entity.methods;
175
+ if (!_.isEmpty(methodsDefinitions)) {
176
+ _.each(methodsDefinitions, (method, name) => {
176
177
  this[name] = method; // NOTE: Methods must be defined in schema as "function() {}", not as "() => {}" so "this" will be assigned correctly
177
178
  });
178
179
  }
179
180
  }
180
181
 
182
+ /**
183
+ * Creates the static properties for this Entity, based on Schema.
184
+ * @private
185
+ */
186
+ _createStatics = () => {
187
+ if (this.isDestroyed) {
188
+ throw Error('this._createStatics is no longer valid. Entity has been destroyed.');
189
+ }
190
+ const staticsDefinitions = this.schema.entity.statics;
191
+ if (!_.isEmpty(staticsDefinitions)) {
192
+ _.each(staticsDefinitions, (value, key) => {
193
+ this[key] = value;
194
+ });
195
+ }
196
+ }
197
+
181
198
  /**
182
199
  * Generates a new unique id and assigns it to this entity.
183
200
  */
@@ -694,21 +711,39 @@ class Entity extends EventEmitter {
694
711
  * @return {array|boolean} diff - Array of property names that have changed, or false
695
712
  */
696
713
  getChanged = () => {
697
- const obj1 = this._originalDataParsed,
698
- obj2 = this.getRawValues(),
699
- diff = Object.keys(obj1).reduce((result, key) => { // from https://stackoverflow.com/a/40610459/9163076
700
- if (obj2 && !obj2.hasOwnProperty(key)) {
714
+ const original = this._originalDataParsed,
715
+ current = this.getRawValues(),
716
+ diff = Object.keys(original).reduce((result, key) => { // from https://stackoverflow.com/a/40610459/9163076
717
+ if (current && !current.hasOwnProperty(key)) {
701
718
  result.push(key);
702
- } else if (_.isEqual(obj1[key], obj2[key])) {
719
+ } else if (_.isEqual(original[key], current[key])) {
703
720
  const resultKeyIndex = result.indexOf(key);
704
721
  result.splice(resultKeyIndex, 1);
705
722
  }
706
723
  return result;
707
- }, Object.keys(obj2));
724
+ }, Object.keys(current));
708
725
 
709
726
  return !_.isEmpty(diff) ? diff : false;
710
727
  }
711
728
 
729
+ /**
730
+ * Gets a comprehensive analysis of what has changed since the last save
731
+ * @return {object} changedPropertyValues - Object representing each changed field and both its original and current value
732
+ */
733
+ getChangedValues = () => {
734
+ const original = this._originalDataParsed,
735
+ current = this.getRawValues(),
736
+ names = this.getChanged();
737
+ const changedPropertyValues = {};
738
+ _.each(names, (name) => {
739
+ changedPropertyValues[name] = {
740
+ original: original[name],
741
+ current: current[name],
742
+ };
743
+ });
744
+ return changedPropertyValues;
745
+ }
746
+
712
747
  /**
713
748
  * Alias for this.submitValues
714
749
  */
@@ -834,6 +834,9 @@ class AjaxRepository extends Repository {
834
834
  * @private
835
835
  */
836
836
  _finalizeSave = (promises) => {
837
+ if (!promises.length) {
838
+ return;
839
+ }
837
840
  return this.axios.all(promises)
838
841
  .then(this.axios.spread((...batchOperationResults) => {
839
842
  // All requests are now complete
@@ -1331,6 +1331,13 @@ export default class Repository extends EventEmitter {
1331
1331
  return this.isInRepository(id);
1332
1332
  }
1333
1333
 
1334
+ /**
1335
+ * Convenience function
1336
+ */
1337
+ saveStaged = () => {
1338
+ return this.save(null, true);
1339
+ }
1340
+
1334
1341
  /**
1335
1342
  * Queues up batch operations for saving
1336
1343
  * new, edited, and deleted entities to storage medium.
@@ -1391,7 +1398,9 @@ export default class Repository extends EventEmitter {
1391
1398
  if (this.combineBatch) {
1392
1399
 
1393
1400
  result = this.batchAsSynchronous ? await this._doBatchAdd(entities) : this._doBatchAdd(entities);
1394
- results.push(result);
1401
+ if (result) {
1402
+ results.push(result);
1403
+ }
1395
1404
 
1396
1405
  } else {
1397
1406
  for (i = 0; i < entities.length; i++) {
@@ -1404,7 +1413,9 @@ export default class Repository extends EventEmitter {
1404
1413
  }
1405
1414
 
1406
1415
  result = this.batchAsSynchronous ? await this._doAdd(entity) : this._doAdd(entity);
1407
- results.push(result);
1416
+ if (result) {
1417
+ results.push(result);
1418
+ }
1408
1419
  }
1409
1420
  }
1410
1421
  }
@@ -1418,7 +1429,9 @@ export default class Repository extends EventEmitter {
1418
1429
  if (this.combineBatch) {
1419
1430
 
1420
1431
  result = this.batchAsSynchronous ? await this._doBatchEdit(entities) : this._doBatchEdit(entities);
1421
- results.push(result);
1432
+ if (result) {
1433
+ results.push(result);
1434
+ }
1422
1435
 
1423
1436
  } else {
1424
1437
  for (i = 0; i < entities.length; i++) {
@@ -1431,7 +1444,9 @@ export default class Repository extends EventEmitter {
1431
1444
  }
1432
1445
 
1433
1446
  result = this.batchAsSynchronous ? await this._doEdit(entity) : this._doEdit(entity);
1434
- results.push(result);
1447
+ if (result) {
1448
+ results.push(result);
1449
+ }
1435
1450
  }
1436
1451
  }
1437
1452
  }
@@ -1445,7 +1460,9 @@ export default class Repository extends EventEmitter {
1445
1460
  if (this.combineBatch) {
1446
1461
 
1447
1462
  result = this.batchAsSynchronous ? await this._doBatchDelete(entities) : this._doBatchDelete(entities);
1448
- results.push(result);
1463
+ if (result) {
1464
+ results.push(result);
1465
+ }
1449
1466
 
1450
1467
  } else {
1451
1468
  for (i = 0; i < entities.length; i++) {
@@ -1456,7 +1473,9 @@ export default class Repository extends EventEmitter {
1456
1473
  } else {
1457
1474
  result = this.batchAsSynchronous ? await this._doDelete(entity) : this._doDelete(entity);
1458
1475
  }
1459
- results.push(result);
1476
+ if (result) {
1477
+ results.push(result);
1478
+ }
1460
1479
  }
1461
1480
  }
1462
1481
  }
@@ -100,6 +100,7 @@ export default class Schema extends EventEmitter {
100
100
 
101
101
  entity: {
102
102
  methods: {}, // NOTE: Methods must be defined as "function() {}", not as "() => {}" so "this" will be assigned correctly
103
+ statics: {},
103
104
  },
104
105
 
105
106
  /**