mirror of
https://github.com/embarklabs/embark.git
synced 2025-02-01 08:26:55 +00:00
1d6da99e8f
display last line on tx fix debugger call listen to source event only after jumping to the end keep track of last tx; add minimal debug feature; fix ast issue initial debugger apis & ui integration prevent crash when step is out of bounds; send all all available data in websocket add debugger commands fix line number tracking in editor; toggle breakpoints replace timeouts with callbacks add debugger manager & refactor refactor debugger api refactor cmd line debugger reduce debugger decoupling reduce debugger decoupling fix debug buttons trigger source update so api triggers ws event to update source location move locals and contracts vars to a json view improve debugger icons simplify debugger data update debug package add command handler to get a contract given a tx; update debugger so it can get a contract by its tx instead of tracking latest txs only update debugger package
194 lines
6.9 KiB
JavaScript
194 lines
6.9 KiB
JavaScript
let fs = require('../../core/fs');
|
|
let utils = require('../../utils/utils');
|
|
const EmbarkJS = require('embarkjs');
|
|
const IpfsApi = require('ipfs-api');
|
|
const Web3 = require('web3');
|
|
const stringify = require('json-stringify-safe');
|
|
const Suggestions = require('./suggestions')
|
|
|
|
class Console {
|
|
constructor(embark, options) {
|
|
this.embark = embark;
|
|
this.events = options.events;
|
|
this.plugins = options.plugins;
|
|
this.version = options.version;
|
|
this.logger = options.logger;
|
|
this.ipc = options.ipc;
|
|
this.config = options.config;
|
|
this.history = [];
|
|
this.cmdHistoryFile = options.cmdHistoryFile || process.env.DEFAULT_CMD_HISTORY_PATH;
|
|
this.loadHistory();
|
|
|
|
if (this.ipc.isServer()) {
|
|
this.ipc.on('console:executeCmd', this.executeCmd.bind(this));
|
|
}
|
|
this.events.setCommandHandler("console:executeCmd", this.executeCmd.bind(this));
|
|
this.events.setCommandHandler("console:history", (cb) => this.getHistory(process.env.DEFAULT_CMD_HISTORY_SIZE, cb));
|
|
this.registerEmbarkJs();
|
|
this.registerConsoleCommands();
|
|
this.registerApi();
|
|
|
|
this.suggestions = new Suggestions(embark, options);
|
|
}
|
|
|
|
registerApi() {
|
|
let plugin = this.plugins.createPlugin('consoleApi', {});
|
|
plugin.registerAPICall('post', '/embark-api/command', (req, res) => {
|
|
this.executeCmd(req.body.command, (err, result) => {
|
|
if (err) {
|
|
return res.send({result: err.message || err});
|
|
}
|
|
if (typeof result === 'string') {
|
|
return res.send({result});
|
|
}
|
|
res.send({result: stringify(result, null, 2)});
|
|
});
|
|
});
|
|
}
|
|
|
|
processEmbarkCmd (cmd) {
|
|
if (cmd === 'help' || cmd === __('help') || cmd === '01189998819991197253') {
|
|
let helpText = [
|
|
__('Welcome to Embark') + ' ' + this.version,
|
|
'',
|
|
__('possible commands are:'),
|
|
'versions - ' + __('display versions in use for libraries and tools like web3 and solc'),
|
|
'history - ' + __('display console commands history'),
|
|
// TODO: only if the blockchain is actually active!
|
|
// will need to pass te current embark state here
|
|
'ipfs - ' + __('instantiated js-ipfs object configured to the current environment (available if ipfs is enabled)'),
|
|
'swarm - ' + __('instantiated swarm-api object configured to the current environment (available if swarm is enabled)'),
|
|
'web3 - ' + __('instantiated web3.js object configured to the current environment'),
|
|
'EmbarkJS - ' + __('EmbarkJS static functions for Storage, Messages, Names, etc.'),
|
|
'quit - ' + __('to immediatly exit (alias: exit)'),
|
|
'',
|
|
__('The web3 object and the interfaces for the deployed contracts and their methods are also available')
|
|
];
|
|
return helpText.join('\n');
|
|
} else if (['quit', 'exit', 'sair', 'sortir', __('quit')].indexOf(cmd) >= 0) {
|
|
utils.exit();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
executeCmd(cmd, callback) {
|
|
if (!(cmd.split(' ')[0] === 'history' || cmd === __('history'))) {
|
|
this.history.push(cmd);
|
|
this.saveHistory();
|
|
}
|
|
var pluginCmds = this.plugins.getPluginsProperty('console', 'console');
|
|
for (let pluginCmd of pluginCmds) {
|
|
let pluginResult = pluginCmd.call(this, cmd, {});
|
|
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 " +
|
|
"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");
|
|
return callback(null, pluginResult);
|
|
}
|
|
} else if (pluginResult.match()) {
|
|
return pluginResult.process(callback);
|
|
}
|
|
}
|
|
|
|
let output = this.processEmbarkCmd(cmd);
|
|
if (output) {
|
|
return callback(null, output);
|
|
}
|
|
|
|
try {
|
|
this.events.request('runcode:eval', cmd, callback);
|
|
}
|
|
catch (e) {
|
|
if (this.ipc.connected && this.ipc.isClient()) {
|
|
return this.ipc.request('console:executeCmd', cmd, callback);
|
|
}
|
|
callback(e);
|
|
}
|
|
}
|
|
|
|
registerEmbarkJs() {
|
|
this.events.emit('runcode:register', 'IpfsApi', IpfsApi, false);
|
|
this.events.emit('runcode:register', 'Web3', Web3, false);
|
|
this.events.emit('runcode:register', 'EmbarkJS', EmbarkJS, false);
|
|
|
|
EmbarkJS.Blockchain.done = true;
|
|
if (this.ipc.connected) {
|
|
return;
|
|
}
|
|
|
|
this.events.once('code-generator-ready', () => {
|
|
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;
|
|
}, '');
|
|
}
|
|
|
|
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'));
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = Console;
|