manyfest 1.0.41 → 1.0.43

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 (42) hide show
  1. package/dist/manyfest.compatible.js +498 -182
  2. package/dist/manyfest.compatible.js.map +1 -0
  3. package/dist/manyfest.compatible.min.js +1 -1
  4. package/dist/manyfest.compatible.min.js.map +1 -1
  5. package/dist/manyfest.js +487 -173
  6. package/dist/manyfest.js.map +1 -0
  7. package/dist/manyfest.min.js +1 -1
  8. package/dist/manyfest.min.js.map +1 -1
  9. package/package.json +3 -3
  10. package/source/Manyfest-CleanWrapCharacters.js +7 -1
  11. package/source/Manyfest-HashTranslation.js +29 -8
  12. package/source/Manyfest-ObjectAddress-CheckAddressExists.js +28 -13
  13. package/source/Manyfest-ObjectAddress-DeleteValue.js +20 -2
  14. package/source/Manyfest-ObjectAddress-GetValue.js +23 -4
  15. package/source/Manyfest-ObjectAddress-Parser.js +39 -32
  16. package/source/Manyfest-ObjectAddress-SetValue.js +14 -2
  17. package/source/Manyfest-ObjectAddressGeneration.js +23 -12
  18. package/source/Manyfest-ParseConditionals.js +3 -3
  19. package/source/Manyfest-SchemaManipulation.js +44 -21
  20. package/source/Manyfest.js +69 -9
  21. package/test/Manyfest_Object_Read_tests.js +13 -0
  22. package/test/Manyfest_Performance_tests.js +48 -0
  23. package/types/Manyfest-CleanWrapCharacters.d.ts +7 -1
  24. package/types/Manyfest-CleanWrapCharacters.d.ts.map +1 -1
  25. package/types/Manyfest-HashTranslation.d.ts +34 -7
  26. package/types/Manyfest-HashTranslation.d.ts.map +1 -1
  27. package/types/Manyfest-ObjectAddress-CheckAddressExists.d.ts +23 -4
  28. package/types/Manyfest-ObjectAddress-CheckAddressExists.d.ts.map +1 -1
  29. package/types/Manyfest-ObjectAddress-DeleteValue.d.ts +25 -6
  30. package/types/Manyfest-ObjectAddress-DeleteValue.d.ts.map +1 -1
  31. package/types/Manyfest-ObjectAddress-GetValue.d.ts +26 -6
  32. package/types/Manyfest-ObjectAddress-GetValue.d.ts.map +1 -1
  33. package/types/Manyfest-ObjectAddress-Parser.d.ts +5 -5
  34. package/types/Manyfest-ObjectAddress-Parser.d.ts.map +1 -1
  35. package/types/Manyfest-ObjectAddress-SetValue.d.ts +18 -5
  36. package/types/Manyfest-ObjectAddress-SetValue.d.ts.map +1 -1
  37. package/types/Manyfest-ObjectAddressGeneration.d.ts +25 -4
  38. package/types/Manyfest-ObjectAddressGeneration.d.ts.map +1 -1
  39. package/types/Manyfest-SchemaManipulation.d.ts +47 -6
  40. package/types/Manyfest-SchemaManipulation.d.ts.map +1 -1
  41. package/types/Manyfest.d.ts +36 -12
  42. package/types/Manyfest.d.ts.map +1 -1
package/dist/manyfest.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
3
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
4
4
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
5
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
6
6
  (function (f) {
@@ -50,11 +50,53 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
50
50
  return r;
51
51
  }()({
52
52
  1: [function (require, module, exports) {
53
+ module.exports = {
54
+ "name": "fable-serviceproviderbase",
55
+ "version": "3.0.15",
56
+ "description": "Simple base classes for fable services.",
57
+ "main": "source/Fable-ServiceProviderBase.js",
58
+ "scripts": {
59
+ "start": "node source/Fable-ServiceProviderBase.js",
60
+ "test": "npx mocha -u tdd -R spec",
61
+ "tests": "npx mocha -u tdd --exit -R spec --grep",
62
+ "coverage": "npx nyc --reporter=lcov --reporter=text-lcov npx mocha -- -u tdd -R spec",
63
+ "build": "npx quack build"
64
+ },
65
+ "mocha": {
66
+ "diff": true,
67
+ "extension": ["js"],
68
+ "package": "./package.json",
69
+ "reporter": "spec",
70
+ "slow": "75",
71
+ "timeout": "5000",
72
+ "ui": "tdd",
73
+ "watch-files": ["source/**/*.js", "test/**/*.js"],
74
+ "watch-ignore": ["lib/vendor"]
75
+ },
76
+ "repository": {
77
+ "type": "git",
78
+ "url": "https://github.com/stevenvelozo/fable-serviceproviderbase.git"
79
+ },
80
+ "keywords": ["entity", "behavior"],
81
+ "author": "Steven Velozo <steven@velozo.com> (http://velozo.com/)",
82
+ "license": "MIT",
83
+ "bugs": {
84
+ "url": "https://github.com/stevenvelozo/fable-serviceproviderbase/issues"
85
+ },
86
+ "homepage": "https://github.com/stevenvelozo/fable-serviceproviderbase",
87
+ "devDependencies": {
88
+ "fable": "^3.0.143",
89
+ "quackage": "^1.0.33"
90
+ }
91
+ };
92
+ }, {}],
93
+ 2: [function (require, module, exports) {
53
94
  /**
54
95
  * Fable Service Base
55
96
  * @author <steven@velozo.com>
56
97
  */
57
98
 
99
+ const libPackage = require('../package.json');
58
100
  class FableServiceProviderBase {
59
101
  // The constructor can be used in two ways:
60
102
  // 1) With a fable, options object and service hash (the options object and service hash are optional)
@@ -67,6 +109,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
67
109
  this.fable = false;
68
110
  }
69
111
 
112
+ // Initialize the services map if it wasn't passed in
113
+ /** @type {Object} */
114
+ this._PackageFableServiceProvider = libPackage;
115
+
70
116
  // initialize options and UUID based on whether the fable was passed in or not.
71
117
  if (this.fable) {
72
118
  this.UUID = pFable.getUUID();
@@ -110,8 +156,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
110
156
 
111
157
  // This is left here in case we want to go back to having different code/base class for "core" services
112
158
  module.exports.CoreServiceProviderBase = FableServiceProviderBase;
113
- }, {}],
114
- 2: [function (require, module, exports) {
159
+ }, {
160
+ "../package.json": 1
161
+ }],
162
+ 3: [function (require, module, exports) {
115
163
  // When a boxed property is passed in, it should have quotes of some
116
164
  // kind around it.
117
165
  //
@@ -127,6 +175,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
127
175
  //
128
176
  // TODO: Should template literals be processed? If so what state do they have access to? That should happen here if so.
129
177
  // TODO: Make a simple class include library with these
178
+ /**
179
+ * @param {string} pCharacter - The character to remove from the start and end of the string
180
+ * @param {string} pString - The string to clean
181
+ *
182
+ * @return {string} The cleaned string
183
+ */
130
184
  const cleanWrapCharacters = (pCharacter, pString) => {
131
185
  if (pString.startsWith(pCharacter) && pString.endsWith(pCharacter)) {
132
186
  return pString.substring(1, pString.length - 1);
@@ -136,7 +190,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
136
190
  };
137
191
  module.exports = cleanWrapCharacters;
138
192
  }, {}],
139
- 3: [function (require, module, exports) {
193
+ 4: [function (require, module, exports) {
140
194
  /**
141
195
  * @author <steven@velozo.com>
142
196
  */
@@ -158,15 +212,27 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
158
212
  * @class ManyfestHashTranslation
159
213
  */
160
214
  class ManyfestHashTranslation {
215
+ /**
216
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
217
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
218
+ */
161
219
  constructor(pInfoLog, pErrorLog) {
162
220
  // Wire in logging
163
221
  this.logInfo = typeof pInfoLog === 'function' ? pInfoLog : libSimpleLog;
164
222
  this.logError = typeof pErrorLog === 'function' ? pErrorLog : libSimpleLog;
165
223
  this.translationTable = {};
166
224
  }
225
+
226
+ /**
227
+ * @return {number} The number of translations in the table
228
+ */
167
229
  translationCount() {
168
230
  return Object.keys(this.translationTable).length;
169
231
  }
232
+
233
+ /**
234
+ * @param {object} pTranslation - An object containing source:destination hash pairs to add to the translation table
235
+ */
170
236
  addTranslation(pTranslation) {
171
237
  // This adds a translation in the form of:
172
238
  // { "SourceHash": "DestinationHash", "SecondSourceHash":"SecondDestinationHash" }
@@ -183,15 +249,23 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
183
249
  }
184
250
  });
185
251
  }
252
+
253
+ /**
254
+ * @param {string} pTranslationHash - The source hash to remove from the translation table
255
+ */
186
256
  removeTranslationHash(pTranslationHash) {
187
- if (pTranslationHash in this.translationTable) {
188
- delete this.translationTable[pTranslationHash];
189
- }
257
+ delete this.translationTable[pTranslationHash];
190
258
  }
191
259
 
192
- // This removes translations.
193
- // If passed a string, just removes the single one.
194
- // If passed an object, it does all the source keys.
260
+ /**
261
+ * This removes translations.
262
+ * If passed a string, just removes the single one.
263
+ * If passed an object, it does all the source keys.
264
+ *
265
+ * @param {string|object} pTranslation - Either a source hash string to remove, or an object containing source:destination hash pairs to remove
266
+ *
267
+ * @return {boolean} True if the removal was successful, false otherwise
268
+ */
195
269
  removeTranslation(pTranslation) {
196
270
  if (typeof pTranslation == 'string') {
197
271
  this.removeTranslationHash(pTranslation);
@@ -210,6 +284,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
210
284
  clearTranslations() {
211
285
  this.translationTable = {};
212
286
  }
287
+
288
+ /**
289
+ * @param {string} pTranslation - The source hash to translate
290
+ *
291
+ * @return {string} The translated hash, or the original if no translation exists
292
+ */
213
293
  translate(pTranslation) {
214
294
  if (pTranslation in this.translationTable) {
215
295
  return this.translationTable[pTranslation];
@@ -220,9 +300,9 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
220
300
  }
221
301
  module.exports = ManyfestHashTranslation;
222
302
  }, {
223
- "./Manyfest-LogToConsole.js": 4
303
+ "./Manyfest-LogToConsole.js": 5
224
304
  }],
225
- 4: [function (require, module, exports) {
305
+ 5: [function (require, module, exports) {
226
306
  /**
227
307
  * @author <steven@velozo.com>
228
308
  */
@@ -238,13 +318,14 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
238
318
  };
239
319
  module.exports = logToConsole;
240
320
  }, {}],
241
- 5: [function (require, module, exports) {
321
+ 6: [function (require, module, exports) {
242
322
  /**
243
323
  * @author <steven@velozo.com>
244
324
  */
245
325
  const libSimpleLog = require('./Manyfest-LogToConsole.js');
246
326
  // This is for resolving functions mid-address
247
327
  const libGetObjectValue = require('./Manyfest-ObjectAddress-GetValue.js');
328
+ const fCleanWrapCharacters = require('./Manyfest-CleanWrapCharacters.js');
248
329
 
249
330
  // TODO: Just until this is a fable service.
250
331
  let _MockFable = {
@@ -270,16 +351,32 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
270
351
  * @class ManyfestObjectAddressResolverCheckAddressExists
271
352
  */
272
353
  class ManyfestObjectAddressResolverCheckAddressExists {
273
- constructor() {
274
- this.getObjectValueClass = new libGetObjectValue(libSimpleLog, libSimpleLog);
354
+ /**
355
+ * @param {function} [pInfoLog] - (optional) Function to use for info logging
356
+ * @param {function} [pErrorLog] - (optional) Function to use for error logging
357
+ */
358
+ constructor(pInfoLog, pErrorLog) {
359
+ // Wire in logging
360
+ this.logInfo = typeof pInfoLog == 'function' ? pInfoLog : libSimpleLog;
361
+ this.logError = typeof pErrorLog == 'function' ? pErrorLog : libSimpleLog;
362
+ this.getObjectValueClass = new libGetObjectValue(this.logInfo, this.logError);
363
+ this.cleanWrapCharacters = fCleanWrapCharacters;
275
364
  }
276
365
 
277
- // Check if an address exists.
278
- //
279
- // This is necessary because the getValueAtAddress function is ambiguous on
280
- // whether the element/property is actually there or not (it returns
281
- // undefined whether the property exists or not). This function checks for
282
- // existance and returns true or false dependent.
366
+ /**
367
+ * Check if an address exists.
368
+ *
369
+ * This is necessary because the getValueAtAddress function is ambiguous on
370
+ * whether the element/property is actually there or not (it returns
371
+ * undefined whether the property exists or not). This function checks for
372
+ * existance and returns true or false dependent.
373
+ *
374
+ * @param {object} pObject - The object to check within
375
+ * @param {string} pAddress - The address to check for
376
+ * @param {object} [pRootObject] - (optional) The root object for function resolution context
377
+ *
378
+ * @return {boolean} - True if the address exists, false if it does not
379
+ */
283
380
  checkAddressExists(pObject, pAddress, pRootObject) {
284
381
  // TODO: Should these throw an error?
285
382
  // Make sure pObject is an object
@@ -412,7 +509,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
412
509
  let tmpFunctionAddress = tmpSubObjectName.substring(0, tmpFunctionStartIndex).trim();
413
510
  //tmpParentAddress = `${tmpParentAddress}${(tmpParentAddress.length > 0) ? '.' : ''}${tmpSubObjectName}`;
414
511
 
415
- if (!typeof pObject[tmpFunctionAddress] == 'function') {
512
+ if (typeof pObject[tmpFunctionAddress] !== 'function') {
416
513
  // The address suggests it is a function, but it is not.
417
514
  return false;
418
515
  }
@@ -427,12 +524,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
427
524
  return this.checkAddressExists(pObject[tmpFunctionAddress].apply(pObject), tmpNewAddress, tmpRootObject);
428
525
  } catch (pError) {
429
526
  // The function call failed, so the address doesn't exist
430
- libSimpleLog.log("Error calling function ".concat(tmpFunctionAddress, " (address [").concat(pAddress, "]): ").concat(pError.message));
527
+ libSimpleLog("Error calling function ".concat(tmpFunctionAddress, " (address [").concat(pAddress, "]): ").concat(pError.message));
431
528
  return false;
432
529
  }
433
530
  } else {
434
531
  // The function doesn't exist, so the address doesn't exist
435
- libSimpleLog.log("Function ".concat(tmpFunctionAddress, " does not exist (address [").concat(pAddress, "])"));
532
+ libSimpleLog("Function ".concat(tmpFunctionAddress, " does not exist (address [").concat(pAddress, "])"));
436
533
  return false;
437
534
  }
438
535
  } else {
@@ -452,12 +549,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
452
549
  return this.checkAddressExists(pObject[tmpFunctionAddress].apply(pObject, tmpArgumentValues), tmpNewAddress, tmpRootObject);
453
550
  } catch (pError) {
454
551
  // The function call failed, so the address doesn't exist
455
- libSimpleLog.log("Error calling function ".concat(tmpFunctionAddress, " (address [").concat(pAddress, "]): ").concat(pError.message));
552
+ libSimpleLog("Error calling function ".concat(tmpFunctionAddress, " (address [").concat(pAddress, "]): ").concat(pError.message));
456
553
  return false;
457
554
  }
458
555
  } else {
459
556
  // The function doesn't exist, so the address doesn't exist
460
- libSimpleLog.log("Function ".concat(tmpFunctionAddress, " does not exist (address [").concat(pAddress, "])"));
557
+ libSimpleLog("Function ".concat(tmpFunctionAddress, " does not exist (address [").concat(pAddress, "])"));
461
558
  return false;
462
559
  }
463
560
  }
@@ -532,14 +629,14 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
532
629
  }
533
630
  }
534
631
  }
535
- ;
536
632
  module.exports = ManyfestObjectAddressResolverCheckAddressExists;
537
633
  }, {
538
- "./Manyfest-LogToConsole.js": 4,
539
- "./Manyfest-ObjectAddress-GetValue.js": 7,
540
- "./Manyfest-ObjectAddress-Parser.js": 8
634
+ "./Manyfest-CleanWrapCharacters.js": 3,
635
+ "./Manyfest-LogToConsole.js": 5,
636
+ "./Manyfest-ObjectAddress-GetValue.js": 8,
637
+ "./Manyfest-ObjectAddress-Parser.js": 9
541
638
  }],
542
- 6: [function (require, module, exports) {
639
+ 7: [function (require, module, exports) {
543
640
  /**
544
641
  * @author <steven@velozo.com>
545
642
  */
@@ -568,6 +665,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
568
665
  * @class ManyfestObjectAddressResolverDeleteValue
569
666
  */
570
667
  class ManyfestObjectAddressResolverDeleteValue {
668
+ /**
669
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
670
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
671
+ */
571
672
  constructor(pInfoLog, pErrorLog) {
572
673
  // Wire in logging
573
674
  this.logInfo = typeof pInfoLog == 'function' ? pInfoLog : libSimpleLog;
@@ -576,11 +677,25 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
576
677
  }
577
678
 
578
679
  // TODO: Dry me
680
+ /**
681
+ * @param {string} pAddress - The address being evaluated
682
+ * @param {object} pRecord - The record being evaluated
683
+ *
684
+ * @return {boolean} True if the record passes the filters, false if it does not
685
+ */
579
686
  checkRecordFilters(pAddress, pRecord) {
580
687
  return fParseConditionals(this, pAddress, pRecord);
581
688
  }
582
689
 
583
- // Delete the value of an element at an address
690
+ /**
691
+ * Delete the value of an element at an address
692
+ *
693
+ * @param {object} pObject - The object to delete the value from
694
+ * @param {string} pAddress - The address to delete the value at
695
+ * @param {string} [pParentAddress] - (optional) The parent address for recursion
696
+ *
697
+ * @return {boolean|object|undefined} - True if the value was deleted, false if it could not be deleted, undefined on error
698
+ */
584
699
  deleteValueAtAddress(pObject, pAddress, pParentAddress) {
585
700
  // Make sure pObject (the object we are meant to be recursing) is an object (which could be an array or object)
586
701
  if (typeof pObject != 'object') return undefined;
@@ -844,11 +959,11 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
844
959
  ;
845
960
  module.exports = ManyfestObjectAddressResolverDeleteValue;
846
961
  }, {
847
- "../source/Manyfest-ParseConditionals.js": 11,
848
- "./Manyfest-CleanWrapCharacters.js": 2,
849
- "./Manyfest-LogToConsole.js": 4
962
+ "../source/Manyfest-ParseConditionals.js": 12,
963
+ "./Manyfest-CleanWrapCharacters.js": 3,
964
+ "./Manyfest-LogToConsole.js": 5
850
965
  }],
851
- 7: [function (require, module, exports) {
966
+ 8: [function (require, module, exports) {
852
967
  /**
853
968
  * @author <steven@velozo.com>
854
969
  */
@@ -880,22 +995,49 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
880
995
  * @class ManyfestObjectAddressResolverGetValue
881
996
  */
882
997
  class ManyfestObjectAddressResolverGetValue {
998
+ /**
999
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
1000
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
1001
+ */
883
1002
  constructor(pInfoLog, pErrorLog) {
884
1003
  // Wire in logging
885
1004
  this.logInfo = typeof pInfoLog == 'function' ? pInfoLog : libSimpleLog;
886
1005
  this.logError = typeof pErrorLog == 'function' ? pErrorLog : libSimpleLog;
887
1006
  this.cleanWrapCharacters = fCleanWrapCharacters;
888
1007
  }
1008
+
1009
+ /**
1010
+ * @param {string} pAddress - The address of the record to check
1011
+ * @param {object} pRecord - The record to check against the filters
1012
+ *
1013
+ * @return {boolean} - True if the record passes the filters, false otherwise
1014
+ */
889
1015
  checkRecordFilters(pAddress, pRecord) {
890
1016
  return fParseConditionals(this, pAddress, pRecord);
891
1017
  }
892
1018
 
893
- // Get the value of an element at an address
1019
+ /**
1020
+ * Get the value of an element at an address
1021
+ *
1022
+ * @param {object} pObject - The object to resolve the address against
1023
+ * @param {string} pAddress - The address to resolve
1024
+ * @param {string} [pParentAddress] - (optional) The parent address for back-navigation
1025
+ * @param {object} [pRootObject] - (optional) The root object for function argument resolution
1026
+ *
1027
+ * @return {any} The value at the address, or undefined if not found
1028
+ */
894
1029
  getValueAtAddress(pObject, pAddress, pParentAddress, pRootObject) {
895
1030
  // Make sure pObject (the object we are meant to be recursing) is an object (which could be an array or object)
896
- if (typeof pObject != 'object') return undefined;
1031
+ if (typeof pObject != 'object') {
1032
+ return undefined;
1033
+ }
1034
+ if (pObject === null) {
1035
+ return undefined;
1036
+ }
897
1037
  // Make sure pAddress (the address we are resolving) is a string
898
- if (typeof pAddress != 'string') return undefined;
1038
+ if (typeof pAddress != 'string') {
1039
+ return undefined;
1040
+ }
899
1041
  // Stash the parent address for later resolution
900
1042
  let tmpParentAddress = "";
901
1043
  if (typeof pParentAddress == 'string') {
@@ -971,7 +1113,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
971
1113
  // 2) The end bracket is after the start bracket
972
1114
  && _MockFable.DataFormat.stringCountEnclosures(pAddress) > 0) {
973
1115
  let tmpFunctionAddress = pAddress.substring(0, tmpFunctionStartIndex).trim();
974
- if (!typeof pObject[tmpFunctionAddress] == 'function') {
1116
+ if (typeof pObject[tmpFunctionAddress] !== 'function') {
975
1117
  // The address suggests it is a function, but it is not.
976
1118
  return false;
977
1119
  }
@@ -1113,7 +1255,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1113
1255
  if (typeof pObject[pAddress] != null) {
1114
1256
  return pObject[pAddress];
1115
1257
  } else {
1116
- return undefined;
1258
+ return null;
1117
1259
  }
1118
1260
  }
1119
1261
  } else {
@@ -1148,7 +1290,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1148
1290
  && _MockFable.DataFormat.stringCountEnclosures(tmpSubObjectName) > 0) {
1149
1291
  let tmpFunctionAddress = tmpSubObjectName.substring(0, tmpFunctionStartIndex).trim();
1150
1292
  tmpParentAddress = "".concat(tmpParentAddress).concat(tmpParentAddress.length > 0 ? '.' : '').concat(tmpSubObjectName);
1151
- if (!typeof pObject[tmpFunctionAddress] == 'function') {
1293
+ if (typeof pObject[tmpFunctionAddress] !== 'function') {
1152
1294
  // The address suggests it is a function, but it is not.
1153
1295
  return false;
1154
1296
  }
@@ -1341,12 +1483,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1341
1483
  ;
1342
1484
  module.exports = ManyfestObjectAddressResolverGetValue;
1343
1485
  }, {
1344
- "../source/Manyfest-ParseConditionals.js": 11,
1345
- "./Manyfest-CleanWrapCharacters.js": 2,
1346
- "./Manyfest-LogToConsole.js": 4,
1347
- "./Manyfest-ObjectAddress-Parser.js": 8
1486
+ "../source/Manyfest-ParseConditionals.js": 12,
1487
+ "./Manyfest-CleanWrapCharacters.js": 3,
1488
+ "./Manyfest-LogToConsole.js": 5,
1489
+ "./Manyfest-ObjectAddress-Parser.js": 9
1348
1490
  }],
1349
- 8: [function (require, module, exports) {
1491
+ 9: [function (require, module, exports) {
1350
1492
  // TODO: This is an inelegant solution to delay the rewrite of Manyfest.
1351
1493
 
1352
1494
  // Fable 3.0 has a service for data formatting that deals well with nested enclosures.
@@ -1357,29 +1499,32 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1357
1499
  // Until we shift Manyfest to be a fable service, these three functions were pulled out of
1358
1500
  // fable to aid in parsing functions with nested enclosures.
1359
1501
 
1502
+ const DEFAULT_START_SYMBOL_MAP = {
1503
+ '{': 0,
1504
+ '[': 1,
1505
+ '(': 2
1506
+ };
1507
+ const DEFAULT_END_SYMBOL_MAP = {
1508
+ '}': 0,
1509
+ ']': 1,
1510
+ ')': 2
1511
+ };
1360
1512
  module.exports = {
1361
1513
  /**
1362
1514
  * Count the number of segments in a string, respecting enclosures
1363
- *
1364
- * @param {string} pString
1365
- * @param {string} pSeparator
1366
- * @param {object} pEnclosureStartSymbolMap
1367
- * @param {object} pEnclosureEndSymbolMap
1368
- * @returns the count of segments in the string as a number
1515
+ *
1516
+ * @param {string} pString
1517
+ * @param {string} [pSeparator]
1518
+ * @param {Record<string, number>} [pEnclosureStartSymbolMap]
1519
+ * @param {Record<string, number>} [pEnclosureEndSymbolMap]
1520
+ *
1521
+ * @return {number} - The number of segments in the string
1369
1522
  */
1370
1523
  stringCountSegments: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) => {
1371
1524
  let tmpString = typeof pString == 'string' ? pString : '';
1372
1525
  let tmpSeparator = typeof pSeparator == 'string' ? pSeparator : '.';
1373
- let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStart : {
1374
- '{': 0,
1375
- '[': 1,
1376
- '(': 2
1377
- };
1378
- let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEnd : {
1379
- '}': 0,
1380
- ']': 1,
1381
- ')': 2
1382
- };
1526
+ let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStartSymbolMap : DEFAULT_START_SYMBOL_MAP;
1527
+ let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEndSymbolMap : DEFAULT_END_SYMBOL_MAP;
1383
1528
  if (pString.length < 1) {
1384
1529
  return 0;
1385
1530
  }
@@ -1410,28 +1555,21 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1410
1555
  },
1411
1556
  /**
1412
1557
  * Get the first segment in a string, respecting enclosures
1413
- *
1414
- * @param {string} pString
1415
- * @param {string} pSeparator
1416
- * @param {object} pEnclosureStartSymbolMap
1417
- * @param {object} pEnclosureEndSymbolMap
1418
- * @returns the first segment in the string as a string
1558
+ *
1559
+ * @param {string} pString
1560
+ * @param {string} [pSeparator]
1561
+ * @param {Record<string, number>} [pEnclosureStartSymbolMap]
1562
+ * @param {Record<string, number>} [pEnclosureEndSymbolMap]
1563
+ *
1564
+ * @return {string} - the first segment in the string as a string
1419
1565
  */
1420
1566
  stringGetFirstSegment: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) => {
1421
1567
  let tmpString = typeof pString == 'string' ? pString : '';
1422
1568
  let tmpSeparator = typeof pSeparator == 'string' ? pSeparator : '.';
1423
- let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStart : {
1424
- '{': 0,
1425
- '[': 1,
1426
- '(': 2
1427
- };
1428
- let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEnd : {
1429
- '}': 0,
1430
- ']': 1,
1431
- ')': 2
1432
- };
1569
+ let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStartSymbolMap : DEFAULT_START_SYMBOL_MAP;
1570
+ let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEndSymbolMap : DEFAULT_END_SYMBOL_MAP;
1433
1571
  if (pString.length < 1) {
1434
- return 0;
1572
+ return '';
1435
1573
  }
1436
1574
  let tmpEnclosureStack = [];
1437
1575
  for (let i = 0; i < tmpString.length; i++) {
@@ -1459,26 +1597,19 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1459
1597
  },
1460
1598
  /**
1461
1599
  * Get all segments in a string, respecting enclosures
1462
- *
1463
- * @param {string} pString
1464
- * @param {string} pSeparator
1465
- * @param {object} pEnclosureStartSymbolMap
1466
- * @param {object} pEnclosureEndSymbolMap
1467
- * @returns the first segment in the string as a string
1600
+ *
1601
+ * @param {string} pString
1602
+ * @param {string} [pSeparator]
1603
+ * @param {Record<string, number>} [pEnclosureStartSymbolMap]
1604
+ * @param {Record<string, number>} [pEnclosureEndSymbolMap]
1605
+ *
1606
+ * @return {Array<string>} - the segments in the string as an array of strings
1468
1607
  */
1469
1608
  stringGetSegments: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) => {
1470
1609
  let tmpString = typeof pString == 'string' ? pString : '';
1471
1610
  let tmpSeparator = typeof pSeparator == 'string' ? pSeparator : '.';
1472
- let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStart : {
1473
- '{': 0,
1474
- '[': 1,
1475
- '(': 2
1476
- };
1477
- let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEnd : {
1478
- '}': 0,
1479
- ']': 1,
1480
- ')': 2
1481
- };
1611
+ let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStartSymbolMap : DEFAULT_START_SYMBOL_MAP;
1612
+ let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEndSymbolMap : DEFAULT_END_SYMBOL_MAP;
1482
1613
  let tmpCurrentSegmentStart = 0;
1483
1614
  let tmpSegmentList = [];
1484
1615
  if (pString.length < 1) {
@@ -1518,8 +1649,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1518
1649
  * If no start or end characters are specified, it will default to parentheses. If the string is not a string, it will return 0.
1519
1650
  *
1520
1651
  * @param {string} pString
1521
- * @param {string} pEnclosureStart
1522
- * @param {string} pEnclosureEnd
1652
+ * @param {string} [pEnclosureStart]
1653
+ * @param {string} [pEnclosureEnd]
1523
1654
  * @returns the count of full in the string
1524
1655
  */
1525
1656
  stringCountEnclosures: (pString, pEnclosureStart, pEnclosureEnd) => {
@@ -1548,9 +1679,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1548
1679
  *
1549
1680
  * @param {string} pString
1550
1681
  * @param {number} pEnclosureIndexToGet
1551
- * @param {string} pEnclosureStart
1552
- * @param {string}} pEnclosureEnd
1553
- * @returns {string}
1682
+ * @param {string} [pEnclosureStart]
1683
+ * @param {string} [pEnclosureEnd]
1684
+ *
1685
+ * @return {string} - The value of the enclosure at the specified index
1554
1686
  */
1555
1687
  stringGetEnclosureValueByIndex: (pString, pEnclosureIndexToGet, pEnclosureStart, pEnclosureEnd) => {
1556
1688
  let tmpString = typeof pString == 'string' ? pString : '';
@@ -1600,7 +1732,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1600
1732
  }
1601
1733
  };
1602
1734
  }, {}],
1603
- 9: [function (require, module, exports) {
1735
+ 10: [function (require, module, exports) {
1604
1736
  /**
1605
1737
  * @author <steven@velozo.com>
1606
1738
  */
@@ -1626,6 +1758,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1626
1758
  * @class ManyfestObjectAddressSetValue
1627
1759
  */
1628
1760
  class ManyfestObjectAddressSetValue {
1761
+ /**
1762
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
1763
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
1764
+ */
1629
1765
  constructor(pInfoLog, pErrorLog) {
1630
1766
  // Wire in logging
1631
1767
  this.logInfo = typeof pInfoLog == 'function' ? pInfoLog : libSimpleLog;
@@ -1633,7 +1769,15 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1633
1769
  this.cleanWrapCharacters = fCleanWrapCharacters;
1634
1770
  }
1635
1771
 
1636
- // Set the value of an element at an address
1772
+ /**
1773
+ * Set the value of an element at an address
1774
+ *
1775
+ * @param {object} pObject - The object to set the value in
1776
+ * @param {string} pAddress - The address to set the value at
1777
+ * @param {any} pValue - The value to set at the address
1778
+ *
1779
+ * @return {boolean} True if the value was set, false otherwise
1780
+ */
1637
1781
  setValueAtAddress(pObject, pAddress, pValue) {
1638
1782
  // Make sure pObject is an object
1639
1783
  if (typeof pObject != 'object') return false;
@@ -1661,17 +1805,25 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1661
1805
  // The "Name" of the Object contained too the left of the bracket
1662
1806
  let tmpBoxedPropertyName = pAddress.substring(0, tmpBracketStartIndex).trim();
1663
1807
 
1808
+ // The "Reference" to the property within it, either an array element or object property
1809
+ let tmpBoxedPropertyReference = pAddress.substring(tmpBracketStartIndex + 1, tmpBracketStopIndex).trim();
1810
+ // Attempt to parse the reference as a number, which will be used as an array element
1811
+ let tmpBoxedPropertyNumber = parseInt(tmpBoxedPropertyReference, 10);
1812
+ let tmpIndexIsNumeric = !isNaN(tmpBoxedPropertyNumber);
1813
+ if (pObject[tmpBoxedPropertyName] == null) {
1814
+ if (tmpIndexIsNumeric) {
1815
+ pObject[tmpBoxedPropertyName] = [];
1816
+ } else {
1817
+ pObject[tmpBoxedPropertyName] = {};
1818
+ }
1819
+ }
1820
+
1664
1821
  // If the subproperty doesn't test as a proper Object, none of the rest of this is possible.
1665
1822
  // This is a rare case where Arrays testing as Objects is useful
1666
1823
  if (typeof pObject[tmpBoxedPropertyName] !== 'object') {
1667
1824
  return false;
1668
1825
  }
1669
1826
 
1670
- // The "Reference" to the property within it, either an array element or object property
1671
- let tmpBoxedPropertyReference = pAddress.substring(tmpBracketStartIndex + 1, tmpBracketStopIndex).trim();
1672
- // Attempt to parse the reference as a number, which will be used as an array element
1673
- let tmpBoxedPropertyNumber = parseInt(tmpBoxedPropertyReference, 10);
1674
-
1675
1827
  // Guard: If the referrant is a number and the boxed property is not an array, or vice versa, return undefined.
1676
1828
  // This seems confusing to me at first read, so explaination:
1677
1829
  // Is the Boxed Object an Array? TRUE
@@ -1689,11 +1841,20 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1689
1841
  tmpBoxedPropertyReference = this.cleanWrapCharacters('"', tmpBoxedPropertyReference);
1690
1842
  tmpBoxedPropertyReference = this.cleanWrapCharacters('`', tmpBoxedPropertyReference);
1691
1843
  tmpBoxedPropertyReference = this.cleanWrapCharacters("'", tmpBoxedPropertyReference);
1844
+ if (!(tmpBoxedPropertyReference in pObject[tmpBoxedPropertyName])) {
1845
+ // If the subobject doesn't exist, create it
1846
+ pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference] = {};
1847
+ }
1692
1848
 
1693
1849
  // Return the value in the property
1850
+ //TODO: For cases where we have chained [][] properties, this needs to recurse somehow
1694
1851
  pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference] = pValue;
1695
1852
  return true;
1696
1853
  } else {
1854
+ while (pObject[tmpBoxedPropertyName].length < tmpBoxedPropertyNumber + 1) {
1855
+ // If the subobject doesn't exist, create it
1856
+ pObject[tmpBoxedPropertyName].push({});
1857
+ }
1697
1858
  pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber] = pValue;
1698
1859
  return true;
1699
1860
  }
@@ -1727,6 +1888,16 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1727
1888
  let tmpBoxedPropertyName = tmpSubObjectName.substring(0, tmpBracketStartIndex).trim();
1728
1889
  let tmpBoxedPropertyReference = tmpSubObjectName.substring(tmpBracketStartIndex + 1, tmpBracketStopIndex).trim();
1729
1890
  let tmpBoxedPropertyNumber = parseInt(tmpBoxedPropertyReference, 10);
1891
+ let tmpIndexIsNumeric = !isNaN(tmpBoxedPropertyNumber);
1892
+
1893
+ //if (typeof(pObject[tmpBoxedPropertyName]) !== 'object')
1894
+ if (pObject[tmpBoxedPropertyName] == null) {
1895
+ if (tmpIndexIsNumeric) {
1896
+ pObject[tmpBoxedPropertyName] = [];
1897
+ } else {
1898
+ pObject[tmpBoxedPropertyName] = {};
1899
+ }
1900
+ }
1730
1901
 
1731
1902
  // Guard: If the referrant is a number and the boxed property is not an array, or vice versa, return undefined.
1732
1903
  // This seems confusing to me at first read, so explaination:
@@ -1742,7 +1913,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1742
1913
  // BUT
1743
1914
  // StudentData.Sections.Algebra.Students is an array, so the ["JaneDoe"].Grade is not possible to access
1744
1915
  // TODO: Should this be an error or something? Should we keep a log of failures like this?
1745
- if (Array.isArray(pObject[tmpBoxedPropertyName]) == isNaN(tmpBoxedPropertyNumber)) {
1916
+ if (Array.isArray(pObject[tmpBoxedPropertyName]) != tmpIndexIsNumeric) {
1746
1917
  return false;
1747
1918
  }
1748
1919
 
@@ -1754,10 +1925,19 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1754
1925
  tmpBoxedPropertyReference = this.cleanWrapCharacters('"', tmpBoxedPropertyReference);
1755
1926
  tmpBoxedPropertyReference = this.cleanWrapCharacters('`', tmpBoxedPropertyReference);
1756
1927
  tmpBoxedPropertyReference = this.cleanWrapCharacters("'", tmpBoxedPropertyReference);
1928
+ if (!(tmpBoxedPropertyReference in pObject[tmpBoxedPropertyName])) {
1929
+ // If the subobject doesn't exist, create it
1930
+ pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference] = {};
1931
+ }
1757
1932
 
1758
1933
  // Recurse directly into the subobject
1759
1934
  return this.setValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference], tmpNewAddress, pValue);
1760
1935
  } else {
1936
+ while (pObject[tmpBoxedPropertyName].length < tmpBoxedPropertyNumber + 1) {
1937
+ // If the subobject doesn't exist, create it
1938
+ pObject[tmpBoxedPropertyName].push({});
1939
+ }
1940
+
1761
1941
  // We parsed a valid number out of the boxed property name, so recurse into the array
1762
1942
  return this.setValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber], tmpNewAddress, pValue);
1763
1943
  }
@@ -1784,10 +1964,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1784
1964
  ;
1785
1965
  module.exports = ManyfestObjectAddressSetValue;
1786
1966
  }, {
1787
- "./Manyfest-CleanWrapCharacters.js": 2,
1788
- "./Manyfest-LogToConsole.js": 4
1967
+ "./Manyfest-CleanWrapCharacters.js": 3,
1968
+ "./Manyfest-LogToConsole.js": 5
1789
1969
  }],
1790
- 10: [function (require, module, exports) {
1970
+ 11: [function (require, module, exports) {
1791
1971
  /**
1792
1972
  * @author <steven@velozo.com>
1793
1973
  */
@@ -1816,21 +1996,33 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1816
1996
  * @class ManyfestObjectAddressGeneration
1817
1997
  */
1818
1998
  class ManyfestObjectAddressGeneration {
1999
+ /**
2000
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
2001
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
2002
+ */
1819
2003
  constructor(pInfoLog, pErrorLog) {
1820
2004
  // Wire in logging
1821
2005
  this.logInfo = typeof pInfoLog == 'function' ? pInfoLog : libSimpleLog;
1822
2006
  this.logError = typeof pErrorLog == 'function' ? pErrorLog : libSimpleLog;
1823
2007
  }
1824
2008
 
1825
- // generateAddressses
1826
- //
1827
- // This flattens an object into a set of key:value pairs for *EVERY SINGLE
1828
- // POSSIBLE ADDRESS* in the object. It can get ... really insane really
1829
- // quickly. This is not meant to be used directly to generate schemas, but
1830
- // instead as a starting point for scripts or UIs.
1831
- //
1832
- // This will return a mega set of key:value pairs with all possible schema
1833
- // permutations and default values (when not an object) and everything else.
2009
+ /**
2010
+ * generateAddressses
2011
+ *
2012
+ * This flattens an object into a set of key:value pairs for *EVERY SINGLE
2013
+ * POSSIBLE ADDRESS* in the object. It can get ... really insane really
2014
+ * quickly. This is not meant to be used directly to generate schemas, but
2015
+ * instead as a starting point for scripts or UIs.
2016
+ *
2017
+ * This will return a mega set of key:value pairs with all possible schema
2018
+ * permutations and default values (when not an object) and everything else.
2019
+ *
2020
+ * @param {any} pObject - The object to generate addresses for
2021
+ * @param {string} [pBaseAddress] - (optional) The base address to start from
2022
+ * @param {object} [pSchema] - (optional) The schema object to append to
2023
+ *
2024
+ * @return {object} The generated schema object
2025
+ */
1834
2026
  generateAddressses(pObject, pBaseAddress, pSchema) {
1835
2027
  let tmpBaseAddress = typeof pBaseAddress == 'string' ? pBaseAddress : '';
1836
2028
  let tmpSchema = typeof pSchema == 'object' ? pSchema : {};
@@ -1843,7 +2035,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1843
2035
  InSchema: false
1844
2036
  };
1845
2037
  if (tmpObjectType == 'object' && pObject == null) {
1846
- tmpObjectType = 'null';
2038
+ tmpObjectType = 'undefined';
1847
2039
  }
1848
2040
  switch (tmpObjectType) {
1849
2041
  case 'string':
@@ -1858,7 +2050,6 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1858
2050
  tmpSchema[tmpBaseAddress] = tmpSchemaObjectEntry;
1859
2051
  break;
1860
2052
  case 'undefined':
1861
- case 'null':
1862
2053
  tmpSchemaObjectEntry.DataType = 'Any';
1863
2054
  tmpSchemaObjectEntry.Default = pObject;
1864
2055
  tmpSchema[tmpBaseAddress] = tmpSchemaObjectEntry;
@@ -1895,9 +2086,9 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1895
2086
  ;
1896
2087
  module.exports = ManyfestObjectAddressGeneration;
1897
2088
  }, {
1898
- "./Manyfest-LogToConsole.js": 4
2089
+ "./Manyfest-LogToConsole.js": 5
1899
2090
  }],
1900
- 11: [function (require, module, exports) {
2091
+ 12: [function (require, module, exports) {
1901
2092
  // Given a string, parse out any conditional expressions and set whether or not to keep the record.
1902
2093
  //
1903
2094
  // For instance:
@@ -2031,7 +2222,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2031
2222
  };
2032
2223
  module.exports = parseConditionals;
2033
2224
  }, {}],
2034
- 12: [function (require, module, exports) {
2225
+ 13: [function (require, module, exports) {
2035
2226
  /**
2036
2227
  * @author <steven@velozo.com>
2037
2228
  */
@@ -2043,30 +2234,41 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2043
2234
  * @class ManyfestSchemaManipulation
2044
2235
  */
2045
2236
  class ManyfestSchemaManipulation {
2237
+ /**
2238
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
2239
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
2240
+ */
2046
2241
  constructor(pInfoLog, pErrorLog) {
2047
2242
  // Wire in logging
2048
2243
  this.logInfo = typeof pInfoLog === 'function' ? pInfoLog : libSimpleLog;
2049
2244
  this.logError = typeof pErrorLog === 'function' ? pErrorLog : libSimpleLog;
2050
2245
  }
2051
2246
 
2052
- // This translates the default address mappings to something different.
2053
- //
2054
- // For instance you can pass in manyfest schema descriptor object:
2055
- // {
2056
- // "Address.Of.a": { "Hash": "a", "Type": "Number" },
2057
- // "Address.Of.b": { "Hash": "b", "Type": "Number" }
2058
- // }
2059
- //
2060
- //
2061
- // And then an address mapping (basically a Hash->Address map)
2062
- // {
2063
- // "a": "New.Address.Of.a",
2064
- // "b": "New.Address.Of.b"
2065
- // }
2066
- //
2067
- // NOTE: This mutates the schema object permanently, altering the base hash.
2068
- // If there is a collision with an existing address, it can lead to overwrites.
2069
- // TODO: Discuss what should happen on collisions.
2247
+ /**
2248
+ * This translates the default address mappings to something different.
2249
+ *
2250
+ * For instance you can pass in manyfest schema descriptor object:
2251
+ * {
2252
+ * "Address.Of.a": { "Hash": "a", "Type": "Number" },
2253
+ * "Address.Of.b": { "Hash": "b", "Type": "Number" }
2254
+ * }
2255
+ *
2256
+ *
2257
+ * And then an address mapping (basically a Hash->Address map)
2258
+ * {
2259
+ * "a": "New.Address.Of.a",
2260
+ * "b": "New.Address.Of.b"
2261
+ * }
2262
+ *
2263
+ * NOTE: This mutates the schema object permanently, altering the base hash.
2264
+ * If there is a collision with an existing address, it can lead to overwrites.
2265
+ * TODO: Discuss what should happen on collisions.
2266
+ *
2267
+ * @param {object} pManyfestSchemaDescriptors - The manyfest schema descriptors to resolve address mappings for
2268
+ * @param {object} pAddressMapping - The address mapping object to use for remapping
2269
+ *
2270
+ * @return {boolean} True if successful, false if there was an error
2271
+ */
2070
2272
  resolveAddressMappings(pManyfestSchemaDescriptors, pAddressMapping) {
2071
2273
  if (typeof pManyfestSchemaDescriptors != 'object') {
2072
2274
  this.logError("Attempted to resolve address mapping but the descriptor was not an object.");
@@ -2088,8 +2290,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2088
2290
  let tmpAddressMappingSet = Object.keys(pAddressMapping);
2089
2291
  tmpAddressMappingSet.forEach(pInputAddress => {
2090
2292
  let tmpNewDescriptorAddress = pAddressMapping[pInputAddress];
2091
- let tmpOldDescriptorAddress = false;
2092
- let tmpDescriptor = false;
2293
+ let tmpOldDescriptorAddress = null;
2294
+ let tmpDescriptor;
2093
2295
 
2094
2296
  // See if there is a matching descriptor either by Address directly or Hash
2095
2297
  if (pInputAddress in pManyfestSchemaDescriptors) {
@@ -2114,12 +2316,26 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2114
2316
  });
2115
2317
  return true;
2116
2318
  }
2319
+
2320
+ /**
2321
+ * @param {object} pManyfestSchemaDescriptors - The manyfest schema descriptors to resolve address mappings for
2322
+ * @param {object} pAddressMapping - The address mapping object to use for remapping
2323
+ *
2324
+ * @return {object} A new object containing the remapped schema descriptors
2325
+ */
2117
2326
  safeResolveAddressMappings(pManyfestSchemaDescriptors, pAddressMapping) {
2118
2327
  // This returns the descriptors as a new object, safely remapping without mutating the original schema Descriptors
2119
2328
  let tmpManyfestSchemaDescriptors = JSON.parse(JSON.stringify(pManyfestSchemaDescriptors));
2120
2329
  this.resolveAddressMappings(tmpManyfestSchemaDescriptors, pAddressMapping);
2121
2330
  return tmpManyfestSchemaDescriptors;
2122
2331
  }
2332
+
2333
+ /**
2334
+ * @param {object} pManyfestSchemaDescriptorsDestination - The destination manyfest schema descriptors
2335
+ * @param {object} pManyfestSchemaDescriptorsSource - The source manyfest schema descriptors
2336
+ *
2337
+ * @return {object} A new object containing the merged schema descriptors
2338
+ */
2123
2339
  mergeAddressMappings(pManyfestSchemaDescriptorsDestination, pManyfestSchemaDescriptorsSource) {
2124
2340
  if (typeof pManyfestSchemaDescriptorsSource != 'object' || typeof pManyfestSchemaDescriptorsDestination != 'object') {
2125
2341
  this.logError("Attempted to merge two schema descriptors but both were not objects.");
@@ -2140,9 +2356,9 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2140
2356
  }
2141
2357
  module.exports = ManyfestSchemaManipulation;
2142
2358
  }, {
2143
- "./Manyfest-LogToConsole.js": 4
2359
+ "./Manyfest-LogToConsole.js": 5
2144
2360
  }],
2145
- 13: [function (require, module, exports) {
2361
+ 14: [function (require, module, exports) {
2146
2362
  /**
2147
2363
  * @author <steven@velozo.com>
2148
2364
  */
@@ -2160,6 +2376,18 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2160
2376
  Descriptors: {}
2161
2377
  };
2162
2378
 
2379
+ /**
2380
+ * @typedef {{
2381
+ * Hash?: string,
2382
+ * Name?: string,
2383
+ * DataType?: string,
2384
+ * Required?: boolean,
2385
+ * Address?: string,
2386
+ * Description?: string,
2387
+ * [key: string]: any,
2388
+ * }} ManifestDescriptor
2389
+ */
2390
+
2163
2391
  /**
2164
2392
  * Manyfest object address-based descriptions and manipulations.
2165
2393
  *
@@ -2172,6 +2400,15 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2172
2400
  } else {
2173
2401
  super(pFable, pManifest, pServiceHash);
2174
2402
  }
2403
+
2404
+ /** @type {import('fable')} */
2405
+ this.fable;
2406
+ /** @type {Record<string, any>} */
2407
+ this.options;
2408
+ /** @type {string} */
2409
+ this.Hash;
2410
+ /** @type {string} */
2411
+ this.UUID;
2175
2412
  this.serviceType = 'Manifest';
2176
2413
 
2177
2414
  // Wire in logging
@@ -2201,9 +2438,14 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2201
2438
  if (!('strict' in this.options)) {
2202
2439
  this.options.strict = false;
2203
2440
  }
2441
+
2442
+ /** @type {string} */
2204
2443
  this.scope = undefined;
2444
+ /** @type {Array<string>} */
2205
2445
  this.elementAddresses = undefined;
2446
+ /** @type {Record<string, string>} */
2206
2447
  this.elementHashes = undefined;
2448
+ /** @type {Record<string, ManifestDescriptor>} */
2207
2449
  this.elementDescriptors = undefined;
2208
2450
  this.reset();
2209
2451
  if (typeof this.options === 'object') {
@@ -2229,7 +2471,27 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2229
2471
  clone() {
2230
2472
  // Make a copy of the options in-place
2231
2473
  let tmpNewOptions = JSON.parse(JSON.stringify(this.options));
2232
- let tmpNewManyfest = new Manyfest(this.getManifest(), this.logInfo, this.logError, tmpNewOptions);
2474
+ let tmpNewManyfest = new Manyfest(this.fable, tmpNewOptions, this.Hash);
2475
+ tmpNewManyfest.logInfo = this.logInfo;
2476
+ tmpNewManyfest.logError = this.logError;
2477
+ //FIXME: mostly written by co-pilot
2478
+ const {
2479
+ Scope,
2480
+ Descriptors,
2481
+ HashTranslations
2482
+ } = this.getManifest();
2483
+ tmpNewManyfest.scope = Scope;
2484
+ tmpNewManyfest.elementDescriptors = Descriptors;
2485
+ tmpNewManyfest.elementAddresses = Object.keys(Descriptors);
2486
+ // Rebuild the element hashes
2487
+ for (let i = 0; i < tmpNewManyfest.elementAddresses.length; i++) {
2488
+ let tmpAddress = tmpNewManyfest.elementAddresses[i];
2489
+ let tmpDescriptor = tmpNewManyfest.elementDescriptors[tmpAddress];
2490
+ tmpNewManyfest.elementHashes[tmpAddress] = tmpAddress;
2491
+ if ('Hash' in tmpDescriptor) {
2492
+ tmpNewManyfest.elementHashes[tmpDescriptor.Hash] = tmpAddress;
2493
+ }
2494
+ }
2233
2495
 
2234
2496
  // Import the hash translations
2235
2497
  tmpNewManyfest.hashTranslations.addTranslation(this.hashTranslations.translationTable);
@@ -2237,9 +2499,15 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2237
2499
  }
2238
2500
 
2239
2501
  // Deserialize a Manifest from a string
2502
+ /**
2503
+ * @param {string} pManifestString - The manifest string to deserialize
2504
+ *
2505
+ * @return {Manyfest} The deserialized manifest
2506
+ */
2240
2507
  deserialize(pManifestString) {
2241
2508
  // TODO: Add guards for bad manifest string
2242
- return this.loadManifest(JSON.parse(pManifestString));
2509
+ this.loadManifest(JSON.parse(pManifestString));
2510
+ return this;
2243
2511
  }
2244
2512
 
2245
2513
  // Load a manifest from an object
@@ -2278,16 +2546,25 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2278
2546
  if ('HashTranslations' in tmpManifest) {
2279
2547
  if (typeof tmpManifest.HashTranslations === 'object') {
2280
2548
  for (let i = 0; i < tmpManifest.HashTranslations.length; i++) {
2281
- // Each translation is
2549
+ // Each translation is
2550
+ //FIXME: ?????????
2282
2551
  }
2283
2552
  }
2284
2553
  }
2285
2554
  }
2286
2555
 
2287
- // Serialize the Manifest to a string
2556
+ /**
2557
+ * Serialize the Manifest to a string
2558
+ *
2559
+ * @return {string} - The serialized manifest
2560
+ */
2288
2561
  serialize() {
2289
2562
  return JSON.stringify(this.getManifest());
2290
2563
  }
2564
+
2565
+ /**
2566
+ * @return {{ Scope: string, Descriptors: Record<string, ManifestDescriptor>, HashTranslations: Record<string, string> }} - A copy of the manifest state.
2567
+ */
2291
2568
  getManifest() {
2292
2569
  return {
2293
2570
  Scope: this.scope,
@@ -2296,7 +2573,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2296
2573
  };
2297
2574
  }
2298
2575
 
2299
- // Add a descriptor to the manifest
2576
+ /**
2577
+ * Add a descriptor to the manifest
2578
+ *
2579
+ * @param {string} pAddress - The address of the element to add the descriptor for.
2580
+ * @param {ManifestDescriptor} pDescriptor - The descriptor object to add.
2581
+ */
2300
2582
  addDescriptor(pAddress, pDescriptor) {
2301
2583
  if (typeof pDescriptor === 'object') {
2302
2584
  // Add the Address into the Descriptor if it doesn't exist:
@@ -2325,14 +2607,29 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2325
2607
  return false;
2326
2608
  }
2327
2609
  }
2610
+
2611
+ /**
2612
+ * @param {string} pHash - The hash of the address to resolve.
2613
+ *
2614
+ * @return {ManifestDescriptor} The descriptor for the address
2615
+ */
2328
2616
  getDescriptorByHash(pHash) {
2329
2617
  return this.getDescriptor(this.resolveHashAddress(pHash));
2330
2618
  }
2619
+
2620
+ /**
2621
+ * @param {string} pAddress - The address of the element to get the descriptor for.
2622
+ *
2623
+ * @return {ManifestDescriptor} The descriptor for the address
2624
+ */
2331
2625
  getDescriptor(pAddress) {
2332
2626
  return this.elementDescriptors[pAddress];
2333
2627
  }
2334
2628
 
2335
- // execute an action function for each descriptor
2629
+ /**
2630
+ * execute an action function for each descriptor
2631
+ * @param {(d: ManifestDescriptor) => void} fAction - The action function to execute for each descriptor.
2632
+ */
2336
2633
  eachDescriptor(fAction) {
2337
2634
  let tmpDescriptorAddresses = Object.keys(this.elementDescriptors);
2338
2635
  for (let i = 0; i < tmpDescriptorAddresses.length; i++) {
@@ -2356,8 +2653,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2356
2653
  // Turn a hash into an address, factoring in the translation table.
2357
2654
  resolveHashAddress(pHash) {
2358
2655
  let tmpAddress = undefined;
2359
- let tmpInElementHashTable = (pHash in this.elementHashes);
2360
- let tmpInTranslationTable = (pHash in this.hashTranslations.translationTable);
2656
+ let tmpInElementHashTable = pHash in this.elementHashes;
2657
+ let tmpInTranslationTable = pHash in this.hashTranslations.translationTable;
2361
2658
 
2362
2659
  // The most straightforward: the hash exists, no translations.
2363
2660
  if (tmpInElementHashTable && !tmpInTranslationTable) {
@@ -2388,18 +2685,28 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2388
2685
  }
2389
2686
  return tmpValue;
2390
2687
  }
2688
+ lintAddress(pAddress) {
2689
+ let tmpLintedAddress = pAddress.trim();
2690
+ // Check for a single . (but not a ..) at the end of the address and remove it.
2691
+ if (tmpLintedAddress.endsWith('..')) {
2692
+ tmpLintedAddress = tmpLintedAddress.slice(0, -1);
2693
+ } else if (tmpLintedAddress.endsWith('.')) {
2694
+ tmpLintedAddress = tmpLintedAddress.slice(0, -1);
2695
+ }
2696
+ return tmpLintedAddress;
2697
+ }
2391
2698
 
2392
2699
  // Get the value of an element at an address
2393
2700
  getValueAtAddress(pObject, pAddress) {
2394
- let tmpLintedAddress = pAddress.trim();
2701
+ let tmpLintedAddress = this.lintAddress(pAddress);
2395
2702
  if (tmpLintedAddress == '') {
2396
2703
  this.logError("(".concat(this.scope, ") Error getting value at address; address is an empty string."), pObject);
2397
2704
  return undefined;
2398
2705
  }
2399
- let tmpValue = this.objectAddressGetValue.getValueAtAddress(pObject, pAddress);
2706
+ let tmpValue = this.objectAddressGetValue.getValueAtAddress(pObject, tmpLintedAddress);
2400
2707
  if (typeof tmpValue == 'undefined') {
2401
2708
  // Try to get a default if it exists
2402
- tmpValue = this.getDefaultValue(this.getDescriptor(pAddress));
2709
+ tmpValue = this.getDefaultValue(this.getDescriptor(tmpLintedAddress));
2403
2710
  }
2404
2711
  return tmpValue;
2405
2712
  }
@@ -2411,7 +2718,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2411
2718
 
2412
2719
  // Set the value of an element at an address
2413
2720
  setValueAtAddress(pObject, pAddress, pValue) {
2414
- return this.objectAddressSetValue.setValueAtAddress(pObject, pAddress, pValue);
2721
+ let tmpLintedAddress = this.lintAddress(pAddress);
2722
+ return this.objectAddressSetValue.setValueAtAddress(pObject, tmpLintedAddress, pValue);
2415
2723
  }
2416
2724
 
2417
2725
  // Delete the value of an element by its hash
@@ -2421,7 +2729,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2421
2729
 
2422
2730
  // Delete the value of an element at an address
2423
2731
  deleteValueAtAddress(pObject, pAddress, pValue) {
2424
- return this.objectAddressDeleteValue.deleteValueAtAddress(pObject, pAddress, pValue);
2732
+ let tmpLintedAddress = this.lintAddress(pAddress);
2733
+ return this.objectAddressDeleteValue.deleteValueAtAddress(pObject, tmpLintedAddress, pValue);
2425
2734
  }
2426
2735
 
2427
2736
  // Validate the consistency of an object against the schema
@@ -2509,7 +2818,11 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2509
2818
  return tmpValidationData;
2510
2819
  }
2511
2820
 
2512
- // Returns a default value, or, the default value for the data type (which is overridable with configuration)
2821
+ /**
2822
+ * Returns a default value, or, the default value for the data type (which is overridable with configuration)
2823
+ *
2824
+ * @param {ManifestDescriptor} pDescriptor - The descriptor definition.
2825
+ */
2513
2826
  getDefaultValue(pDescriptor) {
2514
2827
  if (typeof pDescriptor != 'object') {
2515
2828
  return undefined;
@@ -2566,15 +2879,16 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2566
2879
  ;
2567
2880
  module.exports = Manyfest;
2568
2881
  }, {
2569
- "./Manyfest-HashTranslation.js": 3,
2570
- "./Manyfest-LogToConsole.js": 4,
2571
- "./Manyfest-ObjectAddress-CheckAddressExists.js": 5,
2572
- "./Manyfest-ObjectAddress-DeleteValue.js": 6,
2573
- "./Manyfest-ObjectAddress-GetValue.js": 7,
2574
- "./Manyfest-ObjectAddress-SetValue.js": 9,
2575
- "./Manyfest-ObjectAddressGeneration.js": 10,
2576
- "./Manyfest-SchemaManipulation.js": 12,
2577
- "fable-serviceproviderbase": 1
2882
+ "./Manyfest-HashTranslation.js": 4,
2883
+ "./Manyfest-LogToConsole.js": 5,
2884
+ "./Manyfest-ObjectAddress-CheckAddressExists.js": 6,
2885
+ "./Manyfest-ObjectAddress-DeleteValue.js": 7,
2886
+ "./Manyfest-ObjectAddress-GetValue.js": 8,
2887
+ "./Manyfest-ObjectAddress-SetValue.js": 10,
2888
+ "./Manyfest-ObjectAddressGeneration.js": 11,
2889
+ "./Manyfest-SchemaManipulation.js": 13,
2890
+ "fable-serviceproviderbase": 2
2578
2891
  }]
2579
- }, {}, [13])(13);
2580
- });
2892
+ }, {}, [14])(14);
2893
+ });
2894
+ //# sourceMappingURL=manyfest.js.map