fable 3.0.37 → 3.0.39
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/.config/configstore/update-notifier-npm.json +7 -1
- package/.config/vscode-sqltools/runningInfo.json +1 -1
- package/dist/fable.compatible.js +737 -67
- package/dist/fable.compatible.min.js +8 -8
- package/dist/fable.compatible.min.js.map +1 -1
- package/dist/fable.js +719 -49
- package/dist/fable.min.js +8 -8
- package/dist/fable.min.js.map +1 -1
- package/package.json +6 -3
- package/retold-harness/bookstore-serve-meadow-endpoint-apis.js +2 -4
- package/retold-harness/package.json +3 -3
- package/source/Fable.js +14 -17
- package/source/services/Fable-Service-CSVParser.js +199 -0
- package/source/services/Fable-Service-DataFormat.js +0 -3
- package/source/services/Fable-Service-FilePersistence-Web.js +36 -0
- package/source/services/Fable-Service-FilePersistence.js +127 -0
- package/source/services/Fable-Service-Utility.js +3 -2
- package/test/CSVParser_tests.js +66 -0
- package/test/FilePersistence_tests.js +37 -0
- package/test/Manifest_tests.js +79 -0
- package/test/RestClient_test.js +1 -1
- package/test/data/books.csv +10001 -0
package/dist/fable.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";function _defineProperty2(obj,key,value){key=_toPropertyKey2(key);if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}function _toPropertyKey2(arg){var key=_toPrimitive2(arg,"string");return typeof key==="symbol"?key:String(key);}function _toPrimitive2(input,hint){if(typeof input!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(typeof res!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f();}else if(typeof define==="function"&&define.amd){define([],f);}else{var g;if(typeof window!=="undefined"){g=window;}else if(typeof global!=="undefined"){g=global;}else if(typeof self!=="undefined"){g=self;}else{g=this;}g.Fable=f();}})(function(){var define,module,exports;return function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a;}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r);},p,p.exports,r,e,n,t);}return n[i].exports;}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o;}return r;}()({1:[function(require,module,exports){'use strict';var eachOfLimit=require('async.util.eachoflimit');var withoutIndex=require('async.util.withoutindex');module.exports=function eachLimit(arr,limit,iterator,cb){return eachOfLimit(limit)(arr,withoutIndex(iterator),cb);};},{"async.util.eachoflimit":3,"async.util.withoutindex":14}],2:[function(require,module,exports){'use strict';module.exports=function(tasks){function makeCallback(index){function fn(){if(tasks.length){tasks[index].apply(null,arguments);}return fn.next();}fn.next=function(){return index<tasks.length-1?makeCallback(index+1):null;};return fn;}return makeCallback(0);};},{}],3:[function(require,module,exports){var once=require('async.util.once');var noop=require('async.util.noop');var onlyOnce=require('async.util.onlyonce');var keyIterator=require('async.util.keyiterator');module.exports=function eachOfLimit(limit){return function(obj,iterator,cb){cb=once(cb||noop);obj=obj||[];var nextKey=keyIterator(obj);if(limit<=0){return cb(null);}var done=false;var running=0;var errored=false;(function replenish(){if(done&&running<=0){return cb(null);}while(running<limit&&!errored){var key=nextKey();if(key===null){done=true;if(running<=0){cb(null);}return;}running+=1;iterator(obj[key],key,onlyOnce(function(err){running-=1;if(err){cb(err);errored=true;}else{replenish();}}));}})();};};},{"async.util.keyiterator":7,"async.util.noop":9,"async.util.once":10,"async.util.onlyonce":11}],4:[function(require,module,exports){'use strict';var setImmediate=require('async.util.setimmediate');var restParam=require('async.util.restparam');module.exports=function(fn){return restParam(function(args){var callback=args.pop();args.push(function(){var innerArgs=arguments;if(sync){setImmediate(function(){callback.apply(null,innerArgs);});}else{callback.apply(null,innerArgs);}});var sync=true;fn.apply(this,args);sync=false;});};},{"async.util.restparam":12,"async.util.setimmediate":13}],5:[function(require,module,exports){'use strict';module.exports=Array.isArray||function isArray(obj){return Object.prototype.toString.call(obj)==='[object Array]';};},{}],6:[function(require,module,exports){'use strict';var isArray=require('async.util.isarray');module.exports=function isArrayLike(arr){return isArray(arr)||// has a positive integer length property
|
|
2
2
|
typeof arr.length==='number'&&arr.length>=0&&arr.length%1===0;};},{"async.util.isarray":5}],7:[function(require,module,exports){'use strict';var _keys=require('async.util.keys');var isArrayLike=require('async.util.isarraylike');module.exports=function keyIterator(coll){var i=-1;var len;var keys;if(isArrayLike(coll)){len=coll.length;return function next(){i++;return i<len?i:null;};}else{keys=_keys(coll);len=keys.length;return function next(){i++;return i<len?keys[i]:null;};}};},{"async.util.isarraylike":6,"async.util.keys":8}],8:[function(require,module,exports){'use strict';module.exports=Object.keys||function keys(obj){var _keys=[];for(var k in obj){if(obj.hasOwnProperty(k)){_keys.push(k);}}return _keys;};},{}],9:[function(require,module,exports){'use strict';module.exports=function noop(){};},{}],10:[function(require,module,exports){'use strict';module.exports=function once(fn){return function(){if(fn===null)return;fn.apply(this,arguments);fn=null;};};},{}],11:[function(require,module,exports){'use strict';module.exports=function only_once(fn){return function(){if(fn===null)throw new Error('Callback was already called.');fn.apply(this,arguments);fn=null;};};},{}],12:[function(require,module,exports){'use strict';module.exports=function restParam(func,startIndex){startIndex=startIndex==null?func.length-1:+startIndex;return function(){var length=Math.max(arguments.length-startIndex,0);var rest=new Array(length);for(var index=0;index<length;index++){rest[index]=arguments[index+startIndex];}switch(startIndex){case 0:return func.call(this,rest);case 1:return func.call(this,arguments[0],rest);}};};},{}],13:[function(require,module,exports){(function(setImmediate){(function(){'use strict';var _setImmediate=typeof setImmediate==='function'&&setImmediate;var fallback=function fallback(fn){setTimeout(fn,0);};module.exports=function setImmediate(fn){// not a direct alias for IE10 compatibility
|
|
3
|
-
return(_setImmediate||fallback)(fn);};}).call(this);}).call(this,require("timers").setImmediate);},{"timers":
|
|
3
|
+
return(_setImmediate||fallback)(fn);};}).call(this);}).call(this,require("timers").setImmediate);},{"timers":82}],14:[function(require,module,exports){'use strict';module.exports=function withoutIndex(iterator){return function(value,index,callback){return iterator(value,callback);};};},{}],15:[function(require,module,exports){'use strict';var once=require('async.util.once');var noop=require('async.util.noop');var isArray=require('async.util.isarray');var restParam=require('async.util.restparam');var ensureAsync=require('async.util.ensureasync');var iterator=require('async.iterator');module.exports=function(tasks,cb){cb=once(cb||noop);if(!isArray(tasks))return cb(new Error('First argument to waterfall must be an array of functions'));if(!tasks.length)return cb();function wrapIterator(iterator){return restParam(function(err,args){if(err){cb.apply(null,[err].concat(args));}else{var next=iterator.next();if(next){args.push(wrapIterator(next));}else{args.push(cb);}ensureAsync(iterator).apply(null,args);}});}wrapIterator(iterator(tasks))();};},{"async.iterator":2,"async.util.ensureasync":4,"async.util.isarray":5,"async.util.noop":9,"async.util.once":10,"async.util.restparam":12}],16:[function(require,module,exports){'use strict';exports.byteLength=byteLength;exports.toByteArray=toByteArray;exports.fromByteArray=fromByteArray;var lookup=[];var revLookup=[];var Arr=typeof Uint8Array!=='undefined'?Uint8Array:Array;var code='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';for(var i=0,len=code.length;i<len;++i){lookup[i]=code[i];revLookup[code.charCodeAt(i)]=i;}// Support decoding URL-safe base64 strings, as Node.js does.
|
|
4
4
|
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
|
|
5
5
|
revLookup['-'.charCodeAt(0)]=62;revLookup['_'.charCodeAt(0)]=63;function getLens(b64){var len=b64.length;if(len%4>0){throw new Error('Invalid string. Length must be a multiple of 4');}// Trim off extra bytes after placeholder bytes are found
|
|
6
6
|
// See: https://github.com/beatgammit/base64-js/issues/42
|
|
@@ -238,7 +238,7 @@ let tmpConstructedBufferOutputString='';for(let i=0;i<tmpLineStrings.length;i++)
|
|
|
238
238
|
tmpConstructedBufferOutputString+="".concat(tmpLineStrings[i],"\n");if(tmpObjectStrings[i]!==false){tmpConstructedBufferOutputString+="".concat(tmpObjectStrings[i],"\n");}}if(!this.fileWriter.write(tmpConstructedBufferOutputString,'utf8')){// If the streamwriter returns false, we need to wait for it to drain.
|
|
239
239
|
this.fileWriter.once('drain',this.completeBufferFlushToLogFile.bind(this,tmpFlushComplete));}else{return this.completeBufferFlushToLogFile(tmpFlushComplete);}}}write(pLevel,pLogText,pObject){let tmpLogLine=super.write(pLevel,pLogText,pObject);// Use a very simple array as the write buffer
|
|
240
240
|
this.logLineStrings.push(tmpLogLine);// Write out the object on a separate line if it is passed in
|
|
241
|
-
if(typeof pObject!=='undefined'){this.logObjectStrings.push(JSON.stringify(pObject,null,4));}else{this.logObjectStrings.push(false);}this.flushBufferToLogFile();}}module.exports=SimpleFlatFileLogger;},{"./Fable-Log-Logger-Console.js":25,"fs":18,"path":
|
|
241
|
+
if(typeof pObject!=='undefined'){this.logObjectStrings.push(JSON.stringify(pObject,null,4));}else{this.logObjectStrings.push(false);}this.flushBufferToLogFile();}}module.exports=SimpleFlatFileLogger;},{"./Fable-Log-Logger-Console.js":25,"fs":18,"path":50}],27:[function(require,module,exports){/**
|
|
242
242
|
* Fable Logging Service
|
|
243
243
|
*/const libFableServiceProviderBase=require('fable-serviceproviderbase').CoreServiceProviderBase;class FableLog extends libFableServiceProviderBase{constructor(pSettings,pServiceHash){super(pSettings,pServiceHash);this.serviceType='Logging';let tmpSettings=typeof pSettings==='object'?pSettings:{};this._Settings=tmpSettings;this._Providers=require('./Fable-Log-DefaultProviders-Node.js');this._StreamDefinitions=tmpSettings.hasOwnProperty('LogStreams')?tmpSettings.LogStreams:require('./Fable-Log-DefaultStreams.json');this.logStreams=[];// This object gets decorated for one-time instantiated providers that
|
|
244
244
|
// have multiple outputs, such as bunyan.
|
|
@@ -263,7 +263,7 @@ this.UUID="CORESVC-".concat(Math.floor(Math.random()*(99999-10000)+10000));this.
|
|
|
263
263
|
connectFable(pFable){this.fable=pFable;return true;}}_defineProperty2(FableCoreServiceProviderBase,"isFableService",true);module.exports=FableCoreServiceProviderBase;},{}],29:[function(require,module,exports){/**
|
|
264
264
|
* Fable Service Base
|
|
265
265
|
* @author <steven@velozo.com>
|
|
266
|
-
*/class FableServiceProviderBase{constructor(pFable,pOptions,pServiceHash){this.fable=pFable;this.options=typeof pOptions==='object'?pOptions:{};this.serviceType='Unknown';this.UUID=pFable.getUUID();this.Hash=typeof pServiceHash==='string'?pServiceHash:"".concat(this.UUID);}}_defineProperty2(FableServiceProviderBase,"isFableService",true);module.exports=FableServiceProviderBase;module.exports.CoreServiceProviderBase=require('./Fable-ServiceProviderBase-Preinit.js');},{"./Fable-ServiceProviderBase-Preinit.js":28}],30:[function(require,module,exports){module.exports={"Product":"ApplicationNameHere","ProductVersion":"0.0.0","ConfigFile":false,"LogStreams":[{"level":"trace"}]};},{}],31:[function(require,module,exports){(function(process){(function(){/**
|
|
266
|
+
*/class FableServiceProviderBase{constructor(pFable,pOptions,pServiceHash){this.fable=pFable;this.options=typeof pOptions==='object'?pOptions:typeof pFable==='object'&&!pFable.isFable?pFable:{};this.serviceType='Unknown';if(typeof pFable.getUUID=='function'){this.UUID=pFable.getUUID();}else{this.UUID="NoFABLESVC-".concat(Math.floor(Math.random()*(99999-10000)+10000));}this.Hash=typeof pServiceHash==='string'?pServiceHash:"".concat(this.UUID);}}_defineProperty2(FableServiceProviderBase,"isFableService",true);module.exports=FableServiceProviderBase;module.exports.CoreServiceProviderBase=require('./Fable-ServiceProviderBase-Preinit.js');},{"./Fable-ServiceProviderBase-Preinit.js":28}],30:[function(require,module,exports){module.exports={"Product":"ApplicationNameHere","ProductVersion":"0.0.0","ConfigFile":false,"LogStreams":[{"level":"trace"}]};},{}],31:[function(require,module,exports){(function(process){(function(){/**
|
|
267
267
|
* Fable Settings Template Processor
|
|
268
268
|
*
|
|
269
269
|
* This class allows environment variables to come in via templated expressions, and defaults to be set.
|
|
@@ -274,7 +274,7 @@ connectFable(pFable){this.fable=pFable;return true;}}_defineProperty2(FableCoreS
|
|
|
274
274
|
*/const libPrecedent=require('precedent');class FableSettingsTemplateProcessor{constructor(pDependencies){// Use a no-dependencies templating engine to parse out environment variables
|
|
275
275
|
this.templateProcessor=new libPrecedent();// TODO: Make the environment variable wrap expression demarcation characters configurable?
|
|
276
276
|
this.templateProcessor.addPattern('${','}',pTemplateValue=>{let tmpTemplateValue=pTemplateValue.trim();let tmpSeparatorIndex=tmpTemplateValue.indexOf('|');// If there is no pipe, the default value will end up being whatever the variable name is.
|
|
277
|
-
let tmpDefaultValue=tmpTemplateValue.substring(tmpSeparatorIndex+1);let tmpEnvironmentVariableName=tmpSeparatorIndex>-1?tmpTemplateValue.substring(0,tmpSeparatorIndex):tmpTemplateValue;if(process.env.hasOwnProperty(tmpEnvironmentVariableName)){return process.env[tmpEnvironmentVariableName];}else{return tmpDefaultValue;}});}parseSetting(pString){return this.templateProcessor.parseString(pString);}}module.exports=FableSettingsTemplateProcessor;}).call(this);}).call(this,require('_process'));},{"_process":
|
|
277
|
+
let tmpDefaultValue=tmpTemplateValue.substring(tmpSeparatorIndex+1);let tmpEnvironmentVariableName=tmpSeparatorIndex>-1?tmpTemplateValue.substring(0,tmpSeparatorIndex):tmpTemplateValue;if(process.env.hasOwnProperty(tmpEnvironmentVariableName)){return process.env[tmpEnvironmentVariableName];}else{return tmpDefaultValue;}});}parseSetting(pString){return this.templateProcessor.parseString(pString);}}module.exports=FableSettingsTemplateProcessor;}).call(this);}).call(this,require('_process'));},{"_process":54,"precedent":51}],32:[function(require,module,exports){/**
|
|
278
278
|
* Fable Settings Add-on
|
|
279
279
|
*
|
|
280
280
|
*
|
|
@@ -341,9 +341,655 @@ generateUUIDv4(){let tmpBuffer=new Array(16);var tmpRandomBytes=this.randomByteG
|
|
|
341
341
|
tmpRandomBytes[6]=tmpRandomBytes[6]&0x0f|0x40;tmpRandomBytes[8]=tmpRandomBytes[8]&0x3f|0x80;return this.bytesToUUID(tmpRandomBytes);}// Simple random UUID generation
|
|
342
342
|
generateRandom(){let tmpUUID='';for(let i=0;i<this._UUIDLength;i++){tmpUUID+=this._UUIDRandomDictionary.charAt(Math.floor(Math.random()*(this._UUIDRandomDictionary.length-1)));}return tmpUUID;}// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)
|
|
343
343
|
getUUID(){if(this._UUIDModeRandom){return this.generateRandom();}else{return this.generateUUIDv4();}}}// This is for backwards compatibility
|
|
344
|
-
function autoConstruct(pSettings){return new FableUUID(pSettings);}module.exports=FableUUID;module.exports.new=autoConstruct;},{"./Fable-UUID-Random.js":33,"fable-serviceproviderbase":29}],35:[function(require,module,exports){var http=require('http');var url=require('url');var https=module.exports;for(var key in http){if(http.hasOwnProperty(key))https[key]=http[key];}https.request=function(params,cb){params=validateParams(params);return http.request.call(this,params,cb);};https.get=function(params,cb){params=validateParams(params);return http.get.call(this,params,cb);};function validateParams(params){if(typeof params==='string'){params=url.parse(params);}if(!params.protocol){params.protocol='https:';}if(params.protocol!=='https:'){throw new Error('Protocol "'+params.protocol+'" not supported. Expected "https:"');}return params;}},{"http":
|
|
344
|
+
function autoConstruct(pSettings){return new FableUUID(pSettings);}module.exports=FableUUID;module.exports.new=autoConstruct;},{"./Fable-UUID-Random.js":33,"fable-serviceproviderbase":29}],35:[function(require,module,exports){var http=require('http');var url=require('url');var https=module.exports;for(var key in http){if(http.hasOwnProperty(key))https[key]=http[key];}https.request=function(params,cb){params=validateParams(params);return http.request.call(this,params,cb);};https.get=function(params,cb){params=validateParams(params);return http.get.call(this,params,cb);};function validateParams(params){if(typeof params==='string'){params=url.parse(params);}if(!params.protocol){params.protocol='https:';}if(params.protocol!=='https:'){throw new Error('Protocol "'+params.protocol+'" not supported. Expected "https:"');}return params;}},{"http":62,"url":83}],36:[function(require,module,exports){/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */exports.read=function(buffer,offset,isLE,mLen,nBytes){var e,m;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var nBits=-7;var i=isLE?nBytes-1:0;var d=isLE?-1:1;var s=buffer[offset+i];i+=d;e=s&(1<<-nBits)-1;s>>=-nBits;nBits+=eLen;for(;nBits>0;e=e*256+buffer[offset+i],i+=d,nBits-=8){}m=e&(1<<-nBits)-1;e>>=-nBits;nBits+=mLen;for(;nBits>0;m=m*256+buffer[offset+i],i+=d,nBits-=8){}if(e===0){e=1-eBias;}else if(e===eMax){return m?NaN:(s?-1:1)*Infinity;}else{m=m+Math.pow(2,mLen);e=e-eBias;}return(s?-1:1)*m*Math.pow(2,e-mLen);};exports.write=function(buffer,value,offset,isLE,mLen,nBytes){var e,m,c;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var rt=mLen===23?Math.pow(2,-24)-Math.pow(2,-77):0;var i=isLE?0:nBytes-1;var d=isLE?1:-1;var s=value<0||value===0&&1/value<0?1:0;value=Math.abs(value);if(isNaN(value)||value===Infinity){m=isNaN(value)?1:0;e=eMax;}else{e=Math.floor(Math.log(value)/Math.LN2);if(value*(c=Math.pow(2,-e))<1){e--;c*=2;}if(e+eBias>=1){value+=rt/c;}else{value+=rt*Math.pow(2,1-eBias);}if(value*c>=2){e++;c/=2;}if(e+eBias>=eMax){m=0;e=eMax;}else if(e+eBias>=1){m=(value*c-1)*Math.pow(2,mLen);e=e+eBias;}else{m=value*Math.pow(2,eBias-1)*Math.pow(2,mLen);e=0;}}for(;mLen>=8;buffer[offset+i]=m&0xff,i+=d,m/=256,mLen-=8){}e=e<<mLen|m;eLen+=mLen;for(;eLen>0;buffer[offset+i]=e&0xff,i+=d,e/=256,eLen-=8){}buffer[offset+i-d]|=s*128;};},{}],37:[function(require,module,exports){if(typeof Object.create==='function'){// implementation from standard node.js 'util' module
|
|
345
345
|
module.exports=function inherits(ctor,superCtor){if(superCtor){ctor.super_=superCtor;ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:false,writable:true,configurable:true}});}};}else{// old school shim for old browsers
|
|
346
|
-
module.exports=function inherits(ctor,superCtor){if(superCtor){ctor.super_=superCtor;var TempCtor=function TempCtor(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor();ctor.prototype.constructor=ctor;}};}},{}],38:[function(require,module,exports){
|
|
346
|
+
module.exports=function inherits(ctor,superCtor){if(superCtor){ctor.super_=superCtor;var TempCtor=function TempCtor(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor();ctor.prototype.constructor=ctor;}};}},{}],38:[function(require,module,exports){// When a boxed property is passed in, it should have quotes of some
|
|
347
|
+
// kind around it.
|
|
348
|
+
//
|
|
349
|
+
// For instance:
|
|
350
|
+
// MyValues['Name']
|
|
351
|
+
// MyValues["Age"]
|
|
352
|
+
// MyValues[`Cost`]
|
|
353
|
+
//
|
|
354
|
+
// This function removes the wrapping quotes.
|
|
355
|
+
//
|
|
356
|
+
// Please note it *DOES NOT PARSE* template literals, so backticks just
|
|
357
|
+
// end up doing the same thing as other quote types.
|
|
358
|
+
//
|
|
359
|
+
// TODO: Should template literals be processed? If so what state do they have access to? That should happen here if so.
|
|
360
|
+
// TODO: Make a simple class include library with these
|
|
361
|
+
const cleanWrapCharacters=(pCharacter,pString)=>{if(pString.startsWith(pCharacter)&&pString.endsWith(pCharacter)){return pString.substring(1,pString.length-1);}else{return pString;}};module.exports=cleanWrapCharacters;},{}],39:[function(require,module,exports){/**
|
|
362
|
+
* @author <steven@velozo.com>
|
|
363
|
+
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');/**
|
|
364
|
+
* Hash Translation
|
|
365
|
+
*
|
|
366
|
+
* This is a very simple translation table for hashes, which allows the same schema to resolve
|
|
367
|
+
* differently based on a loaded translation table.
|
|
368
|
+
*
|
|
369
|
+
* This is to prevent the requirement for mutating schemas over and over again when we want to
|
|
370
|
+
* reuse the structure but look up data elements by different addresses.
|
|
371
|
+
*
|
|
372
|
+
* One side-effect of this is that a translation table can "override" the built-in hashes, since
|
|
373
|
+
* this is always used to resolve hashes before any of the functionCallByHash(pHash, ...) perform
|
|
374
|
+
* their lookups by hash.
|
|
375
|
+
*
|
|
376
|
+
* @class ManyfestHashTranslation
|
|
377
|
+
*/class ManyfestHashTranslation{constructor(pInfoLog,pErrorLog){// Wire in logging
|
|
378
|
+
this.logInfo=typeof pInfoLog==='function'?pInfoLog:libSimpleLog;this.logError=typeof pErrorLog==='function'?pErrorLog:libSimpleLog;this.translationTable={};}translationCount(){return Object.keys(this.translationTable).length;}addTranslation(pTranslation){// This adds a translation in the form of:
|
|
379
|
+
// { "SourceHash": "DestinationHash", "SecondSourceHash":"SecondDestinationHash" }
|
|
380
|
+
if(typeof pTranslation!='object'){this.logError("Hash translation addTranslation expected a translation be type object but was passed in ".concat(typeof pTranslation));return false;}let tmpTranslationSources=Object.keys(pTranslation);tmpTranslationSources.forEach(pTranslationSource=>{if(typeof pTranslation[pTranslationSource]!='string'){this.logError("Hash translation addTranslation expected a translation destination hash for [".concat(pTranslationSource,"] to be a string but the referrant was a ").concat(typeof pTranslation[pTranslationSource]));}else{this.translationTable[pTranslationSource]=pTranslation[pTranslationSource];}});}removeTranslationHash(pTranslationHash){if(this.translationTable.hasOwnProperty(pTranslationHash)){delete this.translationTable[pTranslationHash];}}// This removes translations.
|
|
381
|
+
// If passed a string, just removes the single one.
|
|
382
|
+
// If passed an object, it does all the source keys.
|
|
383
|
+
removeTranslation(pTranslation){if(typeof pTranslation=='string'){this.removeTranslationHash(pTranslation);return true;}else if(typeof pTranslation=='object'){let tmpTranslationSources=Object.keys(pTranslation);tmpTranslationSources.forEach(pTranslationSource=>{this.removeTranslation(pTranslationSource);});return true;}else{this.logError("Hash translation removeTranslation expected either a string or an object but the passed-in translation was type ".concat(typeof pTranslation));return false;}}clearTranslations(){this.translationTable={};}translate(pTranslation){if(this.translationTable.hasOwnProperty(pTranslation)){return this.translationTable[pTranslation];}else{return pTranslation;}}}module.exports=ManyfestHashTranslation;},{"./Manyfest-LogToConsole.js":40}],40:[function(require,module,exports){/**
|
|
384
|
+
* @author <steven@velozo.com>
|
|
385
|
+
*/ /**
|
|
386
|
+
* Manyfest simple logging shim (for browser and dependency-free running)
|
|
387
|
+
*/const logToConsole=(pLogLine,pLogObject)=>{let tmpLogLine=typeof pLogLine==='string'?pLogLine:'';console.log("[Manyfest] ".concat(tmpLogLine));if(pLogObject)console.log(JSON.stringify(pLogObject));};module.exports=logToConsole;},{}],41:[function(require,module,exports){/**
|
|
388
|
+
* @author <steven@velozo.com>
|
|
389
|
+
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');/**
|
|
390
|
+
* Object Address Resolver
|
|
391
|
+
*
|
|
392
|
+
* IMPORTANT NOTE: This code is intentionally more verbose than necessary, to
|
|
393
|
+
* be extremely clear what is going on in the recursion for
|
|
394
|
+
* each of the three address resolution functions.
|
|
395
|
+
*
|
|
396
|
+
* Although there is some opportunity to repeat ourselves a
|
|
397
|
+
* bit less in this codebase (e.g. with detection of arrays
|
|
398
|
+
* versus objects versus direct properties), it can make
|
|
399
|
+
* debugging.. challenging. The minified version of the code
|
|
400
|
+
* optimizes out almost anything repeated in here. So please
|
|
401
|
+
* be kind and rewind... meaning please keep the codebase less
|
|
402
|
+
* terse and more verbose so humans can comprehend it.
|
|
403
|
+
*
|
|
404
|
+
*
|
|
405
|
+
* @class ManyfestObjectAddressResolverCheckAddressExists
|
|
406
|
+
*/class ManyfestObjectAddressResolverCheckAddressExists{constructor(pInfoLog,pErrorLog){// Wire in logging
|
|
407
|
+
this.logInfo=typeof pInfoLog=='function'?pInfoLog:libSimpleLog;this.logError=typeof pErrorLog=='function'?pErrorLog:libSimpleLog;}// Check if an address exists.
|
|
408
|
+
//
|
|
409
|
+
// This is necessary because the getValueAtAddress function is ambiguous on
|
|
410
|
+
// whether the element/property is actually there or not (it returns
|
|
411
|
+
// undefined whether the property exists or not). This function checks for
|
|
412
|
+
// existance and returns true or false dependent.
|
|
413
|
+
checkAddressExists(pObject,pAddress){// TODO: Should these throw an error?
|
|
414
|
+
// Make sure pObject is an object
|
|
415
|
+
if(typeof pObject!='object')return false;// Make sure pAddress is a string
|
|
416
|
+
if(typeof pAddress!='string')return false;// TODO: Make this work for things like SomeRootObject.Metadata["Some.People.Use.Bad.Object.Property.Names"]
|
|
417
|
+
let tmpSeparatorIndex=pAddress.indexOf('.');// This is the terminal address string (no more dots so the RECUSION ENDS IN HERE somehow)
|
|
418
|
+
if(tmpSeparatorIndex==-1){// Check if the address refers to a boxed property
|
|
419
|
+
let tmpBracketStartIndex=pAddress.indexOf('[');let tmpBracketStopIndex=pAddress.indexOf(']');// Boxed elements look like this:
|
|
420
|
+
// MyValues[10]
|
|
421
|
+
// MyValues['Name']
|
|
422
|
+
// MyValues["Age"]
|
|
423
|
+
// MyValues[`Cost`]
|
|
424
|
+
//
|
|
425
|
+
// When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
|
|
426
|
+
// The requirements to detect a boxed element are:
|
|
427
|
+
// 1) The start bracket is after character 0
|
|
428
|
+
if(tmpBracketStartIndex>0// 2) The end bracket has something between them
|
|
429
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is data
|
|
430
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex>1){// The "Name" of the Object contained too the left of the bracket
|
|
431
|
+
let tmpBoxedPropertyName=pAddress.substring(0,tmpBracketStartIndex).trim();// If the subproperty doesn't test as a proper Object, none of the rest of this is possible.
|
|
432
|
+
// This is a rare case where Arrays testing as Objects is useful
|
|
433
|
+
if(typeof pObject[tmpBoxedPropertyName]!=='object'){return false;}// The "Reference" to the property within it, either an array element or object property
|
|
434
|
+
let tmpBoxedPropertyReference=pAddress.substring(tmpBracketStartIndex+1,tmpBracketStopIndex).trim();// Attempt to parse the reference as a number, which will be used as an array element
|
|
435
|
+
let tmpBoxedPropertyNumber=parseInt(tmpBoxedPropertyReference,10);// Guard: If the referrant is a number and the boxed property is not an array, or vice versa, return undefined.
|
|
436
|
+
// This seems confusing to me at first read, so explaination:
|
|
437
|
+
// Is the Boxed Object an Array? TRUE
|
|
438
|
+
// And is the Reference inside the boxed Object not a number? TRUE
|
|
439
|
+
// --> So when these are in agreement, it's an impossible access state
|
|
440
|
+
if(Array.isArray(pObject[tmpBoxedPropertyName])==isNaN(tmpBoxedPropertyNumber)){return false;}// 4) If the middle part is *only* a number (no single, double or backtick quotes) it is an array element,
|
|
441
|
+
// otherwise we will try to treat it as a dynamic object property.
|
|
442
|
+
if(isNaN(tmpBoxedPropertyNumber)){// This isn't a number ... let's treat it as a dynamic object property.
|
|
443
|
+
// We would expect the property to be wrapped in some kind of quotes so strip them
|
|
444
|
+
tmpBoxedPropertyReference=this.cleanWrapCharacters('"',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters('`',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters("'",tmpBoxedPropertyReference);// Check if the property exists.
|
|
445
|
+
return pObject[tmpBoxedPropertyName].hasOwnProperty(tmpBoxedPropertyReference);}else{// Use the new in operator to see if the element is in the array
|
|
446
|
+
return tmpBoxedPropertyNumber in pObject[tmpBoxedPropertyName];}}else{// Check if the property exists
|
|
447
|
+
return pObject.hasOwnProperty(pAddress);}}else{let tmpSubObjectName=pAddress.substring(0,tmpSeparatorIndex);let tmpNewAddress=pAddress.substring(tmpSeparatorIndex+1);// Test if the tmpNewAddress is an array or object
|
|
448
|
+
// Check if it's a boxed property
|
|
449
|
+
let tmpBracketStartIndex=tmpSubObjectName.indexOf('[');let tmpBracketStopIndex=tmpSubObjectName.indexOf(']');// Boxed elements look like this:
|
|
450
|
+
// MyValues[42]
|
|
451
|
+
// MyValues['Color']
|
|
452
|
+
// MyValues["Weight"]
|
|
453
|
+
// MyValues[`Diameter`]
|
|
454
|
+
//
|
|
455
|
+
// When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
|
|
456
|
+
// The requirements to detect a boxed element are:
|
|
457
|
+
// 1) The start bracket is after character 0
|
|
458
|
+
if(tmpBracketStartIndex>0// 2) The end bracket has something between them
|
|
459
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is data
|
|
460
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex>1){let tmpBoxedPropertyName=tmpSubObjectName.substring(0,tmpBracketStartIndex).trim();let tmpBoxedPropertyReference=tmpSubObjectName.substring(tmpBracketStartIndex+1,tmpBracketStopIndex).trim();let tmpBoxedPropertyNumber=parseInt(tmpBoxedPropertyReference,10);// Guard: If the referrant is a number and the boxed property is not an array, or vice versa, return undefined.
|
|
461
|
+
// This seems confusing to me at first read, so explaination:
|
|
462
|
+
// Is the Boxed Object an Array? TRUE
|
|
463
|
+
// And is the Reference inside the boxed Object not a number? TRUE
|
|
464
|
+
// --> So when these are in agreement, it's an impossible access state
|
|
465
|
+
// This could be a failure in the recursion chain because they passed something like this in:
|
|
466
|
+
// StudentData.Sections.Algebra.Students[1].Tardy
|
|
467
|
+
// BUT
|
|
468
|
+
// StudentData.Sections.Algebra.Students is an object, so the [1].Tardy is not possible to access
|
|
469
|
+
// This could be a failure in the recursion chain because they passed something like this in:
|
|
470
|
+
// StudentData.Sections.Algebra.Students["JaneDoe"].Grade
|
|
471
|
+
// BUT
|
|
472
|
+
// StudentData.Sections.Algebra.Students is an array, so the ["JaneDoe"].Grade is not possible to access
|
|
473
|
+
// TODO: Should this be an error or something? Should we keep a log of failures like this?
|
|
474
|
+
if(Array.isArray(pObject[tmpBoxedPropertyName])==isNaN(tmpBoxedPropertyNumber)){// Because this is an impossible address, the property doesn't exist
|
|
475
|
+
// TODO: Should we throw an error in this condition?
|
|
476
|
+
return false;}//This is a bracketed value
|
|
477
|
+
// 4) If the middle part is *only* a number (no single, double or backtick quotes) it is an array element,
|
|
478
|
+
// otherwise we will try to reat it as a dynamic object property.
|
|
479
|
+
if(isNaN(tmpBoxedPropertyNumber)){// This isn't a number ... let's treat it as a dynanmic object property.
|
|
480
|
+
tmpBoxedPropertyReference=this.cleanWrapCharacters('"',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters('`',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters("'",tmpBoxedPropertyReference);// Recurse directly into the subobject
|
|
481
|
+
return this.checkAddressExists(pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference],tmpNewAddress);}else{// We parsed a valid number out of the boxed property name, so recurse into the array
|
|
482
|
+
return this.checkAddressExists(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber],tmpNewAddress);}}// If there is an object property already named for the sub object, but it isn't an object
|
|
483
|
+
// then the system can't set the value in there. Error and abort!
|
|
484
|
+
if(pObject.hasOwnProperty(tmpSubObjectName)&&typeof pObject[tmpSubObjectName]!=='object'){return false;}else if(pObject.hasOwnProperty(tmpSubObjectName)){// If there is already a subobject pass that to the recursive thingy
|
|
485
|
+
return this.checkAddressExists(pObject[tmpSubObjectName],tmpNewAddress);}else{// Create a subobject and then pass that
|
|
486
|
+
pObject[tmpSubObjectName]={};return this.checkAddressExists(pObject[tmpSubObjectName],tmpNewAddress);}}}};module.exports=ManyfestObjectAddressResolverCheckAddressExists;},{"./Manyfest-LogToConsole.js":40}],42:[function(require,module,exports){/**
|
|
487
|
+
* @author <steven@velozo.com>
|
|
488
|
+
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');let fParseConditionals=require("../source/Manyfest-ParseConditionals.js");/**
|
|
489
|
+
* Object Address Resolver - DeleteValue
|
|
490
|
+
*
|
|
491
|
+
* IMPORTANT NOTE: This code is intentionally more verbose than necessary, to
|
|
492
|
+
* be extremely clear what is going on in the recursion for
|
|
493
|
+
* each of the three address resolution functions.
|
|
494
|
+
*
|
|
495
|
+
* Although there is some opportunity to repeat ourselves a
|
|
496
|
+
* bit less in this codebase (e.g. with detection of arrays
|
|
497
|
+
* versus objects versus direct properties), it can make
|
|
498
|
+
* debugging.. challenging. The minified version of the code
|
|
499
|
+
* optimizes out almost anything repeated in here. So please
|
|
500
|
+
* be kind and rewind... meaning please keep the codebase less
|
|
501
|
+
* terse and more verbose so humans can comprehend it.
|
|
502
|
+
*
|
|
503
|
+
* TODO: Once we validate this pattern is good to go, break these out into
|
|
504
|
+
* three separate modules.
|
|
505
|
+
*
|
|
506
|
+
* @class ManyfestObjectAddressResolverDeleteValue
|
|
507
|
+
*/class ManyfestObjectAddressResolverDeleteValue{constructor(pInfoLog,pErrorLog){// Wire in logging
|
|
508
|
+
this.logInfo=typeof pInfoLog=='function'?pInfoLog:libSimpleLog;this.logError=typeof pErrorLog=='function'?pErrorLog:libSimpleLog;this.cleanWrapCharacters=fCleanWrapCharacters;}// TODO: Dry me
|
|
509
|
+
checkFilters(pAddress,pRecord){return fParseConditionals(this,pAddress,pRecord);}// Delete the value of an element at an address
|
|
510
|
+
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)
|
|
511
|
+
if(typeof pObject!='object')return undefined;// Make sure pAddress (the address we are resolving) is a string
|
|
512
|
+
if(typeof pAddress!='string')return undefined;// Stash the parent address for later resolution
|
|
513
|
+
let tmpParentAddress="";if(typeof pParentAddress=='string'){tmpParentAddress=pParentAddress;}// TODO: Make this work for things like SomeRootObject.Metadata["Some.People.Use.Bad.Object.Property.Names"]
|
|
514
|
+
let tmpSeparatorIndex=pAddress.indexOf('.');// This is the terminal address string (no more dots so the RECUSION ENDS IN HERE somehow)
|
|
515
|
+
if(tmpSeparatorIndex==-1){// Check if the address refers to a boxed property
|
|
516
|
+
let tmpBracketStartIndex=pAddress.indexOf('[');let tmpBracketStopIndex=pAddress.indexOf(']');// Check for the Object Set Type marker.
|
|
517
|
+
// Note this will not work with a bracket in the same address box set
|
|
518
|
+
let tmpObjectTypeMarkerIndex=pAddress.indexOf('{}');// Boxed elements look like this:
|
|
519
|
+
// MyValues[10]
|
|
520
|
+
// MyValues['Name']
|
|
521
|
+
// MyValues["Age"]
|
|
522
|
+
// MyValues[`Cost`]
|
|
523
|
+
//
|
|
524
|
+
// When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
|
|
525
|
+
// The requirements to detect a boxed element are:
|
|
526
|
+
// 1) The start bracket is after character 0
|
|
527
|
+
if(tmpBracketStartIndex>0// 2) The end bracket has something between them
|
|
528
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is data
|
|
529
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex>1){// The "Name" of the Object contained too the left of the bracket
|
|
530
|
+
let tmpBoxedPropertyName=pAddress.substring(0,tmpBracketStartIndex).trim();// If the subproperty doesn't test as a proper Object, none of the rest of this is possible.
|
|
531
|
+
// This is a rare case where Arrays testing as Objects is useful
|
|
532
|
+
if(typeof pObject[tmpBoxedPropertyName]!=='object'){return false;}// The "Reference" to the property within it, either an array element or object property
|
|
533
|
+
let tmpBoxedPropertyReference=pAddress.substring(tmpBracketStartIndex+1,tmpBracketStopIndex).trim();// Attempt to parse the reference as a number, which will be used as an array element
|
|
534
|
+
let tmpBoxedPropertyNumber=parseInt(tmpBoxedPropertyReference,10);// Guard: If the referrant is a number and the boxed property is not an array, or vice versa, return undefined.
|
|
535
|
+
// This seems confusing to me at first read, so explaination:
|
|
536
|
+
// Is the Boxed Object an Array? TRUE
|
|
537
|
+
// And is the Reference inside the boxed Object not a number? TRUE
|
|
538
|
+
// --> So when these are in agreement, it's an impossible access state
|
|
539
|
+
if(Array.isArray(pObject[tmpBoxedPropertyName])==isNaN(tmpBoxedPropertyNumber)){return false;}// 4) If the middle part is *only* a number (no single, double or backtick quotes) it is an array element,
|
|
540
|
+
// otherwise we will try to treat it as a dynamic object property.
|
|
541
|
+
if(isNaN(tmpBoxedPropertyNumber)){// This isn't a number ... let's treat it as a dynamic object property.
|
|
542
|
+
// We would expect the property to be wrapped in some kind of quotes so strip them
|
|
543
|
+
tmpBoxedPropertyReference=this.cleanWrapCharacters('"',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters('`',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters("'",tmpBoxedPropertyReference);// Return the value in the property
|
|
544
|
+
delete pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference];return true;}else{delete pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber];return true;}}// The requirements to detect a boxed set element are:
|
|
545
|
+
// 1) The start bracket is after character 0
|
|
546
|
+
else if(tmpBracketStartIndex>0// 2) The end bracket is after the start bracket
|
|
547
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is nothing in the brackets
|
|
548
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex==1){let tmpBoxedPropertyName=pAddress.substring(0,tmpBracketStartIndex).trim();if(!Array.isArray(pObject[tmpBoxedPropertyName])){// We asked for a set from an array but it isnt' an array.
|
|
549
|
+
return false;}let tmpInputArray=pObject[tmpBoxedPropertyName];// Count from the end to the beginning so splice doesn't %&%#$ up the array
|
|
550
|
+
for(let i=tmpInputArray.length-1;i>=0;i--){// The filtering is complex but allows config-based metaprogramming directly from schema
|
|
551
|
+
let tmpKeepRecord=this.checkFilters(pAddress,tmpInputArray[i]);if(tmpKeepRecord){// Delete elements end to beginning
|
|
552
|
+
tmpInputArray.splice(i,1);}}return true;}// The object has been flagged as an object set, so treat it as such
|
|
553
|
+
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.
|
|
554
|
+
return false;}delete pObject[tmpObjectPropertyName];return true;}else{// Now is the point in recursion to return the value in the address
|
|
555
|
+
delete pObject[pAddress];return true;}}else{let tmpSubObjectName=pAddress.substring(0,tmpSeparatorIndex);let tmpNewAddress=pAddress.substring(tmpSeparatorIndex+1);// BOXED ELEMENTS
|
|
556
|
+
// Test if the tmpNewAddress is an array or object
|
|
557
|
+
// Check if it's a boxed property
|
|
558
|
+
let tmpBracketStartIndex=tmpSubObjectName.indexOf('[');let tmpBracketStopIndex=tmpSubObjectName.indexOf(']');// Boxed elements look like this:
|
|
559
|
+
// MyValues[42]
|
|
560
|
+
// MyValues['Color']
|
|
561
|
+
// MyValues["Weight"]
|
|
562
|
+
// MyValues[`Diameter`]
|
|
563
|
+
//
|
|
564
|
+
// When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
|
|
565
|
+
// The requirements to detect a boxed element are:
|
|
566
|
+
// 1) The start bracket is after character 0
|
|
567
|
+
if(tmpBracketStartIndex>0// 2) The end bracket has something between them
|
|
568
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is data
|
|
569
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex>1){let tmpBoxedPropertyName=tmpSubObjectName.substring(0,tmpBracketStartIndex).trim();let tmpBoxedPropertyReference=tmpSubObjectName.substring(tmpBracketStartIndex+1,tmpBracketStopIndex).trim();let tmpBoxedPropertyNumber=parseInt(tmpBoxedPropertyReference,10);// Guard: If the referrant is a number and the boxed property is not an array, or vice versa, return undefined.
|
|
570
|
+
// This seems confusing to me at first read, so explaination:
|
|
571
|
+
// Is the Boxed Object an Array? TRUE
|
|
572
|
+
// And is the Reference inside the boxed Object not a number? TRUE
|
|
573
|
+
// --> So when these are in agreement, it's an impossible access state
|
|
574
|
+
// This could be a failure in the recursion chain because they passed something like this in:
|
|
575
|
+
// StudentData.Sections.Algebra.Students[1].Tardy
|
|
576
|
+
// BUT
|
|
577
|
+
// StudentData.Sections.Algebra.Students is an object, so the [1].Tardy is not possible to access
|
|
578
|
+
// This could be a failure in the recursion chain because they passed something like this in:
|
|
579
|
+
// StudentData.Sections.Algebra.Students["JaneDoe"].Grade
|
|
580
|
+
// BUT
|
|
581
|
+
// StudentData.Sections.Algebra.Students is an array, so the ["JaneDoe"].Grade is not possible to access
|
|
582
|
+
// TODO: Should this be an error or something? Should we keep a log of failures like this?
|
|
583
|
+
if(Array.isArray(pObject[tmpBoxedPropertyName])==isNaN(tmpBoxedPropertyNumber)){return false;}// Check if the boxed property is an object.
|
|
584
|
+
if(typeof pObject[tmpBoxedPropertyName]!='object'){return false;}//This is a bracketed value
|
|
585
|
+
// 4) If the middle part is *only* a number (no single, double or backtick quotes) it is an array element,
|
|
586
|
+
// otherwise we will try to reat it as a dynamic object property.
|
|
587
|
+
if(isNaN(tmpBoxedPropertyNumber)){// This isn't a number ... let's treat it as a dynanmic object property.
|
|
588
|
+
tmpBoxedPropertyReference=this.cleanWrapCharacters('"',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters('`',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters("'",tmpBoxedPropertyReference);// Continue to manage the parent address for recursion
|
|
589
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpSubObjectName);// Recurse directly into the subobject
|
|
590
|
+
return this.deleteValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference],tmpNewAddress,tmpParentAddress);}else{// Continue to manage the parent address for recursion
|
|
591
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpSubObjectName);// We parsed a valid number out of the boxed property name, so recurse into the array
|
|
592
|
+
return this.deleteValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber],tmpNewAddress,tmpParentAddress);}}// The requirements to detect a boxed set element are:
|
|
593
|
+
// 1) The start bracket is after character 0
|
|
594
|
+
else if(tmpBracketStartIndex>0// 2) The end bracket is after the start bracket
|
|
595
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is nothing in the brackets
|
|
596
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex==1){let tmpBoxedPropertyName=pAddress.substring(0,tmpBracketStartIndex).trim();if(!Array.isArray(pObject[tmpBoxedPropertyName])){// We asked for a set from an array but it isnt' an array.
|
|
597
|
+
return false;}// We need to enumerate the array and grab the addresses from there.
|
|
598
|
+
let tmpArrayProperty=pObject[tmpBoxedPropertyName];// Managing the parent address is a bit more complex here -- the box will be added for each element.
|
|
599
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpBoxedPropertyName);// The container object is where we have the "Address":SOMEVALUE pairs
|
|
600
|
+
let tmpContainerObject={};for(let i=0;i<tmpArrayProperty.length;i++){let tmpPropertyParentAddress="".concat(tmpParentAddress,"[").concat(i,"]");let tmpValue=this.deleteValueAtAddress(pObject[tmpBoxedPropertyName][i],tmpNewAddress,tmpPropertyParentAddress);tmpContainerObject["".concat(tmpPropertyParentAddress,".").concat(tmpNewAddress)]=tmpValue;}return tmpContainerObject;}// OBJECT SET
|
|
601
|
+
// Note this will not work with a bracket in the same address box set
|
|
602
|
+
let tmpObjectTypeMarkerIndex=pAddress.indexOf('{}');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.
|
|
603
|
+
return false;}// We need to enumerate the Object and grab the addresses from there.
|
|
604
|
+
let tmpObjectProperty=pObject[tmpObjectPropertyName];let tmpObjectPropertyKeys=Object.keys(tmpObjectProperty);// Managing the parent address is a bit more complex here -- the box will be added for each element.
|
|
605
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpObjectPropertyName);// The container object is where we have the "Address":SOMEVALUE pairs
|
|
606
|
+
let tmpContainerObject={};for(let i=0;i<tmpObjectPropertyKeys.length;i++){let tmpPropertyParentAddress="".concat(tmpParentAddress,".").concat(tmpObjectPropertyKeys[i]);let tmpValue=this.deleteValueAtAddress(pObject[tmpObjectPropertyName][tmpObjectPropertyKeys[i]],tmpNewAddress,tmpPropertyParentAddress);// The filtering is complex but allows config-based metaprogramming directly from schema
|
|
607
|
+
let tmpKeepRecord=this.checkFilters(pAddress,tmpValue);if(tmpKeepRecord){tmpContainerObject["".concat(tmpPropertyParentAddress,".").concat(tmpNewAddress)]=tmpValue;}}return tmpContainerObject;}// If there is an object property already named for the sub object, but it isn't an object
|
|
608
|
+
// then the system can't set the value in there. Error and abort!
|
|
609
|
+
if(pObject.hasOwnProperty(tmpSubObjectName)&&typeof pObject[tmpSubObjectName]!=='object'){return undefined;}else if(pObject.hasOwnProperty(tmpSubObjectName)){// If there is already a subobject pass that to the recursive thingy
|
|
610
|
+
// Continue to manage the parent address for recursion
|
|
611
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpSubObjectName);return this.deleteValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,tmpParentAddress);}else{// Create a subobject and then pass that
|
|
612
|
+
// Continue to manage the parent address for recursion
|
|
613
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpSubObjectName);pObject[tmpSubObjectName]={};return this.deleteValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,tmpParentAddress);}}}};module.exports=ManyfestObjectAddressResolverDeleteValue;},{"../source/Manyfest-ParseConditionals.js":46,"./Manyfest-CleanWrapCharacters.js":38,"./Manyfest-LogToConsole.js":40}],43:[function(require,module,exports){/**
|
|
614
|
+
* @author <steven@velozo.com>
|
|
615
|
+
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');let fParseConditionals=require("../source/Manyfest-ParseConditionals.js");/**
|
|
616
|
+
* Object Address Resolver - GetValue
|
|
617
|
+
*
|
|
618
|
+
* IMPORTANT NOTE: This code is intentionally more verbose than necessary, to
|
|
619
|
+
* be extremely clear what is going on in the recursion for
|
|
620
|
+
* each of the three address resolution functions.
|
|
621
|
+
*
|
|
622
|
+
* Although there is some opportunity to repeat ourselves a
|
|
623
|
+
* bit less in this codebase (e.g. with detection of arrays
|
|
624
|
+
* versus objects versus direct properties), it can make
|
|
625
|
+
* debugging.. challenging. The minified version of the code
|
|
626
|
+
* optimizes out almost anything repeated in here. So please
|
|
627
|
+
* be kind and rewind... meaning please keep the codebase less
|
|
628
|
+
* terse and more verbose so humans can comprehend it.
|
|
629
|
+
*
|
|
630
|
+
* TODO: Once we validate this pattern is good to go, break these out into
|
|
631
|
+
* three separate modules.
|
|
632
|
+
*
|
|
633
|
+
* @class ManyfestObjectAddressResolverGetValue
|
|
634
|
+
*/class ManyfestObjectAddressResolverGetValue{constructor(pInfoLog,pErrorLog){// Wire in logging
|
|
635
|
+
this.logInfo=typeof pInfoLog=='function'?pInfoLog:libSimpleLog;this.logError=typeof pErrorLog=='function'?pErrorLog:libSimpleLog;this.cleanWrapCharacters=fCleanWrapCharacters;}checkFilters(pAddress,pRecord){return fParseConditionals(this,pAddress,pRecord);}// Get the value of an element at an address
|
|
636
|
+
getValueAtAddress(pObject,pAddress,pParentAddress,pRootObject){// Make sure pObject (the object we are meant to be recursing) is an object (which could be an array or object)
|
|
637
|
+
if(typeof pObject!='object')return undefined;// Make sure pAddress (the address we are resolving) is a string
|
|
638
|
+
if(typeof pAddress!='string')return undefined;// Stash the parent address for later resolution
|
|
639
|
+
let tmpParentAddress="";if(typeof pParentAddress=='string'){tmpParentAddress=pParentAddress;}// Set the root object to the passed-in object if it isn't set yet. This is expected to be the root object.
|
|
640
|
+
let tmpRootObject=typeof pRootObject=='undefined'?pObject:pRootObject;// TODO: Make this work for things like SomeRootObject.Metadata["Some.People.Use.Bad.Object.Property.Names"]
|
|
641
|
+
let tmpSeparatorIndex=pAddress.indexOf('.');// Adding simple back-navigation in objects
|
|
642
|
+
if(tmpSeparatorIndex==0){// Given an address of "Bundle.Contract.IDContract...Project.IDProject" the ... would be interpreted as two back-navigations from IDContract.
|
|
643
|
+
// When the address is passed in, though, the first . is already eliminated. So we can count the dots.
|
|
644
|
+
let tmpParentAddressParts=tmpParentAddress.split('.');let tmpBackNavigationCount=0;// Count the number of dots
|
|
645
|
+
for(let i=0;i<pAddress.length;i++){if(pAddress.charAt(i)!='.'){break;}tmpBackNavigationCount++;}let tmpParentAddressLength=tmpParentAddressParts.length-tmpBackNavigationCount;if(tmpParentAddressLength<0){// We are trying to back navigate more than we can.
|
|
646
|
+
// TODO: Should this be undefined or should we bank out at the bottom and try to go forward?
|
|
647
|
+
// This seems safest for now.
|
|
648
|
+
return undefined;}else{// We are trying to back navigate to a parent object.
|
|
649
|
+
// Recurse with the back-propagated parent address, and, the new address without the back-navigation dots.
|
|
650
|
+
let tmpRecurseAddress=pAddress.slice(tmpBackNavigationCount);if(tmpParentAddressLength>0){tmpRecurseAddress="".concat(tmpParentAddressParts.slice(0,tmpParentAddressLength).join('.'),".").concat(tmpRecurseAddress);}this.logInfo("Back-navigation detected. Recursing back to address [".concat(tmpRecurseAddress,"]"));return this.getValueAtAddress(tmpRootObject,tmpRecurseAddress);}}// This is the terminal address string (no more dots so the RECUSION ENDS IN HERE somehow)
|
|
651
|
+
if(tmpSeparatorIndex==-1){// Check if the address refers to a boxed property
|
|
652
|
+
let tmpBracketStartIndex=pAddress.indexOf('[');let tmpBracketStopIndex=pAddress.indexOf(']');// Check for the Object Set Type marker.
|
|
653
|
+
// Note this will not work with a bracket in the same address box set
|
|
654
|
+
let tmpObjectTypeMarkerIndex=pAddress.indexOf('{}');// Boxed elements look like this:
|
|
655
|
+
// MyValues[10]
|
|
656
|
+
// MyValues['Name']
|
|
657
|
+
// MyValues["Age"]
|
|
658
|
+
// MyValues[`Cost`]
|
|
659
|
+
//
|
|
660
|
+
// When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
|
|
661
|
+
// The requirements to detect a boxed element are:
|
|
662
|
+
// 1) The start bracket is after character 0
|
|
663
|
+
if(tmpBracketStartIndex>0// 2) The end bracket has something between them
|
|
664
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is data
|
|
665
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex>1){// The "Name" of the Object contained too the left of the bracket
|
|
666
|
+
let tmpBoxedPropertyName=pAddress.substring(0,tmpBracketStartIndex).trim();// If the subproperty doesn't test as a proper Object, none of the rest of this is possible.
|
|
667
|
+
// This is a rare case where Arrays testing as Objects is useful
|
|
668
|
+
if(typeof pObject[tmpBoxedPropertyName]!=='object'){return undefined;}// The "Reference" to the property within it, either an array element or object property
|
|
669
|
+
let tmpBoxedPropertyReference=pAddress.substring(tmpBracketStartIndex+1,tmpBracketStopIndex).trim();// Attempt to parse the reference as a number, which will be used as an array element
|
|
670
|
+
let tmpBoxedPropertyNumber=parseInt(tmpBoxedPropertyReference,10);// Guard: If the referrant is a number and the boxed property is not an array, or vice versa, return undefined.
|
|
671
|
+
// This seems confusing to me at first read, so explaination:
|
|
672
|
+
// Is the Boxed Object an Array? TRUE
|
|
673
|
+
// And is the Reference inside the boxed Object not a number? TRUE
|
|
674
|
+
// --> So when these are in agreement, it's an impossible access state
|
|
675
|
+
if(Array.isArray(pObject[tmpBoxedPropertyName])==isNaN(tmpBoxedPropertyNumber)){return undefined;}// 4) If the middle part is *only* a number (no single, double or backtick quotes) it is an array element,
|
|
676
|
+
// otherwise we will try to treat it as a dynamic object property.
|
|
677
|
+
if(isNaN(tmpBoxedPropertyNumber)){// This isn't a number ... let's treat it as a dynamic object property.
|
|
678
|
+
// We would expect the property to be wrapped in some kind of quotes so strip them
|
|
679
|
+
tmpBoxedPropertyReference=this.cleanWrapCharacters('"',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters('`',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters("'",tmpBoxedPropertyReference);// Return the value in the property
|
|
680
|
+
return pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference];}else{return pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber];}}// The requirements to detect a boxed set element are:
|
|
681
|
+
// 1) The start bracket is after character 0
|
|
682
|
+
else if(tmpBracketStartIndex>0// 2) The end bracket is after the start bracket
|
|
683
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is nothing in the brackets
|
|
684
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex==1){let tmpBoxedPropertyName=pAddress.substring(0,tmpBracketStartIndex).trim();if(!Array.isArray(pObject[tmpBoxedPropertyName])){// We asked for a set from an array but it isnt' an array.
|
|
685
|
+
return false;}let tmpInputArray=pObject[tmpBoxedPropertyName];let tmpOutputArray=[];for(let i=0;i<tmpInputArray.length;i++){// The filtering is complex but allows config-based metaprogramming directly from schema
|
|
686
|
+
let tmpKeepRecord=this.checkFilters(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
|
|
687
|
+
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.
|
|
688
|
+
return false;}return pObject[tmpObjectPropertyName];}else{// Now is the point in recursion to return the value in the address
|
|
689
|
+
return pObject[pAddress];}}else{let tmpSubObjectName=pAddress.substring(0,tmpSeparatorIndex);let tmpNewAddress=pAddress.substring(tmpSeparatorIndex+1);// BOXED ELEMENTS
|
|
690
|
+
// Test if the tmpNewAddress is an array or object
|
|
691
|
+
// Check if it's a boxed property
|
|
692
|
+
let tmpBracketStartIndex=tmpSubObjectName.indexOf('[');let tmpBracketStopIndex=tmpSubObjectName.indexOf(']');// Boxed elements look like this:
|
|
693
|
+
// MyValues[42]
|
|
694
|
+
// MyValues['Color']
|
|
695
|
+
// MyValues["Weight"]
|
|
696
|
+
// MyValues[`Diameter`]
|
|
697
|
+
//
|
|
698
|
+
// When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
|
|
699
|
+
// The requirements to detect a boxed element are:
|
|
700
|
+
// 1) The start bracket is after character 0
|
|
701
|
+
if(tmpBracketStartIndex>0// 2) The end bracket has something between them
|
|
702
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is data
|
|
703
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex>1){let tmpBoxedPropertyName=tmpSubObjectName.substring(0,tmpBracketStartIndex).trim();let tmpBoxedPropertyReference=tmpSubObjectName.substring(tmpBracketStartIndex+1,tmpBracketStopIndex).trim();let tmpBoxedPropertyNumber=parseInt(tmpBoxedPropertyReference,10);// Guard: If the referrant is a number and the boxed property is not an array, or vice versa, return undefined.
|
|
704
|
+
// This seems confusing to me at first read, so explaination:
|
|
705
|
+
// Is the Boxed Object an Array? TRUE
|
|
706
|
+
// And is the Reference inside the boxed Object not a number? TRUE
|
|
707
|
+
// --> So when these are in agreement, it's an impossible access state
|
|
708
|
+
// This could be a failure in the recursion chain because they passed something like this in:
|
|
709
|
+
// StudentData.Sections.Algebra.Students[1].Tardy
|
|
710
|
+
// BUT
|
|
711
|
+
// StudentData.Sections.Algebra.Students is an object, so the [1].Tardy is not possible to access
|
|
712
|
+
// This could be a failure in the recursion chain because they passed something like this in:
|
|
713
|
+
// StudentData.Sections.Algebra.Students["JaneDoe"].Grade
|
|
714
|
+
// BUT
|
|
715
|
+
// StudentData.Sections.Algebra.Students is an array, so the ["JaneDoe"].Grade is not possible to access
|
|
716
|
+
// TODO: Should this be an error or something? Should we keep a log of failures like this?
|
|
717
|
+
if(Array.isArray(pObject[tmpBoxedPropertyName])==isNaN(tmpBoxedPropertyNumber)){return undefined;}// Check if the boxed property is an object.
|
|
718
|
+
if(typeof pObject[tmpBoxedPropertyName]!='object'){return undefined;}//This is a bracketed value
|
|
719
|
+
// 4) If the middle part is *only* a number (no single, double or backtick quotes) it is an array element,
|
|
720
|
+
// otherwise we will try to reat it as a dynamic object property.
|
|
721
|
+
if(isNaN(tmpBoxedPropertyNumber)){// This isn't a number ... let's treat it as a dynanmic object property.
|
|
722
|
+
tmpBoxedPropertyReference=this.cleanWrapCharacters('"',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters('`',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters("'",tmpBoxedPropertyReference);// Continue to manage the parent address for recursion
|
|
723
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpSubObjectName);// Recurse directly into the subobject
|
|
724
|
+
return this.getValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference],tmpNewAddress,tmpParentAddress,tmpRootObject);}else{// Continue to manage the parent address for recursion
|
|
725
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpSubObjectName);// We parsed a valid number out of the boxed property name, so recurse into the array
|
|
726
|
+
return this.getValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber],tmpNewAddress,tmpParentAddress,tmpRootObject);}}// The requirements to detect a boxed set element are:
|
|
727
|
+
// 1) The start bracket is after character 0
|
|
728
|
+
else if(tmpBracketStartIndex>0// 2) The end bracket is after the start bracket
|
|
729
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is nothing in the brackets
|
|
730
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex==1){let tmpBoxedPropertyName=pAddress.substring(0,tmpBracketStartIndex).trim();if(!Array.isArray(pObject[tmpBoxedPropertyName])){// We asked for a set from an array but it isnt' an array.
|
|
731
|
+
return false;}// We need to enumerate the array and grab the addresses from there.
|
|
732
|
+
let tmpArrayProperty=pObject[tmpBoxedPropertyName];// Managing the parent address is a bit more complex here -- the box will be added for each element.
|
|
733
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpBoxedPropertyName);// The container object is where we have the "Address":SOMEVALUE pairs
|
|
734
|
+
let tmpContainerObject={};for(let i=0;i<tmpArrayProperty.length;i++){let tmpPropertyParentAddress="".concat(tmpParentAddress,"[").concat(i,"]");let tmpValue=this.getValueAtAddress(pObject[tmpBoxedPropertyName][i],tmpNewAddress,tmpPropertyParentAddress,tmpRootObject);tmpContainerObject["".concat(tmpPropertyParentAddress,".").concat(tmpNewAddress)]=tmpValue;}return tmpContainerObject;}// OBJECT SET
|
|
735
|
+
// Note this will not work with a bracket in the same address box set
|
|
736
|
+
let tmpObjectTypeMarkerIndex=pAddress.indexOf('{}');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.
|
|
737
|
+
return false;}// We need to enumerate the Object and grab the addresses from there.
|
|
738
|
+
let tmpObjectProperty=pObject[tmpObjectPropertyName];let tmpObjectPropertyKeys=Object.keys(tmpObjectProperty);// Managing the parent address is a bit more complex here -- the box will be added for each element.
|
|
739
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpObjectPropertyName);// The container object is where we have the "Address":SOMEVALUE pairs
|
|
740
|
+
let tmpContainerObject={};for(let i=0;i<tmpObjectPropertyKeys.length;i++){let tmpPropertyParentAddress="".concat(tmpParentAddress,".").concat(tmpObjectPropertyKeys[i]);let tmpValue=this.getValueAtAddress(pObject[tmpObjectPropertyName][tmpObjectPropertyKeys[i]],tmpNewAddress,tmpPropertyParentAddress,tmpRootObject);// The filtering is complex but allows config-based metaprogramming directly from schema
|
|
741
|
+
let tmpKeepRecord=this.checkFilters(pAddress,tmpValue);if(tmpKeepRecord){tmpContainerObject["".concat(tmpPropertyParentAddress,".").concat(tmpNewAddress)]=tmpValue;}}return tmpContainerObject;}// If there is an object property already named for the sub object, but it isn't an object
|
|
742
|
+
// then the system can't set the value in there. Error and abort!
|
|
743
|
+
if(pObject.hasOwnProperty(tmpSubObjectName)&&typeof pObject[tmpSubObjectName]!=='object'){return undefined;}else if(pObject.hasOwnProperty(tmpSubObjectName)){// If there is already a subobject pass that to the recursive thingy
|
|
744
|
+
// Continue to manage the parent address for recursion
|
|
745
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpSubObjectName);return this.getValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,tmpParentAddress,tmpRootObject);}else{// Create a subobject and then pass that
|
|
746
|
+
// Continue to manage the parent address for recursion
|
|
747
|
+
tmpParentAddress="".concat(tmpParentAddress).concat(tmpParentAddress.length>0?'.':'').concat(tmpSubObjectName);pObject[tmpSubObjectName]={};return this.getValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,tmpParentAddress,tmpRootObject);}}}};module.exports=ManyfestObjectAddressResolverGetValue;},{"../source/Manyfest-ParseConditionals.js":46,"./Manyfest-CleanWrapCharacters.js":38,"./Manyfest-LogToConsole.js":40}],44:[function(require,module,exports){/**
|
|
748
|
+
* @author <steven@velozo.com>
|
|
749
|
+
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');/**
|
|
750
|
+
* Object Address Resolver - SetValue
|
|
751
|
+
*
|
|
752
|
+
* IMPORTANT NOTE: This code is intentionally more verbose than necessary, to
|
|
753
|
+
* be extremely clear what is going on in the recursion for
|
|
754
|
+
* each of the three address resolution functions.
|
|
755
|
+
*
|
|
756
|
+
* Although there is some opportunity to repeat ourselves a
|
|
757
|
+
* bit less in this codebase (e.g. with detection of arrays
|
|
758
|
+
* versus objects versus direct properties), it can make
|
|
759
|
+
* debugging.. challenging. The minified version of the code
|
|
760
|
+
* optimizes out almost anything repeated in here. So please
|
|
761
|
+
* be kind and rewind... meaning please keep the codebase less
|
|
762
|
+
* terse and more verbose so humans can comprehend it.
|
|
763
|
+
*
|
|
764
|
+
*
|
|
765
|
+
* @class ManyfestObjectAddressSetValue
|
|
766
|
+
*/class ManyfestObjectAddressSetValue{constructor(pInfoLog,pErrorLog){// Wire in logging
|
|
767
|
+
this.logInfo=typeof pInfoLog=='function'?pInfoLog:libSimpleLog;this.logError=typeof pErrorLog=='function'?pErrorLog:libSimpleLog;this.cleanWrapCharacters=fCleanWrapCharacters;}// Set the value of an element at an address
|
|
768
|
+
setValueAtAddress(pObject,pAddress,pValue){// Make sure pObject is an object
|
|
769
|
+
if(typeof pObject!='object')return false;// Make sure pAddress is a string
|
|
770
|
+
if(typeof pAddress!='string')return false;let tmpSeparatorIndex=pAddress.indexOf('.');if(tmpSeparatorIndex==-1){// Check if it's a boxed property
|
|
771
|
+
let tmpBracketStartIndex=pAddress.indexOf('[');let tmpBracketStopIndex=pAddress.indexOf(']');// Boxed elements look like this:
|
|
772
|
+
// MyValues[10]
|
|
773
|
+
// MyValues['Name']
|
|
774
|
+
// MyValues["Age"]
|
|
775
|
+
// MyValues[`Cost`]
|
|
776
|
+
//
|
|
777
|
+
// When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
|
|
778
|
+
// The requirements to detect a boxed element are:
|
|
779
|
+
// 1) The start bracket is after character 0
|
|
780
|
+
if(tmpBracketStartIndex>0// 2) The end bracket has something between them
|
|
781
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is data
|
|
782
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex>1){// The "Name" of the Object contained too the left of the bracket
|
|
783
|
+
let tmpBoxedPropertyName=pAddress.substring(0,tmpBracketStartIndex).trim();// If the subproperty doesn't test as a proper Object, none of the rest of this is possible.
|
|
784
|
+
// This is a rare case where Arrays testing as Objects is useful
|
|
785
|
+
if(typeof pObject[tmpBoxedPropertyName]!=='object'){return false;}// The "Reference" to the property within it, either an array element or object property
|
|
786
|
+
let tmpBoxedPropertyReference=pAddress.substring(tmpBracketStartIndex+1,tmpBracketStopIndex).trim();// Attempt to parse the reference as a number, which will be used as an array element
|
|
787
|
+
let tmpBoxedPropertyNumber=parseInt(tmpBoxedPropertyReference,10);// Guard: If the referrant is a number and the boxed property is not an array, or vice versa, return undefined.
|
|
788
|
+
// This seems confusing to me at first read, so explaination:
|
|
789
|
+
// Is the Boxed Object an Array? TRUE
|
|
790
|
+
// And is the Reference inside the boxed Object not a number? TRUE
|
|
791
|
+
// --> So when these are in agreement, it's an impossible access state
|
|
792
|
+
if(Array.isArray(pObject[tmpBoxedPropertyName])==isNaN(tmpBoxedPropertyNumber)){return false;}// 4) If the middle part is *only* a number (no single, double or backtick quotes) it is an array element,
|
|
793
|
+
// otherwise we will try to treat it as a dynamic object property.
|
|
794
|
+
if(isNaN(tmpBoxedPropertyNumber)){// This isn't a number ... let's treat it as a dynamic object property.
|
|
795
|
+
// We would expect the property to be wrapped in some kind of quotes so strip them
|
|
796
|
+
tmpBoxedPropertyReference=this.cleanWrapCharacters('"',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters('`',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters("'",tmpBoxedPropertyReference);// Return the value in the property
|
|
797
|
+
pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference]=pValue;return true;}else{pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber]=pValue;return true;}}else{// Now is the time in recursion to set the value in the object
|
|
798
|
+
pObject[pAddress]=pValue;return true;}}else{let tmpSubObjectName=pAddress.substring(0,tmpSeparatorIndex);let tmpNewAddress=pAddress.substring(tmpSeparatorIndex+1);// Test if the tmpNewAddress is an array or object
|
|
799
|
+
// Check if it's a boxed property
|
|
800
|
+
let tmpBracketStartIndex=tmpSubObjectName.indexOf('[');let tmpBracketStopIndex=tmpSubObjectName.indexOf(']');// Boxed elements look like this:
|
|
801
|
+
// MyValues[42]
|
|
802
|
+
// MyValues['Color']
|
|
803
|
+
// MyValues["Weight"]
|
|
804
|
+
// MyValues[`Diameter`]
|
|
805
|
+
//
|
|
806
|
+
// When we are passed SomeObject["Name"] this code below recurses as if it were SomeObject.Name
|
|
807
|
+
// The requirements to detect a boxed element are:
|
|
808
|
+
// 1) The start bracket is after character 0
|
|
809
|
+
if(tmpBracketStartIndex>0// 2) The end bracket has something between them
|
|
810
|
+
&&tmpBracketStopIndex>tmpBracketStartIndex// 3) There is data
|
|
811
|
+
&&tmpBracketStopIndex-tmpBracketStartIndex>1){let tmpBoxedPropertyName=tmpSubObjectName.substring(0,tmpBracketStartIndex).trim();let tmpBoxedPropertyReference=tmpSubObjectName.substring(tmpBracketStartIndex+1,tmpBracketStopIndex).trim();let tmpBoxedPropertyNumber=parseInt(tmpBoxedPropertyReference,10);// Guard: If the referrant is a number and the boxed property is not an array, or vice versa, return undefined.
|
|
812
|
+
// This seems confusing to me at first read, so explaination:
|
|
813
|
+
// Is the Boxed Object an Array? TRUE
|
|
814
|
+
// And is the Reference inside the boxed Object not a number? TRUE
|
|
815
|
+
// --> So when these are in agreement, it's an impossible access state
|
|
816
|
+
// This could be a failure in the recursion chain because they passed something like this in:
|
|
817
|
+
// StudentData.Sections.Algebra.Students[1].Tardy
|
|
818
|
+
// BUT
|
|
819
|
+
// StudentData.Sections.Algebra.Students is an object, so the [1].Tardy is not possible to access
|
|
820
|
+
// This could be a failure in the recursion chain because they passed something like this in:
|
|
821
|
+
// StudentData.Sections.Algebra.Students["JaneDoe"].Grade
|
|
822
|
+
// BUT
|
|
823
|
+
// StudentData.Sections.Algebra.Students is an array, so the ["JaneDoe"].Grade is not possible to access
|
|
824
|
+
// TODO: Should this be an error or something? Should we keep a log of failures like this?
|
|
825
|
+
if(Array.isArray(pObject[tmpBoxedPropertyName])==isNaN(tmpBoxedPropertyNumber)){return false;}//This is a bracketed value
|
|
826
|
+
// 4) If the middle part is *only* a number (no single, double or backtick quotes) it is an array element,
|
|
827
|
+
// otherwise we will try to reat it as a dynamic object property.
|
|
828
|
+
if(isNaN(tmpBoxedPropertyNumber)){// This isn't a number ... let's treat it as a dynanmic object property.
|
|
829
|
+
tmpBoxedPropertyReference=this.cleanWrapCharacters('"',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters('`',tmpBoxedPropertyReference);tmpBoxedPropertyReference=this.cleanWrapCharacters("'",tmpBoxedPropertyReference);// Recurse directly into the subobject
|
|
830
|
+
return this.setValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference],tmpNewAddress,pValue);}else{// We parsed a valid number out of the boxed property name, so recurse into the array
|
|
831
|
+
return this.setValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber],tmpNewAddress,pValue);}}// If there is an object property already named for the sub object, but it isn't an object
|
|
832
|
+
// then the system can't set the value in there. Error and abort!
|
|
833
|
+
if(pObject.hasOwnProperty(tmpSubObjectName)&&typeof pObject[tmpSubObjectName]!=='object'){if(!pObject.hasOwnProperty('__ERROR'))pObject['__ERROR']={};// Put it in an error object so data isn't lost
|
|
834
|
+
pObject['__ERROR'][pAddress]=pValue;return false;}else if(pObject.hasOwnProperty(tmpSubObjectName)){// If there is already a subobject pass that to the recursive thingy
|
|
835
|
+
return this.setValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,pValue);}else{// Create a subobject and then pass that
|
|
836
|
+
pObject[tmpSubObjectName]={};return this.setValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,pValue);}}}};module.exports=ManyfestObjectAddressSetValue;},{"./Manyfest-CleanWrapCharacters.js":38,"./Manyfest-LogToConsole.js":40}],45:[function(require,module,exports){/**
|
|
837
|
+
* @author <steven@velozo.com>
|
|
838
|
+
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');/**
|
|
839
|
+
* Object Address Generation
|
|
840
|
+
*
|
|
841
|
+
* Automagically generate addresses and properties based on a passed-in object,
|
|
842
|
+
* to be used for easy creation of schemas. Meant to simplify the lives of
|
|
843
|
+
* developers wanting to create schemas without typing a bunch of stuff.
|
|
844
|
+
*
|
|
845
|
+
* IMPORTANT NOTE: This code is intentionally more verbose than necessary, to
|
|
846
|
+
* be extremely clear what is going on in the recursion for
|
|
847
|
+
* each of the three address resolution functions.
|
|
848
|
+
*
|
|
849
|
+
* Although there is some opportunity to repeat ourselves a
|
|
850
|
+
* bit less in this codebase (e.g. with detection of arrays
|
|
851
|
+
* versus objects versus direct properties), it can make
|
|
852
|
+
* debugging.. challenging. The minified version of the code
|
|
853
|
+
* optimizes out almost anything repeated in here. So please
|
|
854
|
+
* be kind and rewind... meaning please keep the codebase less
|
|
855
|
+
* terse and more verbose so humans can comprehend it.
|
|
856
|
+
*
|
|
857
|
+
*
|
|
858
|
+
* @class ManyfestObjectAddressGeneration
|
|
859
|
+
*/class ManyfestObjectAddressGeneration{constructor(pInfoLog,pErrorLog){// Wire in logging
|
|
860
|
+
this.logInfo=typeof pInfoLog=='function'?pInfoLog:libSimpleLog;this.logError=typeof pErrorLog=='function'?pErrorLog:libSimpleLog;}// generateAddressses
|
|
861
|
+
//
|
|
862
|
+
// This flattens an object into a set of key:value pairs for *EVERY SINGLE
|
|
863
|
+
// POSSIBLE ADDRESS* in the object. It can get ... really insane really
|
|
864
|
+
// quickly. This is not meant to be used directly to generate schemas, but
|
|
865
|
+
// instead as a starting point for scripts or UIs.
|
|
866
|
+
//
|
|
867
|
+
// This will return a mega set of key:value pairs with all possible schema
|
|
868
|
+
// permutations and default values (when not an object) and everything else.
|
|
869
|
+
generateAddressses(pObject,pBaseAddress,pSchema){let tmpBaseAddress=typeof pBaseAddress=='string'?pBaseAddress:'';let tmpSchema=typeof pSchema=='object'?pSchema:{};let tmpObjectType=typeof pObject;let tmpSchemaObjectEntry={Address:tmpBaseAddress,Hash:tmpBaseAddress,Name:tmpBaseAddress,// This is so scripts and UI controls can force a developer to opt-in.
|
|
870
|
+
InSchema:false};if(tmpObjectType=='object'&&pObject==null){tmpObjectType='null';}switch(tmpObjectType){case'string':tmpSchemaObjectEntry.DataType='String';tmpSchemaObjectEntry.Default=pObject;tmpSchema[tmpBaseAddress]=tmpSchemaObjectEntry;break;case'number':case'bigint':tmpSchemaObjectEntry.DataType='Number';tmpSchemaObjectEntry.Default=pObject;tmpSchema[tmpBaseAddress]=tmpSchemaObjectEntry;break;case'undefined':case'null':tmpSchemaObjectEntry.DataType='Any';tmpSchemaObjectEntry.Default=pObject;tmpSchema[tmpBaseAddress]=tmpSchemaObjectEntry;break;case'object':if(Array.isArray(pObject)){tmpSchemaObjectEntry.DataType='Array';if(tmpBaseAddress!=''){tmpSchema[tmpBaseAddress]=tmpSchemaObjectEntry;}for(let i=0;i<pObject.length;i++){this.generateAddressses(pObject[i],"".concat(tmpBaseAddress,"[").concat(i,"]"),tmpSchema);}}else{tmpSchemaObjectEntry.DataType='Object';if(tmpBaseAddress!=''){tmpSchema[tmpBaseAddress]=tmpSchemaObjectEntry;tmpBaseAddress+='.';}let tmpObjectProperties=Object.keys(pObject);for(let i=0;i<tmpObjectProperties.length;i++){this.generateAddressses(pObject[tmpObjectProperties[i]],"".concat(tmpBaseAddress).concat(tmpObjectProperties[i]),tmpSchema);}}break;case'symbol':case'function':// Symbols and functions neither recurse nor get added to the schema
|
|
871
|
+
break;}return tmpSchema;}};module.exports=ManyfestObjectAddressGeneration;},{"./Manyfest-LogToConsole.js":40}],46:[function(require,module,exports){// Given a string, parse out any conditional expressions and set whether or not to keep the record.
|
|
872
|
+
//
|
|
873
|
+
// For instance:
|
|
874
|
+
// 'files[]<<~?format,==,Thumbnail?~>>'
|
|
875
|
+
// 'files[]<<~?format,==,Metadata?~>>'
|
|
876
|
+
// 'files[]<<~?size,>,4000?~>>'
|
|
877
|
+
//
|
|
878
|
+
// The wrapping parts are the <<~? and ?~>> megabrackets.
|
|
879
|
+
//
|
|
880
|
+
// The function does not need to alter the string -- just check the conditionals within.
|
|
881
|
+
// TODO: Consider making this an es6 class
|
|
882
|
+
// Let's use indexOf since it is apparently the fastest.
|
|
883
|
+
const _ConditionalStanzaStart='<<~?';const _ConditionalStanzaStartLength=_ConditionalStanzaStart.length;const _ConditionalStanzaEnd='?~>>';const _ConditionalStanzaEndLength=_ConditionalStanzaEnd.length;// Test the condition of a value in a record
|
|
884
|
+
const testCondition=(pManyfest,pRecord,pSearchAddress,pSearchComparator,pValue)=>{switch(pSearchComparator){case'!=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)!=pValue;break;case'<':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)<pValue;break;case'>':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)>pValue;break;case'<=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)<=pValue;break;case'>=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)>=pValue;break;case'===':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===pValue;break;case'==':default:return pManyfest.getValueAtAddress(pRecord,pSearchAddress)==pValue;break;}};const parseConditionals=(pManyfest,pAddress,pRecord)=>{let tmpKeepRecord=true;/*
|
|
885
|
+
Algorithm is simple:
|
|
886
|
+
|
|
887
|
+
1. Enuerate start points
|
|
888
|
+
|
|
889
|
+
2. Find stop points within each start point
|
|
890
|
+
3. Check the conditional
|
|
891
|
+
*/let tmpStartIndex=pAddress.indexOf(_ConditionalStanzaStart);while(tmpStartIndex!=-1){let tmpStopIndex=pAddress.indexOf(_ConditionalStanzaEnd,tmpStartIndex+_ConditionalStanzaStartLength);if(tmpStopIndex!=-1){let tmpMagicComparisonPatternSet=pAddress.substring(tmpStartIndex+_ConditionalStanzaStartLength,tmpStopIndex).split(',');let tmpSearchAddress=tmpMagicComparisonPatternSet[0];let tmpSearchComparator=tmpMagicComparisonPatternSet[1];let tmpSearchValue=tmpMagicComparisonPatternSet[2];// Process the piece
|
|
892
|
+
tmpKeepRecord=tmpKeepRecord&&testCondition(pManyfest,pRecord,tmpSearchAddress,tmpSearchComparator,tmpSearchValue);tmpStartIndex=pAddress.indexOf(_ConditionalStanzaStart,tmpStopIndex+_ConditionalStanzaEndLength);}else{tmpStartIndex=-1;}}return tmpKeepRecord;};module.exports=parseConditionals;},{}],47:[function(require,module,exports){/**
|
|
893
|
+
* @author <steven@velozo.com>
|
|
894
|
+
*/let libSimpleLog=require('./Manyfest-LogToConsole.js');/**
|
|
895
|
+
* Schema Manipulation Functions
|
|
896
|
+
*
|
|
897
|
+
* @class ManyfestSchemaManipulation
|
|
898
|
+
*/class ManyfestSchemaManipulation{constructor(pInfoLog,pErrorLog){// Wire in logging
|
|
899
|
+
this.logInfo=typeof pInfoLog==='function'?pInfoLog:libSimpleLog;this.logError=typeof pErrorLog==='function'?pErrorLog:libSimpleLog;}// This translates the default address mappings to something different.
|
|
900
|
+
//
|
|
901
|
+
// For instance you can pass in manyfest schema descriptor object:
|
|
902
|
+
// {
|
|
903
|
+
// "Address.Of.a": { "Hash": "a", "Type": "Number" },
|
|
904
|
+
// "Address.Of.b": { "Hash": "b", "Type": "Number" }
|
|
905
|
+
// }
|
|
906
|
+
//
|
|
907
|
+
//
|
|
908
|
+
// And then an address mapping (basically a Hash->Address map)
|
|
909
|
+
// {
|
|
910
|
+
// "a": "New.Address.Of.a",
|
|
911
|
+
// "b": "New.Address.Of.b"
|
|
912
|
+
// }
|
|
913
|
+
//
|
|
914
|
+
// NOTE: This mutates the schema object permanently, altering the base hash.
|
|
915
|
+
// If there is a collision with an existing address, it can lead to overwrites.
|
|
916
|
+
// TODO: Discuss what should happen on collisions.
|
|
917
|
+
resolveAddressMappings(pManyfestSchemaDescriptors,pAddressMapping){if(typeof pManyfestSchemaDescriptors!='object'){this.logError("Attempted to resolve address mapping but the descriptor was not an object.");return false;}if(typeof pAddressMapping!='object'){// No mappings were passed in
|
|
918
|
+
return true;}// Get the arrays of both the schema definition and the hash mapping
|
|
919
|
+
let tmpManyfestAddresses=Object.keys(pManyfestSchemaDescriptors);let tmpHashMapping={};tmpManyfestAddresses.forEach(pAddress=>{if(pManyfestSchemaDescriptors[pAddress].hasOwnProperty('Hash')){tmpHashMapping[pManyfestSchemaDescriptors[pAddress].Hash]=pAddress;}});let tmpAddressMappingSet=Object.keys(pAddressMapping);tmpAddressMappingSet.forEach(pInputAddress=>{let tmpNewDescriptorAddress=pAddressMapping[pInputAddress];let tmpOldDescriptorAddress=false;let tmpDescriptor=false;// See if there is a matching descriptor either by Address directly or Hash
|
|
920
|
+
if(pManyfestSchemaDescriptors.hasOwnProperty(pInputAddress)){tmpOldDescriptorAddress=pInputAddress;}else if(tmpHashMapping.hasOwnProperty(pInputAddress)){tmpOldDescriptorAddress=tmpHashMapping[pInputAddress];}// If there was a matching descriptor in the manifest, store it in the temporary descriptor
|
|
921
|
+
if(tmpOldDescriptorAddress){tmpDescriptor=pManyfestSchemaDescriptors[tmpOldDescriptorAddress];delete pManyfestSchemaDescriptors[tmpOldDescriptorAddress];}else{// Create a new descriptor! Map it to the input address.
|
|
922
|
+
tmpDescriptor={Hash:pInputAddress};}// Now re-add the descriptor to the manyfest schema
|
|
923
|
+
pManyfestSchemaDescriptors[tmpNewDescriptorAddress]=tmpDescriptor;});return true;}safeResolveAddressMappings(pManyfestSchemaDescriptors,pAddressMapping){// This returns the descriptors as a new object, safely remapping without mutating the original schema Descriptors
|
|
924
|
+
let tmpManyfestSchemaDescriptors=JSON.parse(JSON.stringify(pManyfestSchemaDescriptors));this.resolveAddressMappings(tmpManyfestSchemaDescriptors,pAddressMapping);return tmpManyfestSchemaDescriptors;}mergeAddressMappings(pManyfestSchemaDescriptorsDestination,pManyfestSchemaDescriptorsSource){if(typeof pManyfestSchemaDescriptorsSource!='object'||typeof pManyfestSchemaDescriptorsDestination!='object'){this.logError("Attempted to merge two schema descriptors but both were not objects.");return false;}let tmpSource=JSON.parse(JSON.stringify(pManyfestSchemaDescriptorsSource));let tmpNewManyfestSchemaDescriptors=JSON.parse(JSON.stringify(pManyfestSchemaDescriptorsDestination));// The first passed-in set of descriptors takes precedence.
|
|
925
|
+
let tmpDescriptorAddresses=Object.keys(tmpSource);tmpDescriptorAddresses.forEach(pDescriptorAddress=>{if(!tmpNewManyfestSchemaDescriptors.hasOwnProperty(pDescriptorAddress)){tmpNewManyfestSchemaDescriptors[pDescriptorAddress]=tmpSource[pDescriptorAddress];}});return tmpNewManyfestSchemaDescriptors;}}module.exports=ManyfestSchemaManipulation;},{"./Manyfest-LogToConsole.js":40}],48:[function(require,module,exports){/**
|
|
926
|
+
* @author <steven@velozo.com>
|
|
927
|
+
*/const libFableServiceProviderBase=require('fable-serviceproviderbase');let libSimpleLog=require('./Manyfest-LogToConsole.js');let libHashTranslation=require('./Manyfest-HashTranslation.js');let libObjectAddressCheckAddressExists=require('./Manyfest-ObjectAddress-CheckAddressExists.js');let libObjectAddressGetValue=require('./Manyfest-ObjectAddress-GetValue.js');let libObjectAddressSetValue=require('./Manyfest-ObjectAddress-SetValue.js');let libObjectAddressDeleteValue=require('./Manyfest-ObjectAddress-DeleteValue.js');let libObjectAddressGeneration=require('./Manyfest-ObjectAddressGeneration.js');let libSchemaManipulation=require('./Manyfest-SchemaManipulation.js');const _DefaultConfiguration={Scope:'DEFAULT',Descriptors:{}};/**
|
|
928
|
+
* Manyfest object address-based descriptions and manipulations.
|
|
929
|
+
*
|
|
930
|
+
* @class Manyfest
|
|
931
|
+
*/class Manyfest extends libFableServiceProviderBase{constructor(pFable,pManifest,pServiceHash){if(pFable===undefined){super({});}else{super(pFable,pManifest,pServiceHash);}this.serviceType='Manifest';// Wire in logging
|
|
932
|
+
this.logInfo=libSimpleLog;this.logError=libSimpleLog;// Create an object address resolver and map in the functions
|
|
933
|
+
this.objectAddressCheckAddressExists=new libObjectAddressCheckAddressExists(this.logInfo,this.logError);this.objectAddressGetValue=new libObjectAddressGetValue(this.logInfo,this.logError);this.objectAddressSetValue=new libObjectAddressSetValue(this.logInfo,this.logError);this.objectAddressDeleteValue=new libObjectAddressDeleteValue(this.logInfo,this.logError);if(!this.options.hasOwnProperty('defaultValues')){this.options.defaultValues={"String":"","Number":0,"Float":0.0,"Integer":0,"Boolean":false,"Binary":0,"DateTime":0,"Array":[],"Object":{},"Null":null};}if(!this.options.hasOwnProperty('strict')){this.options.strict=false;}this.scope=undefined;this.elementAddresses=undefined;this.elementHashes=undefined;this.elementDescriptors=undefined;// This can cause a circular dependency chain, so it only gets initialized if the schema specifically calls for it.
|
|
934
|
+
this.dataSolvers=undefined;// So solvers can use their own state
|
|
935
|
+
this.dataSolverState=undefined;this.reset();if(typeof this.options==='object'){this.loadManifest(this.options);}this.schemaManipulations=new libSchemaManipulation(this.logInfo,this.logError);this.objectAddressGeneration=new libObjectAddressGeneration(this.logInfo,this.logError);this.hashTranslations=new libHashTranslation(this.logInfo,this.logError);}/*************************************************************************
|
|
936
|
+
* Schema Manifest Loading, Reading, Manipulation and Serialization Functions
|
|
937
|
+
*/ // Reset critical manifest properties
|
|
938
|
+
reset(){this.scope='DEFAULT';this.elementAddresses=[];this.elementHashes={};this.elementDescriptors={};this.dataSolvers=undefined;this.dataSolverState={};}clone(){// Make a copy of the options in-place
|
|
939
|
+
let tmpNewOptions=JSON.parse(JSON.stringify(this.options));let tmpNewManyfest=new Manyfest(this.getManifest(),this.logInfo,this.logError,tmpNewOptions);// Import the hash translations
|
|
940
|
+
tmpNewManyfest.hashTranslations.addTranslation(this.hashTranslations.translationTable);return tmpNewManyfest;}// Deserialize a Manifest from a string
|
|
941
|
+
deserialize(pManifestString){// TODO: Add guards for bad manifest string
|
|
942
|
+
return this.loadManifest(JSON.parse(pManifestString));}// Load a manifest from an object
|
|
943
|
+
loadManifest(pManifest){if(typeof pManifest!=='object'){this.logError("(".concat(this.scope,") Error loading manifest; expecting an object but parameter was type ").concat(typeof pManifest,"."));}let tmpManifest=typeof pManifest=='object'?pManifest:{};let tmpDescriptorKeys=Object.keys(_DefaultConfiguration);for(let i=0;i<tmpDescriptorKeys.length;i++){if(!tmpManifest.hasOwnProperty(tmpDescriptorKeys[i])){tmpManifest[tmpDescriptorKeys[i]]=JSON.parse(JSON.stringify(_DefaultConfiguration[tmpDescriptorKeys[i]]));}}if(tmpManifest.hasOwnProperty('Scope')){if(typeof tmpManifest.Scope==='string'){this.scope=tmpManifest.Scope;}else{this.logError("(".concat(this.scope,") Error loading scope from manifest; expecting a string but property was type ").concat(typeof tmpManifest.Scope,"."),tmpManifest);}}else{this.logError("(".concat(this.scope,") Error loading scope from manifest object. Property \"Scope\" does not exist in the root of the object."),tmpManifest);}if(tmpManifest.hasOwnProperty('Descriptors')){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("(".concat(this.scope,") Error loading description object from manifest object. Expecting an object in 'Manifest.Descriptors' but the property was type ").concat(typeof tmpManifest.Descriptors,"."),tmpManifest);}}else{this.logError("(".concat(this.scope,") Error loading object description from manifest object. Property \"Descriptors\" does not exist in the root of the Manifest object."),tmpManifest);}}// Serialize the Manifest to a string
|
|
944
|
+
// TODO: Should this also serialize the translation table?
|
|
945
|
+
serialize(){return JSON.stringify(this.getManifest());}getManifest(){return{Scope:this.scope,Descriptors:JSON.parse(JSON.stringify(this.elementDescriptors))};}// Add a descriptor to the manifest
|
|
946
|
+
addDescriptor(pAddress,pDescriptor){if(typeof pDescriptor==='object'){// Add the Address into the Descriptor if it doesn't exist:
|
|
947
|
+
if(!pDescriptor.hasOwnProperty('Address')){pDescriptor.Address=pAddress;}if(!this.elementDescriptors.hasOwnProperty(pAddress)){this.elementAddresses.push(pAddress);}// Add the element descriptor to the schema
|
|
948
|
+
this.elementDescriptors[pAddress]=pDescriptor;// Always add the address as a hash
|
|
949
|
+
this.elementHashes[pAddress]=pAddress;if(pDescriptor.hasOwnProperty('Hash')){// TODO: Check if this is a good idea or not..
|
|
950
|
+
// Collisions are bound to happen with both representations of the address/hash in here and developers being able to create their own hashes.
|
|
951
|
+
this.elementHashes[pDescriptor.Hash]=pAddress;}else{pDescriptor.Hash=pAddress;}return true;}else{this.logError("(".concat(this.scope,") Error loading object descriptor for address '").concat(pAddress,"' from manifest object. Expecting an object but property was type ").concat(typeof pDescriptor,"."));return false;}}getDescriptorByHash(pHash){return this.getDescriptor(this.resolveHashAddress(pHash));}getDescriptor(pAddress){return this.elementDescriptors[pAddress];}// execute an action function for each descriptor
|
|
952
|
+
eachDescriptor(fAction){let tmpDescriptorAddresses=Object.keys(this.elementDescriptors);for(let i=0;i<tmpDescriptorAddresses.length;i++){fAction(this.elementDescriptors[tmpDescriptorAddresses[i]]);}}/*************************************************************************
|
|
953
|
+
* Beginning of Object Manipulation (read & write) Functions
|
|
954
|
+
*/ // Check if an element exists by its hash
|
|
955
|
+
checkAddressExistsByHash(pObject,pHash){return this.checkAddressExists(pObject,this.resolveHashAddress(pHash));}// Check if an element exists at an address
|
|
956
|
+
checkAddressExists(pObject,pAddress){return this.objectAddressCheckAddressExists.checkAddressExists(pObject,pAddress);}// Turn a hash into an address, factoring in the translation table.
|
|
957
|
+
resolveHashAddress(pHash){let tmpAddress=undefined;let tmpInElementHashTable=this.elementHashes.hasOwnProperty(pHash);let tmpInTranslationTable=this.hashTranslations.translationTable.hasOwnProperty(pHash);// The most straightforward: the hash exists, no translations.
|
|
958
|
+
if(tmpInElementHashTable&&!tmpInTranslationTable){tmpAddress=this.elementHashes[pHash];}// There is a translation from one hash to another, and, the elementHashes contains the pointer end
|
|
959
|
+
else if(tmpInTranslationTable&&this.elementHashes.hasOwnProperty(this.hashTranslations.translate(pHash))){tmpAddress=this.elementHashes[this.hashTranslations.translate(pHash)];}// Use the level of indirection only in the Translation Table
|
|
960
|
+
else if(tmpInTranslationTable){tmpAddress=this.hashTranslations.translate(pHash);}// Just treat the hash as an address.
|
|
961
|
+
// TODO: Discuss this ... it is magic but controversial
|
|
962
|
+
else{tmpAddress=pHash;}return tmpAddress;}// Get the value of an element by its hash
|
|
963
|
+
getValueByHash(pObject,pHash){let tmpValue=this.getValueAtAddress(pObject,this.resolveHashAddress(pHash));if(typeof tmpValue=='undefined'){// Try to get a default if it exists
|
|
964
|
+
tmpValue=this.getDefaultValue(this.getDescriptorByHash(pHash));}return tmpValue;}// Get the value of an element at an address
|
|
965
|
+
getValueAtAddress(pObject,pAddress){let tmpValue=this.objectAddressGetValue.getValueAtAddress(pObject,pAddress);if(typeof tmpValue=='undefined'){// Try to get a default if it exists
|
|
966
|
+
tmpValue=this.getDefaultValue(this.getDescriptor(pAddress));}return tmpValue;}// Set the value of an element by its hash
|
|
967
|
+
setValueByHash(pObject,pHash,pValue){return this.setValueAtAddress(pObject,this.resolveHashAddress(pHash),pValue);}// Set the value of an element at an address
|
|
968
|
+
setValueAtAddress(pObject,pAddress,pValue){return this.objectAddressSetValue.setValueAtAddress(pObject,pAddress,pValue);}// Delete the value of an element by its hash
|
|
969
|
+
deleteValueByHash(pObject,pHash,pValue){return this.deleteValueAtAddress(pObject,this.resolveHashAddress(pHash),pValue);}// Delete the value of an element at an address
|
|
970
|
+
deleteValueAtAddress(pObject,pAddress,pValue){return this.objectAddressDeleteValue.deleteValueAtAddress(pObject,pAddress,pValue);}// Validate the consistency of an object against the schema
|
|
971
|
+
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 ".concat(typeof pObject));}let addValidationError=(pAddress,pErrorMessage)=>{tmpValidationData.Error=true;tmpValidationData.Errors.push("Element at address \"".concat(pAddress,"\" ").concat(pErrorMessage,"."));};// Now enumerate through the values and check for anomalies based on the schema
|
|
972
|
+
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"
|
|
973
|
+
// TODO: Do we want to do a different message based on if the property exists but is undefined?
|
|
974
|
+
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
|
|
975
|
+
if(tmpDescriptor.DataType){let tmpElementType=typeof tmpValue;switch(tmpDescriptor.DataType.toString().trim().toLowerCase()){case'string':if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}break;case'number':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}break;case'integer':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}else{let tmpValueString=tmpValue.toString();if(tmpValueString.indexOf('.')>-1){// TODO: Is this an error?
|
|
976
|
+
addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but has a decimal point in the number."));}}break;case'float':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}break;case'DateTime':let tmpValueDate=new Date(tmpValue);if(tmpValueDate.toString()=='Invalid Date'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is not parsable as a Date by Javascript"));}default:// Check if this is a string, in the default case
|
|
977
|
+
// Note this is only when a DataType is specified and it is an unrecognized data type.
|
|
978
|
+
if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," (which auto-converted to String because it was unrecognized) but is of the type ").concat(tmpElementType));}break;}}}return tmpValidationData;}// Returns a default value, or, the default value for the data type (which is overridable with configuration)
|
|
979
|
+
getDefaultValue(pDescriptor){if(typeof pDescriptor!='object'){return undefined;}if(pDescriptor.hasOwnProperty('Default')){return pDescriptor.Default;}else{// Default to a null if it doesn't have a type specified.
|
|
980
|
+
// This will ensure a placeholder is created but isn't misinterpreted.
|
|
981
|
+
let tmpDataType=pDescriptor.hasOwnProperty('DataType')?pDescriptor.DataType:'String';if(this.options.defaultValues.hasOwnProperty(tmpDataType)){return this.options.defaultValues[tmpDataType];}else{// give up and return null
|
|
982
|
+
return null;}}}// Enumerate through the schema and populate default values if they don't exist.
|
|
983
|
+
populateDefaults(pObject,pOverwriteProperties){return this.populateObject(pObject,pOverwriteProperties,// This just sets up a simple filter to see if there is a default set.
|
|
984
|
+
pDescriptor=>{return pDescriptor.hasOwnProperty('Default');});}// Forcefully populate all values even if they don't have defaults.
|
|
985
|
+
// Based on type, this can do unexpected things.
|
|
986
|
+
populateObject(pObject,pOverwriteProperties,fFilter){// Automatically create an object if one isn't passed in.
|
|
987
|
+
let tmpObject=typeof pObject==='object'?pObject:{};// Default to *NOT OVERWRITING* properties
|
|
988
|
+
let tmpOverwriteProperties=typeof pOverwriteProperties=='undefined'?false:pOverwriteProperties;// This is a filter function, which is passed the schema and allows complex filtering of population
|
|
989
|
+
// The default filter function just returns true, populating everything.
|
|
990
|
+
let tmpFilterFunction=typeof fFilter=='function'?fFilter:pDescriptor=>{return true;};this.elementAddresses.forEach(pAddress=>{let tmpDescriptor=this.getDescriptor(pAddress);// Check the filter function to see if this is an address we want to set the value for.
|
|
991
|
+
if(tmpFilterFunction(tmpDescriptor)){// If we are overwriting properties OR the property does not exist
|
|
992
|
+
if(tmpOverwriteProperties||!this.checkAddressExists(tmpObject,pAddress)){this.setValueAtAddress(tmpObject,pAddress,this.getDefaultValue(tmpDescriptor));}}});return tmpObject;}};module.exports=Manyfest;},{"./Manyfest-HashTranslation.js":39,"./Manyfest-LogToConsole.js":40,"./Manyfest-ObjectAddress-CheckAddressExists.js":41,"./Manyfest-ObjectAddress-DeleteValue.js":42,"./Manyfest-ObjectAddress-GetValue.js":43,"./Manyfest-ObjectAddress-SetValue.js":44,"./Manyfest-ObjectAddressGeneration.js":45,"./Manyfest-SchemaManipulation.js":47,"fable-serviceproviderbase":29}],49:[function(require,module,exports){var wrappy=require('wrappy');module.exports=wrappy(once);module.exports.strict=wrappy(onceStrict);once.proto=once(function(){Object.defineProperty(Function.prototype,'once',{value:function value(){return once(this);},configurable:true});Object.defineProperty(Function.prototype,'onceStrict',{value:function value(){return onceStrict(this);},configurable:true});});function once(fn){var f=function f(){if(f.called)return f.value;f.called=true;return f.value=fn.apply(this,arguments);};f.called=false;return f;}function onceStrict(fn){var f=function f(){if(f.called)throw new Error(f.onceError);f.called=true;return f.value=fn.apply(this,arguments);};var name=fn.name||'Function wrapped with `once`';f.onceError=name+" shouldn't be called more than once";f.called=false;return f;}},{"wrappy":86}],50:[function(require,module,exports){(function(process){(function(){// 'path' module extracted from Node.js v8.11.1 (only the posix part)
|
|
347
993
|
// transplited with Babel
|
|
348
994
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
349
995
|
//
|
|
@@ -425,7 +1071,7 @@ if(startDot===-1)startDot=i;else if(preDotState!==1)preDotState=1;}else if(start
|
|
|
425
1071
|
// have a good chance at having a non-empty extension
|
|
426
1072
|
preDotState=-1;}}if(startDot===-1||end===-1||// We saw a non-dot character immediately before the dot
|
|
427
1073
|
preDotState===0||// The (right-most) trimmed path component is exactly '..'
|
|
428
|
-
preDotState===1&&startDot===end-1&&startDot===startPart+1){if(end!==-1){if(startPart===0&&isAbsolute)ret.base=ret.name=path.slice(1,end);else ret.base=ret.name=path.slice(startPart,end);}}else{if(startPart===0&&isAbsolute){ret.name=path.slice(1,startDot);ret.base=path.slice(1,end);}else{ret.name=path.slice(startPart,startDot);ret.base=path.slice(startPart,end);}ret.ext=path.slice(startDot,end);}if(startPart>0)ret.dir=path.slice(0,startPart-1);else if(isAbsolute)ret.dir='/';return ret;},sep:'/',delimiter:':',win32:null,posix:null};posix.posix=posix;module.exports=posix;}).call(this);}).call(this,require('_process'));},{"_process":
|
|
1074
|
+
preDotState===1&&startDot===end-1&&startDot===startPart+1){if(end!==-1){if(startPart===0&&isAbsolute)ret.base=ret.name=path.slice(1,end);else ret.base=ret.name=path.slice(startPart,end);}}else{if(startPart===0&&isAbsolute){ret.name=path.slice(1,startDot);ret.base=path.slice(1,end);}else{ret.name=path.slice(startPart,startDot);ret.base=path.slice(startPart,end);}ret.ext=path.slice(startDot,end);}if(startPart>0)ret.dir=path.slice(0,startPart-1);else if(isAbsolute)ret.dir='/';return ret;},sep:'/',delimiter:':',win32:null,posix:null};posix.posix=posix;module.exports=posix;}).call(this);}).call(this,require('_process'));},{"_process":54}],51:[function(require,module,exports){/**
|
|
429
1075
|
* Precedent Meta-Templating
|
|
430
1076
|
*
|
|
431
1077
|
* @license MIT
|
|
@@ -448,7 +1094,7 @@ preDotState===1&&startDot===end-1&&startDot===startPart+1){if(end!==-1){if(start
|
|
|
448
1094
|
* @param {string} pString - The string to parse
|
|
449
1095
|
* @param {object} pData - Data to pass in as the second argument
|
|
450
1096
|
* @return {string} The result from the parser
|
|
451
|
-
*/parseString(pString,pData){return this.StringParser.parseString(pString,this.ParseTree,pData);}}module.exports=Precedent;},{"./StringParser.js":
|
|
1097
|
+
*/parseString(pString,pData){return this.StringParser.parseString(pString,this.ParseTree,pData);}}module.exports=Precedent;},{"./StringParser.js":52,"./WordTree.js":53}],52:[function(require,module,exports){/**
|
|
452
1098
|
* String Parser
|
|
453
1099
|
*
|
|
454
1100
|
* @license MIT
|
|
@@ -514,7 +1160,7 @@ else{pParserState.Output+=pCharacter;}}/**
|
|
|
514
1160
|
* @param {Object} pParseTree - The parse tree to begin parsing from (usually root)
|
|
515
1161
|
* @param {Object} pData - The data to pass to the function as a second paramter
|
|
516
1162
|
*/parseString(pString,pParseTree,pData){let tmpParserState=this.newParserState(pParseTree);for(var i=0;i<pString.length;i++){// TODO: This is not fast.
|
|
517
|
-
this.parseCharacter(pString[i],tmpParserState,pData);}this.flushOutputBuffer(tmpParserState);return tmpParserState.Output;}}module.exports=StringParser;},{}],
|
|
1163
|
+
this.parseCharacter(pString[i],tmpParserState,pData);}this.flushOutputBuffer(tmpParserState);return tmpParserState.Output;}}module.exports=StringParser;},{}],53:[function(require,module,exports){/**
|
|
518
1164
|
* Word Tree
|
|
519
1165
|
*
|
|
520
1166
|
* @license MIT
|
|
@@ -539,7 +1185,7 @@ this.parseCharacter(pString[i],tmpParserState,pData);}this.flushOutputBuffer(tmp
|
|
|
539
1185
|
* @param {number} pParser - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.
|
|
540
1186
|
* @return {bool} True if adding the pattern was successful
|
|
541
1187
|
*/addPattern(pPatternStart,pPatternEnd,pParser){if(pPatternStart.length<1)return false;if(typeof pPatternEnd==='string'&&pPatternEnd.length<1)return false;let tmpLeaf=this.ParseTree;// Add the tree of leaves iteratively
|
|
542
|
-
for(var i=0;i<pPatternStart.length;i++)tmpLeaf=this.addChild(tmpLeaf,pPatternStart,i);tmpLeaf.PatternStart=pPatternStart;tmpLeaf.PatternEnd=typeof pPatternEnd==='string'&&pPatternEnd.length>0?pPatternEnd:pPatternStart;tmpLeaf.Parse=typeof pParser==='function'?pParser:typeof pParser==='string'?()=>{return pParser;}:pData=>{return pData;};return true;}}module.exports=WordTree;},{}],
|
|
1188
|
+
for(var i=0;i<pPatternStart.length;i++)tmpLeaf=this.addChild(tmpLeaf,pPatternStart,i);tmpLeaf.PatternStart=pPatternStart;tmpLeaf.PatternEnd=typeof pPatternEnd==='string'&&pPatternEnd.length>0?pPatternEnd:pPatternStart;tmpLeaf.Parse=typeof pParser==='function'?pParser:typeof pParser==='string'?()=>{return pParser;}:pData=>{return pData;};return true;}}module.exports=WordTree;},{}],54:[function(require,module,exports){// shim for using process in browser
|
|
543
1189
|
var process=module.exports={};// cached from whatever global is present so that test runners that stub it
|
|
544
1190
|
// don't break things. But we need to wrap it in a try catch in case it is
|
|
545
1191
|
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
|
@@ -557,7 +1203,7 @@ return cachedClearTimeout.call(null,marker);}catch(e){// same as above but when
|
|
|
557
1203
|
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|
558
1204
|
return cachedClearTimeout.call(this,marker);}}}var queue=[];var draining=false;var currentQueue;var queueIndex=-1;function cleanUpNextTick(){if(!draining||!currentQueue){return;}draining=false;if(currentQueue.length){queue=currentQueue.concat(queue);}else{queueIndex=-1;}if(queue.length){drainQueue();}}function drainQueue(){if(draining){return;}var timeout=runTimeout(cleanUpNextTick);draining=true;var len=queue.length;while(len){currentQueue=queue;queue=[];while(++queueIndex<len){if(currentQueue){currentQueue[queueIndex].run();}}queueIndex=-1;len=queue.length;}currentQueue=null;draining=false;runClearTimeout(timeout);}process.nextTick=function(fun){var args=new Array(arguments.length-1);if(arguments.length>1){for(var i=1;i<arguments.length;i++){args[i-1]=arguments[i];}}queue.push(new Item(fun,args));if(queue.length===1&&!draining){runTimeout(drainQueue);}};// v8 likes predictible objects
|
|
559
1205
|
function Item(fun,array){this.fun=fun;this.array=array;}Item.prototype.run=function(){this.fun.apply(null,this.array);};process.title='browser';process.browser=true;process.env={};process.argv=[];process.version='';// empty string to avoid regexp issues
|
|
560
|
-
process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.prependListener=noop;process.prependOnceListener=noop;process.listeners=function(name){return[];};process.binding=function(name){throw new Error('process.binding is not supported');};process.cwd=function(){return'/';};process.chdir=function(dir){throw new Error('process.chdir is not supported');};process.umask=function(){return 0;};},{}],
|
|
1206
|
+
process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.prependListener=noop;process.prependOnceListener=noop;process.listeners=function(name){return[];};process.binding=function(name){throw new Error('process.binding is not supported');};process.cwd=function(){return'/';};process.chdir=function(dir){throw new Error('process.chdir is not supported');};process.umask=function(){return 0;};},{}],55:[function(require,module,exports){(function(global){(function(){/*! https://mths.be/punycode v1.4.1 by @mathias */;(function(root){/** Detect free variables */var freeExports=typeof exports=='object'&&exports&&!exports.nodeType&&exports;var freeModule=typeof module=='object'&&module&&!module.nodeType&&module;var freeGlobal=typeof global=='object'&&global;if(freeGlobal.global===freeGlobal||freeGlobal.window===freeGlobal||freeGlobal.self===freeGlobal){root=freeGlobal;}/**
|
|
561
1207
|
* The `punycode` object.
|
|
562
1208
|
* @name punycode
|
|
563
1209
|
* @type Object
|
|
@@ -712,7 +1358,7 @@ for/* no condition */(q=delta,k=base;;k+=base){t=k<=bias?tMin:k>=bias+tMax?tMax:
|
|
|
712
1358
|
if(typeof define=='function'&&typeof define.amd=='object'&&define.amd){define('punycode',function(){return punycode;});}else if(freeExports&&freeModule){if(module.exports==freeExports){// in Node.js, io.js, or RingoJS v0.8.0+
|
|
713
1359
|
freeModule.exports=punycode;}else{// in Narwhal or RingoJS v0.7.0-
|
|
714
1360
|
for(key in punycode){punycode.hasOwnProperty(key)&&(freeExports[key]=punycode[key]);}}}else{// in Rhino or a web browser
|
|
715
|
-
root.punycode=punycode;}})(this);}).call(this);}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{}],
|
|
1361
|
+
root.punycode=punycode;}})(this);}).call(this);}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{}],56:[function(require,module,exports){// Copyright Joyent, Inc. and other Node contributors.
|
|
716
1362
|
//
|
|
717
1363
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
718
1364
|
// copy of this software and associated documentation files (the
|
|
@@ -736,7 +1382,7 @@ root.punycode=punycode;}})(this);}).call(this);}).call(this,typeof global!=="und
|
|
|
736
1382
|
// obj.hasOwnProperty(prop) will break.
|
|
737
1383
|
// See: https://github.com/joyent/node/issues/1707
|
|
738
1384
|
function hasOwnProperty(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop);}module.exports=function(qs,sep,eq,options){sep=sep||'&';eq=eq||'=';var obj={};if(typeof qs!=='string'||qs.length===0){return obj;}var regexp=/\+/g;qs=qs.split(sep);var maxKeys=1000;if(options&&typeof options.maxKeys==='number'){maxKeys=options.maxKeys;}var len=qs.length;// maxKeys <= 0 means that we should not limit keys count
|
|
739
|
-
if(maxKeys>0&&len>maxKeys){len=maxKeys;}for(var i=0;i<len;++i){var x=qs[i].replace(regexp,'%20'),idx=x.indexOf(eq),kstr,vstr,k,v;if(idx>=0){kstr=x.substr(0,idx);vstr=x.substr(idx+1);}else{kstr=x;vstr='';}k=decodeURIComponent(kstr);v=decodeURIComponent(vstr);if(!hasOwnProperty(obj,k)){obj[k]=v;}else if(isArray(obj[k])){obj[k].push(v);}else{obj[k]=[obj[k],v];}}return obj;};var isArray=Array.isArray||function(xs){return Object.prototype.toString.call(xs)==='[object Array]';};},{}],
|
|
1385
|
+
if(maxKeys>0&&len>maxKeys){len=maxKeys;}for(var i=0;i<len;++i){var x=qs[i].replace(regexp,'%20'),idx=x.indexOf(eq),kstr,vstr,k,v;if(idx>=0){kstr=x.substr(0,idx);vstr=x.substr(idx+1);}else{kstr=x;vstr='';}k=decodeURIComponent(kstr);v=decodeURIComponent(vstr);if(!hasOwnProperty(obj,k)){obj[k]=v;}else if(isArray(obj[k])){obj[k].push(v);}else{obj[k]=[obj[k],v];}}return obj;};var isArray=Array.isArray||function(xs){return Object.prototype.toString.call(xs)==='[object Array]';};},{}],57:[function(require,module,exports){// Copyright Joyent, Inc. and other Node contributors.
|
|
740
1386
|
//
|
|
741
1387
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
742
1388
|
// copy of this software and associated documentation files (the
|
|
@@ -756,10 +1402,10 @@ if(maxKeys>0&&len>maxKeys){len=maxKeys;}for(var i=0;i<len;++i){var x=qs[i].repla
|
|
|
756
1402
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
757
1403
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
758
1404
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
759
|
-
'use strict';var stringifyPrimitive=function stringifyPrimitive(v){switch(typeof v){case'string':return v;case'boolean':return v?'true':'false';case'number':return isFinite(v)?v:'';default:return'';}};module.exports=function(obj,sep,eq,name){sep=sep||'&';eq=eq||'=';if(obj===null){obj=undefined;}if(typeof obj==='object'){return map(objectKeys(obj),function(k){var ks=encodeURIComponent(stringifyPrimitive(k))+eq;if(isArray(obj[k])){return map(obj[k],function(v){return ks+encodeURIComponent(stringifyPrimitive(v));}).join(sep);}else{return ks+encodeURIComponent(stringifyPrimitive(obj[k]));}}).join(sep);}if(!name)return'';return encodeURIComponent(stringifyPrimitive(name))+eq+encodeURIComponent(stringifyPrimitive(obj));};var isArray=Array.isArray||function(xs){return Object.prototype.toString.call(xs)==='[object Array]';};function map(xs,f){if(xs.map)return xs.map(f);var res=[];for(var i=0;i<xs.length;i++){res.push(f(xs[i],i));}return res;}var objectKeys=Object.keys||function(obj){var res=[];for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))res.push(key);}return res;};},{}],
|
|
1405
|
+
'use strict';var stringifyPrimitive=function stringifyPrimitive(v){switch(typeof v){case'string':return v;case'boolean':return v?'true':'false';case'number':return isFinite(v)?v:'';default:return'';}};module.exports=function(obj,sep,eq,name){sep=sep||'&';eq=eq||'=';if(obj===null){obj=undefined;}if(typeof obj==='object'){return map(objectKeys(obj),function(k){var ks=encodeURIComponent(stringifyPrimitive(k))+eq;if(isArray(obj[k])){return map(obj[k],function(v){return ks+encodeURIComponent(stringifyPrimitive(v));}).join(sep);}else{return ks+encodeURIComponent(stringifyPrimitive(obj[k]));}}).join(sep);}if(!name)return'';return encodeURIComponent(stringifyPrimitive(name))+eq+encodeURIComponent(stringifyPrimitive(obj));};var isArray=Array.isArray||function(xs){return Object.prototype.toString.call(xs)==='[object Array]';};function map(xs,f){if(xs.map)return xs.map(f);var res=[];for(var i=0;i<xs.length;i++){res.push(f(xs[i],i));}return res;}var objectKeys=Object.keys||function(obj){var res=[];for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))res.push(key);}return res;};},{}],58:[function(require,module,exports){'use strict';exports.decode=exports.parse=require('./decode');exports.encode=exports.stringify=require('./encode');},{"./decode":56,"./encode":57}],59:[function(require,module,exports){/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ /* eslint-disable node/no-deprecated-api */var buffer=require('buffer');var Buffer=buffer.Buffer;// alternative to using Object.keys for old browsers
|
|
760
1406
|
function copyProps(src,dst){for(var key in src){dst[key]=src[key];}}if(Buffer.from&&Buffer.alloc&&Buffer.allocUnsafe&&Buffer.allocUnsafeSlow){module.exports=buffer;}else{// Copy properties from require('buffer')
|
|
761
1407
|
copyProps(buffer,exports);exports.Buffer=SafeBuffer;}function SafeBuffer(arg,encodingOrOffset,length){return Buffer(arg,encodingOrOffset,length);}SafeBuffer.prototype=Object.create(Buffer.prototype);// Copy static methods from Buffer
|
|
762
|
-
copyProps(Buffer,SafeBuffer);SafeBuffer.from=function(arg,encodingOrOffset,length){if(typeof arg==='number'){throw new TypeError('Argument must not be a number');}return Buffer(arg,encodingOrOffset,length);};SafeBuffer.alloc=function(size,fill,encoding){if(typeof size!=='number'){throw new TypeError('Argument must be a number');}var buf=Buffer(size);if(fill!==undefined){if(typeof encoding==='string'){buf.fill(fill,encoding);}else{buf.fill(fill);}}else{buf.fill(0);}return buf;};SafeBuffer.allocUnsafe=function(size){if(typeof size!=='number'){throw new TypeError('Argument must be a number');}return Buffer(size);};SafeBuffer.allocUnsafeSlow=function(size){if(typeof size!=='number'){throw new TypeError('Argument must be a number');}return buffer.SlowBuffer(size);};},{"buffer":19}],
|
|
1408
|
+
copyProps(Buffer,SafeBuffer);SafeBuffer.from=function(arg,encodingOrOffset,length){if(typeof arg==='number'){throw new TypeError('Argument must not be a number');}return Buffer(arg,encodingOrOffset,length);};SafeBuffer.alloc=function(size,fill,encoding){if(typeof size!=='number'){throw new TypeError('Argument must be a number');}var buf=Buffer(size);if(fill!==undefined){if(typeof encoding==='string'){buf.fill(fill,encoding);}else{buf.fill(fill);}}else{buf.fill(0);}return buf;};SafeBuffer.allocUnsafe=function(size){if(typeof size!=='number'){throw new TypeError('Argument must be a number');}return Buffer(size);};SafeBuffer.allocUnsafeSlow=function(size){if(typeof size!=='number'){throw new TypeError('Argument must be a number');}return buffer.SlowBuffer(size);};},{"buffer":19}],60:[function(require,module,exports){(function(Buffer){(function(){/*! simple-concat. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */module.exports=function(stream,cb){var chunks=[];stream.on('data',function(chunk){chunks.push(chunk);});stream.once('end',function(){if(cb)cb(null,Buffer.concat(chunks));cb=null;});stream.once('error',function(err){if(cb)cb(err);cb=null;});};}).call(this);}).call(this,require("buffer").Buffer);},{"buffer":19}],61:[function(require,module,exports){(function(Buffer){(function(){/*! simple-get. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */module.exports=simpleGet;const concat=require('simple-concat');const decompressResponse=require('decompress-response');// excluded from browser build
|
|
763
1409
|
const http=require('http');const https=require('https');const once=require('once');const querystring=require('querystring');const url=require('url');const isStream=o=>o!==null&&typeof o==='object'&&typeof o.pipe==='function';function simpleGet(opts,cb){opts=Object.assign({maxRedirects:10},typeof opts==='string'?{url:opts}:opts);cb=once(cb);if(opts.url){const{hostname,port,protocol,auth,path}=url.parse(opts.url);// eslint-disable-line node/no-deprecated-api
|
|
764
1410
|
delete opts.url;if(!hostname&&!port&&!protocol&&!auth)opts.path=path;// Relative redirect
|
|
765
1411
|
else Object.assign(opts,{hostname,port,protocol,auth,path});// Absolute redirect
|
|
@@ -771,13 +1417,13 @@ res.resume();// Discard response
|
|
|
771
1417
|
const redirectHost=url.parse(opts.url).hostname;// eslint-disable-line node/no-deprecated-api
|
|
772
1418
|
// If redirected host is different than original host, drop headers to prevent cookie leak (#73)
|
|
773
1419
|
if(redirectHost!==null&&redirectHost!==originalHost){delete opts.headers.cookie;delete opts.headers.authorization;}if(opts.method==='POST'&&[301,302].includes(res.statusCode)){opts.method='GET';// On 301/302 redirect, change POST to GET (see #35)
|
|
774
|
-
delete opts.headers['content-length'];delete opts.headers['content-type'];}if(opts.maxRedirects--===0)return cb(new Error('too many redirects'));else return simpleGet(opts,cb);}const tryUnzip=typeof decompressResponse==='function'&&opts.method!=='HEAD';cb(null,tryUnzip?decompressResponse(res):res);});req.on('timeout',()=>{req.abort();cb(new Error('Request timed out'));});req.on('error',cb);if(isStream(body))body.on('error',cb).pipe(req);else req.end(body);return req;}simpleGet.concat=(opts,cb)=>{return simpleGet(opts,(err,res)=>{if(err)return cb(err);concat(res,(err,data)=>{if(err)return cb(err);if(opts.json){try{data=JSON.parse(data.toString());}catch(err){return cb(err,res,data);}}cb(null,res,data);});});};['get','post','put','patch','head','delete'].forEach(method=>{simpleGet[method]=(opts,cb)=>{if(typeof opts==='string')opts={url:opts};return simpleGet(Object.assign({method:method.toUpperCase()},opts),cb);};});}).call(this);}).call(this,require("buffer").Buffer);},{"buffer":19,"decompress-response":17,"http":
|
|
1420
|
+
delete opts.headers['content-length'];delete opts.headers['content-type'];}if(opts.maxRedirects--===0)return cb(new Error('too many redirects'));else return simpleGet(opts,cb);}const tryUnzip=typeof decompressResponse==='function'&&opts.method!=='HEAD';cb(null,tryUnzip?decompressResponse(res):res);});req.on('timeout',()=>{req.abort();cb(new Error('Request timed out'));});req.on('error',cb);if(isStream(body))body.on('error',cb).pipe(req);else req.end(body);return req;}simpleGet.concat=(opts,cb)=>{return simpleGet(opts,(err,res)=>{if(err)return cb(err);concat(res,(err,data)=>{if(err)return cb(err);if(opts.json){try{data=JSON.parse(data.toString());}catch(err){return cb(err,res,data);}}cb(null,res,data);});});};['get','post','put','patch','head','delete'].forEach(method=>{simpleGet[method]=(opts,cb)=>{if(typeof opts==='string')opts={url:opts};return simpleGet(Object.assign({method:method.toUpperCase()},opts),cb);};});}).call(this);}).call(this,require("buffer").Buffer);},{"buffer":19,"decompress-response":17,"http":62,"https":35,"once":49,"querystring":58,"simple-concat":60,"url":83}],62:[function(require,module,exports){(function(global){(function(){var ClientRequest=require('./lib/request');var response=require('./lib/response');var extend=require('xtend');var statusCodes=require('builtin-status-codes');var url=require('url');var http=exports;http.request=function(opts,cb){if(typeof opts==='string')opts=url.parse(opts);else opts=extend(opts);// Normally, the page is loaded from http or https, so not specifying a protocol
|
|
775
1421
|
// will result in a (valid) protocol-relative url. However, this won't work if
|
|
776
1422
|
// the protocol is something else, like 'file:'
|
|
777
1423
|
var defaultProtocol=global.location.protocol.search(/^https?:$/)===-1?'http:':'';var protocol=opts.protocol||defaultProtocol;var host=opts.hostname||opts.host;var port=opts.port;var path=opts.path||'/';// Necessary for IPv6 addresses
|
|
778
1424
|
if(host&&host.indexOf(':')!==-1)host='['+host+']';// This may be a relative url. The browser should always be able to interpret it correctly.
|
|
779
1425
|
opts.url=(host?protocol+'//'+host:'')+(port?':'+port:'')+path;opts.method=(opts.method||'GET').toUpperCase();opts.headers=opts.headers||{};// Also valid opts.auth, opts.mode
|
|
780
|
-
var req=new ClientRequest(opts);if(cb)req.on('response',cb);return req;};http.get=function get(opts,cb){var req=http.request(opts,cb);req.end();return req;};http.ClientRequest=ClientRequest;http.IncomingMessage=response.IncomingMessage;http.Agent=function(){};http.Agent.defaultMaxSockets=4;http.globalAgent=new http.Agent();http.STATUS_CODES=statusCodes;http.METHODS=['CHECKOUT','CONNECT','COPY','DELETE','GET','HEAD','LOCK','M-SEARCH','MERGE','MKACTIVITY','MKCOL','MOVE','NOTIFY','OPTIONS','PATCH','POST','PROPFIND','PROPPATCH','PURGE','PUT','REPORT','SEARCH','SUBSCRIBE','TRACE','UNLOCK','UNSUBSCRIBE'];}).call(this);}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{"./lib/request":
|
|
1426
|
+
var req=new ClientRequest(opts);if(cb)req.on('response',cb);return req;};http.get=function get(opts,cb){var req=http.request(opts,cb);req.end();return req;};http.ClientRequest=ClientRequest;http.IncomingMessage=response.IncomingMessage;http.Agent=function(){};http.Agent.defaultMaxSockets=4;http.globalAgent=new http.Agent();http.STATUS_CODES=statusCodes;http.METHODS=['CHECKOUT','CONNECT','COPY','DELETE','GET','HEAD','LOCK','M-SEARCH','MERGE','MKACTIVITY','MKCOL','MOVE','NOTIFY','OPTIONS','PATCH','POST','PROPFIND','PROPPATCH','PURGE','PUT','REPORT','SEARCH','SUBSCRIBE','TRACE','UNLOCK','UNSUBSCRIBE'];}).call(this);}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{"./lib/request":64,"./lib/response":65,"builtin-status-codes":20,"url":83,"xtend":87}],63:[function(require,module,exports){(function(global){(function(){exports.fetch=isFunction(global.fetch)&&isFunction(global.ReadableStream);exports.writableStream=isFunction(global.WritableStream);exports.abortController=isFunction(global.AbortController);// The xhr request to example.com may violate some restrictive CSP configurations,
|
|
781
1427
|
// so if we're running in a browser that supports `fetch`, avoid calling getXHR()
|
|
782
1428
|
// and assume support for certain features below.
|
|
783
1429
|
var xhr;function getXHR(){// Cache the xhr value
|
|
@@ -792,7 +1438,7 @@ exports.arraybuffer=exports.fetch||checkTypeSupport('arraybuffer');// These next
|
|
|
792
1438
|
exports.msstream=!exports.fetch&&checkTypeSupport('ms-stream');exports.mozchunkedarraybuffer=!exports.fetch&&checkTypeSupport('moz-chunked-arraybuffer');// If fetch is supported, then overrideMimeType will be supported too. Skip calling
|
|
793
1439
|
// getXHR().
|
|
794
1440
|
exports.overrideMimeType=exports.fetch||(getXHR()?isFunction(getXHR().overrideMimeType):false);function isFunction(value){return typeof value==='function';}xhr=null;// Help gc
|
|
795
|
-
}).call(this);}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{}],
|
|
1441
|
+
}).call(this);}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{}],64:[function(require,module,exports){(function(process,global,Buffer){(function(){var capability=require('./capability');var inherits=require('inherits');var response=require('./response');var stream=require('readable-stream');var IncomingMessage=response.IncomingMessage;var rStates=response.readyStates;function decideMode(preferBinary,useFetch){if(capability.fetch&&useFetch){return'fetch';}else if(capability.mozchunkedarraybuffer){return'moz-chunked-arraybuffer';}else if(capability.msstream){return'ms-stream';}else if(capability.arraybuffer&&preferBinary){return'arraybuffer';}else{return'text';}}var ClientRequest=module.exports=function(opts){var self=this;stream.Writable.call(self);self._opts=opts;self._body=[];self._headers={};if(opts.auth)self.setHeader('Authorization','Basic '+Buffer.from(opts.auth).toString('base64'));Object.keys(opts.headers).forEach(function(name){self.setHeader(name,opts.headers[name]);});var preferBinary;var useFetch=true;if(opts.mode==='disable-fetch'||'requestTimeout'in opts&&!capability.abortController){// If the use of XHR should be preferred. Not typically needed.
|
|
796
1442
|
useFetch=false;preferBinary=true;}else if(opts.mode==='prefer-streaming'){// If streaming is a high priority but binary compatibility and
|
|
797
1443
|
// the accuracy of the 'content-type' header aren't
|
|
798
1444
|
preferBinary=false;}else if(opts.mode==='allow-wrong-content-type'){// If streaming is more important than preserving the 'content-type' header
|
|
@@ -809,7 +1455,7 @@ if(self._mode==='moz-chunked-arraybuffer'){xhr.onprogress=function(){self._onXHR
|
|
|
809
1455
|
* Even though the spec says it should be available in readyState 3,
|
|
810
1456
|
* accessing it throws an exception in IE8
|
|
811
1457
|
*/function statusValid(xhr){try{var status=xhr.status;return status!==null&&status!==0;}catch(e){return false;}}ClientRequest.prototype._onXHRProgress=function(){var self=this;self._resetTimers(false);if(!statusValid(self._xhr)||self._destroyed)return;if(!self._response)self._connect();self._response._onXHRProgress(self._resetTimers.bind(self));};ClientRequest.prototype._connect=function(){var self=this;if(self._destroyed)return;self._response=new IncomingMessage(self._xhr,self._fetchResponse,self._mode,self._resetTimers.bind(self));self._response.on('error',function(err){self.emit('error',err);});self.emit('response',self._response);};ClientRequest.prototype._write=function(chunk,encoding,cb){var self=this;self._body.push(chunk);cb();};ClientRequest.prototype._resetTimers=function(done){var self=this;global.clearTimeout(self._socketTimer);self._socketTimer=null;if(done){global.clearTimeout(self._fetchTimer);self._fetchTimer=null;}else if(self._socketTimeout){self._socketTimer=global.setTimeout(function(){self.emit('timeout');},self._socketTimeout);}};ClientRequest.prototype.abort=ClientRequest.prototype.destroy=function(err){var self=this;self._destroyed=true;self._resetTimers(true);if(self._response)self._response._destroyed=true;if(self._xhr)self._xhr.abort();else if(self._fetchAbortController)self._fetchAbortController.abort();if(err)self.emit('error',err);};ClientRequest.prototype.end=function(data,encoding,cb){var self=this;if(typeof data==='function'){cb=data;data=undefined;}stream.Writable.prototype.end.call(self,data,encoding,cb);};ClientRequest.prototype.setTimeout=function(timeout,cb){var self=this;if(cb)self.once('timeout',cb);self._socketTimeout=timeout;self._resetTimers(false);};ClientRequest.prototype.flushHeaders=function(){};ClientRequest.prototype.setNoDelay=function(){};ClientRequest.prototype.setSocketKeepAlive=function(){};// Taken from http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method
|
|
812
|
-
var unsafeHeaders=['accept-charset','accept-encoding','access-control-request-headers','access-control-request-method','connection','content-length','cookie','cookie2','date','dnt','expect','host','keep-alive','origin','referer','te','trailer','transfer-encoding','upgrade','via'];}).call(this);}).call(this,require('_process'),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{},require("buffer").Buffer);},{"./capability":
|
|
1458
|
+
var unsafeHeaders=['accept-charset','accept-encoding','access-control-request-headers','access-control-request-method','connection','content-length','cookie','cookie2','date','dnt','expect','host','keep-alive','origin','referer','te','trailer','transfer-encoding','upgrade','via'];}).call(this);}).call(this,require('_process'),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{},require("buffer").Buffer);},{"./capability":63,"./response":65,"_process":54,"buffer":19,"inherits":37,"readable-stream":80}],65:[function(require,module,exports){(function(process,global,Buffer){(function(){var capability=require('./capability');var inherits=require('inherits');var stream=require('readable-stream');var rStates=exports.readyStates={UNSENT:0,OPENED:1,HEADERS_RECEIVED:2,LOADING:3,DONE:4};var IncomingMessage=exports.IncomingMessage=function(xhr,response,mode,resetTimers){var self=this;stream.Readable.call(self);self._mode=mode;self.headers={};self.rawHeaders=[];self.trailers={};self.rawTrailers=[];// Fake the 'close' event, but only once 'end' fires
|
|
813
1459
|
self.on('end',function(){// The nextTick is necessary to prevent the 'request' module from causing an infinite loop
|
|
814
1460
|
process.nextTick(function(){self.emit('close');});});if(mode==='fetch'){self._fetchResponse=response;self.url=response.url;self.statusCode=response.status;self.statusMessage=response.statusText;response.headers.forEach(function(header,key){self.headers[key.toLowerCase()]=header;self.rawHeaders.push(key,header);});if(capability.writableStream){var writable=new WritableStream({write:function write(chunk){resetTimers(false);return new Promise(function(resolve,reject){if(self._destroyed){reject();}else if(self.push(Buffer.from(chunk))){resolve();}else{self._resumeFetch=resolve;}});},close:function close(){resetTimers(true);if(!self._destroyed)self.push(null);},abort:function abort(err){resetTimers(true);if(!self._destroyed)self.emit('error',err);}});try{response.body.pipeTo(writable).catch(function(err){resetTimers(true);if(!self._destroyed)self.emit('error',err);});return;}catch(e){}// pipeTo method isn't defined. Can't find a better way to feature test this
|
|
815
1461
|
}// fallback for when writableStream or pipeTo aren't available
|
|
@@ -817,13 +1463,13 @@ var reader=response.body.getReader();function read(){reader.read().then(function
|
|
|
817
1463
|
}}};inherits(IncomingMessage,stream.Readable);IncomingMessage.prototype._read=function(){var self=this;var resolve=self._resumeFetch;if(resolve){self._resumeFetch=null;resolve();}};IncomingMessage.prototype._onXHRProgress=function(resetTimers){var self=this;var xhr=self._xhr;var response=null;switch(self._mode){case'text':response=xhr.responseText;if(response.length>self._pos){var newData=response.substr(self._pos);if(self._charset==='x-user-defined'){var buffer=Buffer.alloc(newData.length);for(var i=0;i<newData.length;i++)buffer[i]=newData.charCodeAt(i)&0xff;self.push(buffer);}else{self.push(newData,self._charset);}self._pos=response.length;}break;case'arraybuffer':if(xhr.readyState!==rStates.DONE||!xhr.response)break;response=xhr.response;self.push(Buffer.from(new Uint8Array(response)));break;case'moz-chunked-arraybuffer':// take whole
|
|
818
1464
|
response=xhr.response;if(xhr.readyState!==rStates.LOADING||!response)break;self.push(Buffer.from(new Uint8Array(response)));break;case'ms-stream':response=xhr.response;if(xhr.readyState!==rStates.LOADING)break;var reader=new global.MSStreamReader();reader.onprogress=function(){if(reader.result.byteLength>self._pos){self.push(Buffer.from(new Uint8Array(reader.result.slice(self._pos))));self._pos=reader.result.byteLength;}};reader.onload=function(){resetTimers(true);self.push(null);};// reader.onerror = ??? // TODO: this
|
|
819
1465
|
reader.readAsArrayBuffer(response);break;}// The ms-stream case handles end separately in reader.onload()
|
|
820
|
-
if(self._xhr.readyState===rStates.DONE&&self._mode!=='ms-stream'){resetTimers(true);self.push(null);}};}).call(this);}).call(this,require('_process'),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{},require("buffer").Buffer);},{"./capability":
|
|
1466
|
+
if(self._xhr.readyState===rStates.DONE&&self._mode!=='ms-stream'){resetTimers(true);self.push(null);}};}).call(this);}).call(this,require('_process'),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{},require("buffer").Buffer);},{"./capability":63,"_process":54,"buffer":19,"inherits":37,"readable-stream":80}],66:[function(require,module,exports){'use strict';function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;subClass.__proto__=superClass;}var codes={};function createErrorType(code,message,Base){if(!Base){Base=Error;}function getMessage(arg1,arg2,arg3){if(typeof message==='string'){return message;}else{return message(arg1,arg2,arg3);}}var NodeError=/*#__PURE__*/function(_Base){_inheritsLoose(NodeError,_Base);function NodeError(arg1,arg2,arg3){return _Base.call(this,getMessage(arg1,arg2,arg3))||this;}return NodeError;}(Base);NodeError.prototype.name=Base.name;NodeError.prototype.code=code;codes[code]=NodeError;}// https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js
|
|
821
1467
|
function oneOf(expected,thing){if(Array.isArray(expected)){var len=expected.length;expected=expected.map(function(i){return String(i);});if(len>2){return"one of ".concat(thing," ").concat(expected.slice(0,len-1).join(', '),", or ")+expected[len-1];}else if(len===2){return"one of ".concat(thing," ").concat(expected[0]," or ").concat(expected[1]);}else{return"of ".concat(thing," ").concat(expected[0]);}}else{return"of ".concat(thing," ").concat(String(expected));}}// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
|
|
822
1468
|
function startsWith(str,search,pos){return str.substr(!pos||pos<0?0:+pos,search.length)===search;}// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
|
|
823
1469
|
function endsWith(str,search,this_len){if(this_len===undefined||this_len>str.length){this_len=str.length;}return str.substring(this_len-search.length,this_len)===search;}// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes
|
|
824
1470
|
function includes(str,search,start){if(typeof start!=='number'){start=0;}if(start+search.length>str.length){return false;}else{return str.indexOf(search,start)!==-1;}}createErrorType('ERR_INVALID_OPT_VALUE',function(name,value){return'The value "'+value+'" is invalid for option "'+name+'"';},TypeError);createErrorType('ERR_INVALID_ARG_TYPE',function(name,expected,actual){// determiner: 'must be' or 'must not be'
|
|
825
1471
|
var determiner;if(typeof expected==='string'&&startsWith(expected,'not ')){determiner='must not be';expected=expected.replace(/^not /,'');}else{determiner='must be';}var msg;if(endsWith(name,' argument')){// For cases like 'first argument'
|
|
826
|
-
msg="The ".concat(name," ").concat(determiner," ").concat(oneOf(expected,'type'));}else{var type=includes(name,'.')?'property':'argument';msg="The \"".concat(name,"\" ").concat(type," ").concat(determiner," ").concat(oneOf(expected,'type'));}msg+=". Received type ".concat(typeof actual);return msg;},TypeError);createErrorType('ERR_STREAM_PUSH_AFTER_EOF','stream.push() after EOF');createErrorType('ERR_METHOD_NOT_IMPLEMENTED',function(name){return'The '+name+' method is not implemented';});createErrorType('ERR_STREAM_PREMATURE_CLOSE','Premature close');createErrorType('ERR_STREAM_DESTROYED',function(name){return'Cannot call '+name+' after a stream was destroyed';});createErrorType('ERR_MULTIPLE_CALLBACK','Callback called multiple times');createErrorType('ERR_STREAM_CANNOT_PIPE','Cannot pipe, not readable');createErrorType('ERR_STREAM_WRITE_AFTER_END','write after end');createErrorType('ERR_STREAM_NULL_VALUES','May not write null values to stream',TypeError);createErrorType('ERR_UNKNOWN_ENCODING',function(arg){return'Unknown encoding: '+arg;},TypeError);createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT','stream.unshift() after end event');module.exports.codes=codes;},{}],
|
|
1472
|
+
msg="The ".concat(name," ").concat(determiner," ").concat(oneOf(expected,'type'));}else{var type=includes(name,'.')?'property':'argument';msg="The \"".concat(name,"\" ").concat(type," ").concat(determiner," ").concat(oneOf(expected,'type'));}msg+=". Received type ".concat(typeof actual);return msg;},TypeError);createErrorType('ERR_STREAM_PUSH_AFTER_EOF','stream.push() after EOF');createErrorType('ERR_METHOD_NOT_IMPLEMENTED',function(name){return'The '+name+' method is not implemented';});createErrorType('ERR_STREAM_PREMATURE_CLOSE','Premature close');createErrorType('ERR_STREAM_DESTROYED',function(name){return'Cannot call '+name+' after a stream was destroyed';});createErrorType('ERR_MULTIPLE_CALLBACK','Callback called multiple times');createErrorType('ERR_STREAM_CANNOT_PIPE','Cannot pipe, not readable');createErrorType('ERR_STREAM_WRITE_AFTER_END','write after end');createErrorType('ERR_STREAM_NULL_VALUES','May not write null values to stream',TypeError);createErrorType('ERR_UNKNOWN_ENCODING',function(arg){return'Unknown encoding: '+arg;},TypeError);createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT','stream.unshift() after end event');module.exports.codes=codes;},{}],67:[function(require,module,exports){(function(process){(function(){// Copyright Joyent, Inc. and other Node contributors.
|
|
827
1473
|
//
|
|
828
1474
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
829
1475
|
// copy of this software and associated documentation files (the
|
|
@@ -868,7 +1514,7 @@ enumerable:false,get:function get(){if(this._readableState===undefined||this._wr
|
|
|
868
1514
|
// has not been initialized yet
|
|
869
1515
|
if(this._readableState===undefined||this._writableState===undefined){return;}// backward compatibility, the user is explicitly
|
|
870
1516
|
// managing destroyed
|
|
871
|
-
this._readableState.destroyed=value;this._writableState.destroyed=value;}});}).call(this);}).call(this,require('_process'));},{"./_stream_readable":
|
|
1517
|
+
this._readableState.destroyed=value;this._writableState.destroyed=value;}});}).call(this);}).call(this,require('_process'));},{"./_stream_readable":69,"./_stream_writable":71,"_process":54,"inherits":37}],68:[function(require,module,exports){// Copyright Joyent, Inc. and other Node contributors.
|
|
872
1518
|
//
|
|
873
1519
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
874
1520
|
// copy of this software and associated documentation files (the
|
|
@@ -891,7 +1537,7 @@ this._readableState.destroyed=value;this._writableState.destroyed=value;}});}).c
|
|
|
891
1537
|
// a passthrough stream.
|
|
892
1538
|
// basically just the most minimal sort of Transform stream.
|
|
893
1539
|
// Every written chunk gets output as-is.
|
|
894
|
-
'use strict';module.exports=PassThrough;var Transform=require('./_stream_transform');require('inherits')(PassThrough,Transform);function PassThrough(options){if(!(this instanceof PassThrough))return new PassThrough(options);Transform.call(this,options);}PassThrough.prototype._transform=function(chunk,encoding,cb){cb(null,chunk);};},{"./_stream_transform":
|
|
1540
|
+
'use strict';module.exports=PassThrough;var Transform=require('./_stream_transform');require('inherits')(PassThrough,Transform);function PassThrough(options){if(!(this instanceof PassThrough))return new PassThrough(options);Transform.call(this,options);}PassThrough.prototype._transform=function(chunk,encoding,cb){cb(null,chunk);};},{"./_stream_transform":70,"inherits":37}],69:[function(require,module,exports){(function(process,global){(function(){// Copyright Joyent, Inc. and other Node contributors.
|
|
895
1541
|
//
|
|
896
1542
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
897
1543
|
// copy of this software and associated documentation files (the
|
|
@@ -1143,7 +1789,7 @@ if(state.decoder)ret=state.buffer.join('');else if(state.buffer.length===1)ret=s
|
|
|
1143
1789
|
ret=state.buffer.consume(n,state.decoder);}return ret;}function endReadable(stream){var state=stream._readableState;debug('endReadable',state.endEmitted);if(!state.endEmitted){state.ended=true;process.nextTick(endReadableNT,state,stream);}}function endReadableNT(state,stream){debug('endReadableNT',state.endEmitted,state.length);// Check that we didn't get one last unshift.
|
|
1144
1790
|
if(!state.endEmitted&&state.length===0){state.endEmitted=true;stream.readable=false;stream.emit('end');if(state.autoDestroy){// In case of duplex streams we need a way to detect
|
|
1145
1791
|
// if the writable side is ready for autoDestroy as well
|
|
1146
|
-
var wState=stream._writableState;if(!wState||wState.autoDestroy&&wState.finished){stream.destroy();}}}}if(typeof Symbol==='function'){Readable.from=function(iterable,opts){if(from===undefined){from=require('./internal/streams/from');}return from(Readable,iterable,opts);};}function indexOf(xs,x){for(var i=0,l=xs.length;i<l;i++){if(xs[i]===x)return i;}return-1;}}).call(this);}).call(this,require('_process'),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{"../errors":
|
|
1792
|
+
var wState=stream._writableState;if(!wState||wState.autoDestroy&&wState.finished){stream.destroy();}}}}if(typeof Symbol==='function'){Readable.from=function(iterable,opts){if(from===undefined){from=require('./internal/streams/from');}return from(Readable,iterable,opts);};}function indexOf(xs,x){for(var i=0,l=xs.length;i<l;i++){if(xs[i]===x)return i;}return-1;}}).call(this);}).call(this,require('_process'),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{"../errors":66,"./_stream_duplex":67,"./internal/streams/async_iterator":72,"./internal/streams/buffer_list":73,"./internal/streams/destroy":74,"./internal/streams/from":76,"./internal/streams/state":78,"./internal/streams/stream":79,"_process":54,"buffer":19,"events":21,"inherits":37,"string_decoder/":81,"util":17}],70:[function(require,module,exports){// Copyright Joyent, Inc. and other Node contributors.
|
|
1147
1793
|
//
|
|
1148
1794
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
1149
1795
|
// copy of this software and associated documentation files (the
|
|
@@ -1229,7 +1875,7 @@ ts.needTransform=true;}};Transform.prototype._destroy=function(err,cb){Duplex.pr
|
|
|
1229
1875
|
stream.push(data);// TODO(BridgeAR): Write a test for these two error cases
|
|
1230
1876
|
// if there's nothing in the write buffer, then that means
|
|
1231
1877
|
// that nothing more will ever be provided
|
|
1232
|
-
if(stream._writableState.length)throw new ERR_TRANSFORM_WITH_LENGTH_0();if(stream._transformState.transforming)throw new ERR_TRANSFORM_ALREADY_TRANSFORMING();return stream.push(null);}},{"../errors":
|
|
1878
|
+
if(stream._writableState.length)throw new ERR_TRANSFORM_WITH_LENGTH_0();if(stream._transformState.transforming)throw new ERR_TRANSFORM_ALREADY_TRANSFORMING();return stream.push(null);}},{"../errors":66,"./_stream_duplex":67,"inherits":37}],71:[function(require,module,exports){(function(process,global){(function(){// Copyright Joyent, Inc. and other Node contributors.
|
|
1233
1879
|
//
|
|
1234
1880
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
1235
1881
|
// copy of this software and associated documentation files (the
|
|
@@ -1364,7 +2010,7 @@ enumerable:false,get:function get(){if(this._writableState===undefined){return f
|
|
|
1364
2010
|
// has not been initialized yet
|
|
1365
2011
|
if(!this._writableState){return;}// backward compatibility, the user is explicitly
|
|
1366
2012
|
// managing destroyed
|
|
1367
|
-
this._writableState.destroyed=value;}});Writable.prototype.destroy=destroyImpl.destroy;Writable.prototype._undestroy=destroyImpl.undestroy;Writable.prototype._destroy=function(err,cb){cb(err);};}).call(this);}).call(this,require('_process'),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{"../errors":
|
|
2013
|
+
this._writableState.destroyed=value;}});Writable.prototype.destroy=destroyImpl.destroy;Writable.prototype._undestroy=destroyImpl.undestroy;Writable.prototype._destroy=function(err,cb){cb(err);};}).call(this);}).call(this,require('_process'),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{"../errors":66,"./_stream_duplex":67,"./internal/streams/destroy":74,"./internal/streams/state":78,"./internal/streams/stream":79,"_process":54,"buffer":19,"inherits":37,"util-deprecate":85}],72:[function(require,module,exports){(function(process){(function(){'use strict';var _Object$setPrototypeO;function _defineProperty(obj,key,value){key=_toPropertyKey(key);if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return typeof key==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(typeof input!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(typeof res!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}var finished=require('./end-of-stream');var kLastResolve=Symbol('lastResolve');var kLastReject=Symbol('lastReject');var kError=Symbol('error');var kEnded=Symbol('ended');var kLastPromise=Symbol('lastPromise');var kHandlePromise=Symbol('handlePromise');var kStream=Symbol('stream');function createIterResult(value,done){return{value:value,done:done};}function readAndResolve(iter){var resolve=iter[kLastResolve];if(resolve!==null){var data=iter[kStream].read();// we defer if data is null
|
|
1368
2014
|
// we can be expecting either 'end' or
|
|
1369
2015
|
// 'error'
|
|
1370
2016
|
if(data!==null){iter[kLastPromise]=null;iter[kLastResolve]=null;iter[kLastReject]=null;resolve(createIterResult(data,false));}}}function onReadable(iter){// we wait for the next tick, because it might
|
|
@@ -1386,7 +2032,7 @@ var data=this[kStream].read();if(data!==null){return Promise.resolve(createIterR
|
|
|
1386
2032
|
// Readable class this is attached to
|
|
1387
2033
|
return new Promise(function(resolve,reject){_this2[kStream].destroy(null,function(err){if(err){reject(err);return;}resolve(createIterResult(undefined,true));});});}),_Object$setPrototypeO),AsyncIteratorPrototype);var createReadableStreamAsyncIterator=function createReadableStreamAsyncIterator(stream){var _Object$create;var iterator=Object.create(ReadableStreamAsyncIteratorPrototype,(_Object$create={},_defineProperty(_Object$create,kStream,{value:stream,writable:true}),_defineProperty(_Object$create,kLastResolve,{value:null,writable:true}),_defineProperty(_Object$create,kLastReject,{value:null,writable:true}),_defineProperty(_Object$create,kError,{value:null,writable:true}),_defineProperty(_Object$create,kEnded,{value:stream._readableState.endEmitted,writable:true}),_defineProperty(_Object$create,kHandlePromise,{value:function value(resolve,reject){var data=iterator[kStream].read();if(data){iterator[kLastPromise]=null;iterator[kLastResolve]=null;iterator[kLastReject]=null;resolve(createIterResult(data,false));}else{iterator[kLastResolve]=resolve;iterator[kLastReject]=reject;}},writable:true}),_Object$create));iterator[kLastPromise]=null;finished(stream,function(err){if(err&&err.code!=='ERR_STREAM_PREMATURE_CLOSE'){var reject=iterator[kLastReject];// reject if we are waiting for data in the Promise
|
|
1388
2034
|
// returned by next() and store the error
|
|
1389
|
-
if(reject!==null){iterator[kLastPromise]=null;iterator[kLastResolve]=null;iterator[kLastReject]=null;reject(err);}iterator[kError]=err;return;}var resolve=iterator[kLastResolve];if(resolve!==null){iterator[kLastPromise]=null;iterator[kLastResolve]=null;iterator[kLastReject]=null;resolve(createIterResult(undefined,true));}iterator[kEnded]=true;});stream.on('readable',onReadable.bind(null,iterator));return iterator;};module.exports=createReadableStreamAsyncIterator;}).call(this);}).call(this,require('_process'));},{"./end-of-stream":
|
|
2035
|
+
if(reject!==null){iterator[kLastPromise]=null;iterator[kLastResolve]=null;iterator[kLastReject]=null;reject(err);}iterator[kError]=err;return;}var resolve=iterator[kLastResolve];if(resolve!==null){iterator[kLastPromise]=null;iterator[kLastResolve]=null;iterator[kLastReject]=null;resolve(createIterResult(undefined,true));}iterator[kEnded]=true;});stream.on('readable',onReadable.bind(null,iterator));return iterator;};module.exports=createReadableStreamAsyncIterator;}).call(this);}).call(this,require('_process'));},{"./end-of-stream":75,"_process":54}],73:[function(require,module,exports){'use strict';function ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);enumerableOnly&&(symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable;})),keys.push.apply(keys,symbols);}return keys;}function _objectSpread(target){for(var i=1;i<arguments.length;i++){var source=null!=arguments[i]?arguments[i]:{};i%2?ownKeys(Object(source),!0).forEach(function(key){_defineProperty(target,key,source[key]);}):Object.getOwnPropertyDescriptors?Object.defineProperties(target,Object.getOwnPropertyDescriptors(source)):ownKeys(Object(source)).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(source,key));});}return target;}function _defineProperty(obj,key,value){key=_toPropertyKey(key);if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return typeof key==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(typeof input!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(typeof res!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}var _require=require('buffer'),Buffer=_require.Buffer;var _require2=require('util'),inspect=_require2.inspect;var custom=inspect&&inspect.custom||'inspect';function copyBuffer(src,target,offset){Buffer.prototype.copy.call(src,target,offset);}module.exports=/*#__PURE__*/function(){function BufferList(){_classCallCheck(this,BufferList);this.head=null;this.tail=null;this.length=0;}_createClass(BufferList,[{key:"push",value:function push(v){var entry={data:v,next:null};if(this.length>0)this.tail.next=entry;else this.head=entry;this.tail=entry;++this.length;}},{key:"unshift",value:function unshift(v){var entry={data:v,next:this.head};if(this.length===0)this.tail=entry;this.head=entry;++this.length;}},{key:"shift",value:function shift(){if(this.length===0)return;var ret=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return ret;}},{key:"clear",value:function clear(){this.head=this.tail=null;this.length=0;}},{key:"join",value:function join(s){if(this.length===0)return'';var p=this.head;var ret=''+p.data;while(p=p.next)ret+=s+p.data;return ret;}},{key:"concat",value:function concat(n){if(this.length===0)return Buffer.alloc(0);var ret=Buffer.allocUnsafe(n>>>0);var p=this.head;var i=0;while(p){copyBuffer(p.data,ret,i);i+=p.data.length;p=p.next;}return ret;}// Consumes a specified amount of bytes or characters from the buffered data.
|
|
1390
2036
|
},{key:"consume",value:function consume(n,hasStrings){var ret;if(n<this.head.data.length){// `slice` is the same for buffers and strings.
|
|
1391
2037
|
ret=this.head.data.slice(0,n);this.head.data=this.head.data.slice(n);}else if(n===this.head.data.length){// First chunk is a perfect match.
|
|
1392
2038
|
ret=this.shift();}else{// Result spans more than one buffer.
|
|
@@ -1395,7 +2041,7 @@ ret=hasStrings?this._getString(n):this._getBuffer(n);}return ret;}},{key:"first"
|
|
|
1395
2041
|
},{key:"_getBuffer",value:function _getBuffer(n){var ret=Buffer.allocUnsafe(n);var p=this.head;var c=1;p.data.copy(ret);n-=p.data.length;while(p=p.next){var buf=p.data;var nb=n>buf.length?buf.length:n;buf.copy(ret,ret.length-n,0,nb);n-=nb;if(n===0){if(nb===buf.length){++c;if(p.next)this.head=p.next;else this.head=this.tail=null;}else{this.head=p;p.data=buf.slice(nb);}break;}++c;}this.length-=c;return ret;}// Make sure the linked list only shows the minimal necessary information.
|
|
1396
2042
|
},{key:custom,value:function value(_,options){return inspect(this,_objectSpread(_objectSpread({},options),{},{// Only inspect one level.
|
|
1397
2043
|
depth:0,// It should not recurse.
|
|
1398
|
-
customInspect:false}));}}]);return BufferList;}();},{"buffer":19,"util":17}],
|
|
2044
|
+
customInspect:false}));}}]);return BufferList;}();},{"buffer":19,"util":17}],74:[function(require,module,exports){(function(process){(function(){'use strict';// undocumented cb() API, needed for core, not for public API
|
|
1399
2045
|
function destroy(err,cb){var _this=this;var readableDestroyed=this._readableState&&this._readableState.destroyed;var writableDestroyed=this._writableState&&this._writableState.destroyed;if(readableDestroyed||writableDestroyed){if(cb){cb(err);}else if(err){if(!this._writableState){process.nextTick(emitErrorNT,this,err);}else if(!this._writableState.errorEmitted){this._writableState.errorEmitted=true;process.nextTick(emitErrorNT,this,err);}}return this;}// we set destroyed to true before firing error callbacks in order
|
|
1400
2046
|
// to make it re-entrance safe in case destroy() is called within callbacks
|
|
1401
2047
|
if(this._readableState){this._readableState.destroyed=true;}// if this is a duplex stream mark the writable part as destroyed as well
|
|
@@ -1404,15 +2050,15 @@ if(this._writableState){this._writableState.destroyed=true;}this._destroy(err||n
|
|
|
1404
2050
|
// For now when you opt-in to autoDestroy we allow
|
|
1405
2051
|
// the error to be emitted nextTick. In a future
|
|
1406
2052
|
// semver major update we should change the default to this.
|
|
1407
|
-
var rState=stream._readableState;var wState=stream._writableState;if(rState&&rState.autoDestroy||wState&&wState.autoDestroy)stream.destroy(err);else stream.emit('error',err);}module.exports={destroy:destroy,undestroy:undestroy,errorOrDestroy:errorOrDestroy};}).call(this);}).call(this,require('_process'));},{"_process":
|
|
2053
|
+
var rState=stream._readableState;var wState=stream._writableState;if(rState&&rState.autoDestroy||wState&&wState.autoDestroy)stream.destroy(err);else stream.emit('error',err);}module.exports={destroy:destroy,undestroy:undestroy,errorOrDestroy:errorOrDestroy};}).call(this);}).call(this,require('_process'));},{"_process":54}],75:[function(require,module,exports){// Ported from https://github.com/mafintosh/end-of-stream with
|
|
1408
2054
|
// permission from the author, Mathias Buus (@mafintosh).
|
|
1409
2055
|
'use strict';var ERR_STREAM_PREMATURE_CLOSE=require('../../../errors').codes.ERR_STREAM_PREMATURE_CLOSE;function once(callback){var called=false;return function(){if(called)return;called=true;for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}callback.apply(this,args);};}function noop(){}function isRequest(stream){return stream.setHeader&&typeof stream.abort==='function';}function eos(stream,opts,callback){if(typeof opts==='function')return eos(stream,null,opts);if(!opts)opts={};callback=once(callback||noop);var readable=opts.readable||opts.readable!==false&&stream.readable;var writable=opts.writable||opts.writable!==false&&stream.writable;var onlegacyfinish=function onlegacyfinish(){if(!stream.writable)onfinish();};var writableEnded=stream._writableState&&stream._writableState.finished;var onfinish=function onfinish(){writable=false;writableEnded=true;if(!readable)callback.call(stream);};var readableEnded=stream._readableState&&stream._readableState.endEmitted;var onend=function onend(){readable=false;readableEnded=true;if(!writable)callback.call(stream);};var onerror=function onerror(err){callback.call(stream,err);};var onclose=function onclose(){var err;if(readable&&!readableEnded){if(!stream._readableState||!stream._readableState.ended)err=new ERR_STREAM_PREMATURE_CLOSE();return callback.call(stream,err);}if(writable&&!writableEnded){if(!stream._writableState||!stream._writableState.ended)err=new ERR_STREAM_PREMATURE_CLOSE();return callback.call(stream,err);}};var onrequest=function onrequest(){stream.req.on('finish',onfinish);};if(isRequest(stream)){stream.on('complete',onfinish);stream.on('abort',onclose);if(stream.req)onrequest();else stream.on('request',onrequest);}else if(writable&&!stream._writableState){// legacy streams
|
|
1410
|
-
stream.on('end',onlegacyfinish);stream.on('close',onlegacyfinish);}stream.on('end',onend);stream.on('finish',onfinish);if(opts.error!==false)stream.on('error',onerror);stream.on('close',onclose);return function(){stream.removeListener('complete',onfinish);stream.removeListener('abort',onclose);stream.removeListener('request',onrequest);if(stream.req)stream.req.removeListener('finish',onfinish);stream.removeListener('end',onlegacyfinish);stream.removeListener('close',onlegacyfinish);stream.removeListener('finish',onfinish);stream.removeListener('end',onend);stream.removeListener('error',onerror);stream.removeListener('close',onclose);};}module.exports=eos;},{"../../../errors":
|
|
2056
|
+
stream.on('end',onlegacyfinish);stream.on('close',onlegacyfinish);}stream.on('end',onend);stream.on('finish',onfinish);if(opts.error!==false)stream.on('error',onerror);stream.on('close',onclose);return function(){stream.removeListener('complete',onfinish);stream.removeListener('abort',onclose);stream.removeListener('request',onrequest);if(stream.req)stream.req.removeListener('finish',onfinish);stream.removeListener('end',onlegacyfinish);stream.removeListener('close',onlegacyfinish);stream.removeListener('finish',onfinish);stream.removeListener('end',onend);stream.removeListener('error',onerror);stream.removeListener('close',onclose);};}module.exports=eos;},{"../../../errors":66}],76:[function(require,module,exports){module.exports=function(){throw new Error('Readable.from is not available in the browser');};},{}],77:[function(require,module,exports){// Ported from https://github.com/mafintosh/pump with
|
|
1411
2057
|
// permission from the author, Mathias Buus (@mafintosh).
|
|
1412
2058
|
'use strict';var eos;function once(callback){var called=false;return function(){if(called)return;called=true;callback.apply(void 0,arguments);};}var _require$codes=require('../../../errors').codes,ERR_MISSING_ARGS=_require$codes.ERR_MISSING_ARGS,ERR_STREAM_DESTROYED=_require$codes.ERR_STREAM_DESTROYED;function noop(err){// Rethrow the error if it exists to avoid swallowing it
|
|
1413
2059
|
if(err)throw err;}function isRequest(stream){return stream.setHeader&&typeof stream.abort==='function';}function destroyer(stream,reading,writing,callback){callback=once(callback);var closed=false;stream.on('close',function(){closed=true;});if(eos===undefined)eos=require('./end-of-stream');eos(stream,{readable:reading,writable:writing},function(err){if(err)return callback(err);closed=true;callback();});var destroyed=false;return function(err){if(closed)return;if(destroyed)return;destroyed=true;// request.destroy just do .end - .abort is what we want
|
|
1414
|
-
if(isRequest(stream))return stream.abort();if(typeof stream.destroy==='function')return stream.destroy();callback(err||new ERR_STREAM_DESTROYED('pipe'));};}function call(fn){fn();}function pipe(from,to){return from.pipe(to);}function popCallback(streams){if(!streams.length)return noop;if(typeof streams[streams.length-1]!=='function')return noop;return streams.pop();}function pipeline(){for(var _len=arguments.length,streams=new Array(_len),_key=0;_key<_len;_key++){streams[_key]=arguments[_key];}var callback=popCallback(streams);if(Array.isArray(streams[0]))streams=streams[0];if(streams.length<2){throw new ERR_MISSING_ARGS('streams');}var error;var destroys=streams.map(function(stream,i){var reading=i<streams.length-1;var writing=i>0;return destroyer(stream,reading,writing,function(err){if(!error)error=err;if(err)destroys.forEach(call);if(reading)return;destroys.forEach(call);callback(error);});});return streams.reduce(pipe);}module.exports=pipeline;},{"../../../errors":
|
|
1415
|
-
return state.objectMode?16:16*1024;}module.exports={getHighWaterMark:getHighWaterMark};},{"../../../errors":
|
|
2060
|
+
if(isRequest(stream))return stream.abort();if(typeof stream.destroy==='function')return stream.destroy();callback(err||new ERR_STREAM_DESTROYED('pipe'));};}function call(fn){fn();}function pipe(from,to){return from.pipe(to);}function popCallback(streams){if(!streams.length)return noop;if(typeof streams[streams.length-1]!=='function')return noop;return streams.pop();}function pipeline(){for(var _len=arguments.length,streams=new Array(_len),_key=0;_key<_len;_key++){streams[_key]=arguments[_key];}var callback=popCallback(streams);if(Array.isArray(streams[0]))streams=streams[0];if(streams.length<2){throw new ERR_MISSING_ARGS('streams');}var error;var destroys=streams.map(function(stream,i){var reading=i<streams.length-1;var writing=i>0;return destroyer(stream,reading,writing,function(err){if(!error)error=err;if(err)destroys.forEach(call);if(reading)return;destroys.forEach(call);callback(error);});});return streams.reduce(pipe);}module.exports=pipeline;},{"../../../errors":66,"./end-of-stream":75}],78:[function(require,module,exports){'use strict';var ERR_INVALID_OPT_VALUE=require('../../../errors').codes.ERR_INVALID_OPT_VALUE;function highWaterMarkFrom(options,isDuplex,duplexKey){return options.highWaterMark!=null?options.highWaterMark:isDuplex?options[duplexKey]:null;}function getHighWaterMark(state,options,duplexKey,isDuplex){var hwm=highWaterMarkFrom(options,isDuplex,duplexKey);if(hwm!=null){if(!(isFinite(hwm)&&Math.floor(hwm)===hwm)||hwm<0){var name=isDuplex?duplexKey:'highWaterMark';throw new ERR_INVALID_OPT_VALUE(name,hwm);}return Math.floor(hwm);}// Default value
|
|
2061
|
+
return state.objectMode?16:16*1024;}module.exports={getHighWaterMark:getHighWaterMark};},{"../../../errors":66}],79:[function(require,module,exports){module.exports=require('events').EventEmitter;},{"events":21}],80:[function(require,module,exports){exports=module.exports=require('./lib/_stream_readable.js');exports.Stream=exports;exports.Readable=exports;exports.Writable=require('./lib/_stream_writable.js');exports.Duplex=require('./lib/_stream_duplex.js');exports.Transform=require('./lib/_stream_transform.js');exports.PassThrough=require('./lib/_stream_passthrough.js');exports.finished=require('./lib/internal/streams/end-of-stream.js');exports.pipeline=require('./lib/internal/streams/pipeline.js');},{"./lib/_stream_duplex.js":67,"./lib/_stream_passthrough.js":68,"./lib/_stream_readable.js":69,"./lib/_stream_transform.js":70,"./lib/_stream_writable.js":71,"./lib/internal/streams/end-of-stream.js":75,"./lib/internal/streams/pipeline.js":77}],81:[function(require,module,exports){// Copyright Joyent, Inc. and other Node contributors.
|
|
1416
2062
|
//
|
|
1417
2063
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
1418
2064
|
// copy of this software and associated documentation files (the
|
|
@@ -1466,13 +2112,13 @@ function utf8End(buf){var r=buf&&buf.length?this.write(buf):'';if(this.lastNeed)
|
|
|
1466
2112
|
function utf16Text(buf,i){if((buf.length-i)%2===0){var r=buf.toString('utf16le',i);if(r){var c=r.charCodeAt(r.length-1);if(c>=0xD800&&c<=0xDBFF){this.lastNeed=2;this.lastTotal=4;this.lastChar[0]=buf[buf.length-2];this.lastChar[1]=buf[buf.length-1];return r.slice(0,-1);}}return r;}this.lastNeed=1;this.lastTotal=2;this.lastChar[0]=buf[buf.length-1];return buf.toString('utf16le',i,buf.length-1);}// For UTF-16LE we do not explicitly append special replacement characters if we
|
|
1467
2113
|
// end on a partial character, we simply let v8 handle that.
|
|
1468
2114
|
function utf16End(buf){var r=buf&&buf.length?this.write(buf):'';if(this.lastNeed){var end=this.lastTotal-this.lastNeed;return r+this.lastChar.toString('utf16le',0,end);}return r;}function base64Text(buf,i){var n=(buf.length-i)%3;if(n===0)return buf.toString('base64',i);this.lastNeed=3-n;this.lastTotal=3;if(n===1){this.lastChar[0]=buf[buf.length-1];}else{this.lastChar[0]=buf[buf.length-2];this.lastChar[1]=buf[buf.length-1];}return buf.toString('base64',i,buf.length-n);}function base64End(buf){var r=buf&&buf.length?this.write(buf):'';if(this.lastNeed)return r+this.lastChar.toString('base64',0,3-this.lastNeed);return r;}// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
|
|
1469
|
-
function simpleWrite(buf){return buf.toString(this.encoding);}function simpleEnd(buf){return buf&&buf.length?this.write(buf):'';}},{"safe-buffer":
|
|
2115
|
+
function simpleWrite(buf){return buf.toString(this.encoding);}function simpleEnd(buf){return buf&&buf.length?this.write(buf):'';}},{"safe-buffer":59}],82:[function(require,module,exports){(function(setImmediate,clearImmediate){(function(){var nextTick=require('process/browser.js').nextTick;var apply=Function.prototype.apply;var slice=Array.prototype.slice;var immediateIds={};var nextImmediateId=0;// DOM APIs, for completeness
|
|
1470
2116
|
exports.setTimeout=function(){return new Timeout(apply.call(setTimeout,window,arguments),clearTimeout);};exports.setInterval=function(){return new Timeout(apply.call(setInterval,window,arguments),clearInterval);};exports.clearTimeout=exports.clearInterval=function(timeout){timeout.close();};function Timeout(id,clearFn){this._id=id;this._clearFn=clearFn;}Timeout.prototype.unref=Timeout.prototype.ref=function(){};Timeout.prototype.close=function(){this._clearFn.call(window,this._id);};// Does not start the time, just sets up the members needed.
|
|
1471
2117
|
exports.enroll=function(item,msecs){clearTimeout(item._idleTimeoutId);item._idleTimeout=msecs;};exports.unenroll=function(item){clearTimeout(item._idleTimeoutId);item._idleTimeout=-1;};exports._unrefActive=exports.active=function(item){clearTimeout(item._idleTimeoutId);var msecs=item._idleTimeout;if(msecs>=0){item._idleTimeoutId=setTimeout(function onTimeout(){if(item._onTimeout)item._onTimeout();},msecs);}};// That's not how node.js implements it but the exposed api is the same.
|
|
1472
2118
|
exports.setImmediate=typeof setImmediate==="function"?setImmediate:function(fn){var id=nextImmediateId++;var args=arguments.length<2?false:slice.call(arguments,1);immediateIds[id]=true;nextTick(function onNextTick(){if(immediateIds[id]){// fn.call() is faster so we optimize for the common use-case
|
|
1473
2119
|
// @see http://jsperf.com/call-apply-segu
|
|
1474
2120
|
if(args){fn.apply(null,args);}else{fn.call(null);}// Prevent ids from leaking
|
|
1475
|
-
exports.clearImmediate(id);}});return id;};exports.clearImmediate=typeof clearImmediate==="function"?clearImmediate:function(id){delete immediateIds[id];};}).call(this);}).call(this,require("timers").setImmediate,require("timers").clearImmediate);},{"process/browser.js":
|
|
2121
|
+
exports.clearImmediate(id);}});return id;};exports.clearImmediate=typeof clearImmediate==="function"?clearImmediate:function(id){delete immediateIds[id];};}).call(this);}).call(this,require("timers").setImmediate,require("timers").clearImmediate);},{"process/browser.js":54,"timers":82}],83:[function(require,module,exports){// Copyright Joyent, Inc. and other Node contributors.
|
|
1476
2122
|
//
|
|
1477
2123
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
1478
2124
|
// copy of this software and associated documentation files (the
|
|
@@ -1619,7 +2265,7 @@ if(psychotic){result.hostname=result.host=isAbsolute?'':srcPath.length?srcPath.s
|
|
|
1619
2265
|
//this especially happens in cases like
|
|
1620
2266
|
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
|
|
1621
2267
|
var authInHost=result.host&&result.host.indexOf('@')>0?result.host.split('@'):false;if(authInHost){result.auth=authInHost.shift();result.host=result.hostname=authInHost.shift();}}mustEndAbs=mustEndAbs||result.host&&srcPath.length;if(mustEndAbs&&!isAbsolute){srcPath.unshift('');}if(!srcPath.length){result.pathname=null;result.path=null;}else{result.pathname=srcPath.join('/');}//to support request.http
|
|
1622
|
-
if(!util.isNull(result.pathname)||!util.isNull(result.search)){result.path=(result.pathname?result.pathname:'')+(result.search?result.search:'');}result.auth=relative.auth||result.auth;result.slashes=result.slashes||relative.slashes;result.href=result.format();return result;};Url.prototype.parseHost=function(){var host=this.host;var port=portPattern.exec(host);if(port){port=port[0];if(port!==':'){this.port=port.substr(1);}host=host.substr(0,host.length-port.length);}if(host)this.hostname=host;};},{"./util":
|
|
2268
|
+
if(!util.isNull(result.pathname)||!util.isNull(result.search)){result.path=(result.pathname?result.pathname:'')+(result.search?result.search:'');}result.auth=relative.auth||result.auth;result.slashes=result.slashes||relative.slashes;result.href=result.format();return result;};Url.prototype.parseHost=function(){var host=this.host;var port=portPattern.exec(host);if(port){port=port[0];if(port!==':'){this.port=port.substr(1);}host=host.substr(0,host.length-port.length);}if(host)this.hostname=host;};},{"./util":84,"punycode":55,"querystring":58}],84:[function(require,module,exports){'use strict';module.exports={isString:function isString(arg){return typeof arg==='string';},isObject:function isObject(arg){return typeof arg==='object'&&arg!==null;},isNull:function isNull(arg){return arg===null;},isNullOrUndefined:function isNullOrUndefined(arg){return arg==null;}};},{}],85:[function(require,module,exports){(function(global){(function(){/**
|
|
1623
2269
|
* Module exports.
|
|
1624
2270
|
*/module.exports=deprecate;/**
|
|
1625
2271
|
* Mark that a method should not be used.
|
|
@@ -1644,12 +2290,12 @@ if(!util.isNull(result.pathname)||!util.isNull(result.search)){result.path=(resu
|
|
|
1644
2290
|
* @returns {Boolean}
|
|
1645
2291
|
* @api private
|
|
1646
2292
|
*/function config(name){// accessing global.localStorage can trigger a DOMException in sandboxed iframes
|
|
1647
|
-
try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.localStorage[name];if(null==val)return false;return String(val).toLowerCase()==='true';}}).call(this);}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{}],
|
|
2293
|
+
try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.localStorage[name];if(null==val)return false;return String(val).toLowerCase()==='true';}}).call(this);}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});},{}],86:[function(require,module,exports){// Returns a wrapper function that returns a wrapped callback
|
|
1648
2294
|
// The wrapper function should do some stuff, and return a
|
|
1649
2295
|
// presumably different callback function.
|
|
1650
2296
|
// This makes sure that own properties are retained, so that
|
|
1651
2297
|
// decorations and such are not lost along the way.
|
|
1652
|
-
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;}}},{}],
|
|
2298
|
+
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;}}},{}],87:[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;}},{}],88:[function(require,module,exports){var libNPMModuleWrapper=require('./Fable.js');if(typeof window==='object'&&!window.hasOwnProperty('Fable')){window.Fable=libNPMModuleWrapper;}module.exports=libNPMModuleWrapper;},{"./Fable.js":90}],89:[function(require,module,exports){/**
|
|
1653
2299
|
* Fable Application Services Management
|
|
1654
2300
|
* @author <steven@velozo.com>
|
|
1655
2301
|
*/const libFableServiceBase=require('fable-serviceproviderbase');class FableService extends libFableServiceBase.CoreServiceProviderBase{constructor(pSettings,pServiceHash){super(pSettings,pServiceHash);this.serviceType='ServiceManager';this.serviceTypes=[];// A map of instantiated services
|
|
@@ -1672,12 +2318,11 @@ pServiceInstance.connectFable(this.fable);if(!this.services.hasOwnProperty(tmpSe
|
|
|
1672
2318
|
// This means you couldn't register another with this type unless it was later registered with a constructor class.
|
|
1673
2319
|
this.services[tmpServiceType]={};}// Add the service to the service map
|
|
1674
2320
|
this.services[tmpServiceType][tmpServiceHash]=pServiceInstance;// If this is the first service of this type, make it the default
|
|
1675
|
-
if(!this.defaultServices.hasOwnProperty(tmpServiceType)){this.setDefaultServiceInstantiation(tmpServiceType,tmpServiceHash);}return pServiceInstance;}setDefaultServiceInstantiation(pServiceType,pServiceHash){if(this.services[pServiceType].hasOwnProperty(pServiceHash)){this.fable[pServiceType]=this.services[pServiceType][pServiceHash];this.defaultServices[pServiceType]=this.services[pServiceType][pServiceHash];return true;}return false;}}module.exports=FableService;module.exports.ServiceProviderBase=libFableServiceBase;module.exports.CoreServiceProviderBase=libFableServiceBase.CoreServiceProviderBase;},{"fable-serviceproviderbase":29}],
|
|
2321
|
+
if(!this.defaultServices.hasOwnProperty(tmpServiceType)){this.setDefaultServiceInstantiation(tmpServiceType,tmpServiceHash);}return pServiceInstance;}setDefaultServiceInstantiation(pServiceType,pServiceHash){if(this.services[pServiceType].hasOwnProperty(pServiceHash)){this.fable[pServiceType]=this.services[pServiceType][pServiceHash];this.defaultServices[pServiceType]=this.services[pServiceType][pServiceHash];return true;}return false;}}module.exports=FableService;module.exports.ServiceProviderBase=libFableServiceBase;module.exports.CoreServiceProviderBase=libFableServiceBase.CoreServiceProviderBase;},{"fable-serviceproviderbase":29}],90:[function(require,module,exports){/**
|
|
1676
2322
|
* Fable Application Services Support Library
|
|
1677
2323
|
* @author <steven@velozo.com>
|
|
1678
2324
|
*/ // Pre-init services
|
|
1679
|
-
const libFableSettings=require('fable-settings');const libFableUUID=require('fable-uuid');const libFableLog=require('fable-log');const libFableServiceManager=require('./Fable-ServiceManager.js')
|
|
1680
|
-
const libFableServiceEnvironmentData=require('./services/Fable-Service-EnvironmentData.js');const libFableServiceDataFormat=require('./services/Fable-Service-DataFormat.js');const libFableServiceMetaTemplate=require('./services/Fable-Service-MetaTemplate.js');const libFableServiceOperation=require('./services/Fable-Service-Operation.js');const libFableServiceRestClient=require('./services/Fable-Service-RestClient.js');const libFableServiceTemplate=require('./services/Fable-Service-Template.js');const libFableServiceUtility=require('./services/Fable-Service-Utility.js');class Fable{constructor(pSettings){// Initialization Phase 0: Set up the lowest level state (core services)
|
|
2325
|
+
const libFableSettings=require('fable-settings');const libFableUUID=require('fable-uuid');const libFableLog=require('fable-log');const libFableServiceManager=require('./Fable-ServiceManager.js');class Fable{constructor(pSettings){// Initialization Phase 0: Set up the lowest level state (core services)
|
|
1681
2326
|
// Container for the core services prototypes.
|
|
1682
2327
|
// This is here so if an API consumer changes the default for a core service,
|
|
1683
2328
|
// fable still runs with what was initialized.
|
|
@@ -1690,9 +2335,31 @@ this._coreServices.ServiceManager=new libFableServiceManager(this);this.serviceM
|
|
|
1690
2335
|
// Initialization Phase 2: Map in the default services.
|
|
1691
2336
|
// They will then be available in the Default service provider set as well.
|
|
1692
2337
|
this.serviceManager.connectPreinitServiceProviderInstance(this._coreServices.ServiceManager);this.serviceManager.connectPreinitServiceProviderInstance(this._coreServices.UUID);this.serviceManager.connectPreinitServiceProviderInstance(this._coreServices.Logging);this.serviceManager.connectPreinitServiceProviderInstance(this._coreServices.SettingsManager);// Initialize and instantiate the default baked-in Data Arithmatic service
|
|
1693
|
-
this.serviceManager.addAndInstantiateServiceType('EnvironmentData',
|
|
1694
|
-
function autoConstruct(pSettings){return new Fable(pSettings);}module.exports=Fable;module.exports.new=autoConstruct;module.exports.LogProviderBase=libFableLog.LogProviderBase;module.exports.ServiceProviderBase=libFableServiceManager.ServiceProviderBase;module.exports.CoreServiceProviderBase=libFableServiceManager.CoreServiceProviderBase;module.exports.precedent=libFableSettings.precedent;},{"./Fable-ServiceManager.js":
|
|
1695
|
-
|
|
2338
|
+
this.serviceManager.addAndInstantiateServiceType('EnvironmentData',require('./services/Fable-Service-EnvironmentData.js'));this.serviceManager.addServiceType('Template',require('./services/Fable-Service-Template.js'));this.serviceManager.addServiceType('MetaTemplate',require('./services/Fable-Service-MetaTemplate.js'));this.serviceManager.addAndInstantiateServiceType('DataFormat',require('./services/Fable-Service-DataFormat.js'));this.serviceManager.addAndInstantiateServiceType('Utility',require('./services/Fable-Service-Utility.js'));this.serviceManager.addServiceType('Operation',require('./services/Fable-Service-Operation.js'));this.serviceManager.addServiceType('RestClient',require('./services/Fable-Service-RestClient.js'));this.serviceManager.addServiceType('CSVParser',require('./services/Fable-Service-CSVParser.js'));this.serviceManager.addServiceType('Manifest',require('manyfest'));}get isFable(){return true;}get settings(){return this._coreServices.SettingsManager.settings;}get settingsManager(){return this._coreServices.SettingsManager;}get log(){return this._coreServices.Logging;}get services(){return this._coreServices.ServiceManager.services;}get defaultServices(){return this._coreServices.ServiceManager.defaultServices;}getUUID(){return this._coreServices.UUID.getUUID();}get fable(){return this;}}// This is for backwards compatibility
|
|
2339
|
+
function autoConstruct(pSettings){return new Fable(pSettings);}module.exports=Fable;module.exports.new=autoConstruct;module.exports.LogProviderBase=libFableLog.LogProviderBase;module.exports.ServiceProviderBase=libFableServiceManager.ServiceProviderBase;module.exports.CoreServiceProviderBase=libFableServiceManager.CoreServiceProviderBase;module.exports.precedent=libFableSettings.precedent;},{"./Fable-ServiceManager.js":89,"./services/Fable-Service-CSVParser.js":91,"./services/Fable-Service-DataFormat.js":92,"./services/Fable-Service-EnvironmentData.js":93,"./services/Fable-Service-MetaTemplate.js":94,"./services/Fable-Service-Operation.js":96,"./services/Fable-Service-RestClient.js":97,"./services/Fable-Service-Template.js":98,"./services/Fable-Service-Utility.js":99,"fable-log":27,"fable-settings":32,"fable-uuid":34,"manyfest":48}],91:[function(require,module,exports){const libFableServiceProviderBase=require('fable-serviceproviderbase');/**
|
|
2340
|
+
* Parsing CSVs. Why? Because it's a thing that needs to be done.
|
|
2341
|
+
*
|
|
2342
|
+
* 1. And the other node CSV parsers had issues with the really messy files we had.
|
|
2343
|
+
*
|
|
2344
|
+
*
|
|
2345
|
+
* 2. None of the CSV parsers dealt with and multi-line quoted string columns
|
|
2346
|
+
* which are apparently a-ok according to the official spec.
|
|
2347
|
+
* Plus a lot of them are asynchronous because apparently that's the best way to
|
|
2348
|
+
* do anything; unfortunately some files have a sequence issue with that.
|
|
2349
|
+
*
|
|
2350
|
+
* @class CSVParser
|
|
2351
|
+
*/class CSVParser extends libFableServiceProviderBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='CSVParser';this.Header=[];this.HeaderFieldNames=[];this.Delimiter=',';this.QuoteCharacter='"';this.CleanCharacters=['\r'];this.HeaderLineIndex=0;this.HasHeader=true;this.HasSetHeader=false;this.EmitHeader=false;this.EmitJSON=true;this.EscapedQuoteString='"';// Current Line Parsing State
|
|
2352
|
+
this.CurrentLine='';this.CurrentRecord=[];this.InQuote=false;this.InEscapedQuote=false;this.LinesParsed=0;this.RowsEmitted=0;}marshalRowToJSON(pRowArray){if(!Array.isArray(pRowArray)){return false;}for(let i=this.HeaderFieldNames.length;i<pRowArray.length;i++){this.HeaderFieldNames[i]="".concat(i);}let tmpObject={};for(let i=0;i<pRowArray.length;i++){tmpObject[this.HeaderFieldNames[i]]=pRowArray[i];}return tmpObject;}// Set the header data, for use in marshalling to JSON.
|
|
2353
|
+
setHeader(pHeaderArray){this.Header=pHeaderArray;for(let i=0;i<this.Header.length;i++){if(typeof this.Header[i]=='undefined'){this.HeaderFieldNames[i]="".concat(i);}else{this.HeaderFieldNames[i]=this.Header[i].toString();}}}resetRowState(){this.CurrentRecord=[];}pushLine(){for(let i=0;i<this.CleanCharacters.length;i++){this.CurrentLine=this.CurrentLine.replace(this.CleanCharacters[i],'');}this.CurrentRecord.push(this.CurrentLine);this.CurrentLine='';}emitRow(pFormatAsJSON){let tmpFormatAsJSON=typeof pFormatAsJSON=='undefined'?this.EmitJSON:pFormatAsJSON;this.RowsEmitted++;let tmpCompletedRecord=this.CurrentRecord;this.CurrentRecord=[];if(tmpFormatAsJSON){return this.marshalRowToJSON(tmpCompletedRecord);}else{return tmpCompletedRecord;}}parseCSVLine(pLineString){this.LinesParsed++;for(let i=0;i<pLineString.length;i++){if(!this.InQuote&&pLineString[i]==this.Delimiter){this.pushLine();}else if(pLineString[i]==this.QuoteCharacter){// If we are in the second part of an escaped quote, ignore it.
|
|
2354
|
+
if(this.InEscapedQuote){this.InEscapedQuote=false;}// If we aren't in a quote, enter quote
|
|
2355
|
+
else if(!this.InQuote){this.InQuote=true;}// We are in a quote, so peek forward to see if this is an "escaped" quote pair
|
|
2356
|
+
else if(i<pLineString.length&&pLineString[i+1]==this.QuoteCharacter){this.CurrentLine+=this.EscapedQuoteString;this.InEscapedQuote=true;}// We are in a quote, this isn't an "escaped" quote pair, so go out of quote mode
|
|
2357
|
+
else{this.InQuote=false;}}else{this.CurrentLine+=pLineString[i];}}// See if we are in a multiline quoted entry -- if not, emit the row.
|
|
2358
|
+
if(!this.InQuote){// Push the last remaining column from the buffer to the current line.
|
|
2359
|
+
this.pushLine();// Check to see if there is a header -- and if so, if this is the header row
|
|
2360
|
+
if(this.HasHeader&&!this.HasSetHeader&&this.RowsEmitted==this.HeaderLineIndex){this.HasSetHeader=true;// Override the format as json bit
|
|
2361
|
+
this.setHeader(this.emitRow(false));// No matter what, formatting this as JSON is silly and we don't want to go there anyway.
|
|
2362
|
+
if(this.EmitHeader){return this.Header;}else{return false;}}else{return this.emitRow();}}else{return false;}}}module.exports=CSVParser;},{"fable-serviceproviderbase":29}],92:[function(require,module,exports){const libFableServiceProviderBase=require('fable-serviceproviderbase');/**
|
|
1696
2363
|
* Data Formatting and Translation Functions
|
|
1697
2364
|
*
|
|
1698
2365
|
* @class DataFormat
|
|
@@ -1887,7 +2554,7 @@ return'';}if(tmpEnclosedValueEndIndex>0&&tmpEnclosedValueEndIndex>tmpEnclosedVal
|
|
|
1887
2554
|
* @param {number} pEnclosureEnd
|
|
1888
2555
|
* @returns {string}
|
|
1889
2556
|
*/stringRemoveEnclosureByIndex(pString,pEnclosureIndexToRemove,pEnclosureStart,pEnclosureEnd){let tmpString=typeof pString=='string'?pString:'';let tmpEnclosureIndexToRemove=typeof pEnclosureIndexToRemove=='number'?pEnclosureIndexToRemove:0;let tmpEnclosureStart=typeof pEnclosureStart=='string'?pEnclosureStart:'(';let tmpEnclosureEnd=typeof pEnclosureEnd=='string'?pEnclosureEnd:')';let tmpEnclosureCount=0;let tmpEnclosureDepth=0;let tmpMatchedEnclosureIndex=false;let tmpEnclosureStartIndex=0;let tmpEnclosureEndIndex=0;for(let i=0;i<tmpString.length;i++){// This is the start of an enclosure
|
|
1890
|
-
if(tmpString[i]==tmpEnclosureStart){tmpEnclosureDepth++;if(tmpEnclosureDepth==1){tmpEnclosureCount++;if(tmpEnclosureIndexToRemove==tmpEnclosureCount-1){tmpMatchedEnclosureIndex=true;tmpEnclosureStartIndex=i;}}}else if(tmpString[i]==tmpEnclosureEnd){tmpEnclosureDepth--;if(tmpEnclosureDepth==0&&tmpMatchedEnclosureIndex&&tmpEnclosureEndIndex<=tmpEnclosureStartIndex){tmpEnclosureEndIndex=i;tmpMatchedEnclosureIndex=false;}}}if(tmpEnclosureCount<=tmpEnclosureIndexToRemove){return tmpString;}let tmpReturnString='';if(tmpEnclosureStartIndex>1){tmpReturnString=tmpString.substring(0,tmpEnclosureStartIndex);}if(tmpString.length>tmpEnclosureEndIndex+1&&tmpEnclosureEndIndex>tmpEnclosureStartIndex){tmpReturnString+=tmpString.substring(tmpEnclosureEndIndex+1);}return tmpReturnString;}}module.exports=DataFormat;},{"fable-serviceproviderbase":29}],
|
|
2557
|
+
if(tmpString[i]==tmpEnclosureStart){tmpEnclosureDepth++;if(tmpEnclosureDepth==1){tmpEnclosureCount++;if(tmpEnclosureIndexToRemove==tmpEnclosureCount-1){tmpMatchedEnclosureIndex=true;tmpEnclosureStartIndex=i;}}}else if(tmpString[i]==tmpEnclosureEnd){tmpEnclosureDepth--;if(tmpEnclosureDepth==0&&tmpMatchedEnclosureIndex&&tmpEnclosureEndIndex<=tmpEnclosureStartIndex){tmpEnclosureEndIndex=i;tmpMatchedEnclosureIndex=false;}}}if(tmpEnclosureCount<=tmpEnclosureIndexToRemove){return tmpString;}let tmpReturnString='';if(tmpEnclosureStartIndex>1){tmpReturnString=tmpString.substring(0,tmpEnclosureStartIndex);}if(tmpString.length>tmpEnclosureEndIndex+1&&tmpEnclosureEndIndex>tmpEnclosureStartIndex){tmpReturnString+=tmpString.substring(tmpEnclosureEndIndex+1);}return tmpReturnString;}}module.exports=DataFormat;},{"fable-serviceproviderbase":29}],93:[function(require,module,exports){const libFableServiceBase=require('../Fable-ServiceManager.js').ServiceProviderBase;class FableServiceEnvironmentData extends libFableServiceBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='EnvironmentData';this.Environment="node.js";}}module.exports=FableServiceEnvironmentData;},{"../Fable-ServiceManager.js":89}],94:[function(require,module,exports){const libFableServiceBase=require('../Fable-ServiceManager.js').ServiceProviderBase;const libPrecedent=require('precedent');class FableServiceMetaTemplate extends libFableServiceBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='MetaTemplate';this._MetaTemplateLibrary=new libPrecedent(this.options);}/**
|
|
1891
2558
|
* Add a Pattern to the Parse Tree
|
|
1892
2559
|
* @method addPattern
|
|
1893
2560
|
* @param {Object} pTree - A node on the parse tree to push the characters into
|
|
@@ -1899,7 +2566,9 @@ if(tmpString[i]==tmpEnclosureStart){tmpEnclosureDepth++;if(tmpEnclosureDepth==1)
|
|
|
1899
2566
|
* @method parseString
|
|
1900
2567
|
* @param {string} pString - The string to parse
|
|
1901
2568
|
* @return {string} The result from the parser
|
|
1902
|
-
*/parseString(pString,pData){return this._MetaTemplateLibrary.parseString(pString,pData);}}module.exports=FableServiceMetaTemplate;},{"../Fable-ServiceManager.js":
|
|
2569
|
+
*/parseString(pString,pData){return this._MetaTemplateLibrary.parseString(pString,pData);}}module.exports=FableServiceMetaTemplate;},{"../Fable-ServiceManager.js":89,"precedent":51}],95:[function(require,module,exports){module.exports={"Metadata":{"GUID":false,"Hash":false,"Title":"","Summary":"","Version":0},"Status":{"Completed":false,"CompletionProgress":0,"CompletionTimeElapsed":0,"Steps":1,"StepsCompleted":0,"StartTime":0,"EndTime":0},"Errors":[],"Log":[]};},{}],96:[function(require,module,exports){const libFableServiceBase=require('../Fable-ServiceManager.js').ServiceProviderBase;const _OperationStatePrototypeString=JSON.stringify(require('./Fable-Service-Operation-DefaultSettings.js'));class FableOperation extends libFableServiceBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='PhasedOperation';this.state=JSON.parse(_OperationStatePrototypeString);this.state.Metadata.GUID=this.fable.getUUID();this.state.Metadata.Hash=this.Hash;this.name=typeof this.options.Name=='string'?this.options.Name:"Unnamed Operation ".concat(this.state.Metadata.GUID);}get GUID(){return this.state.Metadata.GUID;}get log(){return this;}writeOperationLog(pLogLevel,pLogText,pLogObject){this.state.Log.push("".concat(new Date().toUTCString()," [").concat(pLogLevel,"]: ").concat(pLogText));if(typeof pLogObject=='object'){this.state.Log.push(JSON.stringify(pLogObject));}}writeOperationErrors(pLogText,pLogObject){this.state.Errors.push("".concat(pLogText));if(typeof pLogObject=='object'){this.state.Errors.push(JSON.stringify(pLogObject));}}trace(pLogText,pLogObject){this.writeOperationLog('TRACE',pLogText,pLogObject);this.fable.log.trace(pLogText,pLogObject);}debug(pLogText,pLogObject){this.writeOperationLog('DEBUG',pLogText,pLogObject);this.fable.log.debug(pLogText,pLogObject);}info(pLogText,pLogObject){this.writeOperationLog('INFO',pLogText,pLogObject);this.fable.log.info(pLogText,pLogObject);}warn(pLogText,pLogObject){this.writeOperationLog('WARN',pLogText,pLogObject);this.fable.log.warn(pLogText,pLogObject);}error(pLogText,pLogObject){this.writeOperationLog('ERROR',pLogText,pLogObject);this.writeOperationErrors(pLogText,pLogObject);this.fable.log.error(pLogText,pLogObject);}fatal(pLogText,pLogObject){this.writeOperationLog('FATAL',pLogText,pLogObject);this.writeOperationErrors(pLogText,pLogObject);this.fable.log.fatal(pLogText,pLogObject);}}module.exports=FableOperation;},{"../Fable-ServiceManager.js":89,"./Fable-Service-Operation-DefaultSettings.js":95}],97:[function(require,module,exports){const libFableServiceBase=require('../Fable-ServiceManager.js').ServiceProviderBase;const libSimpleGet=require('simple-get');class FableServiceRestClient extends libFableServiceBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.TraceLog=false;if(this.options.TraceLog||this.fable.TraceLog){this.TraceLog=true;}this.dataFormat=this.fable.defaultServices.DataFormat;this.serviceType='RestClient';}executeChunkedRequest(pOptions,fCallback){pOptions.RequestStartTime=this.fable.log.getTimeStamp();if(this.TraceLog){this.fable.log.debug("Beginning ".concat(pOptions.method," request to ").concat(pOptions.url," at ").concat(pOptions.RequestStartTime));}return libSimpleGet(pOptions,(pError,pResponse)=>{if(pError){return fCallback(pError,pResponse);}if(this.TraceLog){let tmpConnectTime=this.fable.log.getTimeStamp();this.fable.log.debug("--> ".concat(pOptions.method," connected in ").concat(this.dataFormat.formatTimeDelta(pOptions.RequestStartTime,tmpConnectTime),"ms code ").concat(pResponse.statusCode));}let tmpData='';pResponse.on('data',pChunk=>{// For JSON, the chunk is the serialized object.
|
|
2570
|
+
if(this.TraceLog){let tmpChunkTime=this.fable.log.getTimeStamp();this.fable.log.debug("--> ".concat(pOptions.method," data chunk size ").concat(pChunk.length,"b received in ").concat(this.dataFormat.formatTimeDelta(pOptions.RequestStartTime,tmpChunkTime),"ms"));}tmpData+=pChunk;});pResponse.on('end',()=>{if(this.TraceLog){let tmpCompletionTime=this.fable.log.getTimeStamp();this.fable.log.debug("==> ".concat(pOptions.method," completed data size ").concat(tmpData.length,"b received in ").concat(this.dataFormat.formatTimeDelta(pOptions.RequestStartTime,tmpCompletionTime),"ms"));}return fCallback(pError,pResponse,tmpData);});});}executeJSONRequest(pOptions,fCallback){pOptions.json=true;pOptions.RequestStartTime=this.fable.log.getTimeStamp();if(this.TraceLog){this.fable.log.debug("Beginning ".concat(pOptions.method," JSON request to ").concat(pOptions.url," at ").concat(pOptions.RequestStartTime));}return libSimpleGet(pOptions,(pError,pResponse)=>{if(pError){return fCallback(pError,pResponse);}if(this.TraceLog){let tmpConnectTime=this.fable.log.getTimeStamp();this.fable.log.debug("--> JSON ".concat(pOptions.method," connected in ").concat(this.dataFormat.formatTimeDelta(pOptions.RequestStartTime,tmpConnectTime),"ms code ").concat(pResponse.statusCode));}pResponse.on('data',pChunk=>{if(this.TraceLog){let tmpChunkTime=this.fable.log.getTimeStamp();this.fable.log.debug("--> JSON ".concat(pOptions.method," data chunk size ").concat(pChunk.length,"b received in ").concat(this.dataFormat.formatTimeDelta(pOptions.RequestStartTime,tmpChunkTime),"ms"));}// In a JSON request, the chunk is the serialized method.
|
|
2571
|
+
return fCallback(pError,pResponse,JSON.parse(pChunk));});pResponse.on('end',()=>{if(this.TraceLog){let tmpCompletionTime=this.fable.log.getTimeStamp();this.fable.log.debug("==> JSON ".concat(pOptions.method," completed - received in ").concat(this.dataFormat.formatTimeDelta(pOptions.RequestStartTime,tmpCompletionTime),"ms"));}});});}getJSON(pOptionsOrURL,fCallback){let tmpRequestOptions=typeof pOptions=='object'?pOptions:{};if(typeof pOptionsOrURL=='string'){tmpRequestOptions.url=pOptionsOrURL;}tmpRequestOptions.method='GET';return this.executeJSONRequest(tmpRequestOptions,fCallback);}putJSON(pOptions,fCallback){if(typeof pOptions.body!='object'){return fCallback(new Error("PUT JSON Error Invalid options object"));}pOptions.method='PUT';return this.executeJSONRequest(pOptions,fCallback);}postJSON(pOptions,fCallback){if(typeof pOptions.body!='object'){return fCallback(new Error("POST JSON Error Invalid options object"));}pOptions.method='POST';return this.executeJSONRequest(pOptions,fCallback);}patchJSON(pOptions,fCallback){if(typeof pOptions.body!='object'){return fCallback(new Error("PATCH JSON Error Invalid options object"));}pOptions.method='PATCH';return this.executeJSONRequest(pOptions,fCallback);}headJSON(pOptions,fCallback){if(typeof pOptions.body!='object'){return fCallback(new Error("HEAD JSON Error Invalid options object"));}pOptions.method='HEAD';return this.executeJSONRequest(pOptions,fCallback);}delJSON(pOptions,fCallback){pOptions.method='DELETE';return this.executeJSONRequest(pOptions,fCallback);}getRawText(pOptionsOrURL,fCallback){let tmpRequestOptions=typeof pOptions=='object'?pOptions:{};if(typeof pOptionsOrURL=='string'){tmpRequestOptions.url=pOptionsOrURL;}tmpRequestOptions.method='GET';return this.executeChunkedRequest(tmpRequestOptions,fCallback);}}module.exports=FableServiceRestClient;},{"../Fable-ServiceManager.js":89,"simple-get":61}],98:[function(require,module,exports){const libFableServiceBase=require('../Fable-ServiceManager.js').ServiceProviderBase;class FableServiceTemplate extends libFableServiceBase{// Underscore and lodash have a behavior, _.template, which compiles a
|
|
1903
2572
|
// string-based template with code snippets into simple executable pieces,
|
|
1904
2573
|
// with the added twist of returning a precompiled function ready to go.
|
|
1905
2574
|
//
|
|
@@ -1919,7 +2588,7 @@ this.renderFunction=false;this.templateString=false;}renderTemplate(pData){retur
|
|
|
1919
2588
|
// underscore code until this is rewritten using precedent.
|
|
1920
2589
|
this.TemplateSource="__p+='"+pTemplateText.replace(this.Matchers.Escaper,pMatch=>{return"\\".concat(this.templateEscapes[pMatch]);}).replace(this.Matchers.Interpolate||this.Matchers.GuaranteedNonMatch,(pMatch,pCode)=>{return"'+\n(".concat(decodeURIComponent(pCode),")+\n'");}).replace(this.Matchers.Evaluate||this.Matchers.GuaranteedNonMatch,(pMatch,pCode)=>{return"';\n".concat(decodeURIComponent(pCode),"\n;__p+='");})+"';\n";this.TemplateSource="with(pTemplateDataObject||{}){\n".concat(this.TemplateSource,"}\n");this.TemplateSource="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n".concat(this.TemplateSource,"return __p;\n");this.renderFunction=new Function('pTemplateDataObject',this.TemplateSource);if(typeof pData!='undefined'){return this.renderFunction(pData);}// Provide the compiled function source as a convenience for build time
|
|
1921
2590
|
// precompilation.
|
|
1922
|
-
this.TemplateSourceCompiled='function(obj){\n'+this.TemplateSource+'}';return this.templateFunction();}}module.exports=FableServiceTemplate;},{"../Fable-ServiceManager.js":
|
|
2591
|
+
this.TemplateSourceCompiled='function(obj){\n'+this.TemplateSource+'}';return this.templateFunction();}}module.exports=FableServiceTemplate;},{"../Fable-ServiceManager.js":89}],99:[function(require,module,exports){const libFableServiceBase=require('../Fable-ServiceManager.js').ServiceProviderBase;// TODO: These are still pretty big -- consider the smaller polyfills
|
|
1923
2592
|
const libAsyncWaterfall=require('async.waterfall');const libAsyncEachLimit=require('async.eachlimit');class FableServiceUtility extends libFableServiceBase{// Underscore and lodash have a behavior, _.template, which compiles a
|
|
1924
2593
|
// string-based template with code snippets into simple executable pieces,
|
|
1925
2594
|
// with the added twist of returning a precompiled function ready to go.
|
|
@@ -1949,8 +2618,9 @@ let tmpChunkSize=typeof pChunkSize=='number'?pChunkSize:0;let tmpChunkCache=type
|
|
|
1949
2618
|
// and: 1986-06-11T09:34:46.012Z+0200
|
|
1950
2619
|
// ... and converts them into javascript timestamps, following the directions of the timezone stuff.
|
|
1951
2620
|
//
|
|
1952
|
-
// This is not meant to replace the more complex libraries.
|
|
1953
|
-
// This *is* meant to be a simple, small, and fast way to convert ISO strings to dates in engines
|
|
2621
|
+
// This is not meant to replace the more complex libraries such as moment or luxon.
|
|
2622
|
+
// This *is* meant to be a simple, small, and fast way to convert ISO strings to dates in engines
|
|
2623
|
+
// with ultra limited JS capabilities where those don't work.
|
|
1954
2624
|
isoStringToDate(pISOString){// Split the string into an array based on the digit groups.
|
|
1955
2625
|
var tmpDateParts=pISOString.split(/\D+/);// Set up a date object with the current time.
|
|
1956
2626
|
var tmpReturnDate=new Date();// Manually parse the parts of the string and set each part for the
|
|
@@ -1970,4 +2640,4 @@ tmpTimeZoneOffsetInHours=parseInt(tmpDateParts[7])+tmpTimeZoneOffsetInMinutes;//
|
|
|
1970
2640
|
if(pISOString.substr(-6,1)=="+"){// Make the offset negative since the hours will need to be subtracted from the date.
|
|
1971
2641
|
tmpTimeZoneOffsetInHours*=-1;}}// Get the current hours for the date and add the offset to get the correct time adjusted for timezone.
|
|
1972
2642
|
tmpReturnDate.setHours(tmpReturnDate.getHours()+tmpTimeZoneOffsetInHours);// Return the Date object calculated from the string.
|
|
1973
|
-
return tmpReturnDate;}}module.exports=FableServiceUtility;},{"../Fable-ServiceManager.js":
|
|
2643
|
+
return tmpReturnDate;}}module.exports=FableServiceUtility;},{"../Fable-ServiceManager.js":89,"async.eachlimit":1,"async.waterfall":15}]},{},[88])(88);});
|