@onehat/data 1.20.9 → 1.21.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.
Files changed (51) hide show
  1. package/cypress/downloads/downloads.html +0 -0
  2. package/cypress/e2e/Entity.cy.js +2 -2
  3. package/cypress/e2e/Property/Base64.cy.js +37 -3
  4. package/cypress/e2e/Property/Boolean.cy.js +30 -0
  5. package/cypress/e2e/Property/Currency.cy.js +41 -0
  6. package/cypress/e2e/Property/Date.cy.js +33 -0
  7. package/cypress/e2e/Property/DateTime.cy.js +33 -0
  8. package/cypress/e2e/Property/Float.cy.js +31 -0
  9. package/cypress/e2e/Property/Integer.cy.js +31 -0
  10. package/cypress/e2e/Property/Json.cy.js +29 -0
  11. package/cypress/e2e/Property/PercentInt.cy.js +32 -0
  12. package/cypress/e2e/Property/Property.cy.js +29 -0
  13. package/cypress/e2e/Property/Time.cy.js +33 -0
  14. package/cypress/e2e/Repository/Repository.cy.js +23 -16
  15. package/cypress/e2e/Schema.cy.js +2 -2
  16. package/package.json +1 -1
  17. package/src/Integration/Browser/Repository/Cookie.js +4 -4
  18. package/src/Integration/Browser/Repository/IndexedDB.js +4 -4
  19. package/src/Integration/Browser/Repository/LocalStorage.js +4 -4
  20. package/src/Integration/Browser/Repository/SecureLocalStorage.js +2 -2
  21. package/src/Integration/Browser/Repository/SecureSessionStorage.js +2 -2
  22. package/src/Integration/Browser/Repository/SessionStorage.js +4 -4
  23. package/src/Integration/ReactNative/Repository/AsyncStorage.js +8 -8
  24. package/src/Integration/ReactNative/Repository/SecureStore.js +4 -4
  25. package/src/Property/Base64.js +21 -11
  26. package/src/Property/Boolean.js +20 -12
  27. package/src/Property/Currency.js +30 -21
  28. package/src/Property/Date.js +23 -14
  29. package/src/Property/DateTime.js +18 -9
  30. package/src/Property/File.js +0 -4
  31. package/src/Property/Float.js +19 -10
  32. package/src/Property/Integer.js +19 -10
  33. package/src/Property/Json.js +22 -13
  34. package/src/Property/Percent.js +2 -2
  35. package/src/Property/PercentInt.js +16 -7
  36. package/src/Property/Property.js +150 -140
  37. package/src/Property/String.js +2 -7
  38. package/src/Property/Time.js +17 -8
  39. package/src/Property/Uuid.js +3 -8
  40. package/src/Property/index.js +2 -0
  41. package/src/Repository/Ajax.js +33 -28
  42. package/src/Repository/LocalFromRemote/Command.js +5 -5
  43. package/src/Repository/LocalFromRemote/CommandRepository.js +1 -1
  44. package/src/Repository/LocalFromRemote/LocalFromRemote.js +18 -17
  45. package/src/Repository/Memory.js +22 -21
  46. package/src/Repository/Null.js +5 -5
  47. package/src/Repository/Offline.js +17 -16
  48. package/src/Repository/OneBuild.js +34 -28
  49. package/src/Repository/OneBuild2.js +16 -10
  50. package/src/Repository/Repository.js +105 -102
  51. package/src/Schema/Schema.js +9 -6
@@ -12,6 +12,133 @@ import _ from 'lodash';
12
12
  */
13
13
  export default class Property extends EventEmitter {
14
14
 
15
+ static defaults = {
16
+
17
+ /**
18
+ * @member {string} name - Could be anything, but OneHat's convention is to use
19
+ * the model name pluralized and underscored, followed by two underscores,
20
+ * followed by the field name singular and underscored (e.g. 'groups_users__id')
21
+ * This convention allows us to have multiple models' data in a single Entity, all flattened
22
+ */
23
+ name: null,
24
+
25
+ /**
26
+ * @member {boolean} allowNull - Is the property required to have a value?
27
+ * Defaults to true.
28
+ */
29
+ allowNull: true,
30
+
31
+ /**
32
+ * @member {function} parse - Custom parse function that overrides
33
+ * Property.parse.
34
+ * Takes one argument:
35
+ * - rawValue {any} - The raw value to parse
36
+ *
37
+ * Note: If you use standard function notation for the parse function,
38
+ * then the Property and Entity (with all other parsed properties and original data)
39
+ * are available inside the function as:
40
+ * - Property: this
41
+ * - Entity: this.getEntity()
42
+ * - Original Data: this.getEntity().getOriginalData()
43
+ *
44
+ * Returns 'parsedValue'
45
+ * @private
46
+ */
47
+ // parse: null,
48
+
49
+ /**
50
+ * @member {(string|string[])} depends - Other properties this property
51
+ * depends upon for its custom "parse" function.
52
+ * @private
53
+ */
54
+ depends: null,
55
+
56
+ /**
57
+ * @member {string} mapping - JS dot-notation path
58
+ * (e.g. "user.username") for how to access the rawValue which will be
59
+ * given to parse(), based on an Entity's _originalData object.
60
+ * @private
61
+ * @readonly
62
+ */
63
+ mapping: null,
64
+
65
+ /**
66
+ * @member {boolean} submitAsString - Whether to submit value as a string, rather than a primitive or complex type
67
+ */
68
+ submitAsString: false,
69
+
70
+ /**
71
+ * @member {boolean} isSortable - Whether this property type is sortable
72
+ */
73
+ isSortable: true,
74
+
75
+ /**
76
+ * @member {boolean} isTempId - Whether this property's ID is temporary
77
+ */
78
+ isTempId: false,
79
+
80
+ // ##################################################################
81
+ // #### These next properties are only for OneBuild repositories ####
82
+ // ##################################################################
83
+
84
+ /**
85
+ * @member {boolean} isVirtual - Whether this property represents a virtual field on server
86
+ */
87
+ isVirtual: false,
88
+
89
+ /**
90
+ * @member {string} title - The human-readable title for this property
91
+ */
92
+ title: null,
93
+
94
+ /**
95
+ * @member {string} tooltip - The human-readable tooltip for this property
96
+ */
97
+ tooltip: null,
98
+
99
+ /**
100
+ * @member {string} fieldGroup - The field group for this property
101
+ */
102
+ fieldGroup: null,
103
+
104
+ /**
105
+ * @member {boolean} isForeignModel - Whether this property belongs to a foreign model
106
+ */
107
+ isForeignModel: false,
108
+
109
+ /**
110
+ * @member {object} filterType - The UI filter type of this property
111
+ */
112
+ filterType: null,
113
+
114
+ /**
115
+ * @member {boolean} isFilteringDisabled - Whether this property is disabled for UI filtering
116
+ */
117
+ isFilteringDisabled: false,
118
+
119
+ /**
120
+ * @member {object} viewerType - The UI viewer type of this property
121
+ */
122
+ viewerType: null,
123
+
124
+ /**
125
+ * @member {object} editorType - The UI editor type of this property
126
+ */
127
+ editorType: null,
128
+
129
+ /**
130
+ * @member {boolean} isEditingDisabled - Whether this property is disabled for UI editing
131
+ */
132
+ isEditingDisabled: false,
133
+
134
+ /**
135
+ * @member {any} defaultValue - Default value for this property if none is supplied
136
+ * @private
137
+ */
138
+ defaultValue: null,
139
+
140
+ };
141
+
15
142
  /**
16
143
  * @constructor
17
144
  * @param {object} config - Object with key/value pairs that define this Property
@@ -19,133 +146,7 @@ export default class Property extends EventEmitter {
19
146
  constructor(config = {}, entity) {
20
147
  super(...arguments);
21
148
 
22
- const defaults = {
23
- /**
24
- * @member {string} name - Could be anything, but OneHat's convention is to use
25
- * the model name pluralized and underscored, followed by two underscores,
26
- * followed by the field name singular and underscored (e.g. 'groups_users__id')
27
- * This convention allows us to have multiple models' data in a single Entity, all flattened
28
- */
29
- name: null,
30
-
31
- /**
32
- * @member {boolean} allowNull - Is the property required to have a value?
33
- * Defaults to true.
34
- */
35
- allowNull: true,
36
-
37
- /**
38
- * @member {function} parse - Custom parse function that overrides
39
- * Property.parse.
40
- * Takes one argument:
41
- * - rawValue {any} - The raw value to parse
42
- *
43
- * Note: If you use standard function notation for the parse function,
44
- * then the Property and Entity (with all other parsed properties and original data)
45
- * are available inside the function as:
46
- * - Property: this
47
- * - Entity: this.getEntity()
48
- * - Original Data: this.getEntity().getOriginalData()
49
- *
50
- * Returns 'parsedValue'
51
- * @private
52
- */
53
- // parse: null,
54
-
55
- /**
56
- * @member {(string|string[])} depends - Other properties this property
57
- * depends upon for its custom "parse" function.
58
- * @private
59
- */
60
- depends: null,
61
-
62
- /**
63
- * @member {string} mapping - JS dot-notation path
64
- * (e.g. "user.username") for how to access the rawValue which will be
65
- * given to parse(), based on an Entity's _originalData object.
66
- * @private
67
- * @readonly
68
- */
69
- mapping: null,
70
-
71
- /**
72
- * @member {any} defaultValue - Default value for this property if none is supplied
73
- * @private
74
- */
75
- defaultValue: null,
76
-
77
- /**
78
- * @member {boolean} submitAsString - Whether to submit value as a string, rather than a primitive or complex type
79
- */
80
- submitAsString: false,
81
-
82
- /**
83
- * @member {boolean} isSortable - Whether this property type is sortable
84
- */
85
- isSortable: true,
86
-
87
- /**
88
- * @member {boolean} isTempId - Whether this property's ID is temporary
89
- */
90
- isTempId: false,
91
-
92
- // ##################################################################
93
- // #### These next properties are only for OneBuild repositories ####
94
- // ##################################################################
95
-
96
- /**
97
- * @member {boolean} isVirtual - Whether this property represents a virtual field on server
98
- */
99
- isVirtual: false,
100
-
101
- /**
102
- * @member {string} title - The human-readable title for this property
103
- */
104
- title: null,
105
-
106
- /**
107
- * @member {string} tooltip - The human-readable tooltip for this property
108
- */
109
- tooltip: null,
110
-
111
- /**
112
- * @member {string} fieldGroup - The field group for this property
113
- */
114
- fieldGroup: null,
115
-
116
- /**
117
- * @member {boolean} isForeignModel - Whether this property belongs to a foreign model
118
- */
119
- isForeignModel: false,
120
-
121
- /**
122
- * @member {object} filterType - The UI filter type of this property
123
- */
124
- filterType: null,
125
-
126
- /**
127
- * @member {boolean} isFilteringDisabled - Whether this property is disabled for UI filtering
128
- */
129
- isFilteringDisabled: false,
130
-
131
- /**
132
- * @member {object} viewerType - The UI viewer type of this property
133
- */
134
- viewerType: null,
135
-
136
- /**
137
- * @member {object} editorType - The UI editor type of this property
138
- */
139
- editorType: null,
140
-
141
- /**
142
- * @member {boolean} isEditingDisabled - Whether this property is disabled for UI editing
143
- */
144
- isEditingDisabled: false,
145
-
146
- };
147
-
148
- _.merge(this, defaults, config);
149
+ _.merge(this, Property.defaults, config);
149
150
  this._originalConfig = config;
150
151
 
151
152
  this.registerEvents([
@@ -186,6 +187,15 @@ export default class Property extends EventEmitter {
186
187
  // / /_/ / __/ /_/ /_/ __/ / (__ )
187
188
  // \____/\___/\__/\__/\___/_/ /____/
188
189
 
190
+ /**
191
+ *
192
+ * @param {object} defaults - Optional defaults to merge with Property.defaults
193
+ * @returns {object} Merged defaults
194
+ */
195
+ static getStaticDefaults(defaults = {}) {
196
+ return _.merge({}, Property.defaults, defaults);
197
+ }
198
+
189
199
 
190
200
  /**
191
201
  * Gets default value. Can be overridden to get dynamic default value.
@@ -206,7 +216,7 @@ export default class Property extends EventEmitter {
206
216
  * Gets "raw" value
207
217
  * @return {any} rawValue
208
218
  */
209
- getRawValue = () => {
219
+ getRawValue() {
210
220
  if (this.isDestroyed) {
211
221
  throw Error('this.getRawValue is no longer valid. Property has been destroyed.');
212
222
  }
@@ -217,7 +227,7 @@ export default class Property extends EventEmitter {
217
227
  * Gets "raw" value in its parsed form
218
228
  * @return {any} rawValue
219
229
  */
220
- getParsedRawValue = () => {
230
+ getParsedRawValue() {
221
231
  if (this.isDestroyed) {
222
232
  throw Error('this.getParsedRawValue is no longer valid. Property has been destroyed.');
223
233
  }
@@ -228,7 +238,7 @@ export default class Property extends EventEmitter {
228
238
  * Gets "parsed" value, without any formatting applied
229
239
  * @return {any} parsedValue
230
240
  */
231
- getParsedValue = () => {
241
+ getParsedValue() {
232
242
  if (this.isDestroyed) {
233
243
  throw Error('this.getParsedValue is no longer valid. Property has been destroyed.');
234
244
  }
@@ -239,7 +249,7 @@ export default class Property extends EventEmitter {
239
249
  * Gets parsed value, formatted for submission to server
240
250
  * @return {any} parsedValue
241
251
  */
242
- getSubmitValue = () => {
252
+ getSubmitValue() {
243
253
  if (this.isDestroyed) {
244
254
  throw Error('this.getSubmitValue is no longer valid. Property has been destroyed.');
245
255
  }
@@ -264,7 +274,7 @@ export default class Property extends EventEmitter {
264
274
  * Gets parsed value, formatted for displaying to user
265
275
  * @return {any} _displayValue
266
276
  */
267
- getDisplayValue = () => {
277
+ getDisplayValue() {
268
278
  if (this.isDestroyed) {
269
279
  throw Error('this.getDisplayValue is no longer valid. Property has been destroyed.');
270
280
  }
@@ -373,7 +383,7 @@ export default class Property extends EventEmitter {
373
383
  * @param {any} rawValue - Value to parse
374
384
  * @return {boolean} isChanged - Whether or not the parsedValue was changed
375
385
  */
376
- setValue = (rawValue) => {
386
+ setValue(rawValue) {
377
387
  if (this.isDestroyed) {
378
388
  throw Error('this.setValue is no longer valid. Property has been destroyed.');
379
389
  }
@@ -408,7 +418,7 @@ export default class Property extends EventEmitter {
408
418
  * @param {any} value - Value to parse
409
419
  * @return {any} value - Parsed value. NOTE: for the Property base class, no parsing actually takes place!
410
420
  */
411
- parse = (value) => {
421
+ parse(value) {
412
422
  if (this.isDestroyed) {
413
423
  throw Error('this.parse is no longer valid. Property has been destroyed.');
414
424
  }
@@ -432,7 +442,7 @@ export default class Property extends EventEmitter {
432
442
  * Sets value of submitAsString
433
443
  * @param {boolean} bool - New value of submitAsString
434
444
  */
435
- setSubmitAsString = (bool) => {
445
+ setSubmitAsString(bool) {
436
446
  if (this.isDestroyed) {
437
447
  throw Error('this.setSubmitAsString is no longer valid. Property has been destroyed.');
438
448
  }
@@ -443,7 +453,7 @@ export default class Property extends EventEmitter {
443
453
  * Gets the Entity object
444
454
  * @return {object} _entity - Entity
445
455
  */
446
- getEntity = () => {
456
+ getEntity() {
447
457
  if (this.isDestroyed) {
448
458
  throw Error('this.getEntity is no longer valid. Property has been destroyed.');
449
459
  }
@@ -454,7 +464,7 @@ export default class Property extends EventEmitter {
454
464
  * Gets the className of this Property type.
455
465
  * @return {string} className
456
466
  */
457
- getClassName = () => {
467
+ getClassName() {
458
468
  if (this.isDestroyed) {
459
469
  throw Error('this.getClassName is no longer valid. Property has been destroyed.');
460
470
  }
@@ -465,7 +475,7 @@ export default class Property extends EventEmitter {
465
475
  * Gets the mapped name of this Property.
466
476
  * @return {string} name
467
477
  */
468
- getMapping = () => {
478
+ getMapping() {
469
479
  if (this.isDestroyed) {
470
480
  throw Error('this.getMapping is no longer valid. Property has been destroyed.');
471
481
  }
@@ -479,7 +489,7 @@ export default class Property extends EventEmitter {
479
489
  * - Removes event listeners
480
490
  * @fires destroy
481
491
  */
482
- destroy = () => {
492
+ destroy() {
483
493
  // parent objects
484
494
  this._entity = null;
485
495
 
@@ -495,7 +505,7 @@ export default class Property extends EventEmitter {
495
505
  this.removeAllListeners();
496
506
  }
497
507
 
498
- toString = () => {
508
+ toString() {
499
509
  if (this.isDestroyed) {
500
510
  throw Error('this.toString is no longer valid. Property has been destroyed.');
501
511
  }
@@ -12,11 +12,6 @@ const TEMP_PREFIX = 'TEMP-';
12
12
  */
13
13
  export default class StringProperty extends Property {
14
14
 
15
- constructor(config = {}) {
16
- super(...arguments);
17
- _.merge(this, config);
18
- }
19
-
20
15
  /**
21
16
  * Parses value to string.
22
17
  * - Strings will pass through unaltered.
@@ -25,14 +20,14 @@ export default class StringProperty extends Property {
25
20
  * @param {any} value
26
21
  * @return {string} parsedValue
27
22
  */
28
- parse = (value) => {
23
+ parse(value) {
29
24
  if (this.isDestroyed) {
30
25
  throw Error('this.parse is no longer valid. Property has been destroyed.');
31
26
  }
32
27
  return Parsers.ParseString(value);
33
28
  }
34
29
 
35
- newId = () => {
30
+ newId() {
36
31
  let id,
37
32
  hasId = false;
38
33
 
@@ -9,16 +9,25 @@ import _ from 'lodash';
9
9
  */
10
10
  export default class TimeProperty extends DateProperty {
11
11
 
12
- constructor(config = {}) {
13
- super(...arguments);
12
+ static defaults = {
13
+ readFormat: 'HH:mm:ss',
14
+ displayFormat: 'HH:mm:ss',
15
+ submitFormat: 'HH:mm:ss',
16
+ };
14
17
 
15
- const defaults = {
16
- readFormat: 'HH:mm:ss',
17
- displayFormat: 'HH:mm:ss',
18
- submitFormat: 'HH:mm:ss',
19
- };
18
+ constructor(config = {}, entity) {
19
+ config = _.merge({}, TimeProperty.defaults, config);
20
+ super(config, entity);
21
+ }
20
22
 
21
- _.merge(this, defaults, config);
23
+ /**
24
+ * Returns the default configuration for this PropertyType, going up the hierarchy.
25
+ * @param {Object} defaults - The default configuration to merge with
26
+ * @returns {Object} The default configuration
27
+ */
28
+ static getStaticDefaults(defaults = {}) {
29
+ const superDefaults = super.getStaticDefaults();
30
+ return _.merge({}, superDefaults, TimeProperty.defaults, defaults);
22
31
  }
23
32
 
24
33
  };
@@ -14,11 +14,6 @@ import _ from 'lodash';
14
14
  * @extends Property
15
15
  */
16
16
  export default class UuidProperty extends Property {
17
-
18
- constructor(config = {}) {
19
- super(...arguments);
20
- _.merge(this, config);
21
- }
22
17
 
23
18
  /**
24
19
  * Gets default value.
@@ -36,21 +31,21 @@ export default class UuidProperty extends Property {
36
31
  /**
37
32
  * Generates a new UUID
38
33
  */
39
- newId = () => {
34
+ newId() {
40
35
  return uuid();
41
36
  }
42
37
 
43
38
  /**
44
39
  * Validates a UUID
45
40
  */
46
- isValid = (value) => {
41
+ isValid(value) {
47
42
  return validate(value);
48
43
  }
49
44
 
50
45
  /**
51
46
  * Determines whether a given UUID is empty (i.e. all zeros)
52
47
  */
53
- isEmpty = (value) => {
48
+ isEmpty(value) {
54
49
  if (_.isNil(value)) {
55
50
  value = this.submitValue;
56
51
  }
@@ -11,6 +11,7 @@ import IntegerProperty from './Integer.js';
11
11
  import JsonProperty, { TagProperty } from './Json.js';
12
12
  import PercentProperty from './Percent.js';
13
13
  import PercentIntProperty from './PercentInt.js';
14
+ import Property from './Property.js';
14
15
  import StringProperty from './String.js';
15
16
  import TimeProperty from './Time.js';
16
17
  import UuidProperty from './Uuid.js';
@@ -27,6 +28,7 @@ const PropertyTypes = {
27
28
  [JsonProperty.type]: JsonProperty,
28
29
  [PercentProperty.type]: PercentProperty,
29
30
  [PercentIntProperty.type]: PercentIntProperty,
31
+ [Property.type]: Property,
30
32
  [StringProperty.type]: StringProperty,
31
33
  [TagProperty.type]: TagProperty,
32
34
  [TimeProperty.type]: TimeProperty,