fable 3.1.52 → 3.1.55
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/fable.js +56 -40
- package/dist/fable.js.map +1 -1
- package/dist/fable.min.js +2 -2
- package/dist/fable.min.js.map +1 -1
- package/docs/index.html +36 -48
- package/package.json +5 -5
- package/source/services/Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-FunctionMap.json +5 -0
- package/source/services/Fable-Service-Utility.js +12 -0
- package/test/ExpressionParser_tests.js +4 -0
package/dist/fable.js
CHANGED
|
@@ -667,21 +667,28 @@ switch(pLevel){case'trace':this.logStreamsTrace.push(pLogger);case'debug':this.l
|
|
|
667
667
|
for(let i=0;i<this._StreamDefinitions.length;i++){let tmpStreamDefinition=Object.assign({loggertype:'default',streamtype:'console',level:'info'},this._StreamDefinitions[i]);if(!(tmpStreamDefinition.loggertype in this._Providers)){console.log(`Error initializing log stream: bad loggertype in stream definition ${JSON.stringify(tmpStreamDefinition)}`);}else{this.addLogger(new this._Providers[tmpStreamDefinition.loggertype](tmpStreamDefinition,this),tmpStreamDefinition.level);}}// Now initialize each one.
|
|
668
668
|
for(let i=0;i<this.logStreams.length;i++){this.logStreams[i].initialize();}}logTime(pMessage,pDatum){let tmpMessage=typeof pMessage!=='undefined'?pMessage:'Time';let tmpTime=new Date();this.info(`${tmpMessage} ${tmpTime} (epoch ${+tmpTime})`,pDatum);}// Get a timestamp
|
|
669
669
|
getTimeStamp(){return+new Date();}getTimeDelta(pTimeStamp){let tmpEndTime=+new Date();return tmpEndTime-pTimeStamp;}// Log the delta between a timestamp, and now with a message
|
|
670
|
-
logTimeDelta(pTimeDelta,pMessage,pDatum){let tmpMessage=typeof pMessage!=='undefined'?pMessage:'Time Measurement';let tmpDatum=typeof pDatum==='object'?pDatum:{};let tmpEndTime=+new Date();this.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms)`,pDatum);}logTimeDeltaHuman(pTimeDelta,pMessage,pDatum){let tmpMessage=typeof pMessage!=='undefined'?pMessage:'Time Measurement';let tmpEndTime=+new Date();let tmpMs=parseInt(pTimeDelta%1000);let tmpSeconds=parseInt(pTimeDelta/1000%60);let tmpMinutes=parseInt(pTimeDelta/(1000*60)%60);let tmpHours=parseInt(pTimeDelta/(1000*60*60));tmpMs=tmpMs<10?"00"+tmpMs:tmpMs<100?"0"+tmpMs:tmpMs;tmpSeconds=tmpSeconds<10?"0"+tmpSeconds:tmpSeconds;tmpMinutes=tmpMinutes<10?"0"+tmpMinutes:tmpMinutes;tmpHours=tmpHours<10?"0"+tmpHours:tmpHours;this.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms) or (${tmpHours}:${tmpMinutes}:${tmpSeconds}.${tmpMs})`,pDatum);}logTimeDeltaRelative(pStartTime,pMessage,pDatum){this.logTimeDelta(this.getTimeDelta(pStartTime),pMessage,pDatum);}logTimeDeltaRelativeHuman(pStartTime,pMessage,pDatum){this.logTimeDeltaHuman(this.getTimeDelta(pStartTime),pMessage,pDatum);}}module.exports=FableLog;module.exports.LogProviderBase=require('./Fable-Log-BaseLogger.js');module.exports.LogProviderConsole=require('./Fable-Log-Logger-Console.js');module.exports.LogProviderFlatfile=require('./Fable-Log-Logger-SimpleFlatFile.js');},{"../package.json":51,"./Fable-Log-BaseLogger.js":52,"./Fable-Log-DefaultProviders-Node.js":53,"./Fable-Log-DefaultStreams.json":54,"./Fable-Log-Logger-Console.js":55,"./Fable-Log-Logger-SimpleFlatFile.js":56,"fable-serviceproviderbase":59}],58:[function(require,module,exports){module.exports={"name":"fable-serviceproviderbase","version":"3.0.
|
|
670
|
+
logTimeDelta(pTimeDelta,pMessage,pDatum){let tmpMessage=typeof pMessage!=='undefined'?pMessage:'Time Measurement';let tmpDatum=typeof pDatum==='object'?pDatum:{};let tmpEndTime=+new Date();this.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms)`,pDatum);}logTimeDeltaHuman(pTimeDelta,pMessage,pDatum){let tmpMessage=typeof pMessage!=='undefined'?pMessage:'Time Measurement';let tmpEndTime=+new Date();let tmpMs=parseInt(pTimeDelta%1000);let tmpSeconds=parseInt(pTimeDelta/1000%60);let tmpMinutes=parseInt(pTimeDelta/(1000*60)%60);let tmpHours=parseInt(pTimeDelta/(1000*60*60));tmpMs=tmpMs<10?"00"+tmpMs:tmpMs<100?"0"+tmpMs:tmpMs;tmpSeconds=tmpSeconds<10?"0"+tmpSeconds:tmpSeconds;tmpMinutes=tmpMinutes<10?"0"+tmpMinutes:tmpMinutes;tmpHours=tmpHours<10?"0"+tmpHours:tmpHours;this.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms) or (${tmpHours}:${tmpMinutes}:${tmpSeconds}.${tmpMs})`,pDatum);}logTimeDeltaRelative(pStartTime,pMessage,pDatum){this.logTimeDelta(this.getTimeDelta(pStartTime),pMessage,pDatum);}logTimeDeltaRelativeHuman(pStartTime,pMessage,pDatum){this.logTimeDeltaHuman(this.getTimeDelta(pStartTime),pMessage,pDatum);}}module.exports=FableLog;module.exports.LogProviderBase=require('./Fable-Log-BaseLogger.js');module.exports.LogProviderConsole=require('./Fable-Log-Logger-Console.js');module.exports.LogProviderFlatfile=require('./Fable-Log-Logger-SimpleFlatFile.js');},{"../package.json":51,"./Fable-Log-BaseLogger.js":52,"./Fable-Log-DefaultProviders-Node.js":53,"./Fable-Log-DefaultStreams.json":54,"./Fable-Log-Logger-Console.js":55,"./Fable-Log-Logger-SimpleFlatFile.js":56,"fable-serviceproviderbase":59}],58:[function(require,module,exports){module.exports={"name":"fable-serviceproviderbase","version":"3.0.17","description":"Simple base classes for fable services.","main":"source/Fable-ServiceProviderBase.js","scripts":{"start":"node source/Fable-ServiceProviderBase.js","test":"npx mocha -u tdd -R spec","tests":"npx mocha -u tdd --exit -R spec --grep","coverage":"npx nyc --reporter=lcov --reporter=text-lcov npx mocha -- -u tdd -R spec","build":"npx quack build","types":"tsc -p ./tsconfig.build.json","check":"tsc -p . --noEmit"},"types":"types/source/Fable-ServiceProviderBase.d.ts","mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable-serviceproviderbase.git"},"keywords":["entity","behavior"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable-serviceproviderbase/issues"},"homepage":"https://github.com/stevenvelozo/fable-serviceproviderbase","devDependencies":{"@types/mocha":"^10.0.10","fable":"^3.1.51","quackage":"^1.0.45","typescript":"^5.9.3"}};},{}],59:[function(require,module,exports){/**
|
|
671
671
|
* Fable Service Base
|
|
672
672
|
* @author <steven@velozo.com>
|
|
673
|
-
*/const libPackage=require('../package.json');class FableServiceProviderBase{
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
673
|
+
*/const libPackage=require('../package.json');class FableServiceProviderBase{/**
|
|
674
|
+
* The constructor can be used in two ways:
|
|
675
|
+
* 1) With a fable, options object and service hash (the options object and service hash are optional)a
|
|
676
|
+
* 2) With an object or nothing as the first parameter, where it will be treated as the options object
|
|
677
|
+
*
|
|
678
|
+
* @param {import('fable')|Record<string, any>} [pFable] - (optional) The fable instance, or the options object if there is no fable
|
|
679
|
+
* @param {Record<string, any>|string} [pOptions] - (optional) The options object, or the service hash if there is no fable
|
|
680
|
+
* @param {string} [pServiceHash] - (optional) The service hash to identify this service instance
|
|
681
|
+
*/constructor(pFable,pOptions,pServiceHash){/** @type {import('fable')} */this.fable;/** @type {string} */this.UUID;/** @type {Record<string, any>} */this.options;/** @type {Record<string, any>} */this.services;/** @type {Record<string, any>} */this.servicesMap;// Check if a fable was passed in; connect it if so
|
|
677
682
|
if(typeof pFable==='object'&&pFable.isFable){this.connectFable(pFable);}else{this.fable=false;}// Initialize the services map if it wasn't passed in
|
|
678
|
-
/** @type {
|
|
683
|
+
/** @type {Record<string, any>} */this._PackageFableServiceProvider=libPackage;// initialize options and UUID based on whether the fable was passed in or not.
|
|
679
684
|
if(this.fable){this.UUID=pFable.getUUID();this.options=typeof pOptions==='object'?pOptions:{};}else{// With no fable, check to see if there was an object passed into either of the first two
|
|
680
685
|
// Parameters, and if so, treat it as the options object
|
|
681
686
|
this.options=typeof pFable==='object'&&!pFable.isFable?pFable:typeof pOptions==='object'?pOptions:{};this.UUID=`CORE-SVC-${Math.floor(Math.random()*(99999-10000)+10000)}`;}// It's expected that the deriving class will set this
|
|
682
687
|
this.serviceType=`Unknown-${this.UUID}`;// The service hash is used to identify the specific instantiation of the service in the services map
|
|
683
|
-
this.Hash=typeof pServiceHash==='string'?pServiceHash:!this.fable&&typeof pOptions==='string'?pOptions:`${this.UUID}`;}
|
|
684
|
-
|
|
688
|
+
this.Hash=typeof pServiceHash==='string'?pServiceHash:!this.fable&&typeof pOptions==='string'?pOptions:`${this.UUID}`;}/**
|
|
689
|
+
* @param {import('fable')} pFable
|
|
690
|
+
*/connectFable(pFable){if(typeof pFable!=='object'||!pFable.isFable){let tmpErrorMessage=`Fable Service Provider Base: Cannot connect to Fable, invalid Fable object passed in. The pFable parameter was a [${typeof pFable}].}`;console.log(tmpErrorMessage);return new Error(tmpErrorMessage);}if(!this.fable){this.fable=pFable;}if(!this.log){this.log=this.fable.Logging;}if(!this.services){this.services=this.fable.services;}if(!this.servicesMap){this.servicesMap=this.fable.servicesMap;}return true;}}_defineProperty2(FableServiceProviderBase,"isFableService",true);module.exports=FableServiceProviderBase;// This is left here in case we want to go back to having different code/base class for "core" services
|
|
691
|
+
module.exports.CoreServiceProviderBase=FableServiceProviderBase;},{"../package.json":58}],60:[function(require,module,exports){module.exports={"name":"fable-settings","version":"3.0.14","description":"A simple, tolerant configuration chain.","main":"source/Fable-Settings.js","scripts":{"start":"node source/Fable-Settings.js","coverage":"./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec","test":"./node_modules/.bin/mocha -u tdd -R spec","build":"./node_modules/.bin/gulp build","docker-dev-build-image":"docker build ./ -f Dockerfile_LUXURYCode -t retold/fable-settings:local","docker-dev-run":"docker run -it -d --name retold-fable-settings-dev -p 30003:8080 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/fable-settings\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" retold/fable-settings:local"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable-settings.git"},"keywords":["configuration"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable-settings/issues"},"homepage":"https://github.com/stevenvelozo/fable-settings","devDependencies":{"quackage":"^1.0.48"},"dependencies":{"fable-serviceproviderbase":"^3.0.17","precedent":"^1.0.15"}};},{}],61:[function(require,module,exports){module.exports={"Product":"ApplicationNameHere","ProductVersion":"0.0.0","ConfigFile":false,"LogStreams":[{"level":"trace"}]};},{}],62:[function(require,module,exports){(function(process){(function(){/**
|
|
685
692
|
* Fable Settings Template Processor
|
|
686
693
|
*
|
|
687
694
|
* This class allows environment variables to come in via templated expressions, and defaults to be set.
|
|
@@ -962,7 +969,7 @@ return false;}// Now see if the function has arguments.
|
|
|
962
969
|
let tmpFunctionArguments=_MockFable.DataFormat.stringGetSegments(_MockFable.DataFormat.stringGetEnclosureValueByIndex(tmpSubObjectName.substring(tmpFunctionAddress.length),0),',');if(tmpFunctionArguments.length==0||tmpFunctionArguments[0]==''){// No arguments... just call the function (bound to the scope of the object it is contained withing)
|
|
963
970
|
if(tmpFunctionAddress in pObject){try{return this.checkAddressExists(pObject[tmpFunctionAddress].apply(pObject),tmpNewAddress,tmpRootObject);}catch(pError){// The function call failed, so the address doesn't exist
|
|
964
971
|
libSimpleLog(`Error calling function ${tmpFunctionAddress} (address [${pAddress}]): ${pError.message}`);return false;}}else{// The function doesn't exist, so the address doesn't exist
|
|
965
|
-
libSimpleLog(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[]
|
|
972
|
+
libSimpleLog(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[];// Now get the value for each argument
|
|
966
973
|
for(let i=0;i<tmpFunctionArguments.length;i++){// Resolve the values for each subsequent entry
|
|
967
974
|
// NOTE: This is where the resolves get really tricky. Recursion within recursion. Programming gom jabbar, yo.
|
|
968
975
|
tmpArgumentValues.push(this.getObjectValueClass.getValueAtAddress(tmpRootObject,tmpFunctionArguments[i]));}//return this.checkAddressExists(pObject[tmpFunctionAddress].apply(pObject, tmpArgumentValues), tmpNewAddress, tmpRootObject);
|
|
@@ -1004,10 +1011,10 @@ return this.checkAddressExists(pObject[tmpBoxedPropertyName][tmpBoxedPropertyRef
|
|
|
1004
1011
|
return this.checkAddressExists(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber],tmpNewAddress,tmpRootObject);}}// If there is an object property already named for the sub object, but it isn't an object
|
|
1005
1012
|
// then the system can't set the value in there. Error and abort!
|
|
1006
1013
|
if(tmpSubObjectName in pObject&&typeof pObject[tmpSubObjectName]!=='object'){return false;}else if(tmpSubObjectName in pObject){// If there is already a subobject pass that to the recursive thingy
|
|
1007
|
-
return this.checkAddressExists(pObject[tmpSubObjectName],tmpNewAddress,tmpRootObject);}else{//
|
|
1008
|
-
|
|
1014
|
+
return this.checkAddressExists(pObject[tmpSubObjectName],tmpNewAddress,tmpRootObject);}else{// The sub-object doesn't exist, so the address doesn't exist
|
|
1015
|
+
return false;}}}}module.exports=ManyfestObjectAddressResolverCheckAddressExists;},{"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83,"./Manyfest-ObjectAddress-GetValue.js":86,"./Manyfest-ObjectAddress-Parser.js":87}],85:[function(require,module,exports){/**
|
|
1009
1016
|
* @author <steven@velozo.com>
|
|
1010
|
-
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');let fParseConditionals=require(`../source/Manyfest-ParseConditionals.js`);/**
|
|
1017
|
+
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');let fParseConditionals=require(`../source/Manyfest-ParseConditionals.js`);let _MockFable={DataFormat:require('./Manyfest-ObjectAddress-Parser.js')};/**
|
|
1011
1018
|
* Object Address Resolver - DeleteValue
|
|
1012
1019
|
*
|
|
1013
1020
|
* IMPORTANT NOTE: This code is intentionally more verbose than necessary, to
|
|
@@ -1047,9 +1054,9 @@ this.logInfo=typeof pInfoLog=='function'?pInfoLog:libSimpleLog;this.logError=typ
|
|
|
1047
1054
|
*/deleteValueAtAddress(pObject,pAddress,pParentAddress){// Make sure pObject (the object we are meant to be recursing) is an object (which could be an array or object)
|
|
1048
1055
|
if(typeof pObject!='object')return undefined;// Make sure pAddress (the address we are resolving) is a string
|
|
1049
1056
|
if(typeof pAddress!='string')return undefined;// Stash the parent address for later resolution
|
|
1050
|
-
let tmpParentAddress="";if(typeof pParentAddress=='string'){tmpParentAddress=pParentAddress;}//
|
|
1051
|
-
let
|
|
1052
|
-
if(
|
|
1057
|
+
let tmpParentAddress="";if(typeof pParentAddress=='string'){tmpParentAddress=pParentAddress;}// Use enclosure-aware parser to find the first segment separator
|
|
1058
|
+
let tmpAddressPartBeginning=_MockFable.DataFormat.stringGetFirstSegment(pAddress);// This is the terminal address string (no more dots so the RECUSION ENDS IN HERE somehow)
|
|
1059
|
+
if(tmpAddressPartBeginning.length==pAddress.length){// Check if the address refers to a boxed property
|
|
1053
1060
|
let tmpBracketStartIndex=pAddress.indexOf('[');let tmpBracketStopIndex=pAddress.indexOf(']');// Check for the Object Set Type marker.
|
|
1054
1061
|
// Note this will not work with a bracket in the same address box set
|
|
1055
1062
|
let tmpObjectTypeMarkerIndex=pAddress.indexOf('{}');// Boxed elements look like this:
|
|
@@ -1089,7 +1096,7 @@ let tmpKeepRecord=this.checkRecordFilters(pAddress,tmpInputArray[i]);if(tmpKeepR
|
|
|
1089
1096
|
tmpInputArray.splice(i,1);}}return true;}// The object has been flagged as an object set, so treat it as such
|
|
1090
1097
|
else if(tmpObjectTypeMarkerIndex>0){let tmpObjectPropertyName=pAddress.substring(0,tmpObjectTypeMarkerIndex).trim();if(typeof pObject[tmpObjectPropertyName]!='object'){// We asked for a set from an array but it isnt' an array.
|
|
1091
1098
|
return false;}delete pObject[tmpObjectPropertyName];return true;}else{// Now is the point in recursion to return the value in the address
|
|
1092
|
-
delete pObject[pAddress];return true;}}else{let tmpSubObjectName=
|
|
1099
|
+
delete pObject[pAddress];return true;}}else{let tmpSubObjectName=tmpAddressPartBeginning;let tmpNewAddress=pAddress.substring(tmpAddressPartBeginning.length+1);// BOXED ELEMENTS
|
|
1093
1100
|
// Test if the tmpNewAddress is an array or object
|
|
1094
1101
|
// Check if it's a boxed property
|
|
1095
1102
|
let tmpBracketStartIndex=tmpSubObjectName.indexOf('[');let tmpBracketStopIndex=tmpSubObjectName.indexOf(']');// Boxed elements look like this:
|
|
@@ -1147,7 +1154,7 @@ if(tmpSubObjectName in pObject&&typeof pObject[tmpSubObjectName]!=='object'){ret
|
|
|
1147
1154
|
// Continue to manage the parent address for recursion
|
|
1148
1155
|
tmpParentAddress=`${tmpParentAddress}${tmpParentAddress.length>0?'.':''}${tmpSubObjectName}`;return this.deleteValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,tmpParentAddress);}else{// Create a subobject and then pass that
|
|
1149
1156
|
// Continue to manage the parent address for recursion
|
|
1150
|
-
tmpParentAddress=`${tmpParentAddress}${tmpParentAddress.length>0?'.':''}${tmpSubObjectName}`;pObject[tmpSubObjectName]={};return this.deleteValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,tmpParentAddress);}}}};module.exports=ManyfestObjectAddressResolverDeleteValue;},{"../source/Manyfest-ParseConditionals.js":90,"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83}],86:[function(require,module,exports){/**
|
|
1157
|
+
tmpParentAddress=`${tmpParentAddress}${tmpParentAddress.length>0?'.':''}${tmpSubObjectName}`;pObject[tmpSubObjectName]={};return this.deleteValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,tmpParentAddress);}}}};module.exports=ManyfestObjectAddressResolverDeleteValue;},{"../source/Manyfest-ParseConditionals.js":90,"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83,"./Manyfest-ObjectAddress-Parser.js":87}],86:[function(require,module,exports){/**
|
|
1151
1158
|
* @author <steven@velozo.com>
|
|
1152
1159
|
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');let fParseConditionals=require(`../source/Manyfest-ParseConditionals.js`);let _MockFable={DataFormat:require('./Manyfest-ObjectAddress-Parser.js')};/**
|
|
1153
1160
|
* Object Address Resolver - GetValue
|
|
@@ -1226,7 +1233,7 @@ return false;}// Now see if the function has arguments.
|
|
|
1226
1233
|
let tmpFunctionArguments=_MockFable.DataFormat.stringGetSegments(_MockFable.DataFormat.stringGetEnclosureValueByIndex(pAddress.substring(tmpFunctionAddress.length),0),',');if(tmpFunctionArguments.length==0||tmpFunctionArguments[0]==''){// No arguments... just call the function (bound to the scope of the object it is contained withing)
|
|
1227
1234
|
if(tmpFunctionAddress in pObject){try{return pObject[tmpFunctionAddress].apply(pObject);}catch(pError){// The function call failed, so the address doesn't exist
|
|
1228
1235
|
console.log(`Error in getValueAtAddress calling function ${tmpFunctionAddress} (address [${pAddress}]): ${pError.message}`);return false;}}else{// The function doesn't exist, so the address doesn't exist
|
|
1229
|
-
console.log(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[]
|
|
1236
|
+
console.log(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[];// Now get the value for each argument
|
|
1230
1237
|
for(let i=0;i<tmpFunctionArguments.length;i++){// Resolve the values for each subsequent entry
|
|
1231
1238
|
// Check if the argument value is a string literal or a reference to an address
|
|
1232
1239
|
if(tmpFunctionArguments[i].length>=2&&(tmpFunctionArguments[i].charAt(0)=='"'||tmpFunctionArguments[i].charAt(0)=="'"||tmpFunctionArguments[i].charAt(0)=="`")&&(tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=='"'||tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=="'"||tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=="`")){// This is a string literal
|
|
@@ -1268,7 +1275,7 @@ return false;}let tmpInputArray=pObject[tmpBoxedPropertyName];let tmpOutputArray
|
|
|
1268
1275
|
let tmpKeepRecord=this.checkRecordFilters(pAddress,tmpInputArray[i]);if(tmpKeepRecord){tmpOutputArray.push(tmpInputArray[i]);}}return tmpOutputArray;}// The object has been flagged as an object set, so treat it as such
|
|
1269
1276
|
else if(tmpObjectTypeMarkerIndex>0){let tmpObjectPropertyName=pAddress.substring(0,tmpObjectTypeMarkerIndex).trim();if(typeof pObject[tmpObjectPropertyName]!='object'){// We asked for a set from an array but it isnt' an array.
|
|
1270
1277
|
return false;}return pObject[tmpObjectPropertyName];}else{// Now is the point in recursion to return the value in the address
|
|
1271
|
-
if(typeof pObject[pAddress]!=
|
|
1278
|
+
if(typeof pObject[pAddress]!='undefined'){return pObject[pAddress];}else{return undefined;}}}else{//let tmpSubObjectName = pAddress.substring(0, tmpSeparatorIndex);
|
|
1272
1279
|
//let tmpNewAddress = pAddress.substring(tmpSeparatorIndex+1);
|
|
1273
1280
|
let tmpSubObjectName=tmpAddressPartBeginning;let tmpNewAddress=pAddress.substring(tmpAddressPartBeginning.length+1);// BOXED ELEMENTS
|
|
1274
1281
|
// Test if the tmpNewAddress is an array or object
|
|
@@ -1293,7 +1300,7 @@ return false;}// Now see if the function has arguments.
|
|
|
1293
1300
|
let tmpFunctionArguments=_MockFable.DataFormat.stringGetSegments(_MockFable.DataFormat.stringGetEnclosureValueByIndex(tmpSubObjectName.substring(tmpFunctionAddress.length),0),',');if(tmpFunctionArguments.length==0||tmpFunctionArguments[0]==''){// No arguments... just call the function (bound to the scope of the object it is contained withing)
|
|
1294
1301
|
if(tmpFunctionAddress in pObject){try{return this.getValueAtAddress(pObject[tmpFunctionAddress].apply(pObject),tmpNewAddress,tmpParentAddress,tmpRootObject);}catch(pError){// The function call failed, so the address doesn't exist
|
|
1295
1302
|
console.log(`Error in getValueAtAddress calling function ${tmpFunctionAddress} (address [${pAddress}]): ${pError.message}`);return false;}}else{// The function doesn't exist, so the address doesn't exist
|
|
1296
|
-
console.log(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[]
|
|
1303
|
+
console.log(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[];// Now get the value for each argument
|
|
1297
1304
|
for(let i=0;i<tmpFunctionArguments.length;i++){// Resolve the values for each subsequent entry
|
|
1298
1305
|
// Check if the argument value is a string literal or a reference to an address
|
|
1299
1306
|
if(tmpFunctionArguments[i].length>=2&&(tmpFunctionArguments[i].charAt(0)=='"'||tmpFunctionArguments[i].charAt(0)=="'"||tmpFunctionArguments[i].charAt(0)=="`")&&(tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=='"'||tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=="'"||tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=="`")){// This is a string literal
|
|
@@ -1370,7 +1377,7 @@ const DEFAULT_START_SYMBOL_MAP={'{':0,'[':1,'(':2};const DEFAULT_END_SYMBOL_MAP=
|
|
|
1370
1377
|
* @param {Record<string, number>} [pEnclosureEndSymbolMap]
|
|
1371
1378
|
*
|
|
1372
1379
|
* @return {number} - The number of segments in the string
|
|
1373
|
-
*/stringCountSegments:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;if(
|
|
1380
|
+
*/stringCountSegments:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;if(tmpString.length<1){return 0;}let tmpSegmentCount=1;let tmpEnclosureStack=[];for(let i=0;i<tmpString.length;i++){// IF This is the start of a segment
|
|
1374
1381
|
if(tmpString[i]==tmpSeparator// AND we are not in a nested portion of the string
|
|
1375
1382
|
&&tmpEnclosureStack.length==0){// Increment the segment count
|
|
1376
1383
|
tmpSegmentCount++;}// IF This is the start of an enclosure
|
|
@@ -1387,7 +1394,7 @@ tmpEnclosureStack.pop();}}return tmpSegmentCount;},/**
|
|
|
1387
1394
|
* @param {Record<string, number>} [pEnclosureEndSymbolMap]
|
|
1388
1395
|
*
|
|
1389
1396
|
* @return {string} - the first segment in the string as a string
|
|
1390
|
-
*/stringGetFirstSegment:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;if(
|
|
1397
|
+
*/stringGetFirstSegment:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;if(tmpString.length<1){return'';}let tmpEnclosureStack=[];for(let i=0;i<tmpString.length;i++){// IF This is the start of a segment
|
|
1391
1398
|
if(tmpString[i]==tmpSeparator// AND we are not in a nested portion of the string
|
|
1392
1399
|
&&tmpEnclosureStack.length==0){// Return the segment
|
|
1393
1400
|
return tmpString.substring(0,i);}// IF This is the start of an enclosure
|
|
@@ -1404,7 +1411,7 @@ tmpEnclosureStack.pop();}}return tmpString;},/**
|
|
|
1404
1411
|
* @param {Record<string, number>} [pEnclosureEndSymbolMap]
|
|
1405
1412
|
*
|
|
1406
1413
|
* @return {Array<string>} - the segments in the string as an array of strings
|
|
1407
|
-
*/stringGetSegments:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;let tmpCurrentSegmentStart=0;let tmpSegmentList=[];if(
|
|
1414
|
+
*/stringGetSegments:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;let tmpCurrentSegmentStart=0;let tmpSegmentList=[];if(tmpString.length<1){return tmpSegmentList;}let tmpEnclosureStack=[];for(let i=0;i<tmpString.length;i++){// IF This is the start of a segment
|
|
1408
1415
|
if(tmpString[i]==tmpSeparator// AND we are not in a nested portion of the string
|
|
1409
1416
|
&&tmpEnclosureStack.length==0){// Return the segment
|
|
1410
1417
|
tmpSegmentList.push(tmpString.substring(tmpCurrentSegmentStart,i));tmpCurrentSegmentStart=i+1;}// IF This is the start of an enclosure
|
|
@@ -1441,7 +1448,7 @@ else if(tmpString[i]==tmpEnclosureEnd){tmpEnclosureDepth--;// Again, only count
|
|
|
1441
1448
|
if(tmpEnclosureDepth==0&&tmpMatchedEnclosureIndex&&tmpEnclosedValueEndIndex<=tmpEnclosedValueStartIndex){tmpEnclosedValueEndIndex=i;tmpMatchedEnclosureIndex=false;}}}if(tmpEnclosureCount<=tmpEnclosureIndexToGet){// Return an empty string if the enclosure is not found
|
|
1442
1449
|
return'';}if(tmpEnclosedValueEndIndex>0&&tmpEnclosedValueEndIndex>tmpEnclosedValueStartIndex){return tmpString.substring(tmpEnclosedValueStartIndex+1,tmpEnclosedValueEndIndex);}else{return tmpString.substring(tmpEnclosedValueStartIndex+1);}}};},{}],88:[function(require,module,exports){/**
|
|
1443
1450
|
* @author <steven@velozo.com>
|
|
1444
|
-
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');/**
|
|
1451
|
+
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');let _MockFable={DataFormat:require('./Manyfest-ObjectAddress-Parser.js')};/**
|
|
1445
1452
|
* Object Address Resolver - SetValue
|
|
1446
1453
|
*
|
|
1447
1454
|
* IMPORTANT NOTE: This code is intentionally more verbose than necessary, to
|
|
@@ -1472,7 +1479,8 @@ this.logInfo=typeof pInfoLog=='function'?pInfoLog:libSimpleLog;this.logError=typ
|
|
|
1472
1479
|
* @return {boolean} True if the value was set, false otherwise
|
|
1473
1480
|
*/setValueAtAddress(pObject,pAddress,pValue){// Make sure pObject is an object
|
|
1474
1481
|
if(typeof pObject!='object')return false;// Make sure pAddress is a string
|
|
1475
|
-
if(typeof pAddress!='string')return false
|
|
1482
|
+
if(typeof pAddress!='string')return false;// Use enclosure-aware parser to find the first segment separator
|
|
1483
|
+
let tmpAddressPartBeginning=_MockFable.DataFormat.stringGetFirstSegment(pAddress);if(tmpAddressPartBeginning.length==pAddress.length){// Check if it's a boxed property
|
|
1476
1484
|
let tmpBracketStartIndex=pAddress.indexOf('[');let tmpBracketStopIndex=pAddress.indexOf(']');// Boxed elements look like this:
|
|
1477
1485
|
// MyValues[10]
|
|
1478
1486
|
// MyValues['Name']
|
|
@@ -1503,7 +1511,7 @@ pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference]={};}// Return the value
|
|
|
1503
1511
|
//TODO: For cases where we have chained [][] properties, this needs to recurse somehow
|
|
1504
1512
|
pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference]=pValue;return true;}else{while(pObject[tmpBoxedPropertyName].length<tmpBoxedPropertyNumber+1){// If the subobject doesn't exist, create it
|
|
1505
1513
|
pObject[tmpBoxedPropertyName].push({});}pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber]=pValue;return true;}}else{// Now is the time in recursion to set the value in the object
|
|
1506
|
-
pObject[pAddress]=pValue;return true;}}else{let tmpSubObjectName=
|
|
1514
|
+
pObject[pAddress]=pValue;return true;}}else{let tmpSubObjectName=tmpAddressPartBeginning;let tmpNewAddress=pAddress.substring(tmpAddressPartBeginning.length+1);// Test if the tmpNewAddress is an array or object
|
|
1507
1515
|
// Check if it's a boxed property
|
|
1508
1516
|
let tmpBracketStartIndex=tmpSubObjectName.indexOf('[');let tmpBracketStopIndex=tmpSubObjectName.indexOf(']');// Boxed elements look like this:
|
|
1509
1517
|
// MyValues[42]
|
|
@@ -1544,7 +1552,7 @@ return this.setValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumb
|
|
|
1544
1552
|
if(tmpSubObjectName in pObject&&typeof pObject[tmpSubObjectName]!=='object'){if(!('__ERROR'in pObject))pObject['__ERROR']={};// Put it in an error object so data isn't lost
|
|
1545
1553
|
pObject['__ERROR'][pAddress]=pValue;return false;}else if(tmpSubObjectName in pObject){// If there is already a subobject pass that to the recursive thingy
|
|
1546
1554
|
return this.setValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,pValue);}else{// Create a subobject and then pass that
|
|
1547
|
-
pObject[tmpSubObjectName]={};return this.setValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,pValue);}}}};module.exports=ManyfestObjectAddressSetValue;},{"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83}],89:[function(require,module,exports){/**
|
|
1555
|
+
pObject[tmpSubObjectName]={};return this.setValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,pValue);}}}};module.exports=ManyfestObjectAddressSetValue;},{"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83,"./Manyfest-ObjectAddress-Parser.js":87}],89:[function(require,module,exports){/**
|
|
1548
1556
|
* @author <steven@velozo.com>
|
|
1549
1557
|
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');/**
|
|
1550
1558
|
* Object Address Generation
|
|
@@ -1604,7 +1612,7 @@ break;}return tmpSchema;}};module.exports=ManyfestObjectAddressGeneration;},{"./
|
|
|
1604
1612
|
const _ConditionalStanzaStart='<<~?';const _ConditionalStanzaStartLength=_ConditionalStanzaStart.length;const _ConditionalStanzaEnd='?~>>';const _ConditionalStanzaEndLength=_ConditionalStanzaEnd.length;// Ugh dependency injection. Can't wait to make these all fable services.
|
|
1605
1613
|
//let libObjectAddressCheckAddressExists = new (require('./Manyfest-ObjectAddress-CheckAddressExists.js'))();
|
|
1606
1614
|
// Test the condition of a value in a record
|
|
1607
|
-
const testCondition=(pManyfest,pRecord,pSearchAddress,pSearchComparator,pValue)=>{switch(pSearchComparator){case'TRUE':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===true;
|
|
1615
|
+
const testCondition=(pManyfest,pRecord,pSearchAddress,pSearchComparator,pValue)=>{switch(pSearchComparator){case'TRUE':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===true;case'FALSE':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===false;case'LNGT':case'LENGTH_GREATER_THAN':switch(typeof pManyfest.getValueAtAddress(pRecord,pSearchAddress)){case'string':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length>pValue;case'object':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length>pValue;default:return false;break;}break;case'LNLT':case'LENGTH_LESS_THAN':switch(typeof pManyfest.getValueAtAddress(pRecord,pSearchAddress)){case'string':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length<pValue;case'object':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length<pValue;default:return false;break;}break;// TODO: Welcome to dependency hell. This fixes itself when we move to fable services.
|
|
1608
1616
|
// case 'EX':
|
|
1609
1617
|
// case 'EXISTS':
|
|
1610
1618
|
// return libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
|
|
@@ -1613,7 +1621,7 @@ const testCondition=(pManyfest,pRecord,pSearchAddress,pSearchComparator,pValue)=
|
|
|
1613
1621
|
// case 'DOES_NOT_EXIST':
|
|
1614
1622
|
// return !libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
|
|
1615
1623
|
// break;
|
|
1616
|
-
case'!=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)!=pValue;
|
|
1624
|
+
case'!=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)!=pValue;case'<':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)<pValue;case'>':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)>pValue;case'<=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)<=pValue;case'>=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)>=pValue;case'===':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===pValue;case'==':default:return pManyfest.getValueAtAddress(pRecord,pSearchAddress)==pValue;}};const parseConditionals=(pManyfest,pAddress,pRecord)=>{let tmpKeepRecord=true;/*
|
|
1617
1625
|
Algorithm is simple:
|
|
1618
1626
|
|
|
1619
1627
|
1. Enuerate start points
|
|
@@ -1707,9 +1715,8 @@ tmpNewManyfest.hashTranslations.addTranslation(this.hashTranslations.translation
|
|
|
1707
1715
|
* @return {Manyfest} The deserialized manifest
|
|
1708
1716
|
*/deserialize(pManifestString){// TODO: Add guards for bad manifest string
|
|
1709
1717
|
this.loadManifest(JSON.parse(pManifestString));return this;}// Load a manifest from an object
|
|
1710
|
-
loadManifest(pManifest){if(typeof pManifest!=='object'){this.logError(`(${this.scope}) Error loading manifest; expecting an object but parameter was type ${typeof pManifest}.`);}let tmpManifest=typeof pManifest=='object'?pManifest:{};let tmpDescriptorKeys=Object.keys(_DefaultConfiguration);for(let i=0;i<tmpDescriptorKeys.length;i++){if(!(tmpDescriptorKeys[i]in tmpManifest)){tmpManifest[tmpDescriptorKeys[i]]=JSON.parse(JSON.stringify(_DefaultConfiguration[tmpDescriptorKeys[i]]));}}if('Scope'in tmpManifest){if(typeof tmpManifest.Scope==='string'){this.scope=tmpManifest.Scope;}else{this.logError(`(${this.scope}) Error loading scope from manifest; expecting a string but property was type ${typeof tmpManifest.Scope}.`,tmpManifest);}}else{this.logError(`(${this.scope}) Error loading scope from manifest object. Property "Scope" does not exist in the root of the object.`,tmpManifest);}if('Descriptors'in tmpManifest){if(typeof tmpManifest.Descriptors==='object'){let tmpDescriptionAddresses=Object.keys(tmpManifest.Descriptors);for(let i=0;i<tmpDescriptionAddresses.length;i++){this.addDescriptor(tmpDescriptionAddresses[i],tmpManifest.Descriptors[tmpDescriptionAddresses[i]]);}}else{this.logError(`(${this.scope}) Error loading description object from manifest object. Expecting an object in 'Manifest.Descriptors' but the property was type ${typeof tmpManifest.Descriptors}.`,tmpManifest);}}else{this.logError(`(${this.scope}) Error loading object description from manifest object. Property "Descriptors" does not exist in the root of the Manifest object.`,tmpManifest);}if('HashTranslations'in tmpManifest){if(typeof tmpManifest.HashTranslations==='object'){
|
|
1711
|
-
|
|
1712
|
-
}}}}/**
|
|
1718
|
+
loadManifest(pManifest){if(typeof pManifest!=='object'){this.logError(`(${this.scope}) Error loading manifest; expecting an object but parameter was type ${typeof pManifest}.`);}let tmpManifest=typeof pManifest=='object'?pManifest:{};let tmpDescriptorKeys=Object.keys(_DefaultConfiguration);for(let i=0;i<tmpDescriptorKeys.length;i++){if(!(tmpDescriptorKeys[i]in tmpManifest)){tmpManifest[tmpDescriptorKeys[i]]=JSON.parse(JSON.stringify(_DefaultConfiguration[tmpDescriptorKeys[i]]));}}if('Scope'in tmpManifest){if(typeof tmpManifest.Scope==='string'){this.scope=tmpManifest.Scope;}else{this.logError(`(${this.scope}) Error loading scope from manifest; expecting a string but property was type ${typeof tmpManifest.Scope}.`,tmpManifest);}}else{this.logError(`(${this.scope}) Error loading scope from manifest object. Property "Scope" does not exist in the root of the object.`,tmpManifest);}if('Descriptors'in tmpManifest){if(typeof tmpManifest.Descriptors==='object'){let tmpDescriptionAddresses=Object.keys(tmpManifest.Descriptors);for(let i=0;i<tmpDescriptionAddresses.length;i++){this.addDescriptor(tmpDescriptionAddresses[i],tmpManifest.Descriptors[tmpDescriptionAddresses[i]]);}}else{this.logError(`(${this.scope}) Error loading description object from manifest object. Expecting an object in 'Manifest.Descriptors' but the property was type ${typeof tmpManifest.Descriptors}.`,tmpManifest);}}else{this.logError(`(${this.scope}) Error loading object description from manifest object. Property "Descriptors" does not exist in the root of the Manifest object.`,tmpManifest);}if('HashTranslations'in tmpManifest){if(typeof tmpManifest.HashTranslations==='object'){// HashTranslations is serialized as a plain object of source:target pairs
|
|
1719
|
+
this.hashTranslations.addTranslation(tmpManifest.HashTranslations);}}}/**
|
|
1713
1720
|
* Serialize the Manifest to a string
|
|
1714
1721
|
*
|
|
1715
1722
|
* @return {string} - The serialized manifest
|
|
@@ -1748,20 +1755,22 @@ else if(tmpInTranslationTable){tmpAddress=this.hashTranslations.translate(pHash)
|
|
|
1748
1755
|
// TODO: Discuss this ... it is magic but controversial
|
|
1749
1756
|
else{tmpAddress=pHash;}return tmpAddress;}// Get the value of an element by its hash
|
|
1750
1757
|
getValueByHash(pObject,pHash){let tmpValue=this.getValueAtAddress(pObject,this.resolveHashAddress(pHash));if(typeof tmpValue=='undefined'){// Try to get a default if it exists
|
|
1751
|
-
tmpValue=this.getDefaultValue(this.getDescriptorByHash(pHash));}return tmpValue;}lintAddress(pAddress){
|
|
1752
|
-
if(
|
|
1758
|
+
tmpValue=this.getDefaultValue(this.getDescriptorByHash(pHash));}return tmpValue;}lintAddress(pAddress){// Guard against non-string input
|
|
1759
|
+
if(typeof pAddress!='string'){return'';}let tmpLintedAddress=pAddress.trim();// Check for a single trailing . (but not a ..) at the end of the address and remove it.
|
|
1760
|
+
// We must not strip '..' because that is back-navigation syntax.
|
|
1761
|
+
if(tmpLintedAddress.endsWith('.')&&!tmpLintedAddress.endsWith('..')){tmpLintedAddress=tmpLintedAddress.slice(0,-1);}return tmpLintedAddress;}// Get the value of an element at an address
|
|
1753
1762
|
getValueAtAddress(pObject,pAddress){let tmpLintedAddress=this.lintAddress(pAddress);if(tmpLintedAddress==''){this.logError(`(${this.scope}) Error getting value at address; address is an empty string.`,pObject);return undefined;}let tmpValue=this.objectAddressGetValue.getValueAtAddress(pObject,tmpLintedAddress);if(typeof tmpValue=='undefined'){// Try to get a default if it exists
|
|
1754
1763
|
tmpValue=this.getDefaultValue(this.getDescriptor(tmpLintedAddress));}return tmpValue;}// Set the value of an element by its hash
|
|
1755
1764
|
setValueByHash(pObject,pHash,pValue){return this.setValueAtAddress(pObject,this.resolveHashAddress(pHash),pValue);}// Set the value of an element at an address
|
|
1756
1765
|
setValueAtAddress(pObject,pAddress,pValue){let tmpLintedAddress=this.lintAddress(pAddress);return this.objectAddressSetValue.setValueAtAddress(pObject,tmpLintedAddress,pValue);}// Delete the value of an element by its hash
|
|
1757
|
-
deleteValueByHash(pObject,pHash
|
|
1758
|
-
deleteValueAtAddress(pObject,pAddress
|
|
1766
|
+
deleteValueByHash(pObject,pHash){return this.deleteValueAtAddress(pObject,this.resolveHashAddress(pHash));}// Delete the value of an element at an address
|
|
1767
|
+
deleteValueAtAddress(pObject,pAddress){let tmpLintedAddress=this.lintAddress(pAddress);return this.objectAddressDeleteValue.deleteValueAtAddress(pObject,tmpLintedAddress);}// Validate the consistency of an object against the schema
|
|
1759
1768
|
validate(pObject){let tmpValidationData={Error:null,Errors:[],MissingElements:[]};if(typeof pObject!=='object'){tmpValidationData.Error=true;tmpValidationData.Errors.push(`Expected passed in object to be type object but was passed in ${typeof pObject}`);}let addValidationError=(pAddress,pErrorMessage)=>{tmpValidationData.Error=true;tmpValidationData.Errors.push(`Element at address "${pAddress}" ${pErrorMessage}.`);};// Now enumerate through the values and check for anomalies based on the schema
|
|
1760
1769
|
for(let i=0;i<this.elementAddresses.length;i++){let tmpDescriptor=this.getDescriptor(this.elementAddresses[i]);let tmpValueExists=this.checkAddressExists(pObject,tmpDescriptor.Address);let tmpValue=this.getValueAtAddress(pObject,tmpDescriptor.Address);if(typeof tmpValue=='undefined'||!tmpValueExists){// This will technically mean that `Object.Some.Value = undefined` will end up showing as "missing"
|
|
1761
1770
|
// TODO: Do we want to do a different message based on if the property exists but is undefined?
|
|
1762
1771
|
tmpValidationData.MissingElements.push(tmpDescriptor.Address);if(tmpDescriptor.Required||this.options.strict){addValidationError(tmpDescriptor.Address,'is flagged REQUIRED but is not set in the object');}}// Now see if there is a data type specified for this element
|
|
1763
1772
|
if(tmpDescriptor.DataType){let tmpElementType=typeof tmpValue;switch(tmpDescriptor.DataType.toString().trim().toLowerCase()){case'string':if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}break;case"precisenumber":if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}else if(!this.numberRegex.test(tmpValue)){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is not a valid number`);}break;case'number':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}break;case'integer':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}else{let tmpValueString=tmpValue.toString();if(tmpValueString.indexOf('.')>-1){// TODO: Is this an error?
|
|
1764
|
-
addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but has a decimal point in the number.`);}}break;case'float':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}break;case'datetime':let tmpValueDate=new Date(tmpValue);if(tmpValueDate.toString()=='Invalid Date'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is not parsable as a Date by Javascript`);}default:// Check if this is a string, in the default case
|
|
1773
|
+
addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but has a decimal point in the number.`);}}break;case'float':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}break;case'boolean':if(tmpElementType!='boolean'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}break;case'datetime':let tmpValueDate=new Date(tmpValue);if(tmpValueDate.toString()=='Invalid Date'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is not parsable as a Date by Javascript`);}break;default:// Check if this is a string, in the default case
|
|
1765
1774
|
// Note this is only when a DataType is specified and it is an unrecognized data type.
|
|
1766
1775
|
if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} (which auto-converted to String because it was unrecognized) but is of the type ${tmpElementType}`);}break;}}}return tmpValidationData;}/**
|
|
1767
1776
|
* Returns a default value, or, the default value for the data type (which is overridable with configuration)
|
|
@@ -1769,7 +1778,8 @@ if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,`has a Dat
|
|
|
1769
1778
|
* @param {ManifestDescriptor} pDescriptor - The descriptor definition.
|
|
1770
1779
|
*/getDefaultValue(pDescriptor){if(typeof pDescriptor!='object'){return undefined;}if('Default'in pDescriptor){return pDescriptor.Default;}else{// Default to a null if it doesn't have a type specified.
|
|
1771
1780
|
// This will ensure a placeholder is created but isn't misinterpreted.
|
|
1772
|
-
let tmpDataType='DataType'in pDescriptor?pDescriptor.DataType:'String';if(tmpDataType in this.options.defaultValues){
|
|
1781
|
+
let tmpDataType='DataType'in pDescriptor?pDescriptor.DataType:'String';if(tmpDataType in this.options.defaultValues){let tmpDefaultValue=this.options.defaultValues[tmpDataType];// Return a copy of mutable defaults (Array and Object) to prevent shared state
|
|
1782
|
+
if(typeof tmpDefaultValue=='object'&&tmpDefaultValue!==null){return JSON.parse(JSON.stringify(tmpDefaultValue));}return tmpDefaultValue;}else{// give up and return null
|
|
1773
1783
|
return null;}}}// Enumerate through the schema and populate default values if they don't exist.
|
|
1774
1784
|
populateDefaults(pObject,pOverwriteProperties){return this.populateObject(pObject,pOverwriteProperties,// This just sets up a simple filter to see if there is a default set.
|
|
1775
1785
|
pDescriptor=>{return'Default'in pDescriptor;});}// Forcefully populate all values even if they don't have defaults.
|
|
@@ -3181,7 +3191,7 @@ try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.
|
|
|
3181
3191
|
// presumably different callback function.
|
|
3182
3192
|
// This makes sure that own properties are retained, so that
|
|
3183
3193
|
// decorations and such are not lost along the way.
|
|
3184
|
-
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],148:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],149:[function(require,module,exports){module.exports={"name":"fable","version":"3.1.
|
|
3194
|
+
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],148:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],149:[function(require,module,exports){module.exports={"name":"fable","version":"3.1.55","description":"A service dependency injection, configuration and logging library.","main":"source/Fable.js","scripts":{"start":"node source/Fable.js","coverage":"./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec","test":"./node_modules/.bin/mocha -u tdd -R spec","build":"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t fable-image:local","docker-dev-run":"docker run -it -d --name fable-dev -p 30001:8080 -p 38086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/fable\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" fable-image:local","docker-dev-shell":"docker exec -it fable-dev /bin/bash","tests":"./node_modules/mocha/bin/_mocha -u tdd --exit -R spec --grep"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"browser":{"./source/service/Fable-Service-EnvironmentData.js":"./source/service/Fable-Service-EnvironmentData-Web.js","./source/service/Fable-Service-FilePersistence.js":"./source/service/Fable-Service-FilePersistence-Web.js"},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable.git"},"keywords":["entity","behavior"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable/issues"},"homepage":"https://github.com/stevenvelozo/fable","devDependencies":{"quackage":"^1.0.50"},"dependencies":{"async.eachlimit":"^0.5.2","async.waterfall":"^0.5.2","big.js":"^7.0.1","cachetrax":"^1.0.4","cookie":"^1.0.2","data-arithmatic":"^1.0.7","dayjs":"^1.11.19","fable-log":"^3.0.16","fable-serviceproviderbase":"^3.0.17","fable-settings":"^3.0.14","fable-uuid":"^3.0.11","manyfest":"^1.0.44","simple-get":"^4.0.1"}};},{}],150:[function(require,module,exports){/**
|
|
3185
3195
|
* Fable Application Services Support Library
|
|
3186
3196
|
* @author <steven@velozo.com>
|
|
3187
3197
|
*/// Pre-init services
|
|
@@ -3957,7 +3967,7 @@ tmpCurrentTokenType='Value';tmpCurrentToken+=tmpCharacter;// continue;
|
|
|
3957
3967
|
// tmpResults.ExpressionParserLog.push(`ExpressionParser.tokenize found an unknown character code ${tmpCharCode} character ${tmpCharacter} in the expression: ${pExpression} at index ${i}`);
|
|
3958
3968
|
// this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);
|
|
3959
3969
|
}if(tmpCurrentTokenType&&tmpCurrentToken.length>0){tmpResults.RawTokens.push(tmpCurrentToken);}tmpResults.OriginalRawTokens=Array.from(tmpResults.RawTokens);// Potentially mutate the tokens based on directives in the tokenized expression
|
|
3960
|
-
this.TokenizerDirectiveMutation.parseDirectives(tmpResults);return tmpResults.RawTokens;}}module.exports=ExpressionTokenizer;},{"./Fable-Service-ExpressionParser-Base.js":159}],162:[function(require,module,exports){module.exports={"sqrt":{"Name":"Square Root","Address":"fable.Math.sqrtPrecise"},"percent":{"Name":"Compute Percent (in IS over OF format)","Address":"fable.Math.percentagePrecise"},"compare":{"Name":"Compare","Address":"fable.Math.comparePrecise"},"abs":{"Name":"Absolute Value","Address":"fable.Math.absPrecise"},"floor":{"Name":"Floor Value","Address":"fable.Math.floorPrecise"},"ceil":{"Name":"Ceiling Value","Address":"fable.Math.ceilPrecise"},"rad":{"Name":"Degrees to Radians","Address":"fable.Math.radPrecise"},"pi":{"Name":"Pi","Address":"fable.Math.piPrecise"},"euler":{"Name":"Euler","Address":"fable.Math.eulerPrecise"},"log":{"Name":"Logarithm","Address":"fable.Math.logPrecise"},"exp":{"Name":"Eulers Number to the Power Of N","Address":"fable.Math.expPrecise"},"sin":{"Name":"Sine","Address":"fable.Math.sin"},"cos":{"Name":"Cosine","Address":"fable.Math.cos"},"tan":{"Name":"Tangent","Address":"fable.Math.tan"},"count":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"countset":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"sortset":{"Name":"Sort Set","Address":"fable.Math.sortSetPrecise"},"bucketset":{"Name":"Bucket Set","Address":"fable.Math.bucketSetPrecise"},"sorthistogram":{"Name":"Sort Histogram","Address":"fable.Math.sortHistogramPrecise"},"sorthistogrambykeys":{"Name":"Sort Histogram by Keys","Address":"fable.Math.sortHistogramByKeys"},"max":{"Name":"Maximum","Address":"fable.Math.maxPrecise"},"min":{"Name":"Minimum","Address":"fable.Math.minPrecise"},"sum":{"Name":"Sum","Address":"fable.Math.sumPrecise"},"avg":{"Name":"Average","Address":"fable.Math.averagePrecise"},"mean":{"Name":"Mean","Address":"fable.Math.meanPrecise"},"median":{"Name":"Median","Address":"fable.Math.medianPrecise"},"mode":{"Name":"Mode","Address":"fable.Math.modePrecise"},"var":{"Name":"Variance (Sample)","Address":"fable.Math.variancePrecise"},"vara":{"Name":"Variance (Sample)","Address":"fable.Math.variancePrecise"},"varp":{"Name":"Variance (Population)","Address":"fable.Math.populationVariancePrecise"},"stdev":{"Name":"Standard Deviation (Sample)","Address":"fable.Math.standardDeviationPrecise"},"stdeva":{"Name":"Standard Deviation (Sample)","Address":"fable.Math.standardDeviationPrecise"},"stdevp":{"Name":"Standard Deviation (Population)","Address":"fable.Math.populationStandardDeviationPrecise"},"round":{"Name":"Round","Address":"fable.Math.roundPrecise"},"tofixed":{"Name":"To Fixed","Address":"fable.Math.toFixedPrecise"},"cumulativesummation":{"Name":"Sum each value in a Histogram or Value Map cumulatively, creating or setting a property with the result on each row","Address":"fable.Math.cumulativeSummation"},"subtractingsummation":{"Name":"Subtract each subsequent value in a Histogram or Value Map cumulatively (by default from the first row), creating or setting a property with the result on each row.","Address":"fable.Math.subtractingSummation"},"iterativeseries":{"Name":"Perform an Iterative Series of Mathematical Operations on Set Elements","Address":"fable.Math.iterativeSeries"},"countsetelements":{"Name":"Count Set Elements in a Histogram or Value Map","Address":"fable.Math.countSetElements"},"getvalue":{"Name":"Get Value from Application State or Services (AppData, etc.)","Address":"fable.Utility.getInternalValueByHash"},"objectkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"objectvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"generatearrayofobjectsfromsets":{"Name":"Generate Array of Objects from Sets","Address":"fable.Utility.generateArrayOfObjectsFromSets"},"objectvaluessortbyexternalobjectarray":{"Name":"Get Array of an Object's values sorted by an external array","Address":"fable.Utility.objectValuesSortByExternalArray"},"setkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"setvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"histogramkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"histogramvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"createarrayfromabsolutevalues":{"Name":"Create Array from Absolute Values","Address":"fable.Utility.createArrayFromAbsoluteValues"},"flatten":{"Name":"flatten an array of values","Address":"fable.Utility.flattenArrayOfSolverInputs"},"findfirstvaluebyexactmatch":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByExactMatchInternal"},"findfirstvaluebystringincludes":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByStringIncludesInternal"},"match":{"Name":"Implementation of sheets MATCH() function","Address":"fable.Utility.findIndexInternal"},"resolvehtmlentities":{"Name":"resolve HTML entities","Address":"fable.DataFormat.resolveHtmlEntities"},"concat":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsInternal"},"concatraw":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsRawInternal"},"arrayconcat":{"Name":"concatenate two or more arrays generating a single output array","Address":"fable.Utility.concatenateArrays"},"join":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsInternal"},"joinraw":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsRawInternal"},"if":{"Name":"perform a conditional operator on two values, and choose one of two outcomes based on the result","Address":"fable.Logic.checkIf"},"when":{"Name":"perform a 'truthy' check on one value, and return one of two outcomes based on the result","Address":"fable.Logic.when"},"entryinset":{"Name":"Entry in Set","Address":"fable.Math.entryInSet"},"smallestinset":{"Name":"Smallest in Set","Address":"fable.Math.smallestInSet"},"largestinset":{"Name":"Largest in Set","Address":"fable.Math.largestInSet"},"aggregationhistogram":{"Name":"Generate a Histogram by Exact Value Aggregation","Address":"fable.Math.histogramAggregationByExactValueFromInternalState"},"aggregationhistogrambyobject":{"Name":"Generate a Histogram by Exact Value Aggregation from Object Property","Address":"fable.Math.histogramAggregationByExactValue"},"distributionhistogram":{"Name":"Generate a Histogram Based on Value Distribution","Address":"fable.Math.histogramDistributionByExactValueFromInternalState"},"distributionhistogrambyobject":{"Name":"Generate a Histogram Based on Value Distribution from Object Property","Address":"fable.Math.histogramDistributionByExactValue"},"setconcatenate":{"Name":"Set Concatenate","Address":"fable.Math.setConcatenate"},"getvaluearray":{"Name":"Get Value Array from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueArrayByHashParametersFromInternal"},"getvalueobject":{"Name":"Get Value Object from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueObjectByHashParametersFromInternal"},"cleanvaluearray":{"Name":"Clean Value Array","Address":"fable.Math.cleanValueArray"},"cleanvalueobject":{"Name":"Clean Value Object","Address":"fable.Math.cleanValueObject"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"randominteger":{"Name":"Random Integer","Address":"fable.DataGeneration.randomInteger"},"randomintegerbetween":{"Name":"Random Integer Between Two Numbers","Address":"fable.DataGeneration.randomIntegerBetween"},"randomintegerupto":{"Name":"Random Integer","Address":"fable.DataGeneration.randomIntegerUpTo"},"randomfloat":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloat"},"randomfloatbetween":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatBetween"},"randomfloatupto":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatUpTo"},"datemilliseconddifference":{"Name":"Date Difference in Milliseconds","Address":"fable.Dates.dateMillisecondDifference"},"dateseconddifference":{"Name":"Date Difference in Seconds","Address":"fable.Dates.dateSecondDifference"},"dateminutedifference":{"Name":"Date Difference in Minutes","Address":"fable.Dates.dateMinuteDifference"},"datehourdifference":{"Name":"Date Difference in Hours","Address":"fable.Dates.dateHourDifference"},"datedaydifference":{"Name":"Date Difference in Days","Address":"fable.Dates.dateDayDifference"},"dateweekdifference":{"Name":"Date Difference in Weeks","Address":"fable.Dates.dateWeekDifference"},"datemonthdifference":{"Name":"Date Difference in Months","Address":"fable.Dates.dateMonthDifference"},"dateyeardifference":{"Name":"Date Difference in Years","Address":"fable.Dates.dateYearDifference"},"datemathadd":{"Name":"Date Math Add","Address":"fable.Dates.dateMath"},"dateaddmilliseconds":{"Name":"Date Add Milliseconds","Address":"fable.Dates.dateAddMilliseconds"},"dateaddseconds":{"Name":"Date Add Seconds","Address":"fable.Dates.dateAddSeconds"},"dateaddminutes":{"Name":"Date Add Minutes","Address":"fable.Dates.dateAddMinutes"},"dateaddhours":{"Name":"Date Add Hours","Address":"fable.Dates.dateAddHours"},"dateadddays":{"Name":"Date Add Days","Address":"fable.Dates.dateAddDays"},"dateaddweeks":{"Name":"Date Add Weeks","Address":"fable.Dates.dateAddWeeks"},"dateaddmonths":{"Name":"Date Add Months","Address":"fable.Dates.dateAddMonths"},"dateaddyears":{"Name":"Date Add Years","Address":"fable.Dates.dateAddYears"},"datefromparts":{"Name":"Date From Parts","Address":"fable.Dates.dateFromParts"},"slice":{"Name":"Slice Array","Address":"fable.Utility.slice"},"createvalueobjectbyhashes":{"Name":"Create Value Object by Hashes","Address":"fable.Utility.createValueObjectByHashes"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"leastsquares":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"linest":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"matrixtranspose":{"Name":"Transpose a Matrix","Address":"fable.Math.matrixTranspose"},"matrixmultiply":{"Name":"Multiply Two Matrices","Address":"fable.Math.matrixMultiply"},"matrixvectormultiply":{"Name":"Multiply a Matrix by a Vector","Address":"fable.Math.matrixVectorMultiply"},"matrixinverse":{"Name":"Inverse a Matrix","Address":"fable.Math.matrixInverse"},"gaussianelimination":{"Name":"Solve a System of Linear Equations using Gaussian Elimination","Address":"fable.Math.gaussianElimination"},"predict":{"Name":"Predict Y Values from X Values using a Regression Model","Address":"fable.Math.predictFromRegressionModel"},"stringcountsegments":{"Name":"Count Segments in a String","Address":"fable.DataFormat.stringCountSegments"},"stringgetsegments":{"Name":"Get Segments from a String","Address":"fable.DataFormat.stringGetSegments"}};},{}],163:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionParserLinter extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-Linter';}lintTokenizedExpression(pTokenizedExpression,pResultObject){let tmpResults=typeof pResultObject==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.LinterResults=[];// Guard against bad data being passed in
|
|
3970
|
+
this.TokenizerDirectiveMutation.parseDirectives(tmpResults);return tmpResults.RawTokens;}}module.exports=ExpressionTokenizer;},{"./Fable-Service-ExpressionParser-Base.js":159}],162:[function(require,module,exports){module.exports={"sqrt":{"Name":"Square Root","Address":"fable.Math.sqrtPrecise"},"percent":{"Name":"Compute Percent (in IS over OF format)","Address":"fable.Math.percentagePrecise"},"compare":{"Name":"Compare","Address":"fable.Math.comparePrecise"},"abs":{"Name":"Absolute Value","Address":"fable.Math.absPrecise"},"floor":{"Name":"Floor Value","Address":"fable.Math.floorPrecise"},"ceil":{"Name":"Ceiling Value","Address":"fable.Math.ceilPrecise"},"rad":{"Name":"Degrees to Radians","Address":"fable.Math.radPrecise"},"pi":{"Name":"Pi","Address":"fable.Math.piPrecise"},"euler":{"Name":"Euler","Address":"fable.Math.eulerPrecise"},"log":{"Name":"Logarithm","Address":"fable.Math.logPrecise"},"exp":{"Name":"Eulers Number to the Power Of N","Address":"fable.Math.expPrecise"},"sin":{"Name":"Sine","Address":"fable.Math.sin"},"cos":{"Name":"Cosine","Address":"fable.Math.cos"},"tan":{"Name":"Tangent","Address":"fable.Math.tan"},"count":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"countset":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"sortset":{"Name":"Sort Set","Address":"fable.Math.sortSetPrecise"},"bucketset":{"Name":"Bucket Set","Address":"fable.Math.bucketSetPrecise"},"sorthistogram":{"Name":"Sort Histogram","Address":"fable.Math.sortHistogramPrecise"},"sorthistogrambykeys":{"Name":"Sort Histogram by Keys","Address":"fable.Math.sortHistogramByKeys"},"max":{"Name":"Maximum","Address":"fable.Math.maxPrecise"},"min":{"Name":"Minimum","Address":"fable.Math.minPrecise"},"sum":{"Name":"Sum","Address":"fable.Math.sumPrecise"},"avg":{"Name":"Average","Address":"fable.Math.averagePrecise"},"mean":{"Name":"Mean","Address":"fable.Math.meanPrecise"},"median":{"Name":"Median","Address":"fable.Math.medianPrecise"},"mode":{"Name":"Mode","Address":"fable.Math.modePrecise"},"var":{"Name":"Variance (Sample)","Address":"fable.Math.variancePrecise"},"vara":{"Name":"Variance (Sample)","Address":"fable.Math.variancePrecise"},"varp":{"Name":"Variance (Population)","Address":"fable.Math.populationVariancePrecise"},"stdev":{"Name":"Standard Deviation (Sample)","Address":"fable.Math.standardDeviationPrecise"},"stdeva":{"Name":"Standard Deviation (Sample)","Address":"fable.Math.standardDeviationPrecise"},"stdevp":{"Name":"Standard Deviation (Population)","Address":"fable.Math.populationStandardDeviationPrecise"},"round":{"Name":"Round","Address":"fable.Math.roundPrecise"},"tofixed":{"Name":"To Fixed","Address":"fable.Math.toFixedPrecise"},"cumulativesummation":{"Name":"Sum each value in a Histogram or Value Map cumulatively, creating or setting a property with the result on each row","Address":"fable.Math.cumulativeSummation"},"subtractingsummation":{"Name":"Subtract each subsequent value in a Histogram or Value Map cumulatively (by default from the first row), creating or setting a property with the result on each row.","Address":"fable.Math.subtractingSummation"},"iterativeseries":{"Name":"Perform an Iterative Series of Mathematical Operations on Set Elements","Address":"fable.Math.iterativeSeries"},"countsetelements":{"Name":"Count Set Elements in a Histogram or Value Map","Address":"fable.Math.countSetElements"},"getvalue":{"Name":"Get Value from Application State or Services (AppData, etc.)","Address":"fable.Utility.getInternalValueByHash"},"setvalue":{"Name":"Set Value to Application State or Services (AppData, etc.)","Address":"fable.Utility.setInternalValueByHash"},"objectkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"objectvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"generatearrayofobjectsfromsets":{"Name":"Generate Array of Objects from Sets","Address":"fable.Utility.generateArrayOfObjectsFromSets"},"objectvaluessortbyexternalobjectarray":{"Name":"Get Array of an Object's values sorted by an external array","Address":"fable.Utility.objectValuesSortByExternalArray"},"setkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"setvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"histogramkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"histogramvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"createarrayfromabsolutevalues":{"Name":"Create Array from Absolute Values","Address":"fable.Utility.createArrayFromAbsoluteValues"},"flatten":{"Name":"flatten an array of values","Address":"fable.Utility.flattenArrayOfSolverInputs"},"findfirstvaluebyexactmatch":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByExactMatchInternal"},"findfirstvaluebystringincludes":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByStringIncludesInternal"},"match":{"Name":"Implementation of sheets MATCH() function","Address":"fable.Utility.findIndexInternal"},"resolvehtmlentities":{"Name":"resolve HTML entities","Address":"fable.DataFormat.resolveHtmlEntities"},"concat":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsInternal"},"concatraw":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsRawInternal"},"arrayconcat":{"Name":"concatenate two or more arrays generating a single output array","Address":"fable.Utility.concatenateArrays"},"join":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsInternal"},"joinraw":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsRawInternal"},"if":{"Name":"perform a conditional operator on two values, and choose one of two outcomes based on the result","Address":"fable.Logic.checkIf"},"when":{"Name":"perform a 'truthy' check on one value, and return one of two outcomes based on the result","Address":"fable.Logic.when"},"entryinset":{"Name":"Entry in Set","Address":"fable.Math.entryInSet"},"smallestinset":{"Name":"Smallest in Set","Address":"fable.Math.smallestInSet"},"largestinset":{"Name":"Largest in Set","Address":"fable.Math.largestInSet"},"aggregationhistogram":{"Name":"Generate a Histogram by Exact Value Aggregation","Address":"fable.Math.histogramAggregationByExactValueFromInternalState"},"aggregationhistogrambyobject":{"Name":"Generate a Histogram by Exact Value Aggregation from Object Property","Address":"fable.Math.histogramAggregationByExactValue"},"distributionhistogram":{"Name":"Generate a Histogram Based on Value Distribution","Address":"fable.Math.histogramDistributionByExactValueFromInternalState"},"distributionhistogrambyobject":{"Name":"Generate a Histogram Based on Value Distribution from Object Property","Address":"fable.Math.histogramDistributionByExactValue"},"setconcatenate":{"Name":"Set Concatenate","Address":"fable.Math.setConcatenate"},"getvaluearray":{"Name":"Get Value Array from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueArrayByHashParametersFromInternal"},"getvalueobject":{"Name":"Get Value Object from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueObjectByHashParametersFromInternal"},"cleanvaluearray":{"Name":"Clean Value Array","Address":"fable.Math.cleanValueArray"},"cleanvalueobject":{"Name":"Clean Value Object","Address":"fable.Math.cleanValueObject"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"randominteger":{"Name":"Random Integer","Address":"fable.DataGeneration.randomInteger"},"randomintegerbetween":{"Name":"Random Integer Between Two Numbers","Address":"fable.DataGeneration.randomIntegerBetween"},"randomintegerupto":{"Name":"Random Integer","Address":"fable.DataGeneration.randomIntegerUpTo"},"randomfloat":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloat"},"randomfloatbetween":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatBetween"},"randomfloatupto":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatUpTo"},"datemilliseconddifference":{"Name":"Date Difference in Milliseconds","Address":"fable.Dates.dateMillisecondDifference"},"dateseconddifference":{"Name":"Date Difference in Seconds","Address":"fable.Dates.dateSecondDifference"},"dateminutedifference":{"Name":"Date Difference in Minutes","Address":"fable.Dates.dateMinuteDifference"},"datehourdifference":{"Name":"Date Difference in Hours","Address":"fable.Dates.dateHourDifference"},"datedaydifference":{"Name":"Date Difference in Days","Address":"fable.Dates.dateDayDifference"},"dateweekdifference":{"Name":"Date Difference in Weeks","Address":"fable.Dates.dateWeekDifference"},"datemonthdifference":{"Name":"Date Difference in Months","Address":"fable.Dates.dateMonthDifference"},"dateyeardifference":{"Name":"Date Difference in Years","Address":"fable.Dates.dateYearDifference"},"datemathadd":{"Name":"Date Math Add","Address":"fable.Dates.dateMath"},"dateaddmilliseconds":{"Name":"Date Add Milliseconds","Address":"fable.Dates.dateAddMilliseconds"},"dateaddseconds":{"Name":"Date Add Seconds","Address":"fable.Dates.dateAddSeconds"},"dateaddminutes":{"Name":"Date Add Minutes","Address":"fable.Dates.dateAddMinutes"},"dateaddhours":{"Name":"Date Add Hours","Address":"fable.Dates.dateAddHours"},"dateadddays":{"Name":"Date Add Days","Address":"fable.Dates.dateAddDays"},"dateaddweeks":{"Name":"Date Add Weeks","Address":"fable.Dates.dateAddWeeks"},"dateaddmonths":{"Name":"Date Add Months","Address":"fable.Dates.dateAddMonths"},"dateaddyears":{"Name":"Date Add Years","Address":"fable.Dates.dateAddYears"},"datefromparts":{"Name":"Date From Parts","Address":"fable.Dates.dateFromParts"},"slice":{"Name":"Slice Array","Address":"fable.Utility.slice"},"createvalueobjectbyhashes":{"Name":"Create Value Object by Hashes","Address":"fable.Utility.createValueObjectByHashes"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"leastsquares":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"linest":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"matrixtranspose":{"Name":"Transpose a Matrix","Address":"fable.Math.matrixTranspose"},"matrixmultiply":{"Name":"Multiply Two Matrices","Address":"fable.Math.matrixMultiply"},"matrixvectormultiply":{"Name":"Multiply a Matrix by a Vector","Address":"fable.Math.matrixVectorMultiply"},"matrixinverse":{"Name":"Inverse a Matrix","Address":"fable.Math.matrixInverse"},"gaussianelimination":{"Name":"Solve a System of Linear Equations using Gaussian Elimination","Address":"fable.Math.gaussianElimination"},"predict":{"Name":"Predict Y Values from X Values using a Regression Model","Address":"fable.Math.predictFromRegressionModel"},"stringcountsegments":{"Name":"Count Segments in a String","Address":"fable.DataFormat.stringCountSegments"},"stringgetsegments":{"Name":"Get Segments from a String","Address":"fable.DataFormat.stringGetSegments"}};},{}],163:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionParserLinter extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-Linter';}lintTokenizedExpression(pTokenizedExpression,pResultObject){let tmpResults=typeof pResultObject==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.LinterResults=[];// Guard against bad data being passed in
|
|
3961
3971
|
if(!Array.isArray(pTokenizedExpression)){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.lintTokenizedExpression was passed a non-array tokenized expression.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return pTokenizedExpression;}if(pTokenizedExpression.length<1){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.lintTokenizedExpression was passed an empty tokenized expression.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return pTokenizedExpression;}// 1. Check for balanced parenthesis
|
|
3962
3972
|
let tmpParenthesisDepth=0;// If it is in a state address, we don't care about the parenthesis
|
|
3963
3973
|
// State addresses are between squiggly brackets
|
|
@@ -4933,6 +4943,12 @@ let tmpChunkSize=typeof pChunkSize=='number'?pChunkSize:0;let tmpChunkCache=type
|
|
|
4933
4943
|
* @param {string} pValueAddress - The manyfest hash/address of the value to get
|
|
4934
4944
|
*/getInternalValueByHash(pValueAddress){// Get the value from the internal manifest and return it
|
|
4935
4945
|
return this.getValueByHash(this.fable,pValueAddress);}/**
|
|
4946
|
+
* Set a value from fable/pict by hash/address
|
|
4947
|
+
*
|
|
4948
|
+
* @param {string} pValueAddress - The manyfest hash/address of the value to get
|
|
4949
|
+
* @param {any} pValue - The value to set
|
|
4950
|
+
*/setInternalValueByHash(pValueAddress,pValue){// Get the value from the internal manifest and return it
|
|
4951
|
+
return this.setValueByHash(this.fable,pValueAddress,pValue);}/**
|
|
4936
4952
|
* Get a value from an object by hash/address
|
|
4937
4953
|
* @param {object} pObject - The object to get the value from
|
|
4938
4954
|
* @param {string} pValueAddress - The manyfest hash/address of the value to get
|