Input: Creates an Entity in the module which is defined by the apx from the given entity definition The entity is then stored in EntCache ( the location of all in Memory entities ) [CODESPLIT] async function genEntity ( par , fun = _ => log . e ( _ ) ) { if ( ! ( 'Entity' in par ) ) { fun ( 'No Entity defined in Par' ) ; return ; } par . Pid = par . Pid || genPid ( ) ; let impkey = ( par . Module + '/' + par . Entity ) ; let mod = ModCache [ par . Module ] ; if ( ! ( par . Entity in mod . files ) ) { log . e ( '<' + par . Entity + '> not in module <' + par . Module + '>' ) ; fun ( 'Null entity' ) ; return ; } if ( ! ( impkey in ImpCache ) ) { let entString = await new Promise ( async ( res , _rej ) => { mod . file ( par . Entity ) . async ( 'string' ) . then ( ( string ) => res ( string ) ) ; } ) ; ImpCache [ impkey ] = indirectEvalImp ( impkey , entString , log , createRequireFromModuleType ( par . Module ) ) ; } EntCache [ par . Pid ] = new Volatile ( new Entity ( Nxs , ImpCache [ impkey ] , par , log ) ) ; fun ( null , par . Pid ) ; }


Input: Delete an entity from the module s memory . If the entity is an Apex of a Module then delete all the entities found in that module as well . [CODESPLIT] function deleteEntity ( pid , fun = ( err , _pid ) => { if ( err ) log . e ( err ) ; } ) { cacheInterface . deleteEntity ( pid , ( err , removedPidArray ) => { //remove ent from EntCache (in RAM) for ( let i = 0 ; i < removedPidArray . length ; i ++ ) { let entPid = removedPidArray [ i ] ; if ( entPid in EntCache ) { delete EntCache [ entPid ] ; } } log . v ( ` ${ ( removedPidArray . length == 1 ) ? 'Entity' : 'Entities' } ${ removedPidArray . join ( ' ' ) } ` ) ; fun ( err , pid ) ; } ) ; }


Input: Save an entity file . Make sure that all nested files exist in the cache prior to saving said file [CODESPLIT] async function saveEntity ( par , fun = ( err , _pid ) => { if ( err ) log . e ( err ) ; } ) { let saveEntity = ( async ( par ) => { await new Promise ( ( res , rej ) => { cacheInterface . saveEntityPar ( par , ( err , pid ) => { if ( err ) { log . e ( err , 'saving ' , pid ) ; rej ( err ) ; } log . v ( ` ${ par . Pid } ` ) ; res ( ) ; } ) ; } ) ; } ) ; //check if the entity is the modules Apex if ( par . Pid != par . Apex ) { //check if the Apex exists in the cache cacheInterface . getEntityPar ( par . Apex , async ( err ) => { if ( err ) { //get the Apex's par from the EntCache let apexPar = await new Promise ( ( res , _rej ) => { EntCache [ par . Apex ] . lock ( ( entityContext ) => { res ( entityContext . Par ) ; return entityContext ; } ) ; } ) ; log . v ( 'Must first save the Apex -- Saving...' ) ; await saveEntity ( apexPar ) ; await saveEntity ( par ) ; fun ( null , par . Pid ) ; } else { //this entity is not the apex and the apex is alread in the cache await saveEntity ( par ) ; fun ( null , par . Pid ) ; } } ) ; } else { await saveEntity ( par ) ; fun ( null , par . Pid ) ; } }


Input: Add a module into the in memory Module Cache ( ModCache ) [CODESPLIT] async function addModule ( modName , modZip , fun ) { //modZip is the uint8array that can be written directly to the cache directory if ( checkFlag ( 'allow-add-module' ) ) { try { let newModname = await cacheInterface . addModule ( modName , modZip ) ; fun ( null , newModname ) ; } catch ( e ) { fun ( e , modName ) ; } } else { let err = 'addModule not permitted in current xGraph process\n' + 'run xgraph with --allow-add-module to enable' ; log . w ( err ) ; fun ( err ) ; } }


Input: Access a file that exists in the module . json [CODESPLIT] function getFile ( module , filename , fun = _ => _ ) { let mod = ModCache [ module ] ; if ( filename in mod . files ) { mod . file ( filename ) . async ( 'string' ) . then ( ( dat ) => { fun ( null , dat ) ; } ) ; return ; } let err = ` ${ filename } ${ module } ` ; log . e ( err ) ; fun ( err ) ; }


Input: Spin up an entity from cache into memory and retrievd its context otherwise just return it s context from memory [CODESPLIT] async function getEntityContext ( pid , fun = _ => _ ) { EntCache [ pid ] = new Volatile ( { } ) ; await EntCache [ pid ] . lock ( ( _entityContext ) => { return new Promise ( ( res , _rej ) => { cacheInterface . getEntityPar ( pid , ( err , data ) => { let par = JSON . parse ( data . toString ( ) ) ; if ( err ) { log . e ( ` ${ data . moduleType } ${ pid } ` ) ; log . e ( err ) ; fun ( 'Unavailable' ) ; return ; } let impkey = par . Module + '/' + par . Entity ; if ( impkey in ImpCache ) { BuildEnt ( ) ; return ; } GetModule ( par . Module , async function ( err , mod ) { if ( err ) { log . e ( 'Module <' + par . Module + '> not available' ) ; fun ( 'Module not available' ) ; return ; } if ( ! ( par . Entity in mod . files ) ) { log . e ( '<' + par . Entity + '> not in module <' + par . Module + '>' ) ; fun ( 'Null entity' ) ; return ; } let entString = await new Promise ( async ( res , _rej ) => { mod . file ( par . Entity ) . async ( 'string' ) . then ( ( string ) => res ( string ) ) ; } ) ; log . v ( ` ${ par . Module } ${ par . Entity . split ( '.' ) [ 0 ] } ` ) ; ImpCache [ impkey ] = indirectEvalImp ( impkey , entString , log , createRequireFromModuleType ( par . Module ) ) ; BuildEnt ( ) ; } ) ; function BuildEnt ( ) { // TODO: rethink the whole process of having to call out a setup and start res ( new Entity ( Nxs , ImpCache [ impkey ] , par , log ) ) ; } } ) ; } ) ; } ) ; fun ( null , EntCache [ pid ] ) ; }


Input:
Starts an instance of a module that exists in the cache . After generating the instance Apex receives a setup and start command synchronously [CODESPLIT] async function genModule ( moduleDefinition , fun = _ => _ ) { moduleDefinition = JSON . parse ( JSON . stringify ( moduleDefinition ) ) ; let moduleDefinitions = moduleDefinition ; if ( 'Module' in moduleDefinition && ( typeof moduleDefinition . Module == 'string' ) ) { moduleDefinitions = { 'Top' : moduleDefinition } ; } let Setup = { } ; let Start = { } ; let PromiseArray = [ ] ; let symbols = { } ; // loop over the keys to assign pids to the local dictionary and the // module definitions (moduleDefinitions) for ( let key in moduleDefinitions ) { symbols [ key ] = genPid ( ) ; } //compile each module for ( let moduleKey in moduleDefinitions ) { //do a GetModule and compile instance for each  PromiseArray . push ( new Promise ( ( res , _rej ) => { let inst = moduleDefinitions [ moduleKey ] ; GetModule ( inst . Module , async function ( err , mod ) { if ( err ) { log . e ( 'GenModule err -' , err ) ; fun ( err ) ; return ; } let pidapx = symbols [ moduleKey ] ; for ( let key in inst . Par ) { let val = inst . Par [ key ] ; if ( typeof val == 'string' ) { if ( val . startsWith ( '$' ) ) { let symbol = val . substr ( 1 ) ; if ( symbol in symbols ) { inst . Par [ key ] = symbols [ symbol ] ; } else { log . w ( ` ${ symbol } ` ) ; log . v ( ` ${ Object . keys ( symbols ) } ` ) ; } } if ( val . startsWith ( '\\' ) ) { let escaping = val . charAt ( 1 ) ; if ( escaping == '$' || escaping == '\\' ) { //these are valid escape character inst . Par [ key ] = val . substr ( 1 ) ; } else { //invalid log . w ( ` \\ ${ escaping } ` ) ; } } } else { inst . Par [ key ] = val ; } } await compileInstance ( pidapx , inst ) ; let schema = await new Promise ( async ( res , _rej ) => { if ( 'schema.json' in mod . files ) { mod . file ( 'schema.json' ) . async ( 'string' ) . then ( function ( schemaString ) { res ( JSON . parse ( schemaString ) ) ; } ) ; } else { log . e ( 'Module <' + inst . Module + '> schema not in ModCache' ) ; res ( ) ; return ; } } ) ; if ( '$Setup' in schema . Apex ) Setup [ pidapx ] = schema . Apex [ '$Setup' ] ; if ( '$Start' in schema . Apex ) Start [ pidapx ] = schema . Apex [ '$Start' ] ; res ( ) ; } ) ; } ) ) ; } await Promise . all ( PromiseArray ) ; log . v ( 'Modules' , JSON . stringify ( symbols , null , 2 ) ) ; log . v ( 'Setup' , JSON . stringify ( Setup , null , 2 ) ) ; log . v ( 'Start' , JSON . stringify ( Start , null , 2 ) ) ; await setup ( ) ; await start ( ) ; fun ( null , ( 'Top' in symbols ) ? symbols [ 'Top' ] : null , symbols ) ; /**
			 * Call setup on the required Module Apexes
			 */ async function setup ( ) { //build the setup promise array let setupArray = [ ] ; for ( let pid in Setup ) { setupArray . push ( new Promise ( ( resolve , _reject ) => { let com = { } ; com . Cmd = Setup [ pid ] ; com . Passport = { } ; com . Passport . To = pid ; com . Passport . Pid = genPid ( ) ; sendMessage ( com , resolve ) ; } ) ) ; } await Promise . all ( setupArray ) ; } /**
				 * Call Start on the required Module Apexes
				 */ async function start ( ) { //build the setup promise array let startArray = [ ] ; for ( let pid in Start ) { startArray . push ( new Promise ( ( resolve , _reject ) => { let com = { } ; com . Cmd = Start [ pid ] ; com . Passport = { } ; com . Passport . To = pid ; com . Passport . Pid = genPid ( ) ; sendMessage ( com , resolve ) ; } ) ) ; } await Promise . all ( startArray ) ; } }


Input: Generate array of entities from module Module must be in cache [CODESPLIT] async function compileInstance ( pidapx , inst , saveRoot = false ) { log . v ( 'compileInstance' , pidapx , JSON . stringify ( inst , null , 2 ) ) ; let Local = { } ; let modnam = ( typeof inst . Module == 'object' ) ? inst . Module . Module : inst . Module ; let mod ; let ents = [ ] ; modnam = modnam . replace ( / :\/ / g , '.' ) ; if ( modnam in ModCache ) { mod = ModCache [ modnam ] ; } else { log . e ( 'Module <' + modnam + '> not in ModCache' ) ; process . exit ( 1 ) ; return ; } let schema = await new Promise ( async ( res , rej ) => { if ( 'schema.json' in mod . files ) { mod . file ( 'schema.json' ) . async ( 'string' ) . then ( function ( schemaString ) { res ( JSON . parse ( schemaString ) ) ; } ) ; } else { log . e ( 'Module <' + modnam + '> schema not in ModCache' ) ; process . exit ( 1 ) ; rej ( ) ; return ; } } ) ; let entkeys = Object . keys ( schema ) ; //set Pids for each entity in the schema for ( let j = 0 ; j < entkeys . length ; j ++ ) { let entkey = entkeys [ j ] ; if ( entkey === 'Apex' ) { Local [ entkey ] = pidapx ; } else { Local [ entkey ] = genPid ( ) ; } } //unpack the par of each ent for ( let j = 0 ; j < entkeys . length ; j ++ ) { let entkey = entkeys [ j ] ; //start with the pars from the schema let ent = schema [ entkey ] ; ent . Pid = Local [ entkey ] ; ent . Module = modnam ; ent . Apex = pidapx ; //unpack the inst pars to the par of the apex of the instance if ( entkey == 'Apex' && 'Par' in inst ) { let pars = Object . keys ( inst . Par ) ; for ( let ipar = 0 ; ipar < pars . length ; ipar ++ ) { let par = pars [ ipar ] ; ent [ par ] = inst . Par [ par ] ; } } //pars all values for symbols let pars = Object . keys ( ent ) ; for ( let ipar = 0 ; ipar < pars . length ; ipar ++ ) { let par = pars [ ipar ] ; let val = ent [ par ] ; if ( entkey == 'Apex' && saveRoot ) { // if (par == '$Setup') { Setup[ent.Pid] = val; } // if (par == '$Start') { Start[ent.Pid] = val; } } ent [ par ] = await symbol ( val ) ; } ents . push ( ent ) ; } let entsPromise = [ ] ; for ( let par of ents ) { entsPromise . push ( ( async function ( ) { let impkey = modnam + '/' + par . Entity ; if ( ! ( impkey in ImpCache ) ) { let entString = await new Promise ( async ( res , _rej ) => { if ( ! ( par . Entity in mod . files ) ) { log . e ( 'Entity <' + par . Entity + '> not in Module <' + modnam + '>' ) ; process . exit ( 1 ) ; return ; } mod . file ( par . Entity ) . async ( 'string' ) . then ( ( string ) => res ( string ) ) ; } ) ; ImpCache [ impkey ] = indirectEvalImp ( impkey , entString , log , createRequireFromModuleType ( modnam ) ) ; } EntCache [ par . Pid ] = new Volatile ( new Entity ( Nxs , ImpCache [ impkey ] , par , log ) ) ; cacheInterface . EntIndex [ par . Pid ] = par . Apex ; } ) ( ) ) ; } await Promise . all ( entsPromise ) ; async function symbol ( val ) { if ( typeof val === 'object' ) { if ( Array . isArray ( val ) ) { val . map ( v => symbol ( v ) ) ; val = await Promise . all ( val ) ; } else { for ( let key in val ) { val [ key ] = await symbol ( val [ key ] ) ; } } return val ; } if ( typeof val !== 'string' ) return val ; let sym = val . substr ( 1 ) ; if ( val . charAt ( 0 ) === '#' && sym in Local ) return Local [ sym ] ; if ( val . charAt ( 0 ) === '\\' ) return sym ; return val ; } }


Input: For retrieving modules Modules come from the cache directory on the harddrive or the ModCache if its already been read to RAM . [CODESPLIT] function GetModule ( ModName , fun = _ => _ ) { ModName = ModName . replace ( / :\/ / g , '.' ) ; if ( ModName in ModCache ) return fun ( null , ModCache [ ModName ] ) ; else cacheInterface . getModule ( ModName , ( err , moduleZip ) => { if ( err ) return fun ( err ) ; ModCache [ ModName ] = moduleZip ; return fun ( null , ModCache [ ModName ] ) ; } ) ; }


Input: Strategy constructor . [CODESPLIT] function Strategy ( options , verify ) { var supportedApiVersions = [ '1' , '2' ] , defaultOptionsByApiVersion = { 1 : { authorizationURL : 'https://www.dropbox.com/1/oauth2/authorize' , tokenURL : 'https://api.dropbox.com/1/oauth2/token' , scopeSeparator : ',' , customHeaders : { } } , 2 : { authorizationURL : 'https://www.dropbox.com/oauth2/authorize' , tokenURL : 'https://api.dropbox.com/oauth2/token' , scopeSeparator : ',' , customHeaders : { 'Content-Type' : 'application/json' } } } ; options = options || { } ; if ( options . apiVersion != null && supportedApiVersions . indexOf ( options . apiVersion . toString ( ) ) === - 1 ) { throw new Error ( 'Unsupported Dropbox API version. Supported versions are "1" and "2".' ) ; } this . _apiVersion = options . apiVersion || '1' ; options . authorizationURL = options . authorizationURL || defaultOptionsByApiVersion [ this . _apiVersion ] . authorizationURL ; options . tokenURL = options . tokenURL || defaultOptionsByApiVersion [ this . _apiVersion ] . tokenURL ; options . scopeSeparator = options . scopeSeparator || defaultOptionsByApiVersion [ this . _apiVersion ] . scopeSeparator ; options . customHeaders = options . customHeaders || defaultOptionsByApiVersion [ this . _apiVersion ] . customHeaders ; OAuth2Strategy . call ( this , options , verify ) ; this . name = 'dropbox-oauth2' ; }


Input: //////////////////////////////////////////////////////////// Only helper functions defined below in this scope [CODESPLIT] async function retrieveModules ( modules ) { modules = JSON . parse ( JSON . stringify ( modules ) ) ; const xgrls = [ ] ; for ( const moduleName in modules ) { const xgrl = Config . Sources [ modules [ moduleName ] . Source ] ; if ( xgrls . indexOf ( xgrl ) === - 1 ) xgrls . push ( xgrl ) ; modules [ moduleName ] . Source = xgrl } // console.dir(xgrls); let promises = [ ] ; for ( const xgrl of xgrls ) { promises . push ( new Promise ( async ( res ) => { let broker ; if ( xgrl in BrokerCache ) { broker = BrokerCache [ xgrl ] ; } else { const timer = log . time ( 'Booting Broker' ) ; broker = new Broker ( xgrl , { ... __options } ) ; BrokerCache [ xgrl ] = broker ; await broker . startup ; log . timeEnd ( timer ) ; } const modulePromises = [ ] ; for ( const moduleName in modules ) { if ( modules [ moduleName ] . Source === xgrl ) { // console.log(`${moduleName} => ${xgrl}`); modulePromises . push ( new Promise ( async ( res ) => { ModCache [ moduleName ] = await broker . getModule ( { Module : moduleName , Version : modules [ moduleName ] . Version || undefined } ) ; res ( ) ; } ) ) } } await Promise . all ( modulePromises ) ; res ( ) ; } ) ) } await Promise . all ( promises ) ; return ; }


Input: Reads in the given config and fills in the Sources Macros [CODESPLIT] function processSources ( cfg ) { if ( typeof cfg [ 'Sources' ] === 'undefined' ) { log . e ( 'You must defined a Sources object.\n' ) ; rejectSetup ( 'You must defined a Sources object.' ) ; return ; } let val , sources , subval ; for ( let key in cfg ) { val = cfg [ key ] ; if ( key == 'Sources' ) { Config . Sources = { } ; sources = cfg [ 'Sources' ] ; for ( let subkey in sources ) { subval = sources [ subkey ] ; switch ( typeof subval ) { case 'string' : { Config . Sources [ subkey ] = Macro ( subval ) ; break ; } case 'object' : { Config . Sources [ subkey ] = { } ; for ( let id in subval ) { Config . Sources [ subkey ] [ id . toLowerCase ( ) ] = ( typeof subval [ id ] == 'string' ) ? Macro ( subval [ id ] ) : subval [ id ] ; } if ( ! ( 'port' in Config . Sources [ subkey ] ) ) { Config . Sources [ subkey ] [ 'port' ] = 27000 ; } break ; } default : { log . e ( ` ${ subkey } ${ typeof subval } ` + 'Must be of type string or object' ) ; } } } } else { Config [ key ] = val ; } } }


Input:
Create a list of all required modules and their brokers [CODESPLIT] function generateModuleCatalog ( ) { // Create new cache and install high level // module subdirectories. Each of these also // has a link to the source of that module (Module.json). let keys = Object . keys ( Config . Modules ) ; for ( let i = 0 ; i < keys . length ; i ++ ) { let key = keys [ i ] ; if ( key == 'Deferred' ) { let arr = Config . Modules [ 'Deferred' ] ; for ( let idx = 0 ; idx < arr . length ; idx ++ ) { let mod = arr [ idx ] ; log . v ( ` ${ mod . Module || mod } ` ) ; if ( typeof mod == 'string' ) { log . w ( 'Adding Module names directly to Deferred is deprecated' ) ; log . w ( ` ${ mod } ` ) ; mod = { Module : mod } ; } if ( ! ( 'Module' in mod ) ) { log . e ( 'Malformed Deferred Module listing' , mod ) ; rejectSetup ( 'Malformed Deferred Module listing' ) ; return ; } logModule ( key , mod ) ; } } else { if ( typeof Config . Modules [ key ] . Module != 'string' ) { log . e ( 'Malformed Module Definition' ) ; log . e ( JSON . stringify ( Config . Modules [ key ] , null , 2 ) ) ; } logModule ( key , Config . Modules [ key ] ) ; } } /**
					 * Add the module to the Modules object if unique
					 * @param {object} mod 		The module object
					 * @param {string} mod.Module	The name of the module
					 * @param {object, string} mod.Source The Module broker or path reference
					 */ function logModule ( key , mod ) { let folder = mod . Module . replace ( / [/:] / g , '.' ) ; if ( ! ( 'Source' in mod ) ) { log . e ( ` ${ key } ${ mod . Module } ` ) ; rejectSetup ( ` ${ key } ` ) ; return ; } let source = { Source : mod . Source , Version : mod . Version } ; if ( ! ( folder in Modules ) ) { Modules [ folder ] = source ; } else { if ( Modules [ folder ] . Source != source . Source || ( Modules [ folder ] . Version != source . Version ) ) { log . e ( ` ${ key } \n ` + ` ${ JSON . stringify ( Modules [ folder ] , null , 2 ) } ` + ` \n ${ JSON . stringify ( source , null , 2 ) } ` ) ; rejectSetup ( 'Broker Mismatch Exception' ) ; return ; } } } }


Input: Add the module to the Modules object if unique [CODESPLIT] function logModule ( key , mod ) { let folder = mod . Module . replace ( / [/:] / g , '.' ) ; if ( ! ( 'Source' in mod ) ) { log . e ( ` ${ key } ${ mod . Module } ` ) ; rejectSetup ( ` ${ key } ` ) ; return ; } let source = { Source : mod . Source , Version : mod . Version } ; if ( ! ( folder in Modules ) ) { Modules [ folder ] = source ; } else { if ( Modules [ folder ] . Source != source . Source || ( Modules [ folder ] . Version != source . Version ) ) { log . e ( ` ${ key } \n ` + ` ${ JSON . stringify ( Modules [ folder ] , null , 2 ) } ` + ` \n ${ JSON . stringify ( source , null , 2 ) } ` ) ; rejectSetup ( 'Broker Mismatch Exception' ) ; return ; } } }


Input: Write the modules and all instances to the cache [CODESPLIT] async function buildApexInstances ( processPidReferences ) { if ( processPidReferences ) { // Assign pids to all instance in Config.Modules for ( let instname in Config . Modules ) { if ( instname == 'Deferred' ) continue ; Apex [ instname ] = genPid ( ) ; } log . v ( 'Apex List' , JSON . stringify ( Apex , null , 2 ) ) ; } // Now populate all of the modules from config.json for ( let instname in Config . Modules ) { if ( instname === 'Deferred' ) continue ; await processApexPar ( Apex [ instname ] , Config . Modules [ instname ] , processPidReferences ) ; } }


Input: ---------------------------------------------------- CompileModule [CODESPLIT] async function processApexPar ( apx , inst , processPidReferences ) { inst = symbolPhase0 ( inst ) ; if ( processPidReferences ) inst . Par = await symbolPhase1 ( inst . Par ) ; inst . Par = await symbolPhase2 ( inst . Par ) ; inst . Par = await symbolPhase3 ( inst . Par ) ; return ; //process {} references function symbolPhase0 ( obj ) { for ( let key in obj ) { if ( typeof obj [ key ] == 'string' ) obj [ key ] = Macro ( obj [ key ] ) ; else if ( typeof obj [ key ] == 'object' ) obj [ key ] = symbolPhase0 ( obj [ key ] ) ; } return obj ; } //process $ references  async function symbolPhase1 ( val ) { if ( typeof val === 'object' ) { if ( Array . isArray ( val ) ) { val = await Promise . all ( val . map ( v => symbolPhase1 ( v ) ) ) ; } else { for ( let key in val ) { val [ key ] = await symbolPhase1 ( val [ key ] ) ; } } return val ; } if ( typeof val !== 'string' ) return val ; let sym = val . substr ( 1 ) ; if ( val . charAt ( 0 ) === '$' ) { if ( sym in Apex ) return Apex [ sym ] ; else { log . v ( sym , Apex ) ; log . e ( ` ${ val } ` ) ; rejectSetup ( ` ${ val } ` ) ; return ; } } return val ; } //process @ system directives async function symbolPhase2 ( val ) { if ( typeof val === 'object' ) { if ( Array . isArray ( val ) ) { val = await Promise . all ( val . map ( v => symbolPhase2 ( v ) ) ) ; } else { for ( let key in val ) { val [ key ] = await symbolPhase2 ( val [ key ] ) ; } } return val ; } if ( typeof val !== 'string' || ( ! val . startsWith ( '@' ) ) ) return val ; let [ directive , path ] = val . split ( ':' ) . map ( v => v . toLocaleLowerCase ( ) . trim ( ) ) ; if ( directive == '@system' ) { let directiveTimer = log . time ( val ) ; let stepTimer = log . time ( 'fs' ) ; let systemPath = Params . config ? Path . dirname ( Params . config ) : CWD ; if ( ! ( Path . isAbsolute ( path ) ) ) { path = Path . join ( Path . resolve ( systemPath ) , path ) ; } let tempConfig ; if ( ! fs . existsSync ( path ) ) { rejectSetup ( ` ${ path } ` ) ; return ; } try { tempConfig = JSON . parse ( fs . readFileSync ( path ) ) ; } catch ( e ) { rejectSetup ( 'Specified configuration file is in an unparsable format.' ) ; return ; } log . timeEnd ( stepTimer ) ; //TODO parse out all $'s, replace with \\$ let systemObject ; try { systemObject = await setup ( tempConfig , false ) ; } catch ( e ) { rejectSetup ( ` ${ path } ` ) ; return ; } try { fs . mkdirSync ( Path . join ( CWD , 'Static' ) ) ; } catch ( e ) { log . v ( e ) ; } stepTimer = log . time ( 'bower' ) ; await new Promise ( async resolve => { // let zip = new jszip(); // let cacheBuffer = Buffer.from(systemObject.Cache, 'base64'); // zip.loadAsync(cacheBuffer).then(async (a) => { // 	for (let key in a.files) { // 		if (key === 'manifest.json') continue; for ( let moduleType in systemObject . ModCache ) { let modZip = new jszip ( ) ; // let moduleZipBinary = await zip.file(key).async('base64'); modZip = await new Promise ( ( res ) => { let modZipBuffer = Buffer . from ( systemObject . ModCache [ moduleType ] , 'base64' ) ; modZip . loadAsync ( modZipBuffer ) . then ( zip => { res ( zip ) ; } ) ; } ) ; if ( ! ( 'bower.json' in modZip . files ) ) continue ; let bowerjson = await modZip . file ( 'bower.json' ) . async ( 'string' ) ; let dependencies = JSON . parse ( bowerjson ) . dependencies ; let packageArray = [ ] ; for ( let bowerModuleName in dependencies ) { if ( dependencies [ bowerModuleName ] . indexOf ( '/' ) > 0 ) { packageArray . push ( ` ${ dependencies [ bowerModuleName ] } ` ) ; } else { packageArray . push ( ` ${ bowerModuleName } ` + ` ${ dependencies [ bowerModuleName ] } ` ) ; } await new Promise ( res => { proc . execSync ( 'bower install "--config.directory=' + ` ${ Path . join ( CWD , 'Static' , 'bower_components' ) } ${ packageArray . join ( '" "' ) } ` ) ; log . v ( ` ${ packageArray . join ( ', ' ) } ` ) ; res ( ) ; } ) ; } let bowerComponentsDir = Path . join ( CWD , 'Static' , 'bower_components' ) ; proc . execSync ( 'bower install "--config.directory=' + ` ${ bowerComponentsDir } ${ packageArray . join ( '" "' ) } ` ) ; log . v ( ` ${ packageArray . join ( ', ' ) } ` ) ; } resolve ( ) ; } ) ; log . timeEnd ( stepTimer ) ; stepTimer = log . time ( 'zip it' ) ; //zip up the ModCache for export to the browser or other subsystems let zip = await new Promise ( resolveZip => { let zip = new jszip ( ) ; let man = [ ] ; for ( let folder in systemObject . ModCache ) { let mod = Buffer . from ( systemObject . ModCache [ folder ] , 'base64' ) ; man . push ( folder ) ; zip . file ( folder , mod , { date : new Date ( 'April 2, 2010 00:00:01' ) //the date is required for zip consistency } ) ; } zip . file ( 'manifest.json' , JSON . stringify ( man ) , { date : new Date ( 'April 2, 2010 00:00:01' ) //the date is required for zip consistency } ) ; zip . generateAsync ( { type : 'base64' } ) . then ( function ( data ) { resolveZip ( { 'Config' : systemObject . Config , 'Cache' : data } ) ; } ) ; } ) ; log . timeEnd ( stepTimer ) ; log . timeEnd ( directiveTimer ) ; return zip ; } return val ; } //process @ files and directories  async function symbolPhase3 ( val ) { if ( typeof val === 'object' ) { if ( Array . isArray ( val ) ) { val = await Promise . all ( val . map ( v => symbolPhase3 ( v ) ) ) ; } else { for ( let key in val ) { val [ key ] = await symbolPhase3 ( val [ key ] ) ; } } return val ; } if ( typeof val !== 'string' || ( ! val . startsWith ( '@' ) ) ) return val ; if ( val . charAt ( 0 ) === '@' ) { let directive = val . substr ( 0 ) ; val = val . split ( ':' ) ; let key = val [ 0 ] . toLocaleLowerCase ( ) . trim ( ) ; let encoding = undefined ; if ( key . split ( ',' ) . length == 2 ) { key = key . split ( ',' ) [ 0 ] . trim ( ) ; let _encoding = key . split ( ',' ) [ 1 ] . trim ( ) ; } val = val . slice ( 1 ) . join ( ':' ) . trim ( ) ; let directiveTimer = log . time ( directive ) ; switch ( key ) { case '@filename' : case '@file' : { log . v ( ` ${ directive } ` ) ; let path ; try { let systemPath = Params . config ? Path . dirname ( Params . config ) : CWD ; if ( Path . isAbsolute ( val ) ) path = val ; else { path = Path . join ( Path . resolve ( systemPath ) , val ) ; } log . timeEnd ( directiveTimer ) ; return fs . readFileSync ( path ) . toString ( encoding ) ; } catch ( err ) { log . e ( '@file: (compileInstance) Error reading file ' , path ) ; log . w ( ` ${ inst . Module } ` ) ; } break ; } case '@folder' : case '@directory' : { log . v ( ` ${ directive } ` ) ; let dir ; try { let systemPath = Params . config ? Path . dirname ( Params . config ) : CWD ; if ( Path . isAbsolute ( val ) ) dir = val ; else dir = Path . join ( Path . resolve ( systemPath ) , val ) ; let _return = await buildDir ( dir ) ; log . timeEnd ( directiveTimer ) ; return _return ; } catch ( err ) { og . e ( 'Error reading directory ' , dir ) ; og . w ( ` ${ inst . Module } ` ) ; } break ; } default : { log . w ( ` ${ key } ` + ` ${ inst . Module } ` ) ; } } log . timeEnd ( directiveTimer ) ; } return val ; } }


Input: process {} references [CODESPLIT] function symbolPhase0 ( obj ) { for ( let key in obj ) { if ( typeof obj [ key ] == 'string' ) obj [ key ] = Macro ( obj [ key ] ) ; else if ( typeof obj [ key ] == 'object' ) obj [ key ] = symbolPhase0 ( obj [ key ] ) ; } return obj ; }


Input: process $ references [CODESPLIT] async function symbolPhase1 ( val ) { if ( typeof val === 'object' ) { if ( Array . isArray ( val ) ) { val = await Promise . all ( val . map ( v => symbolPhase1 ( v ) ) ) ; } else { for ( let key in val ) { val [ key ] = await symbolPhase1 ( val [ key ] ) ; } } return val ; } if ( typeof val !== 'string' ) return val ; let sym = val . substr ( 1 ) ; if ( val . charAt ( 0 ) === '$' ) { if ( sym in Apex ) return Apex [ sym ] ; else { log . v ( sym , Apex ) ; log . e ( ` ${ val } ` ) ; rejectSetup ( ` ${ val } ` ) ; return ; } } return val ; }


Input: process [CODESPLIT] async function symbolPhase2 ( val ) { if ( typeof val === 'object' ) { if ( Array . isArray ( val ) ) { val = await Promise . all ( val . map ( v => symbolPhase2 ( v ) ) ) ; } else { for ( let key in val ) { val [ key ] = await symbolPhase2 ( val [ key ] ) ; } } return val ; } if ( typeof val !== 'string' || ( ! val . startsWith ( '@' ) ) ) return val ; let [ directive , path ] = val . split ( ':' ) . map ( v => v . toLocaleLowerCase ( ) . trim ( ) ) ; if ( directive == '@system' ) { let directiveTimer = log . time ( val ) ; let stepTimer = log . time ( 'fs' ) ; let systemPath = Params . config ? Path . dirname ( Params . config ) : CWD ; if ( ! ( Path . isAbsolute ( path ) ) ) { path = Path . join ( Path . resolve ( systemPath ) , path ) ; } let tempConfig ; if ( ! fs . existsSync ( path ) ) { rejectSetup ( ` ${ path } ` ) ; return ; } try { tempConfig = JSON . parse ( fs . readFileSync ( path ) ) ; } catch ( e ) { rejectSetup ( 'Specified configuration file is in an unparsable format.' ) ; return ; } log . timeEnd ( stepTimer ) ; //TODO parse out all $'s, replace with \\$ let systemObject ; try { systemObject = await setup ( tempConfig , false ) ; } catch ( e ) { rejectSetup ( ` ${ path } ` ) ; return ; } try { fs . mkdirSync ( Path . join ( CWD , 'Static' ) ) ; } catch ( e ) { log . v ( e ) ; } stepTimer = log . time ( 'bower' ) ; await new Promise ( async resolve => { // let zip = new jszip(); // let cacheBuffer = Buffer.from(systemObject.Cache, 'base64'); // zip.loadAsync(cacheBuffer).then(async (a) => { // 	for (let key in a.files) { // 		if (key === 'manifest.json') continue; for ( let moduleType in systemObject . ModCache ) { let modZip = new jszip ( ) ; // let moduleZipBinary = await zip.file(key).async('base64'); modZip = await new Promise ( ( res ) => { let modZipBuffer = Buffer . from ( systemObject . ModCache [ moduleType ] , 'base64' ) ; modZip . loadAsync ( modZipBuffer ) . then ( zip => { res ( zip ) ; } ) ; } ) ; if ( ! ( 'bower.json' in modZip . files ) ) continue ; let bowerjson = await modZip . file ( 'bower.json' ) . async ( 'string' ) ; let dependencies = JSON . parse ( bowerjson ) . dependencies ; let packageArray = [ ] ; for ( let bowerModuleName in dependencies ) { if ( dependencies [ bowerModuleName ] . indexOf ( '/' ) > 0 ) { packageArray . push ( ` ${ dependencies [ bowerModuleName ] } ` ) ; } else { packageArray . push ( ` ${ bowerModuleName } ` + ` ${ dependencies [ bowerModuleName ] } ` ) ; } await new Promise ( res => { proc . execSync ( 'bower install "--config.directory=' + ` ${ Path . join ( CWD , 'Static' , 'bower_components' ) } ${ packageArray . join ( '" "' ) } ` ) ; log . v ( ` ${ packageArray . join ( ', ' ) } ` ) ; res ( ) ; } ) ; } let bowerComponentsDir = Path . join ( CWD , 'Static' , 'bower_components' ) ; proc . execSync ( 'bower install "--config.directory=' + ` ${ bowerComponentsDir } ${ packageArray . join ( '" "' ) } ` ) ; log . v ( ` ${ packageArray . join ( ', ' ) } ` ) ; } resolve ( ) ; } ) ; log . timeEnd ( stepTimer ) ; stepTimer = log . time ( 'zip it' ) ; //zip up the ModCache for export to the browser or other subsystems let zip = await new Promise ( resolveZip => { let zip = new jszip ( ) ; let man = [ ] ; for ( let folder in systemObject . ModCache ) { let mod = Buffer . from ( systemObject . ModCache [ folder ] , 'base64' ) ; man . push ( folder ) ; zip . file ( folder , mod , { date : new Date ( 'April 2, 2010 00:00:01' ) //the date is required for zip consistency } ) ; } zip . file ( 'manifest.json' , JSON . stringify ( man ) , { date : new Date ( 'April 2, 2010 00:00:01' ) //the date is required for zip consistency } ) ; zip . generateAsync ( { type : 'base64' } ) . then ( function ( data ) { resolveZip ( { 'Config' : systemObject . Config , 'Cache' : data } ) ; } ) ; } ) ; log . timeEnd ( stepTimer ) ; log . timeEnd ( directiveTimer ) ; return zip ; } return val ; }


Input: process [CODESPLIT] async function symbolPhase3 ( val ) { if ( typeof val === 'object' ) { if ( Array . isArray ( val ) ) { val = await Promise . all ( val . map ( v => symbolPhase3 ( v ) ) ) ; } else { for ( let key in val ) { val [ key ] = await symbolPhase3 ( val [ key ] ) ; } } return val ; } if ( typeof val !== 'string' || ( ! val . startsWith ( '@' ) ) ) return val ; if ( val . charAt ( 0 ) === '@' ) { let directive = val . substr ( 0 ) ; val = val . split ( ':' ) ; let key = val [ 0 ] . toLocaleLowerCase ( ) . trim ( ) ; let encoding = undefined ; if ( key . split ( ',' ) . length == 2 ) { key = key . split ( ',' ) [ 0 ] . trim ( ) ; let _encoding = key . split ( ',' ) [ 1 ] . trim ( ) ; } val = val . slice ( 1 ) . join ( ':' ) . trim ( ) ; let directiveTimer = log . time ( directive ) ; switch ( key ) { case '@filename' : case '@file' : { log . v ( ` ${ directive } ` ) ; let path ; try { let systemPath = Params . config ? Path . dirname ( Params . config ) : CWD ; if ( Path . isAbsolute ( val ) ) path = val ; else { path = Path . join ( Path . resolve ( systemPath ) , val ) ; } log . timeEnd ( directiveTimer ) ; return fs . readFileSync ( path ) . toString ( encoding ) ; } catch ( err ) { log . e ( '@file: (compileInstance) Error reading file ' , path ) ; log . w ( ` ${ inst . Module } ` ) ; } break ; } case '@folder' : case '@directory' : { log . v ( ` ${ directive } ` ) ; let dir ; try { let systemPath = Params . config ? Path . dirname ( Params . config ) : CWD ; if ( Path . isAbsolute ( val ) ) dir = val ; else dir = Path . join ( Path . resolve ( systemPath ) , val ) ; let _return = await buildDir ( dir ) ; log . timeEnd ( directiveTimer ) ; return _return ; } catch ( err ) { og . e ( 'Error reading directory ' , dir ) ; og . w ( ` ${ inst . Module } ` ) ; } break ; } default : { log . w ( ` ${ key } ` + ` ${ inst . Module } ` ) ; } } log . timeEnd ( directiveTimer ) ; } return val ; }


Input: Build an object to represent a directory [CODESPLIT] async function buildDir ( path ) { let dirObj = { } ; if ( fs . existsSync ( path ) ) { let files = fs . readdirSync ( path ) ; let itemPromises = [ ] ; for ( let file of files ) { itemPromises . push ( new Promise ( async ( resolve ) => { let curPath = path + '/' + file ; if ( fs . lstatSync ( curPath ) . isDirectory ( ) ) { // recurse dirObj [ file ] = await buildDir ( curPath ) ; resolve ( ) ; } else { fs . readFile ( curPath , function ( err , data ) { // log.v(curPath.length > 80 ? curPath.substr(0, 35)  // + ' ... ' + curPath.substr(-40, 40) : curPath); dirObj [ file ] = data . toString ( ) ; resolve ( ) ; } ) ; // dirObj[file] = fs.readFileSync(curPath).toString(encoding); } } ) ) ; } await Promise . all ( itemPromises ) ; return dirObj ; } }


Input: generate a 32 character hexidecimal pid [CODESPLIT] function genPid ( ) { if ( ! Uuid ) { // module.paths = [Path.join(Path.resolve(CacheDir), 'node_modules')]; Uuid = require ( 'uuid/v4' ) ; } let str = Uuid ( ) ; let pid = str . replace ( / - / g , '' ) . toUpperCase ( ) ; return pid ; }


Input: replace the {} macros passed throught the xgraph cli or __options object [CODESPLIT] function Macro ( str ) { str = str . substr ( 0 ) ; // copy for ( let option in __options ) { str = str . replace ( ` ${ option } ` , __options [ option ] ) ; } return str ; }


Input:
Writes the system to the cache [CODESPLIT] async function genesis ( system ) { log . i ( ' [Save Cache]' . padStart ( 80 , '=' ) ) ; log . i ( 'Genesis Compile Start:' ) ; let cacheState = null ; if ( fs . existsSync ( CacheDir ) ) cacheState = 'exists' ; cacheInterface = new CacheInterface ( { path : CacheDir , log } ) ; cleanCache ( ) ; log . i ( 'Saving modules and updating dependencies ...' ) ; await cacheModules ( system . ModCache ) ; if ( ! ( __options . state == 'updateOnly' ) ) { log . i ( 'Saving entities ...' ) ; await cacheApexes ( system . Apex , system . Config . Modules ) ; } Stop ( ) ; ///////////////////////////////////////////////////////////// // //	Only helper functions beyond this point of this scope // /**
			*  Remove the cache if it currently exists in the given directory
			*/ function cleanCache ( ) { // Remove the provided cache directory if ( __options . state == 'development' && cacheState ) { __options . state = 'updateOnly' ; return ; } log . v ( 'Removing the old cache.' ) ; cacheInterface . clean ( ) ; } /**
			 * Write the modules to the cache
			 * @param {Object} ModCache 	//the set of module zips required for this system
			 */ async function cacheModules ( ModCache ) { let timer = log . time ( 'cacheModules' ) ; let ModulePromiseArray = [ ] ; for ( let folder in ModCache ) { ModulePromiseArray . push ( new Promise ( async ( res ) => { await cacheInterface . addModule ( folder , ModCache [ folder ] ) ; log . v ( ` ${ folder } ` ) ; res ( ) ; } ) ) ; } await Promise . all ( ModulePromiseArray ) ; log . timeEnd ( timer ) ; } /**
			 * Write the module Apexes to the cache
			 * @param {Object} Apexes 						//The id:Pid of each apex
			 * @param {Object} ModuleDefinitions 	//the id:ModuleDefinition from Config
			 */ async function cacheApexes ( Apexes , ModuleDefinitions ) { let ModulePromiseArray = [ ] ; for ( let moduleId in Apexes ) { ModulePromiseArray . push ( await cacheInterface . createInstance ( ModuleDefinitions [ moduleId ] , Apexes [ moduleId ] ) ) ; } await Promise . all ( ModulePromiseArray ) ; } /**
			 * Resolves the main promise created during genesis call
			 */ async function Stop ( ) { log . i ( ` ${ new Date ( ) . toString ( ) } ` ) ; log . i ( ' [Finished]' . padStart ( 80 , '=' ) ) ; for ( const xgrl in BrokerCache ) { const broker = BrokerCache [ xgrl ] ; broker . cleanup ( ) ; } log . timeEnd ( compileTimer ) ; resolveMain ( ) ; } }


Input: /////////////////////////////////////////////////////////// Only helper functions beyond this point of this scope Remove the cache if it currently exists in the given directory [CODESPLIT] function cleanCache ( ) { // Remove the provided cache directory if ( __options . state == 'development' && cacheState ) { __options . state = 'updateOnly' ; return ; } log . v ( 'Removing the old cache.' ) ; cacheInterface . clean ( ) ; }


Input: Write the modules to the cache [CODESPLIT] async function cacheModules ( ModCache ) { let timer = log . time ( 'cacheModules' ) ; let ModulePromiseArray = [ ] ; for ( let folder in ModCache ) { ModulePromiseArray . push ( new Promise ( async ( res ) => { await cacheInterface . addModule ( folder , ModCache [ folder ] ) ; log . v ( ` ${ folder } ` ) ; res ( ) ; } ) ) ; } await Promise . all ( ModulePromiseArray ) ; log . timeEnd ( timer ) ; }


Input: Write the module Apexes to the cache [CODESPLIT] async function cacheApexes ( Apexes , ModuleDefinitions ) { let ModulePromiseArray = [ ] ; for ( let moduleId in Apexes ) { ModulePromiseArray . push ( await cacheInterface . createInstance ( ModuleDefinitions [ moduleId ] , Apexes [ moduleId ] ) ) ; } await Promise . all ( ModulePromiseArray ) ; }


Input: Resolves the main promise created during genesis call [CODESPLIT] async function Stop ( ) { log . i ( ` ${ new Date ( ) . toString ( ) } ` ) ; log . i ( ' [Finished]' . padStart ( 80 , '=' ) ) ; for ( const xgrl in BrokerCache ) { const broker = BrokerCache [ xgrl ] ; broker . cleanup ( ) ; } log . timeEnd ( compileTimer ) ; resolveMain ( ) ; }


Input: load protocol to access modules [CODESPLIT] function getProtocolModule ( protocol ) { return new Promise ( function ( resolve , reject ) { let cacheFilepath = path . join ( appdata , protocol ) ; if ( fs . existsSync ( cacheFilepath ) ) { return resolve ( JSON . parse ( fs . readFileSync ( cacheFilepath ) . toString ( ) ) ) ; } let options = { host : 'protocols.xgraphdev.com' , port : 443 , path : '/' + protocol , method : 'GET' , rejectUnauthorized : false , } ; let req = https . request ( options , function ( res ) { res . setEncoding ( 'utf8' ) ; let response = '' ; res . on ( 'data' , function ( chunk ) { response += chunk ; } ) ; res . on ( 'end' , _ => { try { resolve ( JSON . parse ( response ) ) ; try { fs . writeFileSync ( cacheFilepath , response ) ; } catch ( e ) { reject ( { code : 1 , text : ` ${ cacheFilepath } ` + '\n delete file and try again' } ) ; } } catch ( e ) { reject ( { code : 0 , text : 'try and retrieve locally' } ) ; } } ) ; } ) ; req . on ( 'error' , function ( e ) { log . e ( 'problem with request: ' + e . message ) ; reject ( { code : 1 , text : 'problem with request: ' + e . message } ) ; } ) ; // write data to request body req . end ( ) ; } ) ; }


Input: Recursive directory deletion [CODESPLIT] function remDir ( path ) { return ( new Promise ( async ( resolve , _reject ) => { if ( fs . existsSync ( path ) ) { let files = fs . readdirSync ( path ) ; let promiseArray = [ ] ; for ( let fileIndex = 0 ; fileIndex < files . length ; fileIndex ++ ) { promiseArray . push ( new Promise ( async ( resolve2 , _reject2 ) => { let curPath = path + '/' + files [ fileIndex ] ; if ( fs . lstatSync ( curPath ) . isDirectory ( ) ) { // recurse await remDir ( curPath ) ; resolve2 ( ) ; } else { // delete file log . v ( 'Removing Entity ' , files [ fileIndex ] . split ( '.' ) [ 0 ] ) ; fs . unlinkSync ( curPath ) ; resolve2 ( ) ; } } ) ) ; } //make sure all the sub files and directories have been removed; await Promise . all ( promiseArray ) ; log . v ( 'Removing Module Directory ' , path ) ; fs . rmdirSync ( path ) ; resolve ( ) ; } else { log . v ( 'trying to remove nonexistant path ' , path ) ; resolve ( ) ; } } ) ) ; }


Input: get mouse position [CODESPLIT] function getMousePosition ( e ) { var mouseObj = void 0 , originalEvent = e . originalEvent ? e . originalEvent : e ; mouseObj = 'changedTouches' in originalEvent && originalEvent . changedTouches ? originalEvent . changedTouches [ 0 ] : originalEvent ; // clientX, Y 쓰면 스크롤에서 문제 발생 return { clientX : mouseObj . pageX , clientY : mouseObj . pageY } ; }


Input: injects any LAN proxy servers into the request [CODESPLIT] function proxyRequest ( req , res , rule ) { var router , target , path ; injectProxyHeaders ( req , rule ) ; // rewrite the base path of the requested URL path = req . url . replace ( rule . regexp , rule . target . path ) ; if ( useGateway ) { // for HTTP LAN proxies, rewrite the request URL from a relative URL to an absolute URL // also add a header that can be inspected by the unit tests req . url = url . parse ( util . format ( '%s//%s:%s%s' , rule . target . protocol , rule . target . host , rule . target . port , path ) ) . href ; req . headers [ 'X-Forwarded-Url' ] = req . url ; // the proxy target is really the HTTP LAN proxy target = config . gateway ; logger . info ( 'proxy: %s %s --> %s:%s --> %s//%s:%s%s' , req . method , req . url , config . gateway . host , config . gateway . port , rule . target . protocol , rule . target . host , rule . target . port , path ) ; } else { target = rule . target ; logger . info ( 'proxy: %s %s --> %s//%s:%s%s' , req . method , req . url , rule . target . protocol , rule . target . host , rule . target . port , path ) ; req . url = path ; } var errorCallback = function errorCallback ( err , proxyRequest , proxyResponse ) { var status = 500 ; if ( proxyResponse !== undefined && proxyResponse !== null && proxyResponse . statusCode >= 400 ) { status = proxyResponse . statusCode ; } logger . error ( 'proxy: error - %s %s - %s' , proxyRequest . method , proxyRequest . url , err . message ) ; if ( res . status && typeof res . status === 'function' ) { res . status ( status ) . json ( { error : status , message : err . message } ) ; } } ; // get a ProxyServer from the cache router = createRouter ( target ) ; // proxy the request router . web ( req , res , errorCallback ) ; }


Input: factory method to cache / fetch HttpProxy instances [CODESPLIT] function createRouter ( target ) { var key = util . format ( '%s//%s:%s' , target . protocol , target . host , target . port ) , router = routers [ key ] , options ; // httpProxy.createProxyServer options // { //   target : <url string to be parsed with the url module> //   forward: <url string to be parsed with the url module> //   agent  : <object to be passed to http(s).request> //   ssl    : <object to be passed to https.createServer()> //   ws     : <true/false, if you want to proxy websockets> //   xfwd   : <true/false, adds x-forward headers> //   secure : <true/false, verify SSL certificate> //   toProxy: passes the absolute URL as the path (useful for proxying to proxies) // } if ( router === undefined || router === null ) { options = { xfwd : true , secure : ( target . protocol && target . protocol === 'https://' ) , target : key , prependPath : ( useGateway === true ) , toProxy : ( useGateway === true ) } ; router = httpProxy . createProxyServer ( options ) ; routers [ key ] = router ; } return router ; }


Input: support basic auth for LAN HTTP proxied connections if needed HACK : http - proxy uses node s http . request () . pipe () which doesn t properly support the options . auth setting like http . request . write () as of Node v0 . 10 . 24 so this copies the implementation of request . write () from http . request () SOURCE : https : // github . com / joyent / node / blob / 828f14556e0daeae7fdac08fceaa90952de63f73 / lib / _http_client . js#L84 - L88 [CODESPLIT] function injectAuthHeader ( req ) { if ( useGateway === true && typeof ( config . gateway . auth ) === 'string' && req . headers [ 'authorization' ] === undefined ) { req . headers [ 'authorization' ] = 'Basic ' + new Buffer ( config . gateway . auth ) . toString ( 'base64' ) ; } }


Input: inject any custom header values into a proxy request along with the x - forwarded - for x - forwarded - port and via headers [CODESPLIT] function injectProxyHeaders ( req , rule ) { // the HTTP host header is often needed by the target webserver config req . headers [ 'host' ] = rule . target . host + ( rule . target . originalPort ? util . format ( ':%d' , rule . target . originalPort ) : '' ) ; // document that this request was proxied req . headers [ 'via' ] = util . format ( 'http://%s:%s' , req . connection . address ( ) . address , req . connection . address ( ) . port ) ; // inject any custom headers as configured config . headers . forEach ( function ( header ) { var value = header . value , name = header . name ; if ( typeof ( value ) === 'function' ) { value = value . call ( undefined , req ) ; } if ( typeof ( value ) !== 'string' ) { value = '' ; } if ( typeof ( name ) === 'string' ) { req . headers [ name . toLowerCase ( ) ] = value ; } } ) ; injectAuthHeader ( req ) ; }


Input: reads a config file from either the config file specified on the command line or fallback to a file name json - proxy . config in the working directory return true if the file can be read otherwise return false [CODESPLIT] function parseFile ( filepath , config ) { var contents ; filepath = filepath || path . join ( process . cwd ( ) , '/json-proxy.json' ) ; // if we were passed a config file, read and parse it if ( fs . existsSync ( filepath ) ) { try { var data = fs . readFileSync ( filepath ) ; contents = JSON . parse ( data . toString ( ) ) ; config = parseConfig ( contents , config ) ; // replace the token $config_dir in the webroot arg if ( config . server . webroot && config . server . webroot . length > 0 ) { config . server . webroot = config . server . webroot . replace ( "$config_dir" , path . dirname ( filepath ) ) ; } } catch ( ex ) { throw new Error ( 'Cannot parse the config file "' + filepath + '": ' + ex ) ; } } return config ; }


Input: parse a config structure overriding any values in config [CODESPLIT] function parseConfig ( contents , config ) { contents . server = contents . server || { } ; contents . proxy = contents . proxy || { } ; if ( contents . proxy . gateway && typeof ( contents . proxy . gateway ) === "string" && contents . proxy . gateway . length > 0 ) { contents . proxy . gateway = parseGateway ( contents . proxy . gateway ) ; } contents . proxy . forward = parseConfigMap ( contents . proxy . forward , parseForwardRule ) ; contents . proxy . headers = parseConfigMap ( contents . proxy . headers , parseHeaderRule ) ; // override any values in the config object with values specified in the file; config . server . port = contents . server . port || config . server . port ; config . server . webroot = contents . server . webroot || config . server . webroot ; config . server . html5mode = contents . server . html5mode || config . server . html5mode ; config . proxy . gateway = contents . proxy . gateway || config . proxy . gateway ; config . proxy . forward = contents . proxy . forward || config . proxy . forward ; config . proxy . headers = contents . proxy . headers || config . proxy . headers ; return config ; }


Input: transform a config hash object into an array [CODESPLIT] function parseConfigMap ( map , callback ) { var result = [ ] ; if ( ! ( map instanceof Object ) ) { return map ; } for ( var property in map ) { if ( map . hasOwnProperty ( property ) ) { result . push ( callback ( property , map [ property ] ) ) ; } } return result ; }


Input: reads command line parameters [CODESPLIT] function parseCommandLine ( argv , config ) { if ( argv ) { // read the command line arguments if no config file was given parseCommandLineArgument ( argv . port , function ( item ) { config . server . port = item ; } ) ; parseCommandLineArgument ( argv . html5mode , function ( item ) { config . server . html5mode = item ; } ) ; parseCommandLineArgument ( argv . _ , function ( item ) { config . server . webroot = path . normalize ( item ) ; } ) ; parseCommandLineArgument ( argv . gateway , function ( item ) { config . proxy . gateway = parseGateway ( item ) ; } ) ; parseCommandLineArgument ( argv . forward , function ( item ) { var rule = parseForwardRule ( item ) ; var match = false ; config . proxy . forward . forEach ( function ( item ) { if ( item . regexp . source === rule . regexp . source ) { item . target = rule . target ; match = true ; } } ) ; if ( ! match ) { config . proxy . forward . push ( rule ) ; } } ) ; parseCommandLineArgument ( argv . header , function ( item ) { var rule = parseHeaderRule ( item ) ; var match = false ; config . proxy . headers . forEach ( function ( item ) { if ( item . name === rule . name ) { item . value = rule . value ; match = true ; } } ) ; if ( ! match ) { config . proxy . headers . push ( rule ) ; } } ) ; } return config ; }


Input: argv . X will be an array if multiple - X options are provided otherwise argv . X will just be a scalar value [CODESPLIT] function parseCommandLineArgument ( arg , fn ) { if ( typeof ( fn ) !== 'function' ) return ; if ( Array . isArray ( arg ) ) { arg . forEach ( function ( item ) { fn . call ( null , item ) ; } ) ; } else { if ( arg !== null && arg !== undefined ) { fn . call ( null , arg ) ; } } }


Input: parses rule syntax to create forwarding rules [CODESPLIT] function parseForwardRule ( ) { var token , rule ; if ( arguments [ 0 ] === undefined || arguments [ 0 ] === null ) { return ; } if ( typeof ( arguments [ 0 ] ) === "object" ) { return arguments [ 0 ] ; } try { token = tokenize . apply ( null , arguments ) ; rule = { regexp : new RegExp ( '^' + token . name , 'i' ) , target : parseTargetServer ( token . value ) } ; } catch ( e ) { throw new Error ( 'cannot parse the forwarding rule ' + arguments [ 0 ] + ' - ' + e ) ; } return rule ; }


Input: parses a simple hostname : port argument defaulting to port 80 if not specified [CODESPLIT] function parseTargetServer ( value ) { var target , path ; // insert a http protocol handler if not found in the string if ( value . indexOf ( 'http://' ) !== 0 && value . indexOf ( 'https://' ) !== 0 ) { value = 'http://' + value + '/' ; } target = url . parse ( value ) ; path = target . path ; // url.parse() will default to '/' as the path // we can safely strip this for regexp matches to function properly if ( path === '/' ) { path = '' ; } // support an explict set of regexp unnamed captures (prefixed with `$`) // if the pattern doesn't include a match operator like '$1', '$2', '$3', // then use the RegExp lastMatch operator `$&` if the rewrite rule if ( / \$\d / . test ( path ) === false ) { path = [ path , '$&' ] . join ( '' ) ; } return { host : target . hostname , // inject a default port if one wasn't specified port : target . port || ( ( target . protocol === 'https:' ) ? 443 : 80 ) , originalPort : target . port , protocol : target . protocol , path : path } ; }


Input: reads name / value tokens for command line parameters [CODESPLIT] function tokenize ( ) { var token = { name : null , value : null } , temp = null ; if ( arguments . length !== 1 ) { token . name = arguments [ 0 ] ; token . value = arguments [ 1 ] ; return token ; } temp = arguments [ 0 ] ; if ( undefined !== temp && null !== temp ) { temp = temp . split ( '=' ) ; } if ( Array . isArray ( temp ) && temp . length > 1 ) { token . name = temp [ 0 ] ; token . value = temp [ 1 ] ; } return token ; }


Input: Return an error with a specific code [CODESPLIT] function withCode ( code , msg ) { const err = new Error ( msg ) ; err . code = code ; return err ; }


Input: Change workinState for a specific branch [CODESPLIT] function updateWorkingState ( repoState , branch , newWorkingState ) { let workingStates = repoState . getWorkingStates ( ) ; const key = branch . getFullName ( ) ; if ( newWorkingState === null ) { // Delete workingStates = workingStates . delete ( key ) ; } else { // Update the entry in the map workingStates = workingStates . set ( key , newWorkingState ) ; } return repoState . set ( 'workingStates' , workingStates ) ; }


Input: Fetches the given branch s tree from its SHA and __resets any WorkingState for it__ [CODESPLIT] function fetchTree ( repoState , driver , branch ) { // Fetch a working tree for this branch return WorkingUtils . fetch ( driver , branch ) . then ( ( newWorkingState ) => { return updateWorkingState ( repoState , branch , newWorkingState ) ; } ) ; }


Input: Change current branch in the repository ( sync ) . Requires to have fetched the branch . [CODESPLIT] function checkout ( repoState , branch ) { let _branch = branch ; if ( ! ( branch instanceof Branch ) ) { _branch = repoState . getBranch ( branch ) ; if ( branch === null ) { throw Error ( 'Unknown branch ' + branch ) ; } } if ( ! repoState . isFetched ( _branch ) ) { throw Error ( 'Tree for branch ' + _branch . getFullName ( ) + ' must be fetched first' ) ; } return repoState . set ( 'currentBranchName' , _branch . getFullName ( ) ) ; }


Input: Fetch the list of branches in the repository and update them all . Will clear the WorkingStates of all branches that have updated . [CODESPLIT] function fetchBranches ( repoState , driver ) { const oldBranches = repoState . getBranches ( ) ; return driver . fetchBranches ( ) . then ( ( branches ) => { return repoState . set ( 'branches' , branches ) ; } ) . then ( function refreshWorkingStates ( repoState ) { // Remove outdated WorkingStates return oldBranches . reduce ( ( repoState , oldBranch ) => { const fullName = oldBranch . getFullName ( ) ; const newBranch = repoState . getBranch ( fullName ) ; if ( newBranch === null || newBranch . getSha ( ) !== oldBranch . getSha ( ) ) { // Was removed OR updated return updateWorkingState ( repoState , oldBranch , null ) ; } else { // Unchanged return repoState ; } } , repoState ) ; } ) ; }


Input: Initialize a new RepositoryState from the repo of a Driver . Fetch the branches and checkout master or the first available branch . [CODESPLIT] function initialize ( driver ) { const repoState = RepositoryState . createEmpty ( ) ; return fetchBranches ( repoState , driver ) . then ( ( repoState ) => { const branches = repoState . getBranches ( ) ; const master = branches . find ( function isMaster ( branch ) { return branch . getFullName ( ) === 'master' ; } ) ; const branch = master || branches . first ( ) ; return fetchTree ( repoState , driver , branch ) . then ( ( repoState ) => { return checkout ( repoState , branch ) ; } ) ; } ) ; }


Input: Force conversion to an arraybuffer [CODESPLIT] function enforceArrayBuffer ( b , encoding ) { if ( isArrayBuffer ( b ) ) return b ; else if ( isBuffer ( b ) ) return fromBuffer ( b ) ; else return fromString ( b , encoding ) ; }


Input: Force conversion to string with specific encoding [CODESPLIT] function enforceString ( b , encoding ) { if ( is . string ( b ) ) return b ; if ( isArrayBuffer ( b ) ) b = toBuffer ( b ) ; return b . toString ( encoding ) ; }


Input: Tests equality of two ArrayBuffer [CODESPLIT] function equals ( buf1 , buf2 ) { if ( buf1 . byteLength != buf2 . byteLength ) return false ; const dv1 = new Int8Array ( buf1 ) ; const dv2 = new Int8Array ( buf2 ) ; for ( let i = 0 ; i != buf1 . byteLength ; i ++ ) { if ( dv1 [ i ] != dv2 [ i ] ) return false ; } return true ; }


Input: ---- utils ---- [CODESPLIT] function getChange ( parent , sha ) { if ( parent === sha ) { return CHANGE . IDENTICAL ; } else if ( parent === null ) { return CHANGE . ADDED ; } else if ( sha === null ) { return CHANGE . DELETED ; } else { // Both are not null but different return CHANGE . MODIFIED ; } }


Input: Returns a Seq of tree mixing changes and the fetched tree [CODESPLIT] function getMergedFileSet ( workingState ) { return Immutable . Set . fromKeys ( getMergedTreeEntries ( workingState ) . filter ( treeEntry => treeEntry . getType ( ) === TreeEntry . TYPES . BLOB ) ) ; }


Input: Returns a Map of TreeEntry with sha null when the content is not available as sha . [CODESPLIT] function getMergedTreeEntries ( workingState ) { const removedOrModified = workingState . getChanges ( ) . groupBy ( ( change , path ) => { if ( change . getType ( ) === CHANGES . REMOVE ) { return 'remove' ; } else { // Must be UDPATE or CREATE return 'modified' ; } } ) ; const setToRemove = Immutable . Set . fromKeys ( removedOrModified . get ( 'remove' , [ ] ) ) ; const withoutRemoved = workingState . getTreeEntries ( ) . filter ( ( treeEntry , path ) => { return ! setToRemove . contains ( path ) ; } ) ; const addedTreeEntries = removedOrModified . get ( 'modified' , [ ] ) . map ( function toTreeEntry ( change ) { return new TreeEntry ( { sha : change . hasSha ( ) ? change . getSha ( ) : null , mode : '100644' } ) ; } ) ; return withoutRemoved . concat ( addedTreeEntries ) ; }


Input: Returns true if the file differs from initial tree ( including removed ) [CODESPLIT] function hasPendingChanges ( workingState , filepath ) { // Lookup potential changes const change = workingState . getChanges ( ) . get ( filepath ) ; if ( change ) { return true ; } else { // Else lookup tree const treeEntry = workingState . getTreeEntries ( ) . get ( filepath ) ; if ( ! treeEntry ) { throw error . fileNotFound ( filepath ) ; } else { return false ; } } }


Input: Attempts to find a SHA if available for the given file [CODESPLIT] function findSha ( workingState , filepath ) { // Lookup potential changes const change = workingState . getChanges ( ) . get ( filepath ) ; // Else lookup tree const treeEntry = workingState . getTreeEntries ( ) . get ( filepath ) ; if ( change ) { if ( change . getType ( ) == CHANGES . REMOVE ) { throw error . fileNotFound ( filepath ) ; } else { return change . getSha ( ) ; } } else if ( treeEntry ) { return treeEntry . getSha ( ) ; } else { throw error . fileNotFound ( filepath ) ; } }


Input: Create a commit builder from the changes on current branch [CODESPLIT] function prepare ( repoState , opts ) { const workingState = repoState . getCurrentState ( ) ; const changes = workingState . getChanges ( ) ; // Is this an empty commit ? opts . empty = workingState . isClean ( ) ; // Parent SHA opts . parents = new Immutable . List ( [ workingState . getHead ( ) ] ) ; // Get merged tree (with applied changes) opts . treeEntries = WorkingUtils . getMergedTreeEntries ( workingState ) ; // Create map of blobs that needs to be created opts . blobs = changes . filter ( ( change ) => { return ! change . hasSha ( ) ; } ) . map ( ( change ) => { return change . getContent ( ) ; } ) ; return CommitBuilder . create ( opts ) ; }


Input: Flush a commit from the current branch using a driver Then update the reference and pull new workingState [CODESPLIT] function flush ( repoState , driver , commitBuilder , options = { } ) { options = Object . assign ( { branch : repoState . getCurrentBranch ( ) , ignoreEmpty : true } , options ) ; if ( options . ignoreEmpty && commitBuilder . isEmpty ( ) && commitBuilder . getParents ( ) . count ( ) < 2 ) { return Q ( repoState ) ; } // Create new commit return driver . flushCommit ( commitBuilder ) // Forward the branch . then ( ( commit ) => { return driver . forwardBranch ( options . branch , commit . getSha ( ) ) // Fetch new workingState and replace old one . then ( function updateBranch ( ) { const updated = options . branch . merge ( { commit } ) ; return repoState . updateBranch ( options . branch , updated ) ; } , function nonFF ( err ) { if ( err . code === ERRORS . NOT_FAST_FORWARD ) { // Provide the created commit to allow merging it back. err . commit = commit ; } throw err ; } ) ; } ) . then ( function updateWorkingState ( forwardedRepoState ) { const forwardedBranch = forwardedRepoState . getBranch ( options . branch . getFullName ( ) ) ; return RepoUtils . fetchTree ( forwardedRepoState , driver , forwardedBranch ) ; } ) ; }


Input: colorize strings and send to console . log [CODESPLIT] function format ( color , messages ) { var length = messages . length ; if ( length === 0 || typeof ( color ) !== 'string' ) { return ; } return ( util . format . apply ( null , messages ) [ color ] ) ; }


Input: Push a local branch to a remote repository [CODESPLIT] function push ( repoState , driver , opts = { } ) { opts = Object . assign ( { branch : repoState . getCurrentBranch ( ) , force : false , remote : { name : 'origin' } } , opts ) ; return driver . push ( opts ) // Can fail with NOT_FAST_FORWARD // TODO update remote branch in repoState list of branches . thenResolve ( repoState ) ; }


Input: Pulls changes for local branch from remote repository . Loses any pending changes on it . [CODESPLIT] function pull ( repoState , driver , opts = { } ) { opts = Object . assign ( { branch : repoState . getCurrentBranch ( ) , force : false , remote : { name : 'origin' } } , opts ) ; return driver . pull ( opts ) // Update branch SHA . then ( ( ) => { return driver . fetchBranches ( ) ; } ) . then ( ( branches ) => { const updatedBranch = branches . find ( ( br ) => { return br . name === opts . branch . name ; } ) ; repoState = repoState . updateBranch ( opts . branch , updatedBranch ) ; return RepoUtils . fetchTree ( repoState , driver , updatedBranch ) ; } ) ; }


Input: Sync repository with remote by pulling / pushing to the remote . [CODESPLIT] function sync ( repoState , driver , opts = { } ) { opts = Object . assign ( { branch : repoState . getCurrentBranch ( ) , force : false , remote : { name : 'origin' } } , opts ) ; return pull ( repoState , driver , opts ) . fail ( ( err ) => { if ( err . code === ERRORS . REF_NOT_FOUND ) { return Promise ( repoState ) ; } return Promise . reject ( err ) ; } ) . then ( ( newRepoState ) => { return push ( newRepoState , driver , opts ) ; } ) ; }


Input: Computes a TreeConflict between to tree references . Fetches the trees from the repo . The list of conflicts is the minimal set of conflicts . [CODESPLIT] function compareRefs ( driver , base , head ) { const baseRef = base instanceof Branch ? base . getFullName ( ) : base ; const headRef = head instanceof Branch ? head . getFullName ( ) : head ; return driver . findParentCommit ( baseRef , headRef ) . then ( ( parentCommit ) => { // There can be no parent commit return Q . all ( [ parentCommit ? parentCommit . getSha ( ) : null , baseRef , headRef ] . map ( ( ref ) => { return ref ? driver . fetchWorkingState ( ref ) : WorkingState . createEmpty ( ) ; } ) ) ; } ) . spread ( ( parent , base , head ) => { const conflicts = _compareTrees ( parent . getTreeEntries ( ) , base . getTreeEntries ( ) , head . getTreeEntries ( ) ) ; return new TreeConflict ( { base , head , parent , conflicts } ) ; } ) ; }


Input: Merge solved Conflicts back into a TreeConflict . Unsolved conflicts default to keep base . [CODESPLIT] function solveTree ( treeConflict , solved ) { solved = treeConflict . getConflicts ( ) . merge ( solved ) // Solve unresolved conflicts . map ( function defaultSolve ( conflict ) { if ( ! conflict . isSolved ( ) ) { return conflict . keepBase ( ) ; } else { return conflict ; } } ) ; return treeConflict . set ( 'conflicts' , solved ) ; }


Input: Create a merge commit builder [CODESPLIT] function mergeCommit ( treeConflict , parents , options ) { options = options || { } ; const opts = { } ; // Assume the commit is not empty opts . empty = false ; // Parent SHAs opts . parents = new Immutable . List ( parents ) ; opts . author = options . author ; opts . message = options . message || 'Merged commit' ; // Get the solved tree entries const solvedEntries = _getSolvedEntries ( treeConflict ) ; opts . treeEntries = solvedEntries ; // Create map of blobs that needs to be created const solvedConflicts = treeConflict . getConflicts ( ) ; opts . blobs = solvedEntries . filter ( ( treeEntry ) => { return ! treeEntry . hasSha ( ) ; } ) . map ( ( treeEntry , path ) => { return solvedConflicts . get ( path ) . getSolvedContent ( ) ; } ) ; return CommitBuilder . create ( opts ) ; }


Input: ---- Auxiliaries ---- [CODESPLIT] function _compareTrees ( parentEntries , baseEntries , headEntries ) { const headDiff = _diffEntries ( parentEntries , headEntries ) ; const baseDiff = _diffEntries ( parentEntries , baseEntries ) ; // Conflicting paths are paths... // ... modified by both branches const headSet = Immutable . Set . fromKeys ( headDiff ) ; const baseSet = Immutable . Set . fromKeys ( baseDiff ) ; const conflictSet = headSet . intersect ( baseSet ) . filter ( ( filepath ) => { // ...in different manners return ! Immutable . is ( headDiff . get ( filepath ) , baseDiff . get ( filepath ) ) ; } ) ; // Create the map of Conflict return ( new Immutable . Map ( ) ) . withMutations ( ( map ) => { return conflictSet . reduce ( ( map , filepath ) => { const shas = [ parentEntries , baseEntries , headEntries ] . map ( function getSha ( entries ) { if ( ! entries . has ( filepath ) ) return null ; return entries . get ( filepath ) . getSha ( ) || null ; } ) ; return map . set ( filepath , Conflict . create . apply ( undefined , shas ) ) ; } , map ) ; } ) ; }


Input: Returns the final TreeEntries for a solved TreeConflict . [CODESPLIT] function _getSolvedEntries ( treeConflict ) { const parentEntries = treeConflict . getParent ( ) . getTreeEntries ( ) ; const baseEntries = treeConflict . getBase ( ) . getTreeEntries ( ) ; const headEntries = treeConflict . getHead ( ) . getTreeEntries ( ) ; const baseDiff = _diffEntries ( parentEntries , baseEntries ) ; const headDiff = _diffEntries ( parentEntries , headEntries ) ; const resolvedEntries = treeConflict . getConflicts ( ) . map ( ( solvedConflict ) => { // Convert to TreeEntries (or null for deletion) if ( solvedConflict . isDeleted ( ) ) { return null ; } else { return new TreeEntry ( { sha : solvedConflict . getSolvedSha ( ) || null } ) ; } } ) ; return parentEntries . merge ( baseDiff , headDiff , resolvedEntries ) // Remove deleted entries . filter ( function nonNull ( entry ) { return entry !== null ; } ) ; }


Input: Add a new blob to a cache instance [CODESPLIT] function addBlob ( cache , sha , blob ) { const blobs = cache . getBlobs ( ) ; const newBlobs = blobs . set ( sha , blob ) ; const newCache = cache . set ( 'blobs' , newBlobs ) ; return newCache ; }


Input: Utils to create tree structures for files . Convert a filepath to a Seq<String > to use as key path [CODESPLIT] function pathToKeySeq ( path ) { // Remove trailing '/' etc. path = Path . join ( path , '.' ) ; if ( path === '.' ) { return Immutable . Seq ( [ ] ) ; } else { return Immutable . Seq ( path . split ( '/' ) ) ; } }


Input: Generate a files tree from the current branch taking pending changes into account . [CODESPLIT] function get ( repoState , dirPath ) { // Remove trailing '/' etc. const normDirPath = Path . join ( dirPath , '.' ) ; const filepaths = DirUtils . readFilenamesRecursive ( repoState , normDirPath ) ; const tree = { value : File . createDir ( normDirPath ) , children : { } } ; for ( let i = 0 ; i < filepaths . length ; i ++ ) { const relativePath = Path . relative ( normDirPath , filepaths [ i ] ) ; const parts = relativePath . split ( '/' ) ; let node = tree ; let prefix = normDirPath ; for ( let j = 0 ; j < parts . length ; j ++ ) { const head = parts [ j ] ; const isLeaf = ( j === parts . length - 1 ) ; prefix = Path . join ( prefix , head ) ; // Create node if doesn't exist if ( ! node . children [ head ] ) { if ( isLeaf ) { node . children [ head ] = { value : FileUtils . stat ( repoState , filepaths [ i ] ) } ; } else { node . children [ head ] = { value : File . createDir ( prefix ) , children : { } } ; } } node = node . children [ head ] ; } } return TreeNode . fromJS ( tree ) ; }


Input: Normalize a commit coming from the GitHub commit creation API [CODESPLIT] function normCreatedCommit ( ghCommit ) { const commit = Commit . create ( { sha : ghCommit . sha , message : ghCommit . message , author : getSimpleAuthor ( ghCommit . author ) , date : ghCommit . author . date , parents : ghCommit . parents . map ( function getSha ( o ) { return o . sha ; } ) } ) ; return commit ; }


Input: Normalize a commit coming from the GitHub commit listing API [CODESPLIT] function normListedCommit ( ghCommit ) { const commit = Commit . create ( { sha : ghCommit . sha , message : ghCommit . commit . message , author : getCompleteAuthor ( ghCommit ) , date : ghCommit . commit . author . date , files : ghCommit . files , parents : ghCommit . parents . map ( c => c . sha ) } ) ; return commit ; }


Input: Get author from created commit ( no avatar ) [CODESPLIT] function getSimpleAuthor ( author ) { return Author . create ( { name : author . name , email : author . email , date : author . date } ) ; }


Input: Get author from a listed commit ( with avatar ) [CODESPLIT] function getCompleteAuthor ( commit ) { const author = getSimpleAuthor ( commit . commit . author ) ; const avatar = commit . author ? commit . author . avatar_url : gravatar . url ( author . getEmail ( ) ) ; return author . set ( 'avatar' , avatar ) ; }


Input: Fetch a file blob . Required for content access with stat / read . No - op if the file is already fetched . [CODESPLIT] function fetch ( repoState , driver , filepath ) { if ( isFetched ( repoState , filepath ) ) { // No op if already fetched return Q ( repoState ) ; } const workingState = repoState . getCurrentState ( ) ; const blobSha = WorkingUtils . findSha ( workingState , filepath ) ; return BlobUtils . fetch ( repoState , driver , blobSha ) ; }


Input: Stat details about a file . [CODESPLIT] function stat ( repoState , filepath ) { const workingState = repoState . getCurrentState ( ) ; // Lookup potential changes const change = workingState . getChanges ( ) . get ( filepath ) ; // Lookup file entry const treeEntry = workingState . getTreeEntries ( ) . get ( filepath ) ; // Determine SHA of the blob let blobSHA ; if ( change ) { blobSHA = change . getSha ( ) ; } else { blobSHA = treeEntry . getSha ( ) ; } // Get the blob from change or cache let blob ; if ( blobSHA ) { // Get content from cache blob = repoState . getCache ( ) . getBlob ( blobSHA ) ; } else { // No sha, so it must be in changes blob = change . getContent ( ) ; } let fileSize ; if ( blob ) { fileSize = blob . getByteLength ( ) ; } else { // It might have been moved (but not fetched) const originalEntry = workingState . getTreeEntries ( ) . find ( ( entry ) => { return entry . getSha ( ) === blobSHA ; } ) ; fileSize = originalEntry . getBlobSize ( ) ; } return new File ( { type : FILETYPE . FILE , fileSize , path : filepath , content : blob } ) ; }


Input: Read content of a file returns a String [CODESPLIT] function readAsString ( repoState , filepath , encoding ) { const blob = read ( repoState , filepath ) ; return blob . getAsString ( encoding ) ; }


Input: Return true if file exists in working tree false otherwise [CODESPLIT] function exists ( repoState , filepath ) { const workingState = repoState . getCurrentState ( ) ; const mergedFileSet = WorkingUtils . getMergedTreeEntries ( workingState ) ; return mergedFileSet . has ( filepath ) ; }


Input: Create a new file ( must not exists already ) [CODESPLIT] function create ( repoState , filepath , content ) { content = content || '' ; if ( exists ( repoState , filepath ) ) { throw error . fileAlreadyExist ( filepath ) ; } const change = Change . createCreate ( content ) ; return ChangeUtils . setChange ( repoState , filepath , change ) ; }


Input: Write a file ( must exists ) [CODESPLIT] function write ( repoState , filepath , content ) { if ( ! exists ( repoState , filepath ) ) { throw error . fileNotFound ( filepath ) ; } const change = Change . createUpdate ( content ) ; return ChangeUtils . setChange ( repoState , filepath , change ) ; }


Input: Remove a file [CODESPLIT] function remove ( repoState , filepath ) { if ( ! exists ( repoState , filepath ) ) { throw error . fileNotFound ( filepath ) ; } const change = Change . createRemove ( ) ; return ChangeUtils . setChange ( repoState , filepath , change ) ; }


Input: Rename a file [CODESPLIT] function move ( repoState , filepath , newFilepath ) { if ( filepath === newFilepath ) { return repoState ; } const initialWorkingState = repoState . getCurrentState ( ) ; // Create new file, with Sha if possible const sha = WorkingUtils . findSha ( initialWorkingState , filepath ) ; let changeNewFile ; if ( sha ) { changeNewFile = Change . createCreateFromSha ( sha ) ; } else { // Content not available as blob const blob = read ( repoState , filepath ) ; const contentBuffer = blob . getAsBuffer ( ) ; changeNewFile = Change . createCreate ( contentBuffer ) ; } // Remove old file const removedRepoState = remove ( repoState , filepath ) ; // Add new file return ChangeUtils . setChange ( removedRepoState , newFilepath , changeNewFile ) ; }


Input: Returns true if the given file has the same content in both RepositoryState s current working state or is absent from both . [CODESPLIT] function hasChanged ( previousState , newState , filepath ) { const previouslyExists = exists ( previousState , filepath ) ; const newExists = exists ( newState , filepath ) ; if ( ! previouslyExists && ! newExists ) { // Still non existing return false ; } else if ( exists ( previousState , filepath ) !== exists ( newState , filepath ) ) { // The file is absent from one return true ; } else { // Both files exist const prevWorking = previousState . getCurrentState ( ) ; const newWorking = newState . getCurrentState ( ) ; const prevSha = WorkingUtils . findSha ( prevWorking , filepath ) ; const newSha = WorkingUtils . findSha ( newWorking , filepath ) ; if ( prevSha === null && newSha === null ) { // Both have are in pending changes. We can compare their contents return read ( previousState , filepath ) . getAsString ( ) !== read ( newState , filepath ) . getAsString ( ) ; } else { // Content changed if Shas are different, or one of them is null return prevSha !== newSha ; } } }


Input: Initializes the testing infrastructure needed for verifying the behavior of the core proxy library - nock express and httpServer . [CODESPLIT] function setup ( connection , done ) { var config = createDefaultConfig ( ) , options = { proxy : false , headers : { } } ; // reset the global variable with handles to port numbers handles = { } ; if ( connection !== 'direct' ) { options . proxy = true ; config . proxy . gateway = { protocol : 'http:' , host : 'localhost' , port : 0 , auth : 'proxyuser:C0mp13x_!d0rd$$@P!' } ; // optionally test a non-RFC proxy that expects explicit values // for the  Via and/or Host request headers if ( connection === 'non-rfc-proxy' ) { config . proxy . headers [ 'Via' ] = 'http://jedi.example.com' ; config . proxy . headers [ 'Host' ] = 'force.example.com' ; } // the config map will be mutated by the json-proxy library, so clone it options . headers = require ( 'util' ) . _extend ( config . proxy . headers ) ; configureLanProxy ( options , config , function ( ) { configureNock ( options , config ) ; configureExpress ( config , done ) ; } ) } else { configureNock ( options , config ) ; configureExpress ( config , done ) ; } }


Input: configures nock globally for a test run [CODESPLIT] function configureNock ( options , config ) { var result = { } ; // deny all real net connections except for localhost nock . disableNetConnect ( ) ; nock . enableNetConnect ( 'localhost' ) ; function createNock ( url ) { var instance = nock ( url ) , expectedViaHeader = options . headers [ 'Via' ] || 'http://localhost:' + config . proxy . gateway . port , expectedHostHeader = options . headers [ 'Host' ] || / .* / ; if ( options . proxy === true ) { // verify that the request was actually proxied // optionally support downstream proxies with non-RFC expectations on // the Host and Via request headers instance . matchHeader ( 'via' , expectedViaHeader ) ; instance . matchHeader ( 'host' , expectedHostHeader ) ; } // verify the injected header instance . matchHeader ( 'x-test-header' , 'John Doe' ) ; return instance ; } rules = [ createNock ( 'http://api.example.com' ) . get ( '/api/hello' ) . reply ( 200 , '{ "hello": "world" }' ) . get ( '/account?id=1&email=2&sort=asc' ) . reply ( 200 , '{ "email": "john.doe@example.com" }' ) . get ( '/api/notfound' ) . reply ( 404 ) , createNock ( 'http://rewrite.example.com' ) . get ( '/hello' ) . reply ( 200 , '{ "hello": "world" }' ) . get ( '/foo/bar' ) . reply ( 200 , '{ "foo": "bar" }' ) , createNock ( 'http://www.example.com' ) . get ( '/foo/12345/bar' ) . reply ( 200 , '{ "foo": "bar" }' ) . get ( '/subapp/junction/customer/1' ) . reply ( 200 , '{ "id": 1 }' ) , createNock ( 'https://api.example.biz' ) . get ( '/issue/8' ) . reply ( 200 , '{ "reporter": "@heygrady" }' ) , createNock ( 'https://secure.example.com' ) . get ( '/secure/api/hello' ) . reply ( 200 , '{ "hello": "world" }' ) . get ( '/secure/api/notfound' ) . reply ( 404 ) , createNock ( 'https://authorization.example.com' ) . matchHeader ( 'X-Test-Header-Function' , 'Bearer 0123456789abcdef' ) . get ( '/token' ) . reply ( 200 , '{ "author": "ehtb" }' ) ] ; }


Input: Configures an express instance on a dynamically assigned port for serving static files and proxying requests based on the config . [CODESPLIT] function configureExpress ( config , done ) { var portfinder = require ( 'portfinder' ) ; tmp . dir ( function ( err , filepath ) { handles . filepath = filepath ; portfinder . getPort ( function ( err , port ) { if ( err ) throw ( err ) ; handles . port = port ; fs . writeFileSync ( path . join ( handles . filepath , 'index.txt' ) , 'hello, world' ) ; app . use ( proxy . initialize ( config ) ) ; app . use ( express . static ( handles . filepath ) ) ; handles . server = require ( 'http' ) . createServer ( app ) ; handles . server . listen ( handles . port , function ( ) { done ( null , handles . port ) ; } ) ; } ) ; } ) ; }


Input: Creates a simple LAN proxy using a vanilla HTTP server that verifies the state of the proxy credentials and the x - forwarded - url are correct . [CODESPLIT] function configureLanProxy ( options , config , done ) { var portfinder = require ( 'portfinder' ) , request = require ( 'request' ) , credentials = config . proxy . gateway . auth , gatewayPort , expectedAuthorizationHeader , requestViaHeader , responseViaHeader ; handles = handles || { } ; handles . gatewayServer = require ( 'http' ) . createServer ( function ( req , res ) { expectedAuthorizationHeader = 'Basic ' + new Buffer ( credentials ) . toString ( 'base64' ) ; // HACK: node 0.12.x appears to inject a slash at the front //       of absolute URLs //       ex., GET http://www.example.com --> GET /http://www.exampel.com if ( req . url . charAt ( 0 ) === '/' ) { req . url = req . url . substr ( 1 ) ; } // validate the proxy target if ( req . url !== req . headers [ 'x-forwarded-url' ] ) { res . writeHead ( 500 ) ; res . end ( '{ "error": 500, "message": "invalid proxy request, expected X-Forwarded-Url header ' + req . headers [ 'x-forwarded-url' ] + '" }' ) ; return ; } // validate the proxy credentials if ( req . headers [ 'authorization' ] !== expectedAuthorizationHeader ) { res . writeHead ( 401 ) ; res . end ( '{ "error": 401, "message": "invalid proxy credentials, expected ' + expectedAuthorizationHeader + '" }' ) ; return ; } // determine if we are using a proxy that is not RFC compliant requestViaHeader = options . headers [ 'Via' ] || '127.0.0.1:' + handles . port ; responseHostHeader = options . headers [ 'Host' ] || req . headers [ 'host' ] ; responseViaHeader = options . headers [ 'Via' ] || 'http://localhost:' + gatewayPort ; // validate the via header was injected and points to 127.0.0.1 in either ipv4 or ipv6 format if ( req . headers [ 'via' ] === undefined || req . headers [ 'via' ] === null || req . headers [ 'via' ] . indexOf ( requestViaHeader ) === - 1 ) { res . writeHead ( 400 ) ; res . end ( '{ "error": 400, "message": "invalid via header, expected ' + requestViaHeader + '" }' ) ; return ; } // strip the proxy credentials header req . headers [ 'authorization' ] = null ; // simulate the behavior of x-forwarded-for with multiple proxies req . headers [ 'x-forwarded-for' ] = [ req . headers [ 'x-forwarded-for' ] , req . headers [ 'via' ] ] . join ( ', ' ) ; // change the via header to this server req . headers [ 'via' ] = responseViaHeader ; req . headers [ 'host' ] = responseHostHeader ; var errorCallback = function errorCallback ( err , repsonse , body ) { if ( err ) { res . writeHead ( 500 ) ; res . end ( JSON . stringify ( { "error" : 500 , "message" : err . message } ) ) ; return ; } } request ( req , errorCallback ) . pipe ( res ) ; } ) ; portfinder . getPort ( function ( err , port ) { if ( err ) done ( err ) ; config . proxy . gateway . port = port ; gatewayPort = port ; handles . gatewayServer . listen ( port , function ( ) { done ( null ) ; } ) ; } ) ; }


Input: Teardown logic for the reusable test suites [CODESPLIT] function cleanup ( done ) { config = null ; rules . forEach ( function ( rule ) { rule . done ( ) ; } ) ; nock . cleanAll ( ) ; handles . server . close ( ) ; if ( handles . gatewayServer !== undefined && handles . gatewayServer !== null ) { handles . gatewayServer . close ( ) ; } fs . unlinkSync ( path . join ( handles . filepath , '/index.txt' ) ) ; handles = null ; done ( ) ; }


Input: Set a new change to the current WorkingState . Attempt to resolve some cases like removing a file that was added in the first place . [CODESPLIT] function setChange ( repoState , filepath , change ) { let workingState = repoState . getCurrentState ( ) ; let changes = workingState . getChanges ( ) ; const type = change . getType ( ) ; // Simplify change when possible if ( type === CHANGE_TYPE . REMOVE && ! workingState . getTreeEntries ( ) . has ( filepath ) ) { // Removing a file that did not exist before changes = changes . delete ( filepath ) ; } else if ( type === CHANGE_TYPE . CREATE && workingState . getTreeEntries ( ) . has ( filepath ) ) { // Adding back a file that existed already changes = changes . set ( filepath , change . set ( 'type' , CHANGE_TYPE . UPDATE ) ) ; } else { // Push changes to list changes = changes . set ( filepath , change ) ; } // Update workingState and repoState workingState = workingState . set ( 'changes' , changes ) ; return RepoUtils . updateCurrentWorkingState ( repoState , workingState ) ; }


Input: Revert all changes [CODESPLIT] function revertAll ( repoState ) { let workingState = repoState . getCurrentState ( ) ; // Create empty list of changes const changes = new Immutable . OrderedMap ( ) ; // Update workingState and repoState workingState = workingState . set ( 'changes' , changes ) ; return RepoUtils . updateCurrentWorkingState ( repoState , workingState ) ; }


Input: Revert change for a specific file [CODESPLIT] function revertForFile ( repoState , filePath ) { let workingState = repoState . getCurrentState ( ) ; // Remove file from changes map const changes = workingState . getChanges ( ) . delete ( filePath ) ; // Update workingState and repoState workingState = workingState . set ( 'changes' , changes ) ; return RepoUtils . updateCurrentWorkingState ( repoState , workingState ) ; }


Input: Revert changes for a specific directory [CODESPLIT] function revertForDir ( repoState , dirPath ) { let workingState = repoState . getCurrentState ( ) ; let changes = workingState . getChanges ( ) ; // Remove all changes that are in the directory changes = changes . filter ( ( change , filePath ) => { return ! PathUtils . contains ( dirPath , filePath ) ; } ) ; // Update workingState and repoState workingState = workingState . set ( 'changes' , changes ) ; return RepoUtils . updateCurrentWorkingState ( repoState , workingState ) ; }


Input: Revert all removed files [CODESPLIT] function revertAllRemoved ( repoState ) { let workingState = repoState . getCurrentState ( ) ; const changes = workingState . getChanges ( ) . filter ( // Remove all changes that are in the directory ( change ) => { return change . getType ( ) === CHANGE_TYPE . REMOVE ; } ) ; // Update workingState and repoState workingState = workingState . set ( 'changes' , changes ) ; return RepoUtils . updateCurrentWorkingState ( repoState , workingState ) ; }


Input: Normalize a path [CODESPLIT] function normPath ( p ) { p = path . normalize ( p ) ; if ( p [ 0 ] == '/' ) p = p . slice ( 1 ) ; if ( p [ p . length - 1 ] == '/' ) p = p . slice ( 0 , - 1 ) ; if ( p == '.' ) p = '' ; return p ; }


Input: Returns true if the path is under dir [CODESPLIT] function pathContains ( dir , path ) { dir = dir ? normPath ( dir ) + '/' : dir ; path = normPath ( path ) ; return path . indexOf ( dir ) === 0 ; }


Input: List files in a directory ( shallow ) [CODESPLIT] function read ( repoState , dirName ) { dirName = PathUtils . norm ( dirName ) ; const workingState = repoState . getCurrentState ( ) ; const changes = workingState . getChanges ( ) ; const treeEntries = WorkingUtils . getMergedTreeEntries ( workingState ) ; const files = [ ] ; treeEntries . forEach ( ( treeEntry , filepath ) => { // Ignore git submodules if ( treeEntry . getType ( ) !== TreeEntry . TYPES . BLOB ) return ; if ( ! PathUtils . contains ( dirName , filepath ) ) return ; const innerPath = PathUtils . norm ( filepath . replace ( dirName , '' ) ) ; const isDirectory = innerPath . indexOf ( '/' ) >= 0 ; // Make it shallow const name = innerPath . split ( '/' ) [ 0 ] ; const file = new File ( { path : Path . join ( dirName , name ) , type : isDirectory ? FILETYPE . DIRECTORY : FILETYPE . FILE , change : changes . get ( filepath ) , fileSize : treeEntry . blobSize } ) ; files . push ( file ) ; } ) ; // Remove duplicate from entries within directories return uniqueBy ( files , ( file ) => { return file . getName ( ) ; } ) ; }


Input: List files and directories in a directory ( recursive ) . Warning : This recursive implementation is very costly . [CODESPLIT] function readRecursive ( repoState , dirName ) { // TODO improve performance and don't use .read() directly const files = read ( repoState , dirName ) ; let filesInDirs = files . filter ( ( file ) => { return file . isDirectory ( ) ; } ) . map ( ( dir ) => { return readRecursive ( repoState , dir . path ) ; } ) ; filesInDirs = flatten ( filesInDirs ) ; return Array . prototype . concat ( files , filesInDirs ) ; }


Input: List files in a directory ( shallow ) [CODESPLIT] function readFilenames ( repoState , dirName ) { const files = read ( repoState , dirName ) ; return files . map ( ( file ) => { return file . getPath ( ) ; } ) ; }


Input: List files recursively in a directory [CODESPLIT] function readFilenamesRecursive ( repoState , dirName ) { dirName = PathUtils . norm ( dirName ) ; const workingState = repoState . getCurrentState ( ) ; const fileSet = WorkingUtils . getMergedFileSet ( workingState ) ; return fileSet . filter ( ( path ) => { return PathUtils . contains ( dirName , path ) ; } ) . toArray ( ) ; }


Input: Rename a directory [CODESPLIT] function move ( repoState , dirName , newDirName ) { // List entries to move const filesToMove = readFilenamesRecursive ( repoState , dirName ) ; // Push change to remove all entries return filesToMove . reduce ( ( repoState , oldPath ) => { const newPath = Path . join ( newDirName , Path . relative ( dirName , oldPath ) ) ; return FileUtils . move ( repoState , oldPath , newPath ) ; } , repoState ) ; }


Input: Remove a directory : push REMOVE changes for all entries in the directory [CODESPLIT] function remove ( repoState , dirName ) { // List entries to move const filesToRemove = readFilenamesRecursive ( repoState , dirName ) ; // Push change to remove all entries return filesToRemove . reduce ( ( repoState , path ) => { return FileUtils . remove ( repoState , path ) ; } , repoState ) ; }


Input: Create a new branch with the given name . [CODESPLIT] function create ( repositoryState , driver , name , opts = { } ) { const { // Base branch for the new branch base = repositoryState . getCurrentBranch ( ) , // Fetch the working state and switch to it ? checkout = true , // Drop changes from base branch the new working state ? clean = true , // Drop changes from the base branch ? cleanBase = false } = opts ; let createdBranch ; return driver . createBranch ( base , name ) // Update list of branches . then ( ( branch ) => { createdBranch = branch ; let branches = repositoryState . getBranches ( ) ; branches = branches . push ( createdBranch ) ; return repositoryState . set ( 'branches' , branches ) ; } ) // Update working state or fetch it if needed . then ( ( repoState ) => { let baseWk = repoState . getWorkingStateForBranch ( base ) ; if ( ! baseWk ) { return checkout ? RepoUtils . fetchTree ( repoState , driver , createdBranch ) : repoState ; } // Reuse base WorkingState clean const headWk = clean ? baseWk . asClean ( ) : baseWk ; repoState = RepoUtils . updateWorkingState ( repoState , createdBranch , headWk ) ; // Clean base WorkingState baseWk = cleanBase ? baseWk . asClean ( ) : baseWk ; repoState = RepoUtils . updateWorkingState ( repoState , base , baseWk ) ; return repoState ; } ) // Checkout the branch . then ( ( repoState ) => { if ( ! checkout ) { return repoState ; } return RepoUtils . checkout ( repoState , createdBranch ) ; } ) ; }


Input: Fetch the list of branches and update the given branch only . Will update the WorkingState of the branch ( and discard previous [CODESPLIT] function update ( repoState , driver , branchName ) { branchName = Normalize . branchName ( branchName || repoState . getCurrentBranch ( ) ) ; return driver . fetchBranches ( ) . then ( ( branches ) => { const newBranch = branches . find ( ( branch ) => { return branch . getFullName ( ) === branchName ; } ) ; if ( ! newBranch ) { return repoState ; } else { return RepoUtils . fetchTree ( repoState , driver , newBranch ) ; } } ) ; }


Input: Remove the given branch from the repository . [CODESPLIT] function remove ( repoState , driver , branch ) { return driver . deleteBranch ( branch ) . then ( ( ) => { return repoState . updateBranch ( branch , null ) ; } ) ; }


Input: Merge a branch / commit into a branch and update that branch s tree . [CODESPLIT] function merge ( repoState , driver , from , into , options = { } ) { options = Object . assign ( { fetch : true } , options ) ; let updatedInto ; // closure return driver . merge ( from , into , { message : options . message } ) // Can fail here with ERRORS.CONFLICT . then ( function updateInto ( mergeCommit ) { if ( ! mergeCommit ) { // Was a no op return repoState ; } else { updatedInto = into . merge ( { commit : mergeCommit } ) ; repoState = repoState . updateBranch ( into , updatedInto ) ; // invalidate working state return RepoUtils . updateWorkingState ( repoState , into , null ) ; } } ) . then ( function fetchTree ( repositoryState ) { if ( ! options . fetch ) { return repositoryState ; } else { return RepoUtils . fetchTree ( repositoryState , driver , updatedInto ) ; } } ) ; }


Input: Fetch a blob from SHA . [CODESPLIT] function fetch ( repoState , driver , sha ) { if ( isFetched ( repoState , sha ) ) { // No op if already fetched return Q ( repoState ) ; } const cache = repoState . getCache ( ) ; // Fetch the blob return driver . fetchBlob ( sha ) // Then store it in the cache . then ( ( blob ) => { const newCache = CacheUtils . addBlob ( cache , sha , blob ) ; return repoState . set ( 'cache' , newCache ) ; } ) ; }


Input: a private function to automatically refresh the access token when receiving a 401 . Adds rejected requests to a queue to be processed [CODESPLIT] function ( context , options , callback ) { // add the current request to the queue context . retryQueue . push ( [ options , callback ] ) ; // bail if the token is currently being refreshed if ( context . refreshActive ) { return false ; } // ready to refresh context . refreshActive = true ; return request ( { uri : baseUrl + '/oauth2/token' , method : 'POST' , headers : { 'Authorization' : 'Basic ' + new Buffer ( context . clientId + ':' + context . clientSecret ) . toString ( 'base64' ) , 'User-Agent' : userAgent } , form : { grant_type : 'client_credentials' } } , function ( err , res , body ) { context . refreshActive = false ; // if anything but a 200 is returned from the token refresh call, we return the error to the // caller and blow out the retry queue if ( res . statusCode != 200 ) { context . retryQueue = [ ] ; return callback && callback ( res . body , res ) ; } // set the access token on the connection var token = JSON . parse ( body ) ; context . accessToken = token . access_token ; // process the queue of requests for the current connection while ( 0 < context . retryQueue . length ) { var reqArgs = context . retryQueue . pop ( ) ; context . apiRequest ( reqArgs [ 0 ] , reqArgs [ 1 ] ) ; } } ) ; }


Input: Create a connection to the pokitdok API . The version defaults to v4 . You must enter your client ID and client secret or all requests made with your connection will return errors . [CODESPLIT] function PokitDok ( clientId , clientSecret , version ) { this . clientId = clientId ; this . clientSecret = clientSecret ; this . version = version || 'v4' ; this . refreshActive = false ; this . retryQueue = [ ] ; this . accessToken = null ; }


Input: TODO : check react - router version assume that router . js is already created [CODESPLIT] function findRouterNode ( root ) { return root . find ( j . JSXElement , { openingElement : { name : { name : 'Router' } } } ) . nodes ( ) [ 0 ] ; }


Input: private [CODESPLIT] function _action ( type , payload , checklist , optional = [ ] ) { for ( let checkitem of [ 'namespace' , ... checklist ] ) { if ( optional . indexOf ( checkitem ) === - 1 ) { assert ( payload [ checkitem ] , ` ${ type } ${ checkitem } ` ) ; } } const filePath = join ( payload . sourcePath , payload . filePath ) ; const source = readFile ( filePath ) ; const root = j ( source ) ; const models = root . findModels ( payload . namespace ) ; const args = checklist . map ( checkitem => payload [ checkitem ] ) ; models [ type ] . apply ( models , args ) ; writeFile ( filePath , root . toSource ( ) ) ; }


Input: convert an array of features to a single line in SVM - light format . The line starts with a space . [CODESPLIT] function featureArrayToFeatureString ( features , bias , firstFeatureNumber ) { if ( ! Array . isArray ( features ) ) throw new Error ( "Expected an array, but got " + JSON . stringify ( features ) ) var line = ( bias ? " " + firstFeatureNumber + ":" + bias : "" ) ; for ( var feature = 0 ; feature < features . length ; ++ feature ) { var value = features [ feature ] ; if ( value ) line += ( " " + ( feature + firstFeatureNumber + ( bias ? 1 : 0 ) ) + ":" + value . toPrecision ( 5 ) ) ; } return line ; }


Input: add a single feature if it does not exist [CODESPLIT] function ( feature ) { if ( ! ( feature in this . featureNameToFeatureIndex ) ) { var newIndex = this . featureIndexToFeatureName . length ; this . featureIndexToFeatureName . push ( feature ) ; this . featureNameToFeatureIndex [ feature ] = newIndex ; } }


Input: add all features in the given hash or array [CODESPLIT] function ( hash ) { if ( hash instanceof Array ) { for ( var index in hash ) this . addFeature ( hash [ index ] ) ; } else if ( hash instanceof Object ) { for ( var feature in hash ) this . addFeature ( feature ) ; } else throw new Error ( "FeatureLookupTable.addFeatures expects a hash or an array, but got: " + JSON . stringify ( hash ) ) ; }


Input: Convert the given hash of features to a numeric array using 0 for padding . If some features in the hash do not exist - they will be added . [CODESPLIT] function ( hash ) { this . addFeatures ( hash ) ; var array = [ ] ; for ( var featureIndex = 0 ; featureIndex < this . featureIndexToFeatureName . length ; ++ featureIndex ) array [ featureIndex ] = 0 ; if ( hash instanceof Array ) { for ( var i in hash ) array [ this . featureNameToFeatureIndex [ hash [ i ] ] ] = true ; } else if ( hash instanceof Object ) { for ( var feature in hash ) array [ this . featureNameToFeatureIndex [ feature ] ] = hash [ feature ] ; } else throw new Error ( "Unsupported type: " + JSON . stringify ( hash ) ) ; return array ; }


Input: Convert all the given hashes of features to numeric arrays using 0 for padding . If some features in some of the hashes do not exist - they will be added . [CODESPLIT] function ( hashes ) { this . addFeaturess ( hashes ) ; var arrays = [ ] ; for ( var i = 0 ; i < hashes . length ; ++ i ) { arrays [ i ] = [ ] ; for ( var feature in this . featureNameToFeatureIndex ) arrays [ i ] [ this . featureNameToFeatureIndex [ feature ] ] = hashes [ i ] [ feature ] || 0 ; } return arrays ; }


Input: Convert the given numeric array to a hash of features ignoring zero values . [CODESPLIT] function ( array ) { var hash = { } ; for ( var feature in this . featureNameToFeatureIndex ) { if ( array [ this . featureNameToFeatureIndex [ feature ] ] ) hash [ feature ] = array [ this . featureNameToFeatureIndex [ feature ] ] ; } return hash ; }


Input: Convert the given numeric arrays to array of hashes of features ignoring zero values . [CODESPLIT] function ( arrays ) { var hashes = [ ] ; for ( var i = 0 ; i < arrays . length ; ++ i ) hashes [ i ] = this . arrayToHash ( arrays [ i ] ) ; return hashes ; }


Input: HOMER - Hierarchy Of Multilabel classifiERs . See : [CODESPLIT] function ( opts ) { opts = opts || { } ; if ( ! opts . multilabelClassifierType ) { console . dir ( opts ) ; throw new Error ( "opts.multilabelClassifierType is null" ) ; } this . multilabelClassifierType = opts . multilabelClassifierType ; this . splitLabel = opts . splitLabel || function ( label ) { return label . split ( / @ / ) ; } this . joinLabel = opts . joinLabel || function ( superlabel ) { return superlabel . join ( "@" ) ; } this . root = { superlabelClassifier : this . newMultilabelClassifier ( ) , mapSuperlabelToBranch : { } } this . allClasses = { } ; }