2018-10-08 09:04:34 +00:00
let fs = require ( '../../core/fs' ) ;
2018-08-31 08:24:45 +00:00
let utils = require ( '../../utils/utils' ) ;
2018-08-30 09:41:13 +00:00
const EmbarkJS = require ( 'embarkjs' ) ;
const IpfsApi = require ( 'ipfs-api' ) ;
const Web3 = require ( 'web3' ) ;
2018-08-31 10:53:31 +00:00
const stringify = require ( 'json-stringify-safe' ) ;
2018-10-13 23:12:35 +00:00
const Suggestions = require ( './suggestions' )
2018-08-31 08:24:45 +00:00
2017-03-30 11:12:39 +00:00
class Console {
2018-10-13 23:12:35 +00:00
constructor ( embark , options ) {
this . embark = embark ;
2017-12-17 23:34:41 +00:00
this . events = options . events ;
2017-03-30 11:12:39 +00:00
this . plugins = options . plugins ;
this . version = options . version ;
2018-08-10 14:54:21 +00:00
this . logger = options . logger ;
2018-08-08 12:42:45 +00:00
this . ipc = options . ipc ;
2018-08-30 09:41:13 +00:00
this . config = options . config ;
2018-10-08 09:04:34 +00:00
this . history = [ ] ;
this . cmdHistoryFile = options . cmdHistoryFile || process . env . DEFAULT _CMD _HISTORY _PATH ;
this . loadHistory ( ) ;
2017-03-02 12:44:24 +00:00
2018-08-08 12:42:45 +00:00
if ( this . ipc . isServer ( ) ) {
this . ipc . on ( 'console:executeCmd' , this . executeCmd . bind ( this ) ) ;
}
2018-08-31 08:24:45 +00:00
this . events . setCommandHandler ( "console:executeCmd" , this . executeCmd . bind ( this ) ) ;
2018-10-08 09:04:34 +00:00
this . events . setCommandHandler ( "console:history" , ( cb ) => this . getHistory ( process . env . DEFAULT _CMD _HISTORY _SIZE , cb ) ) ;
2018-08-30 09:41:13 +00:00
this . registerEmbarkJs ( ) ;
2018-10-08 09:04:34 +00:00
this . registerConsoleCommands ( ) ;
2018-08-31 09:32:52 +00:00
this . registerApi ( ) ;
2018-10-13 23:12:35 +00:00
2018-10-16 01:42:57 +00:00
this . suggestions = new Suggestions ( embark , options ) ;
2018-08-31 09:32:52 +00:00
}
registerApi ( ) {
let plugin = this . plugins . createPlugin ( 'consoleApi' , { } ) ;
plugin . registerAPICall ( 'post' , '/embark-api/command' , ( req , res ) => {
2018-10-12 16:07:38 +00:00
this . executeCmd ( req . body . command , ( err , result ) => {
if ( err ) {
return res . send ( { result : err . message || err } ) ;
}
2018-08-31 11:00:16 +00:00
if ( typeof result === 'string' ) {
return res . send ( { result } ) ;
}
2018-08-31 10:53:31 +00:00
res . send ( { result : stringify ( result , null , 2 ) } ) ;
2018-08-31 09:32:52 +00:00
} ) ;
} ) ;
2017-03-02 12:44:24 +00:00
}
2017-03-30 11:12:39 +00:00
processEmbarkCmd ( cmd ) {
2018-05-08 21:49:46 +00:00
if ( cmd === 'help' || cmd === _ _ ( 'help' ) ) {
2017-03-30 11:12:39 +00:00
let helpText = [
2018-05-08 21:49:46 +00:00
_ _ ( 'Welcome to Embark' ) + ' ' + this . version ,
2017-03-30 11:12:39 +00:00
'' ,
2018-05-08 21:49:46 +00:00
_ _ ( 'possible commands are:' ) ,
'versions - ' + _ _ ( 'display versions in use for libraries and tools like web3 and solc' ) ,
2018-10-08 09:04:34 +00:00
'history - ' + _ _ ( 'display console commands history' ) ,
2017-03-30 11:12:39 +00:00
// TODO: only if the blockchain is actually active!
// will need to pass te current embark state here
2018-05-18 19:56:36 +00:00
'ipfs - ' + _ _ ( 'instantiated js-ipfs object configured to the current environment (available if ipfs is enabled)' ) ,
2018-09-12 02:57:46 +00:00
'swarm - ' + _ _ ( 'instantiated swarm-api object configured to the current environment (available if swarm is enabled)' ) ,
2018-05-08 21:49:46 +00:00
'web3 - ' + _ _ ( 'instantiated web3.js object configured to the current environment' ) ,
2018-09-04 18:12:12 +00:00
'EmbarkJS - ' + _ _ ( 'EmbarkJS static functions for Storage, Messages, Names, etc.' ) ,
2018-05-08 21:49:46 +00:00
'quit - ' + _ _ ( 'to immediatly exit (alias: exit)' ) ,
2017-03-30 11:12:39 +00:00
'' ,
2018-05-08 21:49:46 +00:00
_ _ ( 'The web3 object and the interfaces for the deployed contracts and their methods are also available' )
2017-03-30 11:12:39 +00:00
] ;
return helpText . join ( '\n' ) ;
2018-05-08 21:49:46 +00:00
} else if ( [ 'quit' , 'exit' , 'sair' , 'sortir' , _ _ ( 'quit' ) ] . indexOf ( cmd ) >= 0 ) {
2017-03-30 11:12:39 +00:00
utils . exit ( ) ;
}
return false ;
2017-03-02 12:44:24 +00:00
}
2016-09-23 04:31:09 +00:00
2017-03-30 11:12:39 +00:00
executeCmd ( cmd , callback ) {
2018-10-08 09:04:34 +00:00
if ( ! ( cmd . split ( ' ' ) [ 0 ] === 'history' || cmd === _ _ ( 'history' ) ) ) {
this . history . push ( cmd ) ;
this . saveHistory ( ) ;
}
2017-12-29 23:21:36 +00:00
var pluginCmds = this . plugins . getPluginsProperty ( 'console' , 'console' ) ;
for ( let pluginCmd of pluginCmds ) {
2018-08-08 12:42:45 +00:00
let pluginResult = pluginCmd . call ( this , cmd , { } ) ;
2018-08-10 14:54:21 +00:00
if ( typeof pluginResult !== 'object' ) {
if ( pluginResult !== false && pluginResult !== 'false' && pluginResult !== undefined ) {
this . logger . warn ( "[DEPRECATED] In future versions of embark, we expect the console command to return an object " +
2018-08-10 15:14:28 +00:00
"having 2 functions: match and process. The documentation with example can be found here: https://embark.status.im/docs/plugin_reference.html#embark-registerConsoleCommand-callback-options" ) ;
2018-08-10 14:54:21 +00:00
return callback ( null , pluginResult ) ;
}
} else if ( pluginResult . match ( ) ) {
2018-08-08 12:42:45 +00:00
return pluginResult . process ( callback ) ;
}
2017-03-30 11:12:39 +00:00
}
2018-05-18 15:04:49 +00:00
2017-03-30 11:12:39 +00:00
let output = this . processEmbarkCmd ( cmd ) ;
if ( output ) {
2018-08-08 12:42:45 +00:00
return callback ( null , output ) ;
2017-03-30 11:12:39 +00:00
}
2018-05-18 14:42:30 +00:00
2017-03-30 11:12:39 +00:00
try {
2018-08-15 10:03:50 +00:00
this . events . request ( 'runcode:eval' , cmd , callback ) ;
2017-03-30 11:12:39 +00:00
}
catch ( e ) {
2018-08-08 12:42:45 +00:00
if ( this . ipc . connected && this . ipc . isClient ( ) ) {
return this . ipc . request ( 'console:executeCmd' , cmd , callback ) ;
2017-03-30 11:12:39 +00:00
}
2018-08-15 09:40:51 +00:00
callback ( e ) ;
2017-02-16 01:24:42 +00:00
}
2016-09-23 04:31:09 +00:00
}
2018-08-30 09:41:13 +00:00
registerEmbarkJs ( ) {
2018-08-31 08:24:45 +00:00
this . events . emit ( 'runcode:register' , 'IpfsApi' , IpfsApi , false ) ;
this . events . emit ( 'runcode:register' , 'Web3' , Web3 , false ) ;
this . events . emit ( 'runcode:register' , 'EmbarkJS' , EmbarkJS , false ) ;
2018-08-30 09:41:13 +00:00
2018-09-20 10:02:21 +00:00
EmbarkJS . Blockchain . done = true ;
if ( this . ipc . connected ) {
return ;
}
2018-08-30 09:41:13 +00:00
2018-09-20 10:02:21 +00:00
this . events . once ( 'code-generator-ready' , ( ) => {
2018-08-30 09:41:13 +00:00
this . events . request ( 'code-generator:embarkjs:provider-code' , ( code ) => {
const func = ( ) => { } ;
this . events . request ( 'runcode:eval' , code , func , true ) ;
this . events . request ( 'runcode:eval' , this . getInitProviderCode ( ) , func , true ) ;
} ) ;
} ) ;
}
getInitProviderCode ( ) {
const codeTypes = {
'communication' : this . config . communicationConfig || { } ,
'names' : this . config . namesystemConfig || { } ,
'storage' : this . config . storageConfig || { }
} ;
return this . plugins . getPluginsFor ( 'initConsoleCode' ) . reduce ( ( acc , plugin ) => {
Object . keys ( codeTypes ) . forEach ( codeTypeName => {
( plugin . embarkjs _init _console _code [ codeTypeName ] || [ ] ) . forEach ( initCode => {
let [ block , shouldInit ] = initCode ;
if ( shouldInit . call ( plugin , codeTypes [ codeTypeName ] ) ) {
acc += block ;
}
} ) ;
} ) ;
return acc ;
} , '' ) ;
}
2018-10-08 09:04:34 +00:00
registerConsoleCommands ( ) {
this . embark . registerConsoleCommand ( ( cmd , _options ) => {
let [ cmdName , length ] = cmd . split ( ' ' ) ;
return {
match : ( ) => cmdName === 'history' ,
process : ( callback ) => this . getHistory ( length , callback )
} ;
} ) ;
}
loadHistory ( ) {
if ( fs . existsSync ( this . cmdHistoryFile ) ) {
fs . readFileSync ( this . cmdHistoryFile )
. toString ( )
. split ( '\n' )
. reverse ( )
. forEach ( ( cmd ) => { this . history . push ( cmd ) ; } ) ;
}
}
getHistory ( _length , callback ) {
if ( typeof _length === "string" ) {
_length = parseInt ( _length , 10 ) ;
if ( isNaN ( _length ) ) return callback ( "Invalid argument. Please provide an integer." ) ;
}
let length = _length || process . env . DEFAULT _CMD _HISTORY _SIZE ;
return callback ( null , this . history
. slice ( Math . max ( 0 , this . history . length - length ) )
. filter ( line => line . trim ( ) )
. reverse ( )
. join ( '\n' ) ) ;
}
saveHistory ( ) {
if ( fs . existsSync ( utils . dirname ( this . cmdHistoryFile ) ) ) {
fs . writeFileSync ( this . cmdHistoryFile ,
this . history
. slice ( Math . max ( 0 , this . history . length - process . env . DEFAULT _CMD _HISTORY _SIZE ) )
. reverse ( )
. filter ( line => line . trim ( ) )
. join ( '\n' ) ) ;
}
}
2017-03-30 11:12:39 +00:00
}
2016-09-23 04:31:09 +00:00
module . exports = Console ;