manyfest 1.0.31 → 1.0.32

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/dist/manyfest.js CHANGED
@@ -242,7 +242,14 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
242
242
  /**
243
243
  * @author <steven@velozo.com>
244
244
  */
245
- let libSimpleLog = require('./Manyfest-LogToConsole.js');
245
+ const libSimpleLog = require('./Manyfest-LogToConsole.js');
246
+ // This is for resolving functions mid-address
247
+ const libGetObjectValue = require('./Manyfest-ObjectAddress-GetValue.js');
248
+
249
+ // TODO: Just until this is a fable service.
250
+ let _MockFable = {
251
+ DataFormat: require('./Manyfest-ObjectAddress-Parser.js')
252
+ };
246
253
 
247
254
  /**
248
255
  * Object Address Resolver
@@ -263,7 +270,9 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
263
270
  * @class ManyfestObjectAddressResolverCheckAddressExists
264
271
  */
265
272
  class ManyfestObjectAddressResolverCheckAddressExists {
266
- constructor() {}
273
+ constructor() {
274
+ this.getObjectValueClass = new libGetObjectValue(libSimpleLog, libSimpleLog);
275
+ }
267
276
 
268
277
  // Check if an address exists.
269
278
  //
@@ -271,21 +280,52 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
271
280
  // whether the element/property is actually there or not (it returns
272
281
  // undefined whether the property exists or not). This function checks for
273
282
  // existance and returns true or false dependent.
274
- checkAddressExists(pObject, pAddress) {
283
+ checkAddressExists(pObject, pAddress, pRootObject) {
275
284
  // TODO: Should these throw an error?
276
285
  // Make sure pObject is an object
277
286
  if (typeof pObject != 'object') return false;
278
287
  // Make sure pAddress is a string
279
288
  if (typeof pAddress != 'string') return false;
280
289
 
281
- // TODO: Make this work for things like SomeRootObject.Metadata["Some.People.Use.Bad.Object.Property.Names"]
282
- let tmpSeparatorIndex = pAddress.indexOf('.');
290
+ // Set the root object to the passed-in object if it isn't set yet. This is expected to be the root object.
291
+ // NOTE: This was added to support functions mid-stream
292
+ let tmpRootObject = typeof pRootObject == 'undefined' ? pObject : pRootObject;
293
+
294
+ // DONE: Make this work for things like SomeRootObject.Metadata["Some.People.Use.Bad.Object.Property.Names"]
295
+ let tmpAddressPartBeginning = _MockFable.DataFormat.stringGetFirstSegment(pAddress);
283
296
 
284
297
  // This is the terminal address string (no more dots so the RECUSION ENDS IN HERE somehow)
285
- if (tmpSeparatorIndex == -1) {
298
+ if (tmpAddressPartBeginning.length == pAddress.length) {
286
299
  // Check if the address refers to a boxed property
287
300
  let tmpBracketStartIndex = pAddress.indexOf('[');
288
301
  let tmpBracketStopIndex = pAddress.indexOf(']');
302
+
303
+ // Check if there is a function somewhere in the address... parenthesis start should only be in a function
304
+ let tmpFunctionStartIndex = pAddress.indexOf('(');
305
+
306
+ // NOTE THAT FUNCTIONS MUST RESOLVE FIRST
307
+ // Functions look like this
308
+ // MyFunction()
309
+ // MyFunction(Some.Address)
310
+ // MyFunction(Some.Address,Some.Other.Address)
311
+ // MyFunction(Some.Address,Some.Other.Address,Some.Third.Address)
312
+ //
313
+ // This could be enhanced to allow purely numeric and string values to be passed to the function. For now,
314
+ // To heck with that. This is a simple function call.
315
+ //
316
+ // The requirements to detect a function are:
317
+ // 1) The start bracket is after character 0
318
+ if (tmpFunctionStartIndex > 0
319
+ // 2) The end bracket is after the start bracket
320
+ && _MockFable.DataFormat.stringCountEnclosures(pAddress) > 0) {
321
+ let tmpFunctionAddress = pAddress.substring(0, tmpFunctionStartIndex).trim();
322
+ if (pObject.hasOwnProperty(tmpFunctionAddress) && typeof pObject[tmpFunctionAddress] == 'function') {
323
+ return true;
324
+ } else {
325
+ // The address suggests it is a function, but it is not.
326
+ return false;
327
+ }
328
+ }
289
329
  // Boxed elements look like this:
290
330
  // MyValues[10]
291
331
  // MyValues['Name']
@@ -295,7 +335,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
295
335
  // When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
296
336
  // The requirements to detect a boxed element are:
297
337
  // 1) The start bracket is after character 0
298
- if (tmpBracketStartIndex > 0
338
+ else if (tmpBracketStartIndex > 0
299
339
  // 2) The end bracket has something between them
300
340
  && tmpBracketStopIndex > tmpBracketStartIndex
301
341
  // 3) There is data
@@ -343,13 +383,59 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
343
383
  return pObject.hasOwnProperty(pAddress);
344
384
  }
345
385
  } else {
346
- let tmpSubObjectName = pAddress.substring(0, tmpSeparatorIndex);
347
- let tmpNewAddress = pAddress.substring(tmpSeparatorIndex + 1);
386
+ let tmpSubObjectName = tmpAddressPartBeginning;
387
+ let tmpNewAddress = pAddress.substring(tmpAddressPartBeginning.length + 1);
348
388
 
349
389
  // Test if the tmpNewAddress is an array or object
350
390
  // Check if it's a boxed property
351
391
  let tmpBracketStartIndex = tmpSubObjectName.indexOf('[');
352
392
  let tmpBracketStopIndex = tmpSubObjectName.indexOf(']');
393
+
394
+ // Check if there is a function somewhere in the address... parenthesis start should only be in a function
395
+ let tmpFunctionStartIndex = tmpSubObjectName.indexOf('(');
396
+
397
+ // NOTE THAT FUNCTIONS MUST RESOLVE FIRST
398
+ // Functions look like this
399
+ // MyFunction()
400
+ // MyFunction(Some.Address)
401
+ // MyFunction(Some.Address,Some.Other.Address)
402
+ // MyFunction(Some.Address,Some.Other.Address,Some.Third.Address)
403
+ //
404
+ // This could be enhanced to allow purely numeric and string values to be passed to the function. For now,
405
+ // To heck with that. This is a simple function call.
406
+ //
407
+ // The requirements to detect a function are:
408
+ // 1) The start bracket is after character 0
409
+ if (tmpFunctionStartIndex > 0
410
+ // 2) The end bracket is after the start bracket
411
+ && _MockFable.DataFormat.stringCountEnclosures(tmpSubObjectName) > 0) {
412
+ let tmpFunctionAddress = tmpSubObjectName.substring(0, tmpFunctionStartIndex).trim();
413
+ //tmpParentAddress = `${tmpParentAddress}${(tmpParentAddress.length > 0) ? '.' : ''}${tmpSubObjectName}`;
414
+
415
+ if (!typeof pObject[tmpFunctionAddress] == 'function') {
416
+ // The address suggests it is a function, but it is not.
417
+ return false;
418
+ }
419
+
420
+ // Now see if the function has arguments.
421
+ // Implementation notes: * ARGUMENTS MUST SHARE THE SAME ROOT OBJECT CONTEXT *
422
+ let tmpFunctionArguments = _MockFable.DataFormat.stringGetSegments(_MockFable.DataFormat.stringGetEnclosureValueByIndex(tmpSubObjectName.substring(tmpFunctionAddress.length), 0), ',');
423
+ if (tmpFunctionArguments.length == 0 || tmpFunctionArguments[0] == '') {
424
+ // No arguments... just call the function (bound to the scope of the object it is contained withing)
425
+ return this.checkAddressExists(pObject[tmpFunctionAddress].apply(pObject), tmpNewAddress, tmpRootObject);
426
+ } else {
427
+ let tmpArgumentValues = [];
428
+ let tmpRootObject = typeof pRootObject == 'undefined' ? pObject : pRootObject;
429
+
430
+ // Now get the value for each argument
431
+ for (let i = 0; i < tmpFunctionArguments.length; i++) {
432
+ // Resolve the values for each subsequent entry
433
+ // NOTE: This is where the resolves get really tricky. Recursion within recursion. Programming gom jabbar, yo.
434
+ tmpArgumentValues.push(this.getObjectValueClass.getValueAtAddress(tmpRootObject, tmpFunctionArguments[i]));
435
+ }
436
+ return this.checkAddressExists(pObject[tmpFunctionAddress].apply(pObject, tmpArgumentValues), tmpNewAddress, tmpRootObject);
437
+ }
438
+ }
353
439
  // Boxed elements look like this:
354
440
  // MyValues[42]
355
441
  // MyValues['Color']
@@ -359,7 +445,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
359
445
  // When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
360
446
  // The requirements to detect a boxed element are:
361
447
  // 1) The start bracket is after character 0
362
- if (tmpBracketStartIndex > 0
448
+ else if (tmpBracketStartIndex > 0
363
449
  // 2) The end bracket has something between them
364
450
  && tmpBracketStopIndex > tmpBracketStartIndex
365
451
  // 3) There is data
@@ -398,10 +484,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
398
484
  tmpBoxedPropertyReference = this.cleanWrapCharacters("'", tmpBoxedPropertyReference);
399
485
 
400
486
  // Recurse directly into the subobject
401
- return this.checkAddressExists(pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference], tmpNewAddress);
487
+ return this.checkAddressExists(pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference], tmpNewAddress, tmpRootObject);
402
488
  } else {
403
489
  // We parsed a valid number out of the boxed property name, so recurse into the array
404
- return this.checkAddressExists(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber], tmpNewAddress);
490
+ return this.checkAddressExists(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber], tmpNewAddress, tmpRootObject);
405
491
  }
406
492
  }
407
493
 
@@ -411,11 +497,11 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
411
497
  return false;
412
498
  } else if (pObject.hasOwnProperty(tmpSubObjectName)) {
413
499
  // If there is already a subobject pass that to the recursive thingy
414
- return this.checkAddressExists(pObject[tmpSubObjectName], tmpNewAddress);
500
+ return this.checkAddressExists(pObject[tmpSubObjectName], tmpNewAddress, tmpRootObject);
415
501
  } else {
416
502
  // Create a subobject and then pass that
417
503
  pObject[tmpSubObjectName] = {};
418
- return this.checkAddressExists(pObject[tmpSubObjectName], tmpNewAddress);
504
+ return this.checkAddressExists(pObject[tmpSubObjectName], tmpNewAddress, tmpRootObject);
419
505
  }
420
506
  }
421
507
  }
@@ -423,7 +509,9 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
423
509
  ;
424
510
  module.exports = ManyfestObjectAddressResolverCheckAddressExists;
425
511
  }, {
426
- "./Manyfest-LogToConsole.js": 4
512
+ "./Manyfest-LogToConsole.js": 4,
513
+ "./Manyfest-ObjectAddress-GetValue.js": 7,
514
+ "./Manyfest-ObjectAddress-Parser.js": 8
427
515
  }],
428
516
  6: [function (require, module, exports) {
429
517
  /**
@@ -631,7 +719,6 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
631
719
  if (typeof pObject[tmpBoxedPropertyName] != 'object') {
632
720
  return false;
633
721
  }
634
-
635
722
  //This is a bracketed value
636
723
  // 4) If the middle part is *only* a number (no single, double or backtick quotes) it is an array element,
637
724
  // otherwise we will try to reat it as a dynamic object property.
@@ -731,7 +818,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
731
818
  ;
732
819
  module.exports = ManyfestObjectAddressResolverDeleteValue;
733
820
  }, {
734
- "../source/Manyfest-ParseConditionals.js": 10,
821
+ "../source/Manyfest-ParseConditionals.js": 11,
735
822
  "./Manyfest-CleanWrapCharacters.js": 2,
736
823
  "./Manyfest-LogToConsole.js": 4
737
824
  }],
@@ -742,6 +829,9 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
742
829
  let libSimpleLog = require('./Manyfest-LogToConsole.js');
743
830
  let fCleanWrapCharacters = require('./Manyfest-CleanWrapCharacters.js');
744
831
  let fParseConditionals = require("../source/Manyfest-ParseConditionals.js");
832
+ let _MockFable = {
833
+ DataFormat: require('./Manyfest-ObjectAddress-Parser.js')
834
+ };
745
835
 
746
836
  /**
747
837
  * Object Address Resolver - GetValue
@@ -789,14 +879,14 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
789
879
  // Set the root object to the passed-in object if it isn't set yet. This is expected to be the root object.
790
880
  let tmpRootObject = typeof pRootObject == 'undefined' ? pObject : pRootObject;
791
881
 
792
- // TODO: Make this work for things like SomeRootObject.Metadata["Some.People.Use.Bad.Object.Property.Names"]
793
- let tmpSeparatorIndex = pAddress.indexOf('.');
882
+ // DONE: Make this work for things like SomeRootObject.Metadata["Some.People.Use.Bad.Object.Property.Names"]
883
+ let tmpAddressPartBeginning = _MockFable.DataFormat.stringGetFirstSegment(pAddress);
794
884
 
795
885
  // Adding simple back-navigation in objects
796
- if (tmpSeparatorIndex == 0) {
886
+ if (tmpAddressPartBeginning == '') {
797
887
  // Given an address of "Bundle.Contract.IDContract...Project.IDProject" the ... would be interpreted as two back-navigations from IDContract.
798
888
  // When the address is passed in, though, the first . is already eliminated. So we can count the dots.
799
- let tmpParentAddressParts = tmpParentAddress.split('.');
889
+ let tmpParentAddressParts = _MockFable.DataFormat.stringGetSegments(tmpParentAddress);
800
890
  let tmpBackNavigationCount = 0;
801
891
 
802
892
  // Count the number of dots
@@ -825,7 +915,9 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
825
915
  }
826
916
 
827
917
  // This is the terminal address string (no more dots so the RECUSION ENDS IN HERE somehow)
828
- if (tmpSeparatorIndex == -1) {
918
+ if (tmpAddressPartBeginning.length == pAddress.length) {
919
+ // TODO: Optimize this by having these calls only happen when the previous fails.
920
+ // TODO: Alternatively look for all markers in one pass?
829
921
  // Check if the address refers to a boxed property
830
922
  let tmpBracketStartIndex = pAddress.indexOf('[');
831
923
  let tmpBracketStopIndex = pAddress.indexOf(']');
@@ -834,6 +926,55 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
834
926
  // Note this will not work with a bracket in the same address box set
835
927
  let tmpObjectTypeMarkerIndex = pAddress.indexOf('{}');
836
928
 
929
+ // Check if there is a function somewhere in the address... parenthesis start should only be in a function
930
+ let tmpFunctionStartIndex = pAddress.indexOf('(');
931
+
932
+ // NOTE THAT FUNCTIONS MUST RESOLVE FIRST
933
+ // Functions look like this
934
+ // MyFunction()
935
+ // MyFunction(Some.Address)
936
+ // MyFunction(Some.Address,Some.Other.Address)
937
+ // MyFunction(Some.Address,Some.Other.Address,Some.Third.Address)
938
+ //
939
+ // This could be enhanced to allow purely numeric and string values to be passed to the function. For now,
940
+ // To heck with that. This is a simple function call.
941
+ //
942
+ // The requirements to detect a function are:
943
+ // 1) The start bracket is after character 0
944
+ if (tmpFunctionStartIndex > 0
945
+ // 2) The end bracket is after the start bracket
946
+ && _MockFable.DataFormat.stringCountEnclosures(pAddress) > 0) {
947
+ let tmpFunctionAddress = pAddress.substring(0, tmpFunctionStartIndex).trim();
948
+ if (!typeof pObject[tmpFunctionAddress] == 'function') {
949
+ // The address suggests it is a function, but it is not.
950
+ return false;
951
+ }
952
+
953
+ // Now see if the function has arguments.
954
+ // Implementation notes: * ARGUMENTS MUST SHARE THE SAME ROOT OBJECT CONTEXT *
955
+ let tmpFunctionArguments = _MockFable.DataFormat.stringGetSegments(_MockFable.DataFormat.stringGetEnclosureValueByIndex(pAddress.substring(tmpFunctionAddress.length), 0), ',');
956
+ if (tmpFunctionArguments.length == 0 || tmpFunctionArguments[0] == '') {
957
+ // No arguments... just call the function (bound to the scope of the object it is contained withing)
958
+ return pObject[tmpFunctionAddress].apply(pObject);
959
+ } else {
960
+ let tmpArgumentValues = [];
961
+ let tmpRootObject = typeof pRootObject == 'undefined' ? pObject : pRootObject;
962
+
963
+ // Now get the value for each argument
964
+ for (let i = 0; i < tmpFunctionArguments.length; i++) {
965
+ if (tmpFunctionArguments[i][0] == "'" && tmpFunctionArguments[i][tmpFunctionArguments[i].length - 1] == "'") {
966
+ tmpArgumentValues.push(tmpFunctionArguments[i].substring(1, tmpFunctionArguments[i].length - 1));
967
+ } else if (tmpFunctionArguments[i][0] == '"' && tmpFunctionArguments[i][tmpFunctionArguments[i].length - 1] == '"') {
968
+ tmpArgumentValues.push(tmpFunctionArguments[i].substring(1, tmpFunctionArguments[i].length - 1));
969
+ } else if (tmpFunctionArguments[i][0] == "`" && tmpFunctionArguments[i][tmpFunctionArguments[i].length - 1] == "`") {
970
+ tmpArgumentValues.push(tmpFunctionArguments[i].substring(1, tmpFunctionArguments[i].length - 1));
971
+ } else {
972
+ tmpArgumentValues.push(this.getValueAtAddress(tmpRootObject, tmpFunctionArguments[i]));
973
+ }
974
+ }
975
+ return pObject[tmpFunctionAddress].apply(pObject, tmpArgumentValues);
976
+ }
977
+ }
837
978
  // Boxed elements look like this:
838
979
  // MyValues[10]
839
980
  // MyValues['Name']
@@ -843,7 +984,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
843
984
  // When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
844
985
  // The requirements to detect a boxed element are:
845
986
  // 1) The start bracket is after character 0
846
- if (tmpBracketStartIndex > 0
987
+ else if (tmpBracketStartIndex > 0
847
988
  // 2) The end bracket has something between them
848
989
  && tmpBracketStopIndex > tmpBracketStartIndex
849
990
  // 3) There is data
@@ -926,14 +1067,60 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
926
1067
  }
927
1068
  }
928
1069
  } else {
929
- let tmpSubObjectName = pAddress.substring(0, tmpSeparatorIndex);
930
- let tmpNewAddress = pAddress.substring(tmpSeparatorIndex + 1);
1070
+ //let tmpSubObjectName = pAddress.substring(0, tmpSeparatorIndex);
1071
+ //let tmpNewAddress = pAddress.substring(tmpSeparatorIndex+1);
1072
+ let tmpSubObjectName = tmpAddressPartBeginning;
1073
+ let tmpNewAddress = pAddress.substring(tmpAddressPartBeginning.length + 1);
931
1074
 
932
1075
  // BOXED ELEMENTS
933
1076
  // Test if the tmpNewAddress is an array or object
934
1077
  // Check if it's a boxed property
935
1078
  let tmpBracketStartIndex = tmpSubObjectName.indexOf('[');
936
1079
  let tmpBracketStopIndex = tmpSubObjectName.indexOf(']');
1080
+
1081
+ // Check if there is a function somewhere in the address... parenthesis start should only be in a function
1082
+ let tmpFunctionStartIndex = tmpSubObjectName.indexOf('(');
1083
+
1084
+ // NOTE THAT FUNCTIONS MUST RESOLVE FIRST
1085
+ // Functions look like this
1086
+ // MyFunction()
1087
+ // MyFunction(Some.Address)
1088
+ // MyFunction(Some.Address,Some.Other.Address)
1089
+ // MyFunction(Some.Address,Some.Other.Address,Some.Third.Address)
1090
+ //
1091
+ // This could be enhanced to allow purely numeric and string values to be passed to the function. For now,
1092
+ // To heck with that. This is a simple function call.
1093
+ //
1094
+ // The requirements to detect a function are:
1095
+ // 1) The start bracket is after character 0
1096
+ if (tmpFunctionStartIndex > 0
1097
+ // 2) The end bracket is after the start bracket
1098
+ && _MockFable.DataFormat.stringCountEnclosures(tmpSubObjectName) > 0) {
1099
+ let tmpFunctionAddress = tmpSubObjectName.substring(0, tmpFunctionStartIndex).trim();
1100
+ tmpParentAddress = "".concat(tmpParentAddress).concat(tmpParentAddress.length > 0 ? '.' : '').concat(tmpSubObjectName);
1101
+ if (!typeof pObject[tmpFunctionAddress] == 'function') {
1102
+ // The address suggests it is a function, but it is not.
1103
+ return false;
1104
+ }
1105
+
1106
+ // Now see if the function has arguments.
1107
+ // Implementation notes: * ARGUMENTS MUST SHARE THE SAME ROOT OBJECT CONTEXT *
1108
+ let tmpFunctionArguments = _MockFable.DataFormat.stringGetSegments(_MockFable.DataFormat.stringGetEnclosureValueByIndex(tmpSubObjectName.substring(tmpFunctionAddress.length), 0), ',');
1109
+ if (tmpFunctionArguments.length == 0 || tmpFunctionArguments[0] == '') {
1110
+ // No arguments... just call the function (bound to the scope of the object it is contained withing)
1111
+ return this.getValueAtAddress(pObject[tmpFunctionAddress].apply(pObject), tmpNewAddress, tmpParentAddress, tmpRootObject);
1112
+ } else {
1113
+ let tmpArgumentValues = [];
1114
+ let tmpRootObject = typeof pRootObject == 'undefined' ? pObject : pRootObject;
1115
+
1116
+ // Now get the value for each argument
1117
+ for (let i = 0; i < tmpFunctionArguments.length; i++) {
1118
+ // Resolve the values for each subsequent entry
1119
+ tmpArgumentValues.push(this.getValueAtAddress(tmpRootObject, tmpFunctionArguments[i]));
1120
+ }
1121
+ return this.getValueAtAddress(pObject[tmpFunctionAddress].apply(pObject, tmpArgumentValues), tmpNewAddress, tmpParentAddress, tmpRootObject);
1122
+ }
1123
+ }
937
1124
  // Boxed elements look like this:
938
1125
  // MyValues[42]
939
1126
  // MyValues['Color']
@@ -943,7 +1130,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
943
1130
  // When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
944
1131
  // The requirements to detect a boxed element are:
945
1132
  // 1) The start bracket is after character 0
946
- if (tmpBracketStartIndex > 0
1133
+ else if (tmpBracketStartIndex > 0
947
1134
  // 2) The end bracket has something between them
948
1135
  && tmpBracketStopIndex > tmpBracketStartIndex
949
1136
  // 3) There is data
@@ -1073,11 +1260,266 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1073
1260
  ;
1074
1261
  module.exports = ManyfestObjectAddressResolverGetValue;
1075
1262
  }, {
1076
- "../source/Manyfest-ParseConditionals.js": 10,
1263
+ "../source/Manyfest-ParseConditionals.js": 11,
1077
1264
  "./Manyfest-CleanWrapCharacters.js": 2,
1078
- "./Manyfest-LogToConsole.js": 4
1265
+ "./Manyfest-LogToConsole.js": 4,
1266
+ "./Manyfest-ObjectAddress-Parser.js": 8
1079
1267
  }],
1080
1268
  8: [function (require, module, exports) {
1269
+ // TODO: This is an inelegant solution to delay the rewrite of Manyfest.
1270
+
1271
+ // Fable 3.0 has a service for data formatting that deals well with nested enclosures.
1272
+
1273
+ // The Manyfest library predates fable 3.0 and the services structure of it, so the functions
1274
+ // are more or less pure javascript and as functional as they can be made to be.
1275
+
1276
+ // Until we shift Manyfest to be a fable service, these three functions were pulled out of
1277
+ // fable to aid in parsing functions with nested enclosures.
1278
+
1279
+ module.exports = {
1280
+ /**
1281
+ * Count the number of segments in a string, respecting enclosures
1282
+ *
1283
+ * @param {string} pString
1284
+ * @param {string} pSeparator
1285
+ * @param {object} pEnclosureStartSymbolMap
1286
+ * @param {object} pEnclosureEndSymbolMap
1287
+ * @returns the count of segments in the string as a number
1288
+ */
1289
+ stringCountSegments: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) => {
1290
+ let tmpString = typeof pString == 'string' ? pString : '';
1291
+ let tmpSeparator = typeof pSeparator == 'string' ? pSeparator : '.';
1292
+ let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStart : {
1293
+ '{': 0,
1294
+ '[': 1,
1295
+ '(': 2
1296
+ };
1297
+ let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEnd : {
1298
+ '}': 0,
1299
+ ']': 1,
1300
+ ')': 2
1301
+ };
1302
+ if (pString.length < 1) {
1303
+ return 0;
1304
+ }
1305
+ let tmpSegmentCount = 1;
1306
+ let tmpEnclosureStack = [];
1307
+ for (let i = 0; i < tmpString.length; i++) {
1308
+ // IF This is the start of a segment
1309
+ if (tmpString[i] == tmpSeparator
1310
+ // AND we are not in a nested portion of the string
1311
+ && tmpEnclosureStack.length == 0) {
1312
+ // Increment the segment count
1313
+ tmpSegmentCount++;
1314
+ }
1315
+ // IF This is the start of an enclosure
1316
+ else if (tmpEnclosureStartSymbolMap.hasOwnProperty(tmpString[i])) {
1317
+ // Add it to the stack!
1318
+ tmpEnclosureStack.push(tmpEnclosureStartSymbolMap[tmpString[i]]);
1319
+ }
1320
+ // IF This is the end of an enclosure
1321
+ else if (tmpEnclosureEndSymbolMap.hasOwnProperty(tmpString[i])
1322
+ // AND it matches the current nest level symbol
1323
+ && tmpEnclosureEndSymbolMap[tmpString[i]] == tmpEnclosureStack[tmpEnclosureStack.length - 1]) {
1324
+ // Pop it off the stack!
1325
+ tmpEnclosureStack.pop();
1326
+ }
1327
+ }
1328
+ return tmpSegmentCount;
1329
+ },
1330
+ /**
1331
+ * Get the first segment in a string, respecting enclosures
1332
+ *
1333
+ * @param {string} pString
1334
+ * @param {string} pSeparator
1335
+ * @param {object} pEnclosureStartSymbolMap
1336
+ * @param {object} pEnclosureEndSymbolMap
1337
+ * @returns the first segment in the string as a string
1338
+ */
1339
+ stringGetFirstSegment: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) => {
1340
+ let tmpString = typeof pString == 'string' ? pString : '';
1341
+ let tmpSeparator = typeof pSeparator == 'string' ? pSeparator : '.';
1342
+ let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStart : {
1343
+ '{': 0,
1344
+ '[': 1,
1345
+ '(': 2
1346
+ };
1347
+ let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEnd : {
1348
+ '}': 0,
1349
+ ']': 1,
1350
+ ')': 2
1351
+ };
1352
+ if (pString.length < 1) {
1353
+ return 0;
1354
+ }
1355
+ let tmpEnclosureStack = [];
1356
+ for (let i = 0; i < tmpString.length; i++) {
1357
+ // IF This is the start of a segment
1358
+ if (tmpString[i] == tmpSeparator
1359
+ // AND we are not in a nested portion of the string
1360
+ && tmpEnclosureStack.length == 0) {
1361
+ // Return the segment
1362
+ return tmpString.substring(0, i);
1363
+ }
1364
+ // IF This is the start of an enclosure
1365
+ else if (tmpEnclosureStartSymbolMap.hasOwnProperty(tmpString[i])) {
1366
+ // Add it to the stack!
1367
+ tmpEnclosureStack.push(tmpEnclosureStartSymbolMap[tmpString[i]]);
1368
+ }
1369
+ // IF This is the end of an enclosure
1370
+ else if (tmpEnclosureEndSymbolMap.hasOwnProperty(tmpString[i])
1371
+ // AND it matches the current nest level symbol
1372
+ && tmpEnclosureEndSymbolMap[tmpString[i]] == tmpEnclosureStack[tmpEnclosureStack.length - 1]) {
1373
+ // Pop it off the stack!
1374
+ tmpEnclosureStack.pop();
1375
+ }
1376
+ }
1377
+ return tmpString;
1378
+ },
1379
+ /**
1380
+ * Get all segments in a string, respecting enclosures
1381
+ *
1382
+ * @param {string} pString
1383
+ * @param {string} pSeparator
1384
+ * @param {object} pEnclosureStartSymbolMap
1385
+ * @param {object} pEnclosureEndSymbolMap
1386
+ * @returns the first segment in the string as a string
1387
+ */
1388
+ stringGetSegments: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) => {
1389
+ let tmpString = typeof pString == 'string' ? pString : '';
1390
+ let tmpSeparator = typeof pSeparator == 'string' ? pSeparator : '.';
1391
+ let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStart : {
1392
+ '{': 0,
1393
+ '[': 1,
1394
+ '(': 2
1395
+ };
1396
+ let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEnd : {
1397
+ '}': 0,
1398
+ ']': 1,
1399
+ ')': 2
1400
+ };
1401
+ let tmpCurrentSegmentStart = 0;
1402
+ let tmpSegmentList = [];
1403
+ if (pString.length < 1) {
1404
+ return tmpSegmentList;
1405
+ }
1406
+ let tmpEnclosureStack = [];
1407
+ for (let i = 0; i < tmpString.length; i++) {
1408
+ // IF This is the start of a segment
1409
+ if (tmpString[i] == tmpSeparator
1410
+ // AND we are not in a nested portion of the string
1411
+ && tmpEnclosureStack.length == 0) {
1412
+ // Return the segment
1413
+ tmpSegmentList.push(tmpString.substring(tmpCurrentSegmentStart, i));
1414
+ tmpCurrentSegmentStart = i + 1;
1415
+ }
1416
+ // IF This is the start of an enclosure
1417
+ else if (tmpEnclosureStartSymbolMap.hasOwnProperty(tmpString[i])) {
1418
+ // Add it to the stack!
1419
+ tmpEnclosureStack.push(tmpEnclosureStartSymbolMap[tmpString[i]]);
1420
+ }
1421
+ // IF This is the end of an enclosure
1422
+ else if (tmpEnclosureEndSymbolMap.hasOwnProperty(tmpString[i])
1423
+ // AND it matches the current nest level symbol
1424
+ && tmpEnclosureEndSymbolMap[tmpString[i]] == tmpEnclosureStack[tmpEnclosureStack.length - 1]) {
1425
+ // Pop it off the stack!
1426
+ tmpEnclosureStack.pop();
1427
+ }
1428
+ }
1429
+ if (tmpCurrentSegmentStart < tmpString.length) {
1430
+ tmpSegmentList.push(tmpString.substring(tmpCurrentSegmentStart));
1431
+ }
1432
+ return tmpSegmentList;
1433
+ },
1434
+ /**
1435
+ * Count the number of enclosures in a string based on the start and end characters.
1436
+ *
1437
+ * If no start or end characters are specified, it will default to parentheses. If the string is not a string, it will return 0.
1438
+ *
1439
+ * @param {string} pString
1440
+ * @param {string} pEnclosureStart
1441
+ * @param {string} pEnclosureEnd
1442
+ * @returns the count of full in the string
1443
+ */
1444
+ stringCountEnclosures: (pString, pEnclosureStart, pEnclosureEnd) => {
1445
+ let tmpString = typeof pString == 'string' ? pString : '';
1446
+ let tmpEnclosureStart = typeof pEnclosureStart == 'string' ? pEnclosureStart : '(';
1447
+ let tmpEnclosureEnd = typeof pEnclosureEnd == 'string' ? pEnclosureEnd : ')';
1448
+ let tmpEnclosureCount = 0;
1449
+ let tmpEnclosureDepth = 0;
1450
+ for (let i = 0; i < tmpString.length; i++) {
1451
+ // This is the start of an enclosure
1452
+ if (tmpString[i] == tmpEnclosureStart) {
1453
+ if (tmpEnclosureDepth == 0) {
1454
+ tmpEnclosureCount++;
1455
+ }
1456
+ tmpEnclosureDepth++;
1457
+ } else if (tmpString[i] == tmpEnclosureEnd) {
1458
+ tmpEnclosureDepth--;
1459
+ }
1460
+ }
1461
+ return tmpEnclosureCount;
1462
+ },
1463
+ /**
1464
+ * Get the value of the enclosure at the specified index.
1465
+ *
1466
+ * If the index is not a number, it will default to 0. If the string is not a string, it will return an empty string. If the enclosure is not found, it will return an empty string. If the enclosure
1467
+ *
1468
+ * @param {string} pString
1469
+ * @param {number} pEnclosureIndexToGet
1470
+ * @param {string} pEnclosureStart
1471
+ * @param {string}} pEnclosureEnd
1472
+ * @returns {string}
1473
+ */
1474
+ stringGetEnclosureValueByIndex: (pString, pEnclosureIndexToGet, pEnclosureStart, pEnclosureEnd) => {
1475
+ let tmpString = typeof pString == 'string' ? pString : '';
1476
+ let tmpEnclosureIndexToGet = typeof pEnclosureIndexToGet == 'number' ? pEnclosureIndexToGet : 0;
1477
+ let tmpEnclosureStart = typeof pEnclosureStart == 'string' ? pEnclosureStart : '(';
1478
+ let tmpEnclosureEnd = typeof pEnclosureEnd == 'string' ? pEnclosureEnd : ')';
1479
+ let tmpEnclosureCount = 0;
1480
+ let tmpEnclosureDepth = 0;
1481
+ let tmpMatchedEnclosureIndex = false;
1482
+ let tmpEnclosedValueStartIndex = 0;
1483
+ let tmpEnclosedValueEndIndex = 0;
1484
+ for (let i = 0; i < tmpString.length; i++) {
1485
+ // This is the start of an enclosure
1486
+ if (tmpString[i] == tmpEnclosureStart) {
1487
+ tmpEnclosureDepth++;
1488
+
1489
+ // Only count enclosures at depth 1, but still this parses both pairs of all of them.
1490
+ if (tmpEnclosureDepth == 1) {
1491
+ tmpEnclosureCount++;
1492
+ if (tmpEnclosureIndexToGet == tmpEnclosureCount - 1) {
1493
+ // This is the start of *the* enclosure
1494
+ tmpMatchedEnclosureIndex = true;
1495
+ tmpEnclosedValueStartIndex = i;
1496
+ }
1497
+ }
1498
+ }
1499
+ // This is the end of an enclosure
1500
+ else if (tmpString[i] == tmpEnclosureEnd) {
1501
+ tmpEnclosureDepth--;
1502
+
1503
+ // Again, only count enclosures at depth 1, but still this parses both pairs of all of them.
1504
+ if (tmpEnclosureDepth == 0 && tmpMatchedEnclosureIndex && tmpEnclosedValueEndIndex <= tmpEnclosedValueStartIndex) {
1505
+ tmpEnclosedValueEndIndex = i;
1506
+ tmpMatchedEnclosureIndex = false;
1507
+ }
1508
+ }
1509
+ }
1510
+ if (tmpEnclosureCount <= tmpEnclosureIndexToGet) {
1511
+ // Return an empty string if the enclosure is not found
1512
+ return '';
1513
+ }
1514
+ if (tmpEnclosedValueEndIndex > 0 && tmpEnclosedValueEndIndex > tmpEnclosedValueStartIndex) {
1515
+ return tmpString.substring(tmpEnclosedValueStartIndex + 1, tmpEnclosedValueEndIndex);
1516
+ } else {
1517
+ return tmpString.substring(tmpEnclosedValueStartIndex + 1);
1518
+ }
1519
+ }
1520
+ };
1521
+ }, {}],
1522
+ 9: [function (require, module, exports) {
1081
1523
  /**
1082
1524
  * @author <steven@velozo.com>
1083
1525
  */
@@ -1264,7 +1706,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1264
1706
  "./Manyfest-CleanWrapCharacters.js": 2,
1265
1707
  "./Manyfest-LogToConsole.js": 4
1266
1708
  }],
1267
- 9: [function (require, module, exports) {
1709
+ 10: [function (require, module, exports) {
1268
1710
  /**
1269
1711
  * @author <steven@velozo.com>
1270
1712
  */
@@ -1374,7 +1816,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1374
1816
  }, {
1375
1817
  "./Manyfest-LogToConsole.js": 4
1376
1818
  }],
1377
- 10: [function (require, module, exports) {
1819
+ 11: [function (require, module, exports) {
1378
1820
  // Given a string, parse out any conditional expressions and set whether or not to keep the record.
1379
1821
  //
1380
1822
  // For instance:
@@ -1395,7 +1837,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1395
1837
  const _ConditionalStanzaEndLength = _ConditionalStanzaEnd.length;
1396
1838
 
1397
1839
  // Ugh dependency injection. Can't wait to make these all fable services.
1398
- let libObjectAddressCheckAddressExists = new (require('./Manyfest-ObjectAddress-CheckAddressExists.js'))();
1840
+ //let libObjectAddressCheckAddressExists = new (require('./Manyfest-ObjectAddress-CheckAddressExists.js'))();
1399
1841
 
1400
1842
  // Test the condition of a value in a record
1401
1843
  const testCondition = (pManyfest, pRecord, pSearchAddress, pSearchComparator, pValue) => {
@@ -1408,7 +1850,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1408
1850
  break;
1409
1851
  case 'LNGT':
1410
1852
  case 'LENGTH_GREATER_THAN':
1411
- switch (typeof typeof pManyfest.getValueAtAddress(pRecord, pSearchAddress)) {
1853
+ switch (typeof pManyfest.getValueAtAddress(pRecord, pSearchAddress)) {
1412
1854
  case 'string':
1413
1855
  return pManyfest.getValueAtAddress(pRecord, pSearchAddress).length > pValue;
1414
1856
  break;
@@ -1422,7 +1864,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1422
1864
  break;
1423
1865
  case 'LNLT':
1424
1866
  case 'LENGTH_LESS_THAN':
1425
- switch (typeof typeof pManyfest.getValueAtAddress(pRecord, pSearchAddress)) {
1867
+ switch (typeof pManyfest.getValueAtAddress(pRecord, pSearchAddress)) {
1426
1868
  case 'string':
1427
1869
  return pManyfest.getValueAtAddress(pRecord, pSearchAddress).length < pValue;
1428
1870
  break;
@@ -1434,17 +1876,15 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1434
1876
  break;
1435
1877
  }
1436
1878
  break;
1437
- case 'FALSE':
1438
- return pManyfest.getValueAtAddress(pRecord, pSearchAddress) === false;
1439
- break;
1440
- case 'EX':
1441
- case 'EXISTS':
1442
- return libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
1443
- break;
1444
- case 'DNEX':
1445
- case 'DOES_NOT_EXIST':
1446
- return !libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
1447
- break;
1879
+ // TODO: Welcome to dependency hell. This fixes itself when we move to fable services.
1880
+ // case 'EX':
1881
+ // case 'EXISTS':
1882
+ // return libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
1883
+ // break;
1884
+ // case 'DNEX':
1885
+ // case 'DOES_NOT_EXIST':
1886
+ // return !libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
1887
+ // break;
1448
1888
  case '!=':
1449
1889
  return pManyfest.getValueAtAddress(pRecord, pSearchAddress) != pValue;
1450
1890
  break;
@@ -1478,7 +1918,6 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1478
1918
  2. Find stop points within each start point
1479
1919
  3. Check the conditional
1480
1920
  */
1481
-
1482
1921
  let tmpStartIndex = pAddress.indexOf(_ConditionalStanzaStart);
1483
1922
  while (tmpStartIndex != -1) {
1484
1923
  let tmpStopIndex = pAddress.indexOf(_ConditionalStanzaEnd, tmpStartIndex + _ConditionalStanzaStartLength);
@@ -1510,10 +1949,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1510
1949
  return tmpKeepRecord;
1511
1950
  };
1512
1951
  module.exports = parseConditionals;
1513
- }, {
1514
- "./Manyfest-ObjectAddress-CheckAddressExists.js": 5
1515
- }],
1516
- 11: [function (require, module, exports) {
1952
+ }, {}],
1953
+ 12: [function (require, module, exports) {
1517
1954
  /**
1518
1955
  * @author <steven@velozo.com>
1519
1956
  */
@@ -1624,7 +2061,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1624
2061
  }, {
1625
2062
  "./Manyfest-LogToConsole.js": 4
1626
2063
  }],
1627
- 12: [function (require, module, exports) {
2064
+ 13: [function (require, module, exports) {
1628
2065
  /**
1629
2066
  * @author <steven@velozo.com>
1630
2067
  */
@@ -2039,10 +2476,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2039
2476
  "./Manyfest-ObjectAddress-CheckAddressExists.js": 5,
2040
2477
  "./Manyfest-ObjectAddress-DeleteValue.js": 6,
2041
2478
  "./Manyfest-ObjectAddress-GetValue.js": 7,
2042
- "./Manyfest-ObjectAddress-SetValue.js": 8,
2043
- "./Manyfest-ObjectAddressGeneration.js": 9,
2044
- "./Manyfest-SchemaManipulation.js": 11,
2479
+ "./Manyfest-ObjectAddress-SetValue.js": 9,
2480
+ "./Manyfest-ObjectAddressGeneration.js": 10,
2481
+ "./Manyfest-SchemaManipulation.js": 12,
2045
2482
  "fable-serviceproviderbase": 1
2046
2483
  }]
2047
- }, {}, [12])(12);
2484
+ }, {}, [13])(13);
2048
2485
  });