|  |  | @@ -193,30 +193,86 @@ var globSync = require('glob').sync; | 
		
	
		
			
			|  |  |  | const { readdir } = require("fs").promises | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // Directory shallow walk and do perform on each dir. | 
		
	
		
			
			|  |  |  | const dirs = async (perform, path) => { | 
		
	
		
			
			|  |  |  | for (const dir of await readdir(path || selectedinstance.root, { withFileTypes: true })) { | 
		
	
		
			
			|  |  |  | if (dir.isDirectory()) perform(dir) | 
		
	
		
			
			|  |  |  | const dirs = async (perform, src, target, options) => { | 
		
	
		
			
			|  |  |  | var rs = [] | 
		
	
		
			
			|  |  |  | for (const dir of await readdir(src || selectedinstance.root, { withFileTypes: true })) { | 
		
	
		
			
			|  |  |  | if (dir.isDirectory()) rs.push( perform(dir, src, target, options) ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return any(rs) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var fsMove = async function(from, to, options) { | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if(!options?.innernode) { | 
		
	
		
			
			|  |  |  | var exists = fs.existsSync(from); | 
		
	
		
			
			|  |  |  | var stats = exists && fs.statSync(from); | 
		
	
		
			
			|  |  |  | var isDirectory = exists && stats.isDirectory(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | var isDirectory = options.innernode.isDirectory() | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(!isDirectory) return fs.renameSync(from, to) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | fs.mkdirSync(to, { recursive : true }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var rs = []; | 
		
	
		
			
			|  |  |  | for (const innernode of await readdir(from, { withFileTypes: true })) { | 
		
	
		
			
			|  |  |  | rs.push( fsMove( path.join(from, innernode.name), path.join(to, innernode.name), { innernode } ) ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return any(rs) | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // PB : TODO -- Should return a bunch of promises to wait for... | 
		
	
		
			
			|  |  |  | var copyrecursive = function(src, dest, perform, args) { | 
		
	
		
			
			|  |  |  | var exists = fs.existsSync(src); | 
		
	
		
			
			|  |  |  | var stats = exists && fs.statSync(src); | 
		
	
		
			
			|  |  |  | var isDirectory = exists && stats.isDirectory(); | 
		
	
		
			
			|  |  |  | if (isDirectory) { | 
		
	
		
			
			|  |  |  | fs.mkdirSync(dest); | 
		
	
		
			
			|  |  |  | dirs( function(childItemName) { | 
		
	
		
			
			|  |  |  | copyrecursive(path.join(src, childItemName), | 
		
	
		
			
			|  |  |  | path.join(dest, childItemName)); | 
		
	
		
			
			|  |  |  | }, src ) | 
		
	
		
			
			|  |  |  | // fs.readdirSync(src).forEach(function(childItemName) { | 
		
	
		
			
			|  |  |  | //   copyrecursive(path.join(src, childItemName), | 
		
	
		
			
			|  |  |  | //                     path.join(dest, childItemName)); | 
		
	
		
			
			|  |  |  | // }); | 
		
	
		
			
			|  |  |  | } else { | 
		
	
		
			
			|  |  |  | fs.copyFileSync(src, dest); | 
		
	
		
			
			|  |  |  | var copyrecursive = async function(src, target, options) { | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if(!options?.innernode) { | 
		
	
		
			
			|  |  |  | var exists = fs.existsSync(src); | 
		
	
		
			
			|  |  |  | var stats = exists && fs.statSync(src); | 
		
	
		
			
			|  |  |  | var isDirectory = exists && stats.isDirectory(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | var isDirectory = options.innernode.isDirectory() | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(!isDirectory) return fs.copyFileSync(src, target) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | fs.mkdirSync(target, { recursive : true }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var rs = []; | 
		
	
		
			
			|  |  |  | for (const innernode of await readdir(src, { withFileTypes: true })) { | 
		
	
		
			
			|  |  |  | rs.push( copyrecursive( path.join(src, innernode.name), path.join(target, innernode.name), { innernode } ) | 
		
	
		
			
			|  |  |  | // .then(()=>{ | 
		
	
		
			
			|  |  |  | //   return any(actions.map( a => ()=>a(dir, { isDirectory : true}) )) | 
		
	
		
			
			|  |  |  | // }) | 
		
	
		
			
			|  |  |  | ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return any(rs) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // return fswalk( src, {}, [ | 
		
	
		
			
			|  |  |  | //     (src, options)=> { | 
		
	
		
			
			|  |  |  | //       if(options.innernode.isDirectory()) fs.mkdirSync(options.target, { recursive : true }) | 
		
	
		
			
			|  |  |  | //       else fs.copyFileSync(src, options.target) | 
		
	
		
			
			|  |  |  | //     } | 
		
	
		
			
			|  |  |  | //  ]) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // var exists = fs.existsSync(src); | 
		
	
		
			
			|  |  |  | // var stats = exists && fs.statSync(src); | 
		
	
		
			
			|  |  |  | // var isDirectory = exists && stats.isDirectory(); | 
		
	
		
			
			|  |  |  | // if (isDirectory) { | 
		
	
		
			
			|  |  |  | //   fs.mkdirSync(dest, { recursive : true }); | 
		
	
		
			
			|  |  |  | //   return dirs( function(childItemName) { | 
		
	
		
			
			|  |  |  | //     return copyrecursive(path.join(src, childItemName.name), | 
		
	
		
			
			|  |  |  | //                       path.join(dest, childItemName.name)); | 
		
	
		
			
			|  |  |  | //   }, src ) | 
		
	
		
			
			|  |  |  | // } else { | 
		
	
		
			
			|  |  |  | //   fs.copyFileSync(src, dest); | 
		
	
		
			
			|  |  |  | // } | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // var renamerecursive = function(from, to){ | 
		
	
	
		
			
			|  |  | @@ -239,67 +295,129 @@ var copyrecursive = function(src, dest, perform, args) { | 
		
	
		
			
			|  |  |  | // } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var regexreplaceall = function(content, strOrregexp, substitutes){ | 
		
	
		
			
			|  |  |  | var regexreplaceall = function(content, ps){ | 
		
	
		
			
			|  |  |  | var repmatches | 
		
	
		
			
			|  |  |  | var replaced = content; | 
		
	
		
			
			|  |  |  | while (repmatches = strOrregexp.exec(content)) { | 
		
	
		
			
			|  |  |  | while (repmatches = ps.strOrregexp.exec(content)) { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(content.length > 0) { | 
		
	
		
			
			|  |  |  | var replacement = repmatches[0] | 
		
	
		
			
			|  |  |  | for(var m = 1; m < repmatches.length; m++) { | 
		
	
		
			
			|  |  |  | replacement = replacement.replace(matches[i], substitutes[i-1]) | 
		
	
		
			
			|  |  |  | replacement = replacement.replace(repmatches[m], ps.substitutes[m-1]) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | replaced.replace( repmatches[0], replacement ) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | replaced = replaced.replace( repmatches[0], replacement ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return replaced | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // filesystem walk | 
		
	
		
			
			|  |  |  | const fswalk = async (pathToWalk, options, actions) => { | 
		
	
		
			
			|  |  |  | // options = options || { depthfirst : true } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if(!options.innernode) { | 
		
	
		
			
			|  |  |  | var exists = fs.existsSync(pathToWalk); | 
		
	
		
			
			|  |  |  | var stats = exists && fs.statSync(pathToWalk); | 
		
	
		
			
			|  |  |  | var isDirectory = exists && stats.isDirectory(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | var isDirectory = options.innernode.isDirectory() | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(!isDirectory) return any(actions.map( a => ()=>a( pathToWalk, utils.assign({}, options | 
		
	
		
			
			|  |  |  | , { pathToWalk, innernode : options.innernode || { isDirectory : function(){ return true } } }) ) )) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | var rs = []; | 
		
	
		
			
			|  |  |  | for (const innernode of await readdir(pathToWalk, { withFileTypes: true })) { | 
		
	
		
			
			|  |  |  | rs.push( fswalk( path.join(pathToWalk, innernode.name), utils.assign({}, options, {pathToWalk, innernode }), actions ) | 
		
	
		
			
			|  |  |  | // .then(()=>{ | 
		
	
		
			
			|  |  |  | //   return any(actions.map( a => ()=>a(innernode, { isDirectory : true}) )) | 
		
	
		
			
			|  |  |  | // }) | 
		
	
		
			
			|  |  |  | ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | // Wait for the walk to complete before renaming directories. | 
		
	
		
			
			|  |  |  | Array.prototype.push.apply(rs, actions.map( a => ()=>a( pathToWalk, utils.assign({}, options | 
		
	
		
			
			|  |  |  | , { pathToWalk, innernode : options.innernode || { isDirectory : function(){ return true } } } ) ) )) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return any(rs) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var fsrecurse = function(target, options, actions, root) { | 
		
	
		
			
			|  |  |  | var exists = fs.existsSync(target); | 
		
	
		
			
			|  |  |  | var stats = exists && fs.statSync(target); | 
		
	
		
			
			|  |  |  | var isDirectory = exists && stats.isDirectory(); | 
		
	
		
			
			|  |  |  | if (isDirectory) { | 
		
	
		
			
			|  |  |  | dirs( function(childItemName) { | 
		
	
		
			
			|  |  |  | fsrecurse(path.join(target, childItemName) | 
		
	
		
			
			|  |  |  | var tasks = [] | 
		
	
		
			
			|  |  |  | tasks.push( dirs( function(childItemName) { | 
		
	
		
			
			|  |  |  | return fsrecurse(path.join(target, childItemName.name) | 
		
	
		
			
			|  |  |  | , options, actions, root); | 
		
	
		
			
			|  |  |  | }, target ) | 
		
	
		
			
			|  |  |  | }, target )) | 
		
	
		
			
			|  |  |  | return any(tasks) | 
		
	
		
			
			|  |  |  | } else { | 
		
	
		
			
			|  |  |  | var prevActionResult = null; | 
		
	
		
			
			|  |  |  | actions.forEach( (action) => prevActionResult = action.apply(null, target, options) ) | 
		
	
		
			
			|  |  |  | return any( actions.map( (action) =>   prevActionResult = action.apply(null, target, options) )) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var fslink = function(target, options){  fs.linkSync( options.from, options.to ) } | 
		
	
		
			
			|  |  |  | // var fslink = function(to, options){  try { fs.linkSync( to, options.from ) } catch(e) { throw e } } | 
		
	
		
			
			|  |  |  | var fslink = function(to, options){ fs.symlinkSync( to, options.from /*, type = "junction"*/ ) } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var fsrename = function(target, options){ | 
		
	
		
			
			|  |  |  | var replaced = target; // PB : TODO -- streaming and async.. | 
		
	
		
			
			|  |  |  | // PB : TODO -- streaming and async.. target could be a stream a string or a filesystem item or a tree node... | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var targetname = options.innernode?.name || path.parse(target).base; | 
		
	
		
			
			|  |  |  | var replaced = targetname; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | options.patternsubstitutions.forEach( ps => { replaced = regexreplaceall( replaced, ps ) }) | 
		
	
		
			
			|  |  |  | if(replaced && replaced !== target) fs.renameSync(target, replaced) | 
		
	
		
			
			|  |  |  | return replaced | 
		
	
		
			
			|  |  |  | if(replaced && replaced !== targetname) { | 
		
	
		
			
			|  |  |  | var tr = target.replace( targetname, replaced ) | 
		
	
		
			
			|  |  |  | fs.renameSync(target, tr) | 
		
	
		
			
			|  |  |  | return tr; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else return replaced | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var fscontentreplace = function( target, options ){ | 
		
	
		
			
			|  |  |  | // do many replacements in one shot in the file. | 
		
	
		
			
			|  |  |  | if(options.processingtype === 'inplace' && options.sourcetype === 'filesystem' ) { | 
		
	
		
			
			|  |  |  | var content = fs.readFileSync(target) // PB : TODO -- streaming and async.. | 
		
	
		
			
			|  |  |  | if(options.processingtype === 'inplace' && options.sourcetype === 'filesystem' && !options.innernode.isDirectory() ) { | 
		
	
		
			
			|  |  |  | var content = fs.readFileSync(target, { encoding: 'utf8' }) // PB : TODO -- streaming and async.. | 
		
	
		
			
			|  |  |  | options.patternsubstitutions.forEach( ps => { content = regexreplaceall( content, ps ) }) | 
		
	
		
			
			|  |  |  | fs.writeFileSync(target, content) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var templatelink = function(target, options){ | 
		
	
		
			
			|  |  |  | var targetPath = target.replace(options.workingtarget, options.destinationroot); | 
		
	
		
			
			|  |  |  | var targetPathBaseDir = targetPath.split("/").pop() | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var linkTobase = regexreplaceall( target, /(__link__)(__base__)-server-lib/, [ '', options.base] ) | 
		
	
		
			
			|  |  |  | var linkFromName = regexreplaceall( target, /(__link____base__-server-lib)/, [ '' ] ) | 
		
	
		
			
			|  |  |  | var linkToName = regexreplaceall( linkFromName, new Regexp(targetPathBaseDir), [ linkTobase ] ) | 
		
	
		
			
			|  |  |  | var targetSubPath = target.replace(options.workingtarget + '/', '' ); | 
		
	
		
			
			|  |  |  | var targetSubPathsplit = targetSubPath.split("/") | 
		
	
		
			
			|  |  |  | var targetPathBaseDir = `${targetSubPathsplit[0]}/${targetSubPathsplit[1]}` | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var linkToSubPathReplacement = `${options.base}-server-lib/common` | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // var rgxp = new RegExp(`(__link__)${options.base}-server-lib`, "g") | 
		
	
		
			
			|  |  |  | var rgxp = new RegExp(`(__link__${options.base}-server-lib)`, "g") | 
		
	
		
			
			|  |  |  | var linkToSubPath = targetSubPath | 
		
	
		
			
			|  |  |  | var b = target.match(rgxp) | 
		
	
		
			
			|  |  |  | var linkFromName  = regexreplaceall( target, { strOrregexp : rgxp, substitutes : [ '' ] } ) | 
		
	
		
			
			|  |  |  | linkFromName = linkFromName.replace(options.workingtarget, options.destinationroot) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if(linkTobase) { // Only if the pattern matches which is link instruction. | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // PB : DONT DLELETE EVERYTHING ??? Only the linkable ones... Or use an add strategy without deleting... | 
		
	
		
			
			|  |  |  | fs.unlinkSync( target ); fslink( { from : linkFromName, to : linkToName }  ) | 
		
	
		
			
			|  |  |  | if( b ) { | 
		
	
		
			
			|  |  |  | // Only if the pattern matches which is link instruction. | 
		
	
		
			
			|  |  |  | linkToSubPath = regexreplaceall( linkToSubPath, { strOrregexp : rgxp, substitutes : [ '' ] } ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | options.patternsubstitutions.forEach( ps => { linkToSubPath = regexreplaceall( linkToSubPath, ps ) }) | 
		
	
		
			
			|  |  |  | var linkToName = `${options.destinationroot}/${linkToSubPath}` | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(b){ | 
		
	
		
			
			|  |  |  | linkToSubPath = linkToSubPath.replace( targetPathBaseDir, linkToSubPathReplacement) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // PB : DONT DELETE EVERYTHING ??? Only the linkable ones... Or use an add strategy without deleting... | 
		
	
		
			
			|  |  |  | fs.unlinkSync( target ); | 
		
	
		
			
			|  |  |  | fslink( `${options.destinationroot}/${linkToSubPath}`, { from : linkFromName } ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | fsMove( `${options.workingtarget}/${linkToSubPath}`, linkToName ) | 
		
	
		
			
			|  |  |  | // fsMove( `${options.workingtarget}/${linkToSubPath}`, linkFromName  ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
			|  |  | @@ -2145,6 +2263,8 @@ var op = { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | console.log('elxr g model [modelname] => generate a model named [modelname]'); | 
		
	
		
			
			|  |  |  | console.log('elxr g vmodel [modelname] => generate a model named [modelname]'); | 
		
	
		
			
			|  |  |  | console.log('elxr g vmodel  [modelname] --server=true => generate only a server model named [modelname]'); | 
		
	
		
			
			|  |  |  | console.log('elxr g vmodel  [modelname] --all=true => default generate server and client model named [modelname]'); | 
		
	
		
			
			|  |  |  | console.log('elxr g => regenerate all known models'); | 
		
	
		
			
			|  |  |  | return | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
			|  |  | @@ -2247,6 +2367,7 @@ var op = { | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | , 'vmodel' : (options)=>{ | 
		
	
		
			
			|  |  |  | // node --inspect-brk elxr/index.js g vmodel qlabresults --server=true | 
		
	
		
			
			|  |  |  | options = options || { | 
		
	
		
			
			|  |  |  | generate : processedArgs['all'] ? 'all' :  processedArgs['server'] ? 'server' : processedArgs['client'] ? 'client' : null | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
			|  |  | @@ -2256,32 +2377,50 @@ var op = { | 
		
	
		
			
			|  |  |  | var name = processedArgs._[2]; | 
		
	
		
			
			|  |  |  | if(!name) return 'No name specified for generation' | 
		
	
		
			
			|  |  |  | var templateverse = `${selectedinstance.root}/bbhverse/__universe__/vmodel` | 
		
	
		
			
			|  |  |  | // var templateverse = `${selectedinstance.root}/bbhverse/__universe__/vmodel/__base__-server-lib/common/lib` | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | var workingtarget = `${selectedinstance.root}/.elxr/run-${runtimestamp}/temp/vmodelworkingdir` | 
		
	
		
			
			|  |  |  | var destination = `${selectedinstance.root}` | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // Create a tmp working copy for staging the changes. | 
		
	
		
			
			|  |  |  | copyrecursive(templateverse,  workingtarget) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | var patternsubstitutions = [ { strOrregexp : /(__name__)/, substitutes : [name]} ] | 
		
	
		
			
			|  |  |  | var options = { source : templateverse, target : workingtarget, destinationroot : destination, workingtarget | 
		
	
		
			
			|  |  |  | , processingtype : 'inplace', sourcetype : 'filesystem', patternsubstitutions } | 
		
	
		
			
			|  |  |  | fsrecurse( workingtarget, options | 
		
	
		
			
			|  |  |  | , [ function(workingtarget, options){ | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // A series of tasks to be executed on each pattern in patternsubstitutions. | 
		
	
		
			
			|  |  |  | return [ | 
		
	
		
			
			|  |  |  | // PB : TODO -- Contentreplace is better addressed in memory instead of file IO so do all regexps in sequence in one shot and then rename. | 
		
	
		
			
			|  |  |  | (filename, options)=>{ fscontentreplace( filename, options ) } | 
		
	
		
			
			|  |  |  | , (from, options)=>{ fsrename( from, options ) } | 
		
	
		
			
			|  |  |  | ].map( t => t(workingtarget, options) ) | 
		
	
		
			
			|  |  |  | }] | 
		
	
		
			
			|  |  |  | ) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // Post process links in place. | 
		
	
		
			
			|  |  |  | fsrecurse( workingtarget, options, [ templatelink ] ) | 
		
	
		
			
			|  |  |  | return copyrecursive(templateverse,  workingtarget).then( r => { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var base = 'chess'  // -- The server base from where this instance was dervied from. | 
		
	
		
			
			|  |  |  | var patternsubstitutions = [ | 
		
	
		
			
			|  |  |  | { strOrregexp : /(__name__)/g, substitutes : [name]} | 
		
	
		
			
			|  |  |  | , { strOrregexp : /(__instance__)/g, substitutes : [selectedinstance.instanceName]} | 
		
	
		
			
			|  |  |  | , { strOrregexp : /(__base__)/g, substitutes : [base]} | 
		
	
		
			
			|  |  |  | , { strOrregexp : /(__microservice__)/g, substitutes : [selectedinstance.microservice || selectedinstance.instanceName]} | 
		
	
		
			
			|  |  |  | , { strOrregexp : /(__microclient__)/g, substitutes : [selectedinstance.microclient || `${selectedinstance.instanceName}-client` || 'client']} // PB : TODO -- elixir-client etc... use a config to find the microclient.. | 
		
	
		
			
			|  |  |  | ] | 
		
	
		
			
			|  |  |  | var options = { source : templateverse, target : workingtarget | 
		
	
		
			
			|  |  |  | , base , destinationroot : destination, workingtarget | 
		
	
		
			
			|  |  |  | , processingtype : 'inplace', sourcetype : 'filesystem', patternsubstitutions } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | var actions = [ | 
		
	
		
			
			|  |  |  | fswalk( workingtarget, options | 
		
	
		
			
			|  |  |  | , [ function(t, o){ | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // A series of tasks to be executed on each pattern in patternsubstitutions. | 
		
	
		
			
			|  |  |  | return any([ | 
		
	
		
			
			|  |  |  | // PB : TODO -- Contentreplace is better addressed in memory instead of file IO so do all regexps in sequence in one shot and then rename. | 
		
	
		
			
			|  |  |  | ()=>{ return fscontentreplace( t, o ) } | 
		
	
		
			
			|  |  |  | , ()=>{ return fsrename( t, o ) } | 
		
	
		
			
			|  |  |  | ]) | 
		
	
		
			
			|  |  |  | }] ) | 
		
	
		
			
			|  |  |  | // Post process links in place. | 
		
	
		
			
			|  |  |  | , () => dirs((innernode, s,  t, o ) => fswalk( path.join(workingtarget, innernode.name), utils.assign({}, o, { innernode }), [ templatelink ] ) | 
		
	
		
			
			|  |  |  | , workingtarget, null, options) | 
		
	
		
			
			|  |  |  | // Move to the final destination. Whole tree should move only top level folders are required. | 
		
	
		
			
			|  |  |  | // , () => fswalk( workingtarget, options, [ fsrename ]) | 
		
	
		
			
			|  |  |  | // , () => dirs( ( child, src, target, options )=>{ return fs.renameSync(path.join(src, child.name), path.join(target, child.name) )  } | 
		
	
		
			
			|  |  |  | // , workingtarget, destination ) | 
		
	
		
			
			|  |  |  | ] | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return any(actions); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Move to the final destination. Whole tree should move only top level folders are required. | 
		
	
		
			
			|  |  |  | dirs(( child )=>{ return fs.renameSync(path.join(workingtarget, child), path.join(destination, child) )  }, workingtarget ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
			|  |  | @@ -4510,7 +4649,9 @@ var startElxr = function() { | 
		
	
		
			
			|  |  |  | , ...detectedinstanceoptions.slice(-2), promptkeys ) | 
		
	
		
			
			|  |  |  | // promptkeys = utils.assign(promptkeys, clioverrides) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(cmdprompts.instanceName) { | 
		
	
		
			
			|  |  |  | // startElxr requires instance // Independent cmds should have already been bypassed. | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // if(cmdprompts.instanceName) { | 
		
	
		
			
			|  |  |  | // not an instanceless cmd. | 
		
	
		
			
			|  |  |  | console.dir(selectedinstance) | 
		
	
		
			
			|  |  |  | try { | 
		
	
	
		
			
			|  |  | @@ -4598,8 +4739,8 @@ var startElxr = function() { | 
		
	
		
			
			|  |  |  | initinstances(selectedinstance) | 
		
	
		
			
			|  |  |  | return selectedinstance | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else return Promise.resolve(true) | 
		
	
		
			
			|  |  |  | // } | 
		
	
		
			
			|  |  |  | // else return Promise.resolve(true) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | .then(()=>{ | 
		
	
		
			
			|  |  |  | runconfig = { NODE_ENV: selectedinstance.node_env } |