refactor(@embark/core): move Engine into embark-core

This also moves other modules and packages into `embark-core` which are
affected by the move of `Engine`.

It did some clean-up of some modules (e.g. `lib/utils/utils.js` had a lot of
stuff that was not used anywhere).

This is the first step to start typing our core inside out. For now we're just
moving code into their dedicated package, after that we can address making
use of TypeScript features as we see fit.
This commit is contained in:
Pascal Precht 2019-10-30 15:36:21 +01:00
parent 6afe1ace08
commit 96b6dd27c0
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
86 changed files with 3436 additions and 3553 deletions

View File

@ -22,6 +22,8 @@ module.exports = (api) => {
['@babel/plugin-proposal-decorators', {
legacy: true
}],
'@babel/plugin-proposal-export-namespace-from',
'@babel/plugin-proposal-export-default-from',
'@babel/plugin-syntax-dynamic-import',
['@babel/plugin-proposal-class-properties', {
loose: true

View File

@ -52,6 +52,8 @@
"core-js": "3.3.5",
"embark-utils": "^5.0.0-alpha.1",
"embarkjs": "^5.0.0-alpha.1",
"embark-core": "^5.0.0-alpha.1",
"embark-logger": "^5.0.0-alpha.1",
"fs-extra": "8.1.0",
"parse-json": "4.0.0",
"vm2": "3.6.4",

View File

@ -1,11 +1,11 @@
import { Callback, Embark, Events } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import { __ } from "embark-i18n";
import { Logger } from 'embark-logger';
import * as fs from "./fs";
import VM from "./vm";
export { fs, VM };
import { Callback, Embark, Events, Logger } /* supplied by @types/embark in packages/embark-typings */ from "embark";
class CodeRunner {
private logger: Logger;
private events: Events;

View File

@ -1,6 +1,7 @@
import { each } from "async";
import { Callback, Logger } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import { Callback } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import { compact, dappPath, isEs6Module, recursiveMerge } from "embark-utils";
import { Logger } from 'embark-logger';
import * as path from "path";
import { NodeVM, NodeVMOptions } from "vm2";

View File

@ -50,8 +50,8 @@ class Console {
this.executeCmd(cmd, (err: any, result: any) => {
if (err) {
// reformat for IPC reply
err = { name: "Console error", message: err, stack: err.stack };
return cb(err);
const error = { name: "Console error", message: err, stack: err.stack };
return cb(error);
}
cb(null, util.inspect(result));
});
@ -178,7 +178,7 @@ class Console {
this.saveHistory(cmd);
}
const plugins = this.plugins.getPluginsProperty("console", "console");
const helpDescriptions = [];
const helpDescriptions: any[] = [];
for (const plugin of plugins) {
if (plugin.description) {
helpDescriptions.push({

View File

@ -1,6 +1,6 @@
/*globals describe, it*/
import Console from '../lib';
import Logger from 'embark-logger';
import { Logger } from 'embark-logger';
import { joinPath, setUpEnv } from 'embark-utils';
import assert from 'assert';
import { version } from '../../package.json';

View File

@ -34,29 +34,44 @@
"_build": "npm run solo -- build",
"ci": "npm run qa",
"clean": "npm run reset",
"lint": "eslint process.js src/",
"qa": "npm-run-all lint _build",
"lint": "npm-run-all lint:*",
"lint:js": "eslint process.js src/",
"// lint:ts": "tslint -c tslint.json \"src/**/*.ts\"",
"qa": "npm-run-all lint typecheck _build",
"reset": "npx rimraf dist embark-*.tgz package",
"solo": "embark-solo"
"solo": "embark-solo",
"typecheck": "tsc"
},
"eslintConfig": {
"extends": "../../../.eslintrc.json"
},
"dependencies": {
"@babel/runtime-corejs3": "7.6.3",
"colors": "1.3.2",
"core-js": "3.3.5",
"embark-i18n": "^5.0.0-alpha.1",
"embark-utils": "^5.0.0-alpha.1",
"embark-logger": "^5.0.0-alpha.1",
"decompress": "4.2.0",
"flatted": "0.2.3",
"fs-extra": "8.1.0",
"globule": "1.2.1",
"lodash.clonedeep": "4.5.0",
"node-ipc": "9.1.1",
"uuid": "3.3.2"
"parse-json": "4.0.0",
"shelljs": "0.8.3",
"uuid": "3.3.2",
"window-size": "1.1.1"
},
"devDependencies": {
"@babel/core": "7.6.4",
"babel-jest": "24.9.0",
"embark-solo": "^5.0.0-alpha.0",
"eslint": "5.7.0",
"npm-run-all": "4.1.5",
"rimraf": "3.0.0"
"rimraf": "3.0.0",
"tslint": "5.16.0",
"typescript": "3.6.3"
},
"engines": {
"node": ">=10.17.0 <12.0.0",

View File

@ -0,0 +1,761 @@
import * as fs from './fs';
import { Plugins } from './plugins';
import { Plugin } from './plugin';
import { EmbarkEmitter as Events } from './events';
import { filesMatchingPattern, fileMatchesPattern } from './utils/utils';
const path = require('path');
const deepEqual = require('deep-equal');
const web3 = require('web3');
const constants = require('embark-core/constants');
import { __ } from 'embark-i18n';
import {
buildUrlFromConfig,
canonicalHost,
dappPath,
defaultHost,
File,
Types,
recursiveMerge,
AddressUtils,
unitRegex,
getWeiBalanceFromString,
prepareContractsConfig,
getExternalContractUrl
} from 'embark-utils';
import { Logger } from 'embark-logger';
const cloneDeep = require('lodash.clonedeep');
const { replaceZeroAddressShorthand } = AddressUtils;
import { getBlockchainDefaults, getContractDefaults } from './configDefaults';
const DEFAULT_CONFIG_PATH = 'config/';
const embark5ChangesUrl = 'https://embark.status.im/docs/migrating_from_3.x.html#Updating-to-v5';
export class Config {
env = 'default';
blockchainConfig: any = {};
contractsConfig: any = {};
pipelineConfig: any = {};
namesystemConfig: any = {};
communicationConfig: any = {};
webServerConfig: any;
storageConfig: any;
chainTracker: any = {};
assetFiles: any = {};
contractsFiles: File[] = [];
configDir: string;
chainsFile = './chains.json';
plugins: Plugins;
logger: Logger;
package: any;
events: Events;
embarkConfig: any = {};
context: any;
version: string;
shownNoAccountConfigMsg = false; // flag to ensure "no account config" message is only displayed once to the user
corsParts: string[] = [];
providerUrl = null;
contractDirectories: string[] = [];
buildDir: any;
dappPath = dappPath;
constructor(options) {
this.env = options.env || 'default';
this.webServerConfig = options.webServerConfig;
this.configDir = options.configDir || DEFAULT_CONFIG_PATH;
this.chainsFile = options.chainsFile;
this.plugins = options.plugins;
this.logger = options.logger;
this.package = options.package;
this.events = options.events;
this.context = options.context || [constants.contexts.any];
this.version = options.version;
this.registerEvents();
}
setConfig(configName, newConfig, cb) {
this[configName] = newConfig;
cb();
}
registerEvents() {
this.events.setCommandHandler("config:cors:add", (url) => {
this.corsParts.push(url);
this._updateBlockchainCors();
});
this.events.setCommandHandler("config:contractsConfig", (cb) => {
cb(null, this.contractsConfig);
});
this.events.setCommandHandler("config:storageConfig", (cb) => {
cb(null, this.storageConfig);
});
this.events.setCommandHandler("config:contractsConfig:set", this.setConfig.bind(this, 'contractsConfig'));
this.events.setCommandHandler("config:blockchainConfig:set", this.setConfig.bind(this, 'blockchainConfig'));
this.events.setCommandHandler("config:storageConfig:set", this.setConfig.bind(this, 'storageConfig'));
this.events.setCommandHandler("config:namesystemConfig:set", this.setConfig.bind(this, 'namesystemConfig'));
this.events.setCommandHandler("config:communicationConfig:set", this.setConfig.bind(this, 'communicationConfig'));
this.events.setCommandHandler("config:contractsFiles", (cb) => {
cb(null, this.contractsFiles);
});
// TODO: refactor this so reading the file can be done with a normal resolver or something that takes advantage of the plugin api
this.events.setCommandHandler("config:contractsFiles:add", (filename, resolver) => {
resolver = resolver || function(callback) { callback(fs.readFileSync(filename).toString()); };
this.contractsFiles.push(new File({path: filename, originalPath: filename, type: Types.custom, resolver}));
});
this.events.setCommandHandler("config:contractsFiles:reset", (cb) => {
this.contractsFiles.forEach((file) => {
if (file.path.includes(".embark")) {
fs.removeSync(file.path);
}
this.contractsFiles = this.contractsFiles.filter((contractFile) => contractFile.path !== file.path);
});
cb();
});
this.events.on('file-remove', (fileType, removedPath) => {
if (fileType !== 'contract') {
return;
}
const normalizedPath = path.normalize(removedPath);
this.contractsFiles = this.contractsFiles.filter(file => path.normalize(file.path) !== normalizedPath);
});
}
loadConfigFiles(options) {
let interceptLogs = options.interceptLogs;
if (options.interceptLogs === undefined) {
interceptLogs = true;
}
if (!fs.existsSync(options.embarkConfig)) {
this.logger.error(__('Cannot find file %s Please ensure you are running this command inside the Dapp folder', options.embarkConfig));
process.exit(1);
}
this.embarkConfig = fs.readJSONSync(options.embarkConfig);
this.embarkConfig.plugins = this.embarkConfig.plugins || {};
this.plugins = new Plugins({
plugins: this.embarkConfig.plugins,
logger: this.logger,
interceptLogs,
events: this.events,
config: this,
context: this.context,
env: this.env,
version: this.version
});
this.plugins.loadPlugins();
this.loadEmbarkConfigFile();
this.loadBlockchainConfigFile();
this.loadStorageConfigFile();
this.loadContractFiles();
this.loadCommunicationConfigFile();
this.loadNameSystemConfigFile();
this.loadPipelineConfigFile();
this.loadAssetFiles();
this.loadContractsConfigFile();
this.loadExternalContractsFiles();
this.loadWebServerConfigFile();
this.loadPluginContractFiles();
this._updateBlockchainCors();
}
reloadConfig() {
this.loadEmbarkConfigFile();
this.loadBlockchainConfigFile();
this.loadStorageConfigFile();
this.loadContractFiles();
this.loadCommunicationConfigFile();
this.loadNameSystemConfigFile();
this.loadPipelineConfigFile();
this.loadAssetFiles();
this.loadContractsConfigFile();
this.loadExternalContractsFiles();
this._updateBlockchainCors();
}
loadContractFiles() {
const loadedContractFiles = this.loadFiles(this.embarkConfig.contracts);
// `this.contractsFiles` could've been mutated at runtime using
// either `config:contractsFiles:add` event or through calls to
// `loadExternalContractsFiles()`, so we have to make sure we preserve
// those added files before we reset `this.contractsFiles`.
//
// We do that by determining the difference between `loadedContractFiles` and the ones
// already in memory in `this.contractsFiles`.
const addedContractFiles = this.contractsFiles.filter(existingFile => !loadedContractFiles.some(file => file.originalPath === existingFile.originalPath));
this.contractsFiles = loadedContractFiles.concat(addedContractFiles);
}
_updateBlockchainCors() {
const blockchainConfig = this.blockchainConfig;
const storageConfig = this.storageConfig;
const webServerConfig = this.webServerConfig;
let corsParts = cloneDeep(this.corsParts);
if (blockchainConfig.isDev) {
corsParts.push('*');
}
if (webServerConfig && webServerConfig.host) {
corsParts.push(buildUrlFromConfig(webServerConfig));
}
if (storageConfig && storageConfig.enabled) {
// if getUrl is specified in the config, that needs to be included in cors
// instead of the concatenated protocol://host:port
if (storageConfig.upload.getUrl) {
// remove /ipfs or /bzz: from getUrl if it's there
let getUrlParts = storageConfig.upload.getUrl.split('/');
getUrlParts = getUrlParts.slice(0, 3);
const host = canonicalHost(getUrlParts[2].split(':')[0]);
const port = getUrlParts[2].split(':')[1];
getUrlParts[2] = port ? [host, port].join(':') : host;
corsParts.push(getUrlParts.join('/'));
} else {
corsParts.push(buildUrlFromConfig(storageConfig.upload));
}
}
// Add cors for the proxy and whisper
corsParts.push(constants.embarkResourceOrigin);
corsParts = Array.from(new Set(corsParts));
this.corsParts = corsParts;
const cors = corsParts.join(',');
if (blockchainConfig.rpcCorsDomain === 'auto') {
blockchainConfig.rpcCorsDomain = cors;
} else if (typeof blockchainConfig.rpcCorsDomain === 'object') {
let tempCors = blockchainConfig.rpcCorsDomain.auto ? corsParts : [];
tempCors = tempCors.concat(blockchainConfig.rpcCorsDomain.additionalCors || []);
blockchainConfig.rpcCorsDomain = tempCors.join(',');
}
if (blockchainConfig.wsOrigins === 'auto') {
blockchainConfig.wsOrigins = cors;
} else if (typeof blockchainConfig.wsOrigins === 'object') {
let tempCors = blockchainConfig.wsOrigins.auto ? corsParts : [];
tempCors = tempCors.concat(blockchainConfig.wsOrigins.additionalCors || []);
blockchainConfig.wsOrigins = tempCors.join(',');
}
}
_loadConfigFile(configFilePath, defaultConfig, enabledByDefault = false) {
if (!configFilePath) {
const configToReturn = defaultConfig.default || {};
configToReturn.enabled = enabledByDefault;
return configToReturn;
}
configFilePath = configFilePath.replace('.json', '').replace('.js', '');
let config;
if (fs.existsSync(configFilePath + '.js')) {
delete require.cache[configFilePath + '.js'];
config = require(configFilePath + '.js');
} else if (fs.existsSync(configFilePath + '.json')) {
config = fs.readJSONSync(configFilePath + '.json');
} else {
this.logger.warn(__("no config file found at %s using default config", configFilePath));
return defaultConfig.default || {};
}
return config;
}
_doMergeConfig(config, defaultConfig, env) {
const configObject = recursiveMerge(defaultConfig, config);
if (env) {
if (env === 'test' && !configObject[env]) {
// Disabled all configs in tests as they are opt in
return Object.assign({}, defaultConfig.default, {enabled: false});
}
return recursiveMerge(configObject.default || {}, configObject[env]);
} else if (env !== false) {
this.logger.info(__("No environment called %s found. Using defaults.", env));
}
return configObject;
}
_loadAndMergeConfig(configFilePath, defaultConfig, env, enabledByDefault = false) {
const config = this._loadConfigFile(configFilePath, defaultConfig, enabledByDefault);
return this._doMergeConfig(config, defaultConfig, env);
}
_getFileOrObject(object, filePath, property) {
if (typeof object === 'object') {
return object[property] ? dappPath(object[property]) : object[property];
}
return dappPath(object, filePath);
}
/*eslint complexity: ["error", 30]*/
loadBlockchainConfigFile() {
const blockchainDefaults = getBlockchainDefaults(this.env);
const configFilePath = this._getFileOrObject(this.configDir, 'blockchain', 'blockchain');
const userConfig = this._loadConfigFile(configFilePath, blockchainDefaults, true);
const envConfig = userConfig[this.env];
if (envConfig) {
if (envConfig.ethereumClientName || envConfig.hasOwnProperty('isDev') || envConfig.hasOwnProperty('mineWhenNeeded')) {
this.logger.error(__('The blockchain config has changed quite a bit in Embark 5\nPlease visit %s to know what has to be changed', embark5ChangesUrl.underline));
process.exit(1);
}
if (envConfig.clientConfig) {
Object.assign(envConfig, envConfig.clientConfig);
delete envConfig.clientConfig;
}
switch (envConfig.miningMode) {
case 'dev': envConfig.isDev = true; break;
case 'auto': envConfig.isDev = false; envConfig.mineWhenNeeded = true; break;
case 'always': envConfig.isDev = false; envConfig.mineWhenNeeded = false; envConfig.mine = true; break;
case 'off': envConfig.isDev = false; envConfig.mineWhenNeeded = false; envConfig.mine = false; break;
default: envConfig.isDev = false;
}
if (envConfig.cors) {
const autoIndex = envConfig.cors.indexOf('auto');
envConfig.rpcCorsDomain = {};
envConfig.wsOrigins = {};
if (autoIndex > -1) {
envConfig.rpcCorsDomain.auto = true;
envConfig.wsOrigins.auto = true;
envConfig.cors.splice(autoIndex, 1);
} else {
envConfig.rpcCorsDomain.auto = false;
envConfig.wsOrigins.auto = false;
}
envConfig.rpcCorsDomain.additionalCors = envConfig.cors;
envConfig.wsOrigins.additionalCors = envConfig.cors;
delete envConfig.cors;
}
userConfig[this.env] = envConfig;
}
this.blockchainConfig = this._doMergeConfig(userConfig, blockchainDefaults, this.env);
if (!configFilePath) {
this.blockchainConfig.default = true;
}
if (this.blockchainConfig.targetGasLimit && this.blockchainConfig.targetGasLimit.toString().match(unitRegex)) {
this.blockchainConfig.targetGasLimit = getWeiBalanceFromString(this.blockchainConfig.targetGasLimit, web3);
}
if (this.blockchainConfig.gasPrice && this.blockchainConfig.gasPrice.toString().match(unitRegex)) {
this.blockchainConfig.gasPrice = getWeiBalanceFromString(this.blockchainConfig.gasPrice, web3);
}
if (this.blockchainConfig.accounts) {
this.blockchainConfig.accounts.forEach(acc => {
if (acc.balance && acc.balance.toString().match(unitRegex)) {
acc.balance = getWeiBalanceFromString(acc.balance, web3);
}
});
}
if (!this.blockchainConfig.endpoint) {
const urlConfig = (this.blockchainConfig.wsHost) ? {
host: this.blockchainConfig.wsHost,
port: this.blockchainConfig.wsPort,
type: 'ws'
} : {
host: this.blockchainConfig.rpcHost,
port: this.blockchainConfig.rpcPort,
type: 'rpc'
};
this.blockchainConfig.endpoint = buildUrlFromConfig(urlConfig);
this.blockchainConfig.isAutoEndpoint = true;
}
if (
!this.shownNoAccountConfigMsg &&
(/rinkeby|testnet|livenet/).test(this.blockchainConfig.networkType) &&
!(this.blockchainConfig.accounts && this.blockchainConfig.accounts.find(acc => acc.password)) &&
!this.blockchainConfig.isDev &&
this.env !== 'development' && this.env !== 'test') {
this.logger.warn((
'\n=== ' + __('Cannot unlock account - account config missing').bold + ' ===\n' +
__('Geth is configured to sync to a testnet/livenet and needs to unlock an account ' +
'to allow your dApp to interact with geth, however, the address and password must ' +
'be specified in your blockchain config. Please update your blockchain config with ' +
'a valid address and password: \n') +
` - config/blockchain.js > ${this.env} > account\n\n`.italic +
__('Please also make sure the keystore file for the account is located at: ') +
'\n - Mac: ' + `~/Library/Ethereum/${this.env}/keystore`.italic +
'\n - Linux: ' + `~/.ethereum/${this.env}/keystore`.italic +
'\n - Windows: ' + `%APPDATA%\\Ethereum\\${this.env}\\keystore`.italic) +
__('\n\nAlternatively, you could change ' +
`config/blockchain.js > ${this.env} > networkType`.italic +
__(' to ') +
'"custom"\n'.italic).yellow
);
this.shownNoAccountConfigMsg = true;
}
const accountDocsMessage = __('For more info, check the docs: %s', 'https://embark.status.im/docs/blockchain_accounts_configuration.html'.underline);
if (this.blockchainConfig.account) {
this.logger.error(__('The `account` config for the blockchain was removed. Please use `accounts` instead.'));
this.logger.error(accountDocsMessage);
process.exit(1);
}
if (this.blockchainConfig.simulatorMnemonic) {
this.logger.error(__('The `simulatorMnemonic` config for the blockchain was removed. Please use `accounts` instead.'));
this.logger.error(accountDocsMessage);
process.exit(1);
}
this.events.emit('config:load:blockchain', this.blockchainConfig);
}
loadContractsConfigFile() {
let configObject = getContractDefaults(this.embarkConfig.versions);
const contractsConfigs = this.plugins.getPluginsProperty('contractsConfig', 'contractsConfigs');
contractsConfigs.forEach(function(pluginConfig) {
configObject = recursiveMerge(configObject, pluginConfig);
});
const configFilePath = this._getFileOrObject(this.configDir, 'contracts', 'contracts');
let newContractsConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
if (newContractsConfig.contracts) {
this.logger.error(__('`contracts` has been renamed `deploy` in contracts config\nFor more information: %s', embark5ChangesUrl.underline));
process.exit(1);
}
if (newContractsConfig.deployment) {
this.logger.error(__('`deployment` has been removed from contracts config and is now part of blockchain config\nFor more information: %s', embark5ChangesUrl.underline));
process.exit(1);
}
if (newContractsConfig.gas.match(unitRegex)) {
newContractsConfig.gas = getWeiBalanceFromString(newContractsConfig.gas, web3);
}
newContractsConfig = prepareContractsConfig(newContractsConfig);
const afterDeploy = newContractsConfig.afterDeploy;
if (Array.isArray(afterDeploy)) {
newContractsConfig.afterDeploy = afterDeploy.map(replaceZeroAddressShorthand);
}
if (!deepEqual(newContractsConfig, this.contractsConfig)) {
this.contractsConfig = newContractsConfig;
}
this.events.emit('config:load:contracts', this.contractsConfig);
}
loadExternalContractsFiles() {
const contracts = this.contractsConfig.contracts;
const storageConfig = this.storageConfig;
if (storageConfig && storageConfig.upload && storageConfig.upload.getUrl) {
this.providerUrl = storageConfig.upload.getUrl;
}
for (const contractName in contracts) {
const contract = contracts[contractName];
if (!contract.file) {
continue;
}
let externalContractFile;
if (contract.file.startsWith('http') || contract.file.startsWith('git') || contract.file.startsWith('ipfs') || contract.file.startsWith('bzz')) {
const fileObj = getExternalContractUrl(contract.file, this.providerUrl);
if (!fileObj) {
return this.logger.error(__("HTTP contract file not found") + ": " + contract.file);
}
externalContractFile = new File({ path: fileObj.filePath, originalPath: fileObj.filePath, type: Types.http, basedir: '', externalUrl: fileObj.url, storageConfig });
} else if (fs.existsSync(contract.file)) {
externalContractFile = new File({ path: contract.file, originalPath: contract.file, type: Types.dappFile, basedir: '', storageConfig });
} else if (fs.existsSync(path.join('./node_modules/', contract.file))) {
const completePath = path.join('./node_modules/', contract.file);
externalContractFile = new File({ path: completePath, originalPath: completePath, type: Types.dappFile, basedir: '', storageConfig });
}
if (externalContractFile) {
const index = this.contractsFiles.findIndex(contractFile => contractFile.originalPath === externalContractFile.originalPath);
// It's important that we only add `externalContractFile` if it doesn't exist already
// within `contractsFiles`, otherwise we keep adding duplicates in subsequent
// compilation routines creating a memory leak.
if (index > -1) {
this.contractsFiles[index] = externalContractFile;
} else {
this.contractsFiles.push(externalContractFile);
}
} else {
this.logger.error(__("contract file not found") + ": " + contract.file);
}
}
}
loadStorageConfigFile() {
const versions = recursiveMerge({"ipfs-api": "17.2.4"}, this.embarkConfig.versions || {});
const configObject = {
default: {
versions,
enabled: true,
available_providers: ["ipfs", "swarm"],
ipfs_bin: "ipfs",
upload: {
provider: "ipfs",
protocol: "http",
host : defaultHost,
port: 5001,
getUrl: "http://localhost:8080/ipfs/"
},
dappConnection: [{provider: "ipfs", host: "localhost", port: 5001, getUrl: "http://localhost:8080/ipfs/"}]
}
};
const configFilePath = this._getFileOrObject(this.configDir, 'storage', 'storage');
this.storageConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
this.events.emit('config:load:storage', this.storageConfig);
}
loadNameSystemConfigFile() {
// todo: spec out names for registration in the file itself for a dev chain
const configObject = {
default: {
enabled: false
}
};
const configFilePath = this._getFileOrObject(this.configDir, 'namesystem', 'namesystem');
this.namesystemConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
}
loadCommunicationConfigFile() {
const configObject = {
default: {
enabled: true,
provider: "whisper",
available_providers: ["whisper"],
connection: {
host: defaultHost,
port: 8557,
type: "ws"
}
}
};
const configFilePath = this._getFileOrObject(this.configDir, 'communication', 'communication');
this.communicationConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
this.events.emit('config:load:communication', this.communicationConfig);
}
loadWebServerConfigFile() {
const configObject = {
enabled: true,
host: defaultHost,
openBrowser: true,
port: 8000,
enableCatchAll: true,
protocol: "http"
};
const configFilePath = this._getFileOrObject(this.configDir, 'webserver', 'webserver');
const webServerConfig = this._loadAndMergeConfig(configFilePath, configObject, false);
if (webServerConfig.https) {
try {
webServerConfig.certOptions = {
key: fs.readFileSync(webServerConfig.key),
cert: fs.readFileSync(webServerConfig.cert)
};
webServerConfig.protocol = 'https';
} catch (e) {
this.logger.error(e.message);
this.logger.warn('Invalid path for key/cert in config/webserver.js. Using http instead.');
webServerConfig.certOptions = {};
webServerConfig.protocol = 'http';
}
}
if (configFilePath === false) {
this.webServerConfig = {enabled: false};
return;
}
if (this.webServerConfig) {
// cli flags to `embark run` should override configFile and defaults (configObject)
this.webServerConfig = recursiveMerge(webServerConfig, this.webServerConfig);
} else {
this.webServerConfig = webServerConfig;
}
if (!this.pipelineConfig.enabled) {
this.webServerConfig.enabled = false;
}
this.events.emit('config:load:webserver', this.webServerConfig);
}
loadEmbarkConfigFile() {
const configObject = {
options: {
solc: {
"optimize": true,
"optimize-runs": 200
}
},
generationDir: "embarkArtifacts"
};
this.embarkConfig = recursiveMerge(configObject, this.embarkConfig);
const contracts = this.embarkConfig.contracts;
// determine contract 'root' directories
this.contractDirectories = contracts.map((dir) => {
return dir.split("**")[0];
}).map((dir) => {
return dir.split("*.")[0];
});
this.contractDirectories.push(constants.httpContractsDirectory);
this.buildDir = this.embarkConfig.buildDir;
this.configDir = this.embarkConfig.config;
}
loadPipelineConfigFile() {
const defaultPipelineConfig = {
typescript: false,
enabled: true
};
let pipelineConfigPath = this._getFileOrObject(this.configDir, 'pipeline', 'pipeline');
// Embark applications in "simple" mode that aren't aware of `pipeline.js` configuration capabilities
// won't have a pipeline config path so we need to perform this safety check here, otherwise the
// next expression is going to throw.
if (pipelineConfigPath !== undefined) {
// At this point, `pipelineConfigPath` could be either `config/pipeline` or a filepath including its extension.
// We need to make sure that we always have an extension.
pipelineConfigPath = `${dappPath(pipelineConfigPath)}${path.extname(pipelineConfigPath) === '.js' ? '' : '.js'}`;
}
let pipelineConfig = defaultPipelineConfig;
if (pipelineConfigPath && fs.existsSync(pipelineConfigPath)) {
delete require.cache[pipelineConfigPath];
pipelineConfig = recursiveMerge(
recursiveMerge(true, pipelineConfig),
require(pipelineConfigPath)
);
}
this.pipelineConfig = pipelineConfig;
this.events.emit('config:load:pipeline', this.pipelineConfig);
}
loadAssetFiles() {
if (!this.embarkConfig.app) { return; }
Object.keys(this.embarkConfig.app).forEach(targetFile => {
this.assetFiles[targetFile] = this.loadFiles(this.embarkConfig.app[targetFile]);
});
}
loadFiles(files) {
const self = this;
const originalFiles = filesMatchingPattern(files);
const readFiles: File[] = [];
const storageConfig = self.storageConfig;
originalFiles.filter(function(file) {
return (file[0] === '$' || file.indexOf('.') >= 0);
}).filter(function(file) {
const basedir = findMatchingExpression(file, files);
readFiles.push(new File({path: file, originalPath: file, type: Types.dappFile, basedir, storageConfig}));
});
const filesFromPlugins: File[] = [];
const filePlugins = self.plugins.getPluginsFor('pipelineFiles');
filePlugins.forEach((plugin: Plugin) => {
try {
const fileObjects = plugin.runFilePipeline();
for (let i = 0; i < fileObjects.length; i++) {
const fileObject = fileObjects[i];
filesFromPlugins.push(fileObject);
}
} catch (err) {
self.logger.error(err.message);
}
});
filesFromPlugins.filter(function(file) {
if ((file.intendedPath && fileMatchesPattern(files, file.intendedPath)) || fileMatchesPattern(files, file.file)) {
readFiles.push(file);
}
});
return readFiles;
}
// NOTE: this doesn't work for internal modules
loadPluginContractFiles() {
const self = this;
const storageConfig = self.storageConfig;
const contractsPlugins = this.plugins.getPluginsFor('contractFiles');
contractsPlugins.forEach((plugin: Plugin) => {
plugin.contractsFiles.forEach(file => {
const filename = file.replace('./', '');
self.contractsFiles.push(new File({ path: filename, originalPath: path.join(plugin.pluginPath, filename), pluginPath: plugin.pluginPath, type: Types.custom, storageConfig,
resolver(callback) {
callback(plugin.loadPluginFile(file));
}
}));
});
});
}
}
function findMatchingExpression(filename, filesExpressions) {
for (const fileExpression of filesExpressions) {
const matchingFiles = filesMatchingPattern(fileExpression);
for (const matchFile of matchingFiles) {
if (matchFile === filename) {
return path.dirname(fileExpression).replace(/\*/g, '');
}
}
}
return path.dirname(filename);
}

View File

@ -39,23 +39,23 @@ export function getBlockchainDefaults(env) {
export function getContractDefaults(embarkConfigVersions) {
const defaultVersions = {
"web3": "1.2.1",
"solc": "0.5.0"
web3: "1.2.1",
solc: "0.5.0"
};
const versions = recursiveMerge(defaultVersions, embarkConfigVersions || {});
return {
"default": {
"versions": versions,
"dappConnection": [
default: {
versions: versions,
dappConnection: [
"$WEB3",
"ws://localhost:8546",
"localhost:8545"
],
"dappAutoEnable": true,
"strategy": constants.deploymentStrategy.implicit,
"gas": "auto",
"deploy": {
dappAutoEnable: true,
strategy: constants.deploymentStrategy.implicit,
gas: "auto",
deploy: {
}
}
};

View File

@ -1,11 +1,63 @@
import {ProcessManager, IPC} from 'embark-core';
import { Config } from './config';
import { Plugins } from './plugins';
import { EmbarkEmitter as Events } from './events';
import { ProcessManager } from './processes/processManager';
import { IPC } from './ipc';
import { ServicesMonitor } from './services_monitor';
import { normalizeInput } from 'embark-utils';
import { Logger } from 'embark-logger';
const EMBARK_PROCESS_NAME = 'embark';
const utils = require('../utils/utils');
const Logger = require('embark-logger');
export class Engine {
env: string;
client: string;
locale: string;
embarkConfig: any;
interceptLogs: boolean;
version: string;
logFile: string;
logLevel: string;
events: Events;
context: any;
useDashboard: boolean;
webServerConfig: any;
webpackConfigName: string;
singleUseAuthToken: boolean;
ipcRole = 'client';
logger: Logger;
config: Config | undefined;
plugins: Plugins | undefined;
ipc: IPC | undefined;
processManager: ProcessManager | undefined;
servicesMonitor: ServicesMonitor | undefined;
package: any;
isDev: boolean | undefined;
class Engine {
constructor(options) {
this.env = options.env;
this.client = options.client;
@ -21,24 +73,23 @@ class Engine {
this.webServerConfig = options.webServerConfig;
this.webpackConfigName = options.webpackConfigName;
this.singleUseAuthToken = options.singleUseAuthToken;
this.package = options.package;
this.ipcRole = options.ipcRole || 'client';
}
init(_options, callback) {
callback = callback || function () {};
const Events = require('./events.js');
const Config = require('./config.js');
callback = callback || function() {};
let options = _options || {};
const options = _options || {};
this.events = options.events || this.events || new Events();
this.logger = options.logger || new Logger({context: this.context, logLevel: options.logLevel || this.logLevel || 'info', events: this.events, logFile: this.logFile});
this.config = new Config({env: this.env, logger: this.logger, events: this.events, context: this.context, webServerConfig: this.webServerConfig, version: this.version});
this.config = new Config({env: this.env, logger: this.logger, events: this.events, context: this.context, webServerConfig: this.webServerConfig, version: this.version, package: this.package});
this.config.loadConfigFiles({embarkConfig: this.embarkConfig, interceptLogs: this.interceptLogs});
this.plugins = this.config.plugins;
this.isDev = this.config && this.config.blockchainConfig && (this.config.blockchainConfig.isDev || this.config.blockchainConfig.default);
if (this.interceptLogs || this.interceptLogs === undefined) {
utils.interceptLogs(console, this.logger);
interceptLogs(console, this.logger);
}
this.ipc = new IPC({logger: this.logger, ipcRole: this.ipcRole});
@ -55,28 +106,36 @@ class Engine {
}
startEngine(cb) {
this.plugins.emitAndRunActionsForEvent("embark:engine:started", {}, (err) => {
if (err) {
console.error("error starting engine");
console.error(err);
process.exit(1);
}
if (this.plugins) {
this.plugins.emitAndRunActionsForEvent("embark:engine:started", {}, (err) => {
if (err) {
console.error("error starting engine");
console.error(err);
process.exit(1);
}
cb();
});
} else {
cb();
});
}
}
registerModule(moduleName, options) {
this.plugins.loadInternalPlugin(moduleName, options || {});
if (this.plugins) {
this.plugins.loadInternalPlugin(moduleName, options || {});
}
}
registerModulePackage(moduleName, options) {
return this.plugins.loadInternalPlugin(moduleName, options || {}, true);
registerModulePackage(moduleName, options?: any) {
if (this.plugins) {
return this.plugins.loadInternalPlugin(moduleName, options || {}, true);
}
}
registerModuleGroup(groupName, _options) {
let options = _options || {};
const options = _options || {};
let groups = {
const groups = {
blockchain: this.blockchainComponents,
coreComponents: this.coreComponents,
stackComponents: this.stackComponents,
@ -94,14 +153,14 @@ class Engine {
cockpit: this.cockpitModules
};
let group = groups[groupName];
const group = groups[groupName];
if (!group) {
throw new Error("unknown service: " + groupName);
}
// need to be careful with circular references due to passing the web3 object
//this.logger.trace("calling: " + serviceName + "(" + JSON.stringify(options) + ")");
// this.logger.trace("calling: " + serviceName + "(" + JSON.stringify(options) + ")");
return group.apply(this, [options]);
}
@ -122,6 +181,7 @@ class Engine {
}
coreComponents() {
// TODO: should be made into a component
this.processManager = new ProcessManager({
events: this.events,
@ -129,17 +189,22 @@ class Engine {
plugins: this.plugins
});
const ServicesMonitor = require('./services_monitor.js');
this.servicesMonitor = new ServicesMonitor({events: this.events, logger: this.logger, plugins: this.plugins});
this.servicesMonitor.addCheck('Embark', (cb) => {
return cb({name: 'Embark ' + this.version, status: 'on'});
}, 0);
let plugin = this.plugins.createPlugin('coreservicesplugin', {});
plugin.registerActionForEvent("embark:engine:started", (_params, cb) => {
this.servicesMonitor.startMonitor();
cb();
});
if (this.servicesMonitor) {
this.servicesMonitor.addCheck('Embark', (cb) => {
return cb({name: 'Embark ' + this.version, status: 'on'});
}, 0);
if (this.plugins) {
const plugin = this.plugins.createPlugin('coreservicesplugin', {});
plugin.registerActionForEvent("embark:engine:started", (_params, cb) => {
this.servicesMonitor && this.servicesMonitor.startMonitor();
cb();
});
}
}
this.registerModulePackage('embark-code-runner', {ipc: this.ipc});
// TODO: we shouldn't need useDashboard
@ -236,14 +301,35 @@ class Engine {
this.registerModulePackage('embark-ens');
}
cockpitModules() {
this.registerModulePackage('embark-authenticator', {singleUseAuthToken: this.singleUseAuthToken});
this.registerModulePackage('embark-api', {plugins: this.plugins});
// Register logs for the cockpit console
this.events.request('process:logs:register', {processName: EMBARK_PROCESS_NAME, eventName: "log", silent: false, alwaysAlreadyLogged: true});
}
}
module.exports = Engine;
function interceptLogs(consoleContext, logger) {
const context: any = {};
context.console = consoleContext;
context.console.log = function() {
logger.info(normalizeInput(arguments));
};
context.console.warn = function() {
logger.warn(normalizeInput(arguments));
};
context.console.info = function() {
logger.info(normalizeInput(arguments));
};
context.console.debug = function() {
// TODO: ue JSON.stringify
logger.debug(normalizeInput(arguments));
};
context.console.trace = function() {
logger.trace(normalizeInput(arguments));
};
context.console.dir = function() {
logger.dir(normalizeInput(arguments));
};
}

View File

@ -1,5 +1,5 @@
import { __ } from 'embark-i18n';
var EventEmitter = require('events');
const EventEmitter = require('events');
const cloneDeep = require('lodash.clonedeep');
const fs = require('fs-extra');
@ -8,22 +8,26 @@ function debugEventsEnabled() {
return process && process.env && process.env.DEBUGEVENTS;
}
function warnIfLegacy(eventName) {
const legacyEvents = [];
function warnIfLegacy(eventName: string) {
const legacyEvents: string[] = [];
if (legacyEvents.indexOf(eventName) >= 0) {
console.info(__("this event is deprecated and will be removed in future versions %s", eventName));
}
}
function getOrigin() {
if (!(debugEventsEnabled())) return "";
let origin = ((new Error().stack).split("at ")[3]).trim();
origin = origin.split("(")[0].trim();
return origin;
if (!(debugEventsEnabled())) { return ""; }
const stack = new Error().stack;
if (stack) {
let origin = stack.split("at ")[3].trim();
origin = origin.split("(")[0].trim();
return origin;
}
return '';
}
function log(eventType, eventName, origin) {
if (!(debugEventsEnabled())) return;
function log(eventType, eventName, origin?: string) {
if (!(debugEventsEnabled())) { return; }
if (['end', 'prefinish', 'error', 'new', 'demo', 'block', 'version'].indexOf(eventName) >= 0) {
return;
}
@ -32,8 +36,11 @@ function log(eventType, eventName, origin) {
}
// fs.appendFileSync(".embark/events.log", (new Error().stack) + "\n");
if (!origin && origin !== "") {
origin = ((new Error().stack).split("at ")[3]).trim();
origin = origin.split("(")[0].trim();
const stack = new Error().stack;
if (stack) {
origin = stack.split("at ")[3].trim();
origin = origin.split("(")[0].trim();
}
// origin = getOrigin();
}
@ -50,7 +57,7 @@ function log(eventType, eventName, origin) {
// cmdNames[cmdName] = origin;
// }
class EmbarkEmitter extends EventEmitter {
export class EmbarkEmitter extends EventEmitter {
emit(requestName, ...args) {
warnIfLegacy(arguments[0]);
@ -59,7 +66,6 @@ class EmbarkEmitter extends EventEmitter {
}
}
// EmbarkEmitter.prototype.log = log;
EmbarkEmitter.prototype.log = log;
@ -98,8 +104,8 @@ EmbarkEmitter.prototype.setHandler = function(requestName, cb) {
};
EmbarkEmitter.prototype.request2 = function() {
let requestName = arguments[0];
let other_args = [].slice.call(arguments, 1);
const requestName = arguments[0];
const other_args: any[] = [].slice.call(arguments, 1);
log("\nREQUEST", requestName);
warnIfLegacy(requestName);
@ -112,10 +118,10 @@ EmbarkEmitter.prototype.request2 = function() {
}
}
let promise = new Promise((resolve, reject) => {
const promise = new Promise((resolve, reject) => {
other_args.push(
(err, ...res) => {
if (err) return reject(err);
if (err) { return reject(err); }
if (res.length && res.length > 1) {
return resolve(res);
}
@ -126,7 +132,7 @@ EmbarkEmitter.prototype.request2 = function() {
this._emit('request:' + requestName, ...other_args);
});
let ogStack = (new Error().stack);
const ogStack = (new Error().stack);
promise.catch((e) => {
if (debugEventsEnabled()) {
@ -141,8 +147,8 @@ EmbarkEmitter.prototype.request2 = function() {
};
EmbarkEmitter.prototype.request = function() {
let requestName = arguments[0];
let other_args = [].slice.call(arguments, 1);
const requestName = arguments[0];
const other_args = [].slice.call(arguments, 1);
log("\nREQUEST(OLD)", requestName);
warnIfLegacy(requestName);
@ -160,7 +166,7 @@ EmbarkEmitter.prototype.request = function() {
// if we don't have a command handler set for this event yet,
// store it and fire it once a command handler is set
if (!this.listeners(listenerName).length) {
if(!toFire[listenerName]) {
if (!toFire[listenerName]) {
toFire[listenerName] = [];
}
toFire[listenerName].push(other_args);
@ -177,9 +183,9 @@ EmbarkEmitter.prototype.setCommandHandler = function(requestName, cb) {
// let origin = ((new Error().stack).split("at ")[3]).trim();
// origin = origin.split("(")[0].trim();
let origin = getOrigin();
const origin = getOrigin();
let listener = function(_cb) {
const listener = function(_cb) {
log("== REQUEST RESPONSE", requestName, origin);
cb.call(this, ...arguments);
};
@ -232,5 +238,3 @@ EmbarkEmitter.prototype.setCommandHandlerOnce = function(requestName, cb) {
cb.call(this, ...arguments);
});
};
module.exports = EmbarkEmitter;

View File

@ -0,0 +1,93 @@
/* global module process require */
/* tslint:disable */
import { joinPath } from 'embark-utils';
import * as fs from 'fs-extra';
import parseJson from 'parse-json';
import * as path from 'path';
import 'colors';
export function mkdirpSync(args: any) { return fs.mkdirpSync(args); }
export function mkdirp(args: any, args2?: any) { return fs.mkdirp(args, args2); }
export function readdir(args: any, args2?: any) { return fs.readdir(args, args2); }
export function stat(args: any, args2?: any) { return fs.stat(args, args2); }
export function remove(args: any, args2: any) { return fs.remove(args, args2); }
export function copy(args: any, args2?: any, args3?: any, args4?: any) { return fs.copy(args, args2, args3, args4); }
export function copySync(args: any, args2?: any, args3?: any) { return fs.copySync(args, args2, args3); }
export function move(args: any, args2?: any, args3?: any, args4?: any) { return fs.move(args, args2, args3, args4); }
export function moveSync(args: any, args2?: any, args3?: any) { return fs.moveSync(args, args2, args3); }
export function symlink(args: any, args2?: any, args3?: any, args4?: any) { return fs.symlink(args, args2, args3, args4); }
export function appendFileSync(args: any, args2: any, args3?: any) { return fs.appendFileSync(args, args2, args3); }
export function writeFile(args: any, args2: any, args3?: any, args4?: any) { return fs.writeFile(args, args2, args3, args4); }
export function writeFileSync(args: any, args2: any, args3?: any) { return fs.writeFileSync(args, args2, args3); }
export function readFile(args: any, args2?: any, args3?: any) { return fs.readFile(args, args2, args3); }
export function readFileSync(args: any, args2?: any) { return fs.readFileSync(args, args2); }
export function readdirSync(args: any, args2?: any) { return fs.readdirSync(args, args2); }
export function statSync(args: any, args2?: any) { return fs.statSync(args, args2); }
export function readJSONSync(args: any, args2?: any) {
let json;
try {
json = parseJson(readFileSync(args, args2));
} catch (e) {
console.error('error: '.red + args.green.underline + ' ' + e.message.green);
process.exit(1);
}
return json;
}
export function writeJSONSync(args: any, args2: any, args3?: any) { return fs.writeJSONSync(args, args2, args3); }
export function outputJSONSync(args: any, args2: any, args3?: any) { return fs.outputJSONSync(args, args2, args3); }
export function writeJson(args: any, args2: any, args3?: any, args4?: any) { return fs.writeJson(args, args2, args3, args4); }
export function existsSync(args: any) { return fs.existsSync(args); }
export function ensureFileSync(args: any) { return fs.ensureFileSync(args); }
export function ensureDirSync(args: any, args2?: any) { return fs.ensureDirSync(args, args2); }
export function access(args: any, args2?: any, args3?: any) { return fs.access(args, args2, args3); }
export function removeSync(args: any) { return fs.removeSync(args); }
export function createWriteStream(args: any, args2?: any) { return fs.createWriteStream(args, args2); }
export function copyPreserve(sourceFilePath, targetFilePath) {
const implementation = (sourceFilePath, targetFilePath) => {
let ext = 1;
let preserved = targetFilePath;
while (fs.existsSync(preserved)) {
const extname = path.extname(targetFilePath);
preserved = joinPath(
path.dirname(targetFilePath),
`${path.basename(targetFilePath, extname)}.${ext}${extname}`
);
ext++;
}
if (preserved !== targetFilePath) {
fs.copySync(targetFilePath, preserved);
}
fs.copySync(sourceFilePath, targetFilePath);
};
return implementation(sourceFilePath, targetFilePath);
}
export function outputFileSync(args: any, args2: any, args3?: any) { return fs.outputFileSync(args, args2, args3); }

View File

@ -1,5 +0,0 @@
export { ProcessLauncher } from './processes/processLauncher';
export { ProcessManager } from './processes/processManager';
export { ProcessWrapper } from './processes/processWrapper';
export { IPC } from './ipc';

View File

@ -0,0 +1,14 @@
export { ProcessLauncher } from './processes/processLauncher';
export { ProcessWrapper } from './processes/processWrapper';
export { Config } from './config';
export { IPC } from './ipc';
export { Engine } from './engine';
import { EmbarkEmitter as Events } from './events';
export { Events };
export { Plugins } from './plugins';
export { TestLogger } from './utils/test_logger';
export { TemplateGenerator } from './utils/template_generator';
import * as fs from './fs';
export { fs };

View File

@ -0,0 +1,363 @@
import { fileMatchesPattern } from './utils/utils';
import { __ } from 'embark-i18n';
import { dappPath, embarkPath, isEs6Module, joinPath } from 'embark-utils';
import { Logger } from 'embark-logger';
const constants = require('embark-core/constants');
const fs = require('fs-extra');
const deepEqual = require('deep-equal');
// TODO: pass other params like blockchainConfig, contract files, etc..
export class Plugin {
dappPath = dappPath;
embarkPath = embarkPath;
name: string;
isInternal: boolean;
pluginModule: any;
pluginPath: string;
pluginConfig: any;
shouldInterceptLogs: boolean;
clientWeb3Providers: any[] = [];
beforeDeploy: any[] = [];
contractsGenerators: any[] = [];
generateCustomContractCode = null;
testContractFactory = null;
pipeline: any[] = [];
pipelineFiles: any[] = [];
console: any[] = [];
contractsConfigs: any[] = [];
contractsFiles: any[] = [];
compilers: any[] = [];
serviceChecks: any[] = [];
dappGenerators: any[] = [];
pluginTypes: string[] = [];
uploadCmds: any[] = [];
apiCalls: any[] = [];
imports: any[] = [];
embarkjs_code: any[] = [];
generated_code: any[] = [];
embarkjs_init_code: any[] = [];
embarkjs_init_console_code: any[] = [];
fs: any;
afterContractsDeployActions: any[] = [];
onDeployActions: any[] = [];
eventActions: any = {};
_loggerObject: Logger;
events: any;
config: any;
plugins: any;
env: any;
loaded = false;
currentContext: any;
acceptedContext: any;
version: string;
constants: any;
logger: Logger;
constructor(options) {
this.name = options.name;
this.isInternal = options.isInternal;
this.pluginModule = options.pluginModule;
this.pluginPath = options.pluginPath;
this.pluginConfig = options.pluginConfig;
this.shouldInterceptLogs = options.interceptLogs;
this.fs = fs;
this._loggerObject = options.logger;
this.logger = this._loggerObject; // Might get changed if we do intercept
this.events = options.events;
this.config = options.config;
this.plugins = options.plugins;
this.env = options.env;
this.currentContext = options.context;
this.acceptedContext = options.pluginConfig.context || [constants.contexts.any];
this.version = options.version;
this.constants = constants;
if (!Array.isArray(this.currentContext)) {
this.currentContext = [this.currentContext];
}
if (!Array.isArray(this.acceptedContext)) {
this.acceptedContext = [this.acceptedContext];
}
}
_log(type) {
this._loggerObject[type](this.name + ':', ...[].slice.call(arguments, 1));
}
setUpLogger() {
this.logger = {
log: this._log.bind(this, 'log'),
warn: this._log.bind(this, 'warn'),
error: this._log.bind(this, 'error'),
info: this._log.bind(this, 'info'),
debug: this._log.bind(this, 'debug'),
trace: this._log.bind(this, 'trace'),
dir: this._log.bind(this, 'dir')
};
}
isContextValid() {
if (this.currentContext.includes(constants.contexts.any) || this.acceptedContext.includes(constants.contexts.any)) {
return true;
}
return this.acceptedContext.some(context => {
return this.currentContext.includes(context);
});
}
hasContext(context) {
return this.currentContext.includes(context);
}
loadPlugin() {
if (!this.isContextValid()) {
this.logger.warn(__('Plugin {{name}} can only be loaded in the context of "{{contexts}}"', {name: this.name, contexts: this.acceptedContext.join(', ')}));
return false;
}
this.loaded = true;
if (this.shouldInterceptLogs) {
this.setUpLogger();
}
if (isEs6Module(this.pluginModule)) {
if (this.pluginModule.default) {
this.pluginModule = this.pluginModule.default;
}
return new this.pluginModule(this);
}
this.pluginModule.call(this, this);
}
loadInternalPlugin() {
if (isEs6Module(this.pluginModule)) {
if (this.pluginModule.default) {
this.pluginModule = this.pluginModule.default;
}
}
return new this.pluginModule(this, this.pluginConfig); /*eslint no-new: "off"*/
}
loadPluginFile(filename) {
return fs.readFileSync(this.pathToFile(filename)).toString();
}
pathToFile(filename) {
if (!this.pluginPath) {
throw new Error('pluginPath not defined for plugin: ' + this.name);
}
return joinPath(this.pluginPath, filename);
}
// TODO: add deploy provider
registerClientWeb3Provider(cb) {
this.clientWeb3Providers.push(cb);
this.addPluginType('clientWeb3Provider');
}
registerContractsGeneration(cb) {
this.contractsGenerators.push(cb);
this.addPluginType('contractGeneration');
}
registerCustomContractGenerator(cb) {
this.generateCustomContractCode = cb;
this.addPluginType('customContractGeneration');
}
registerTestContractFactory(cb) {
this.testContractFactory = cb;
this.addPluginType('testContractFactory');
}
registerPipeline(matcthingFiles, cb) {
// TODO: generate error for more than one pipeline per plugin
this.pipeline.push({matcthingFiles, cb});
this.addPluginType('pipeline');
}
registerDappGenerator(framework, cb) {
this.dappGenerators.push({framework, cb});
this.pluginTypes.push('dappGenerator');
}
registerCustomType(type) {
this.pluginTypes.push(type);
}
addFileToPipeline(file, intendedPath, options) {
this.pipelineFiles.push({file, intendedPath, options});
this.addPluginType('pipelineFiles');
}
addContractFile(file) {
if (this.isInternal) {
throw new Error("this API cannot work for internal modules. please use an event command instead: config:contractsFiles:add");
}
this.contractsFiles.push(file);
this.addPluginType('contractFiles');
}
registerConsoleCommand(optionsOrCb) {
if (typeof optionsOrCb === 'function') {
this.logger.warn(__('Registering console commands with function syntax is deprecated and will likely be removed in future versions of Embark'));
this.logger.info(__('You can find the new API documentation here: %s', 'https://embark.status.im/docs/plugin_reference.html#registerConsoleCommand-options'.underline));
}
this.console.push(optionsOrCb);
this.addPluginType('console');
}
// TODO: this only works for services done on startup
registerServiceCheck(checkName, checkFn, time) {
this.serviceChecks.push({checkName, checkFn, time});
this.addPluginType('serviceChecks');
}
has(pluginType) {
return this.pluginTypes.indexOf(pluginType) >= 0;
}
addPluginType(pluginType) {
this.pluginTypes.push(pluginType);
this.pluginTypes = Array.from(new Set(this.pluginTypes));
}
generateProvider(args) {
return this.clientWeb3Providers.map(function(cb) {
return cb.call(this, args);
}).join("\n");
}
generateContracts(args) {
return this.contractsGenerators.map(function(cb) {
return cb.call(this, args);
}).join("\n");
}
registerContractConfiguration(config) {
this.contractsConfigs.push(config);
this.addPluginType('contractsConfig');
}
registerCompiler(extension, cb) {
this.compilers.push({extension, cb});
this.addPluginType('compilers');
}
registerUploadCommand(cmd, cb) {
this.uploadCmds.push({cmd, cb});
this.addPluginType('uploadCmds');
}
addCodeToEmbarkJS(code) {
this.addPluginType('embarkjsCode');
// TODO: what is this/why
if (!this.embarkjs_code.some((existingCode) => deepEqual(existingCode, code))) {
this.embarkjs_code.push(code);
}
}
addGeneratedCode(codeCb) {
this.addPluginType('generatedCode');
this.generated_code.push(codeCb);
}
addProviderInit(providerType, code, initCondition) {
this.embarkjs_init_code[providerType] = this.embarkjs_init_code[providerType] || [];
this.embarkjs_init_code[providerType].push([code, initCondition]);
this.addPluginType('initCode');
}
addConsoleProviderInit(providerType, code, initCondition) {
this.embarkjs_init_console_code[providerType] = this.embarkjs_init_console_code[providerType] || [];
this.addPluginType('initConsoleCode');
const toAdd = [code, initCondition];
if (!this.embarkjs_init_console_code[providerType].some((initConsoleCode) => deepEqual(initConsoleCode, toAdd))) {
this.embarkjs_init_console_code[providerType].push(toAdd);
}
}
registerImportFile(importName, importLocation) {
this.imports.push([importName, importLocation]);
this.addPluginType('imports');
}
registerActionForEvent(eventName, cb) {
if (!this.eventActions[eventName]) {
this.eventActions[eventName] = [];
}
this.eventActions[eventName].push(cb);
this.addPluginType('eventActions');
}
registerAPICall(method, endpoint, cb) {
this.apiCalls.push({method, endpoint, cb});
this.addPluginType('apiCalls');
this.events.emit('plugins:register:api', {method, endpoint, cb});
}
runFilePipeline() {
return this.pipelineFiles.map(file => {
let obj: any = {};
obj.filename = file.file.replace('./', '');
obj.content = this.loadPluginFile(file.file).toString();
obj.intendedPath = file.intendedPath;
obj.options = file.options;
obj.path = this.pathToFile(obj.filename);
return obj;
});
}
runPipeline(args) {
// TODO: should iterate the pipelines
let pipeline = this.pipeline[0];
let shouldRunPipeline = fileMatchesPattern(pipeline.matcthingFiles, args.targetFile);
if (shouldRunPipeline) {
return pipeline.cb.call(this, args);
}
return args.source;
}
}

View File

@ -0,0 +1,272 @@
import * as fs from './fs';
import { Plugin } from './plugin';
import { EmbarkEmitter as Events } from './events';
import { Config } from './config';
import * as async from 'async';
import { dappPath, embarkPath } from 'embark-utils';
import { Logger } from 'embark-logger';
export class Plugins {
pluginList = [];
interceptLogs: boolean;
plugins: Plugin[] = [];
logger: Logger;
events: Events;
config: Config;
context: any;
fs: any;
env: string;
version: string;
static deprecated = {
'embarkjs-connector-web3': '4.1.0'
};
constructor(options) {
this.pluginList = options.plugins || [];
this.interceptLogs = options.interceptLogs;
// TODO: need backup 'NullLogger'
this.logger = options.logger;
this.events = options.events;
this.config = options.config;
this.context = options.context;
this.fs = fs;
this.env = options.env;
this.version = options.version;
}
loadPlugins() {
Object.entries(Plugins.deprecated).forEach(([pluginName, embarkVersion]) => {
if (this.pluginList[pluginName]) {
delete this.pluginList[pluginName];
this.logger.warn(`${pluginName} plugin was not loaded because it has been deprecated as of embark v${embarkVersion}, please remove it from this project's embark.json and package.json`);
}
});
Object.entries(this.pluginList).forEach(([pluginName, pluginConfig]) => {
this.loadPlugin(pluginName, pluginConfig);
});
}
listPlugins() {
return this.plugins.reduce((list: string[], plugin) => {
if (plugin.loaded) {
list.push(plugin.name);
}
return list;
}, []);
}
// for services that act as a plugin but have core functionality
createPlugin(pluginName, pluginConfig) {
const plugin = {};
const pluginPath = false;
const pluginWrapper = new Plugin({
name: pluginName,
pluginModule: plugin,
pluginConfig,
logger: this.logger,
pluginPath,
interceptLogs: this.interceptLogs,
events: this.events,
config: this.config,
plugins: this.plugins,
fs: this.fs,
isInternal: true,
context: this.context
});
this.plugins.push(pluginWrapper);
return pluginWrapper;
}
loadInternalPlugin(pluginName, pluginConfig, isPackage?: boolean) {
let pluginPath, plugin;
if (isPackage) {
pluginPath = pluginName;
plugin = require(pluginName);
} else {
pluginPath = embarkPath('dist/lib/modules/' + pluginName);
plugin = require(pluginPath);
}
if (plugin.default) {
plugin = plugin.default;
}
const pluginWrapper = new Plugin({
name: pluginName,
pluginModule: plugin,
pluginConfig: pluginConfig || {},
logger: this.logger,
pluginPath,
interceptLogs: this.interceptLogs,
events: this.events,
config: this.config,
plugins: this.plugins,
fs: this.fs,
isInternal: true,
context: this.context,
env: this.env
});
const pluginInstance = pluginWrapper.loadInternalPlugin();
this.plugins.push(pluginWrapper);
return pluginInstance;
}
loadPlugin(pluginName, pluginConfig) {
const pluginPath = dappPath('node_modules', pluginName);
let plugin = require(pluginPath);
if (plugin.default) {
plugin = plugin.default;
}
const pluginWrapper = new Plugin({
name: pluginName,
pluginModule: plugin,
pluginConfig,
logger: this.logger,
pluginPath,
interceptLogs: this.interceptLogs,
events: this.events,
config: this.config,
plugins: this.plugins,
fs: this.fs,
isInternal: false,
context: this.context,
version: this.version
});
pluginWrapper.loadPlugin();
this.plugins.push(pluginWrapper);
}
getPluginsFor(pluginType) {
return this.plugins.filter(function(plugin) {
return plugin.has(pluginType);
});
}
getPluginsProperty(pluginType, property, sub_property?: any) {
const matchingPlugins = this.plugins.filter(function(plugin) {
return plugin.has(pluginType);
});
// Sort internal plugins first
matchingPlugins.sort((a, b) => {
if (a.isInternal) {
return -1;
}
if (b.isInternal) {
return 1;
}
return 0;
});
let matchingProperties = matchingPlugins.map((plugin) => {
if (sub_property) {
return plugin[property][sub_property];
}
return plugin[property];
});
// Remove empty properties
matchingProperties = matchingProperties.filter((property) => property);
// return flattened list
if (matchingProperties.length === 0) { return []; }
return matchingProperties.reduce((a, b) => a.concat(b)) || [];
}
getPluginsPropertyAndPluginName(pluginType, property, sub_property) {
const matchingPlugins = this.plugins.filter(function(plugin) {
return plugin.has(pluginType);
});
// Sort internal plugins first
matchingPlugins.sort((a, b) => {
if (a.isInternal) {
return -1;
}
if (b.isInternal) {
return 1;
}
return 0;
});
let matchingProperties: any[] = [];
matchingPlugins.map((plugin) => {
if (sub_property) {
const newList = [];
for (const kall of (plugin[property][sub_property] || [])) {
matchingProperties.push([kall, plugin.name]);
}
return newList;
}
const newList = [];
for (const kall of (plugin[property] || [])) {
matchingProperties.push([kall, plugin.name]);
}
return newList;
});
// Remove empty properties
matchingProperties = matchingProperties.filter((property) => property[0]);
// return flattened list
if (matchingProperties.length === 0) { return []; }
// return matchingProperties.reduce((a,b) => { return a.concat(b); }) || [];
return matchingProperties;
}
// TODO: because this is potentially hanging, we should issue a trace warning if the event does not exists
runActionsForEvent(eventName, args, cb) {
const self = this;
if (typeof (args) === 'function') {
cb = args;
args = [];
}
const actionPlugins = this.getPluginsPropertyAndPluginName('eventActions', 'eventActions', eventName);
if (actionPlugins.length === 0) {
return cb(null, args);
}
this.events.log("ACTION", eventName, "");
async.reduce(actionPlugins, args, function(current_args, pluginObj: any, nextEach) {
const [plugin, pluginName] = pluginObj;
self.events.log("== ACTION FOR " + eventName, plugin.name, pluginName);
if (typeof (args) === 'function') {
plugin.call(plugin, (...params) => {
nextEach(...params || current_args);
});
} else {
plugin.call(plugin, args, (...params) => {
nextEach(...params || current_args);
});
}
}, cb);
}
emitAndRunActionsForEvent(eventName, args, cb) {
if (typeof (args) === 'function') {
cb = args;
args = [];
}
this.events.emit(eventName, args);
return this.runActionsForEvent(eventName, args, cb);
}
}

View File

@ -0,0 +1,103 @@
import { EmbarkEmitter as Events } from './events';
import { Plugins } from './plugins';
import { __ } from 'embark-i18n';
import { Logger } from 'embark-logger';
export class ServicesMonitor {
events: Events;
logger: Logger;
plugins: Plugins;
checkList: any = {};
checkTimers: any = {};
checkState: any = {};
working = false;
constructor(options) {
this.events = options.events;
this.logger = options.logger;
this.plugins = options.plugins;
this.events.setCommandHandler("services:register", (checkName, checkFn, time, initialStatus) => {
this.addCheck(checkName, checkFn, time, initialStatus);
});
}
initCheck(checkName) {
const self = this;
const check = this.checkList[checkName];
if (!check) {
return false;
}
self.events.on('check:' + checkName, function(obj) {
if (check && check.status === 'off' && obj.status === 'on') {
self.events.emit('check:backOnline:' + checkName);
}
if (check && check.status === 'on' && obj.status === 'off') {
self.events.emit('check:wentOffline:' + checkName);
}
check.status = obj.status;
// const newState = {name: obj.name, status: obj.status, serviceName: checkName};
// if (!deepEqual(newState, self.checkState[checkName])) {
self.checkState[checkName] = {name: obj.name, status: obj.status, serviceName: checkName};
self.events.emit("servicesState", self.checkState);
// }
});
if (check.interval !== 0) {
self.checkTimers[checkName] = setInterval(function() {
check.fn.call(check.fn, function(obj) {
self.events.emit('check:' + checkName, obj);
});
}, check.interval);
}
check.fn.call(check.fn, function(obj) {
self.events.emit('check:' + checkName, obj);
});
}
addCheck(checkName, checkFn, time, initialState?: any) {
this.logger.trace('add check: ' + checkName);
this.checkList[checkName] = {fn: checkFn, interval: time || 5000, status: initialState};
if (this.working) {
this.initCheck(checkName);
}
}
stopCheck(name) {
clearInterval(this.checkTimers[name]);
delete this.checkTimers[name];
delete this.checkList[name];
delete this.checkState[name];
}
startMonitor() {
const self = this;
this.working = true;
this.logger.trace('startMonitor');
const servicePlugins = this.plugins.getPluginsProperty('serviceChecks', 'serviceChecks');
servicePlugins.forEach(function(pluginCheck) {
self.addCheck(pluginCheck.checkName, pluginCheck.checkFn, pluginCheck.time);
});
Object.keys(this.checkList).forEach(checkName => {
try {
self.initCheck(checkName);
} catch (err) {
self.logger.error(__("error running service check"));
self.logger.error(err.message);
}
});
}
}

View File

@ -1,7 +1,12 @@
import { __ } from 'embark-i18n';
const fs = require('../core/fs.js');
import decompress from 'decompress';
import * as path from 'path';
import shelljs from 'shelljs';
import * as fs from '../fs';
const hostedGitInfo = require('hosted-git-info');
const utils = require('./utils.js');
import { filesMatchingPattern } from './utils';
import {
embarkPath,
downloadFile,
@ -27,7 +32,7 @@ const REPLACEMENTS = {
'gitlab.com/': 'gitlab:'
};
class TemplateGenerator {
export class TemplateGenerator {
constructor(templateName) {
this.isInsideMonorepo = isInsideMonorepoSync();
if (this.isInsideMonorepo) {
@ -46,7 +51,7 @@ class TemplateGenerator {
async download(url, tmpFilePath, browse) {
console.log(__('Installing template from ' + browse).green);
console.log(__('Downloading template...').green);
fs.mkdirpSync(utils.dirname(tmpFilePath));
fs.mkdirpSync(path.dirname(tmpFilePath));
try {
await promisify(downloadFile)(url, tmpFilePath);
} catch (e) {
@ -96,7 +101,7 @@ class TemplateGenerator {
}
extract(filePath, destinationFolder, cb = () => {}) {
utils.extractZip(
extractZip(
filePath,
destinationFolder,
{
@ -139,7 +144,7 @@ class TemplateGenerator {
);
execSync(`npm pack ${templateSpecifier}`, {cwd: tmpDir, stdio: 'ignore'});
const packed = utils.filesMatchingPattern(
const packed = filesMatchingPattern(
[joinPath(tmpDir, '*.tgz')]
)[0];
@ -162,7 +167,7 @@ class TemplateGenerator {
}
installTemplate(templatePath, name, installPackages, cb) {
utils.cd(templatePath);
shelljs.cd(templatePath);
const pkgJson = fs.readJSONSync('./package.json');
if (!(/demo/).test(name)) {
@ -260,7 +265,7 @@ class TemplateGenerator {
let templateAndBranch = uri.split('#');
if (templateAndBranch.length === 1) {
fallback = true;
embarkVersion = semver(require('../../../package.json').version);
embarkVersion = semver(require(embarkPath('package.json')).version);
templateAndBranch.push(`${embarkVersion.major}.${embarkVersion.minor}`);
}
templateAndBranch[0] = `embark-framework/embark-${templateAndBranch[0]}-template`;
@ -306,4 +311,9 @@ class TemplateGenerator {
});
}
}
module.exports = TemplateGenerator;
function extractZip(filename, packageDirectory, opts, cb) {
decompress(filename, packageDirectory, opts).then((_files) => {
cb();
});
}

View File

@ -2,7 +2,7 @@ require('colors');
// TODO: just logFunction changes, probably doesn't need a whole new module just
// for this
class TestLogger {
export class TestLogger {
constructor(options) {
this.logLevels = ['error', 'warn', 'info', 'debug', 'trace'];
this.logLevel = options.logLevel || 'info';
@ -52,5 +52,3 @@ class TestLogger {
}
}
module.exports = TestLogger;

View File

@ -0,0 +1,9 @@
export function filesMatchingPattern(files) {
const globule = require('globule');
return globule.find(files, {nonull: true});
}
export function fileMatchesPattern(patterns, intendedPath) {
const globule = require('globule');
return globule.isMatch(patterns, intendedPath);
}

View File

@ -0,0 +1,5 @@
{
"extends": "../../../tsconfig.json",
"include": ["src/**/*"]
}

View File

@ -0,0 +1,4 @@
{
"extends": "../../../tslint.json"
}

View File

@ -1,7 +1,7 @@
import { Maybe } from "embark";
import * as i18n from "i18n";
import { Maybe } from 'embark';
import * as i18n from 'i18n';
declare module "embark-i18n" {
declare module 'embark-i18n' {
function setOrDetectLocale(locale: Maybe<string>): void;
function __(
phraseOrOptions: string | i18n.TranslateOptions,

View File

@ -1,20 +1,20 @@
import colors from "colors/safe";
import * as i18n from "i18n";
import * as osLocale from "os-locale";
import * as path from "path";
import colors from 'colors/safe';
import * as i18n from 'i18n';
import * as osLocale from 'os-locale';
import * as path from 'path';
import { Maybe } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import { Maybe } /* supplied by @types/embark in packages/embark-typings */ from 'embark';
enum LocalType {
Specified = "specified",
Detected = "detected",
Specified = 'specified',
Detected = 'detected',
}
enum SupportedLanguage {
En = "en",
Pt = "pt",
Fr = "fr",
Es = "es",
En = 'en',
Pt = 'pt',
Fr = 'fr',
Es = 'es',
}
const DEFAULT_LANGUAGE = SupportedLanguage.En;
@ -22,7 +22,7 @@ const DEFAULT_LANGUAGE = SupportedLanguage.En;
const i18nEmbark = { __: null };
i18n.configure({
directory: path.join(__dirname, "../", "locales"),
directory: path.join(__dirname, '../', 'locales'),
locales: Object.values(SupportedLanguage),
register: i18nEmbark,
syncFiles: false,

View File

@ -7,7 +7,7 @@ const util = require('util');
const DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss:SSS';
const LOG_REGEX = new RegExp(/\[(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d:\d\d\d)\] (?:\[(\w*)\]:?)?\s?\s?(.*)/gmi);
class Logger {
export class Logger {
constructor(options) {
this.events = options.events || {emit: function(){}};
this.logLevels = Object.keys(Logger.logLevels);
@ -167,5 +167,3 @@ Logger.prototype.dir = function (txt) {
Logger.prototype.shouldLog = function (level) {
return (this.logLevels.indexOf(level) <= this.logLevels.indexOf(this.logLevel));
};
module.exports = Logger;

View File

@ -1,11 +1,11 @@
import "./src/prettier-plugin-solidity";
import "./src/remix-debug-debugtest";
import './src/prettier-plugin-solidity';
import './src/remix-debug-debugtest';
export * from "./src/callbacks";
export * from "./src/contract";
export * from "./src/embark";
export * from "./src/contractsConfig";
export * from "./src/embarkConfig";
export * from "./src/logger";
export * from "./src/maybe";
export * from "./src/plugins";
export * from './src/callbacks';
export * from './src/contract';
export * from './src/embark';
export * from './src/contractsConfig';
export * from './src/embarkConfig';
export * from './src/logger';
export * from './src/maybe';
export * from './src/plugins';

View File

@ -1,4 +1,4 @@
import { ABIDefinition } from "web3/eth/abi";
import { ABIDefinition } from 'web3/eth/abi';
export interface Contract {
abiDefinition: ABIDefinition[];

View File

@ -1,5 +1,5 @@
import { Logger } from "./logger";
import { Plugins } from "./plugins";
import { Logger } from './logger';
import { Plugins } from './plugins';
type CommandCallback = (
opt1?: any,

View File

@ -1,4 +1,4 @@
import {Callback} from "./callbacks";
import {Callback} from './callbacks';
export interface Plugin {
dappGenerators: any;

View File

@ -1 +1 @@
declare module "prettier-plugin-solidity";
declare module 'prettier-plugin-solidity';

View File

@ -1 +1 @@
declare module "remix-debug-debugtest";
declare module 'remix-debug-debugtest';

View File

@ -13,6 +13,8 @@ declare module "embark-utils" {
function checkIsAvailable(url: string, callback: any): void;
function dockerHostSwap(host: string): string;
function buildUrl(protocol: string, host: string, port: number, type: string): string;
function buildUrlFromConfig(config: any): string;
function canonicalHost(host: string): string;
function dappPath(...names: string[]): string;
function diagramPath(...names: string[]): string;
function escapeHtml(message: any): string;

View File

@ -52,6 +52,7 @@
"colors": "1.3.2",
"core-js": "3.3.5",
"embark-i18n": "^5.0.0-alpha.1",
"embark-logger": "^5.0.0-alpha.1",
"ethereumjs-wallet": "0.6.3",
"find-up": "2.1.0",
"follow-redirects": "1.8.0",

View File

@ -9,7 +9,7 @@ const {utils} = require('web3');
const path = require('path');
const ERROR_ACCOUNT = 'ERROR_ACCOUNT';
class AccountParser {
export default class AccountParser {
static parseAccountsConfig(accountsConfig, web3, dappPath, logger, nodeAccounts) {
let accounts = [];
if (accountsConfig && accountsConfig.length) {
@ -153,5 +153,3 @@ class AccountParser {
return ERROR_ACCOUNT;
}
}
module.exports = AccountParser;

View File

@ -1,6 +1,6 @@
const ZERO_ADDRESS_SHORTHAND_REGEX = /^0x0$/;
const ZERO_ADDRESS_SHORTHAND_SEARCH_REGEX = /'0x0'/g;
export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
export function extendZeroAddressShorthand(value: string) {
if (value.match(ZERO_ADDRESS_SHORTHAND_REGEX) !== null) {

View File

@ -1,4 +1,4 @@
const merge = require("merge");
const merge = require('merge');
export function last(array: any) {
return array[array.length - 1];

View File

@ -1,23 +1,23 @@
import { __ } from "embark-i18n";
import * as fs from "fs-extra";
import * as path from "path";
import { downloadFile } from "./network";
import { dappPath, embarkPath } from "./pathUtils";
import { ImportRemapping, prepareForCompilation } from "./solidity/remapImports";
import { __ } from 'embark-i18n';
import * as fs from 'fs-extra';
import * as path from 'path';
import { downloadFile } from './network';
import { dappPath, embarkPath } from './pathUtils';
import { ImportRemapping, prepareForCompilation } from './solidity/remapImports';
const HTTP_CONTRACTS_DIRECTORY = ".embark/contracts/";
const HTTP_CONTRACTS_DIRECTORY = '.embark/contracts/';
export enum Types {
embarkInternal = "embark_internal",
dappFile = "dapp_file",
custom = "custom",
http = "http",
embarkInternal = 'embark_internal',
dappFile = 'dapp_file',
custom = 'custom',
http = 'http',
}
export class File {
public type: Types;
public externalUrl: string = "";
public path = "";
public externalUrl: string = '';
public path = '';
public basedir: string;
public resolver: (callback: (content: string) => void) => void;
public pluginPath: string;
@ -29,16 +29,16 @@ export class File {
constructor(options: any) {
this.type = options.type;
this.basedir = options.basedir || "";
this.basedir = options.basedir || '';
this.resolver = options.resolver;
this.pluginPath = options.pluginPath ? options.pluginPath : "";
this.pluginPath = options.pluginPath ? options.pluginPath : '';
this.storageConfig = options.storageConfig;
this.providerUrl = "";
this.originalPath = options.originalPath || "";
this.providerUrl = '';
this.originalPath = options.originalPath || '';
if (this.type === Types.custom && this.pluginPath) {
this.path = path.join(this.pluginPath, options.path).replace(dappPath(), "");
if (this.path.startsWith("/")) {
this.path = path.join(this.pluginPath, options.path).replace(dappPath(), '');
if (this.path.startsWith('/')) {
this.path = this.path.substring(1);
}
} else if (this.type === Types.http) {
@ -53,8 +53,8 @@ export class File {
}
public async prepareForCompilation(isCoverage = false) {
if (!this.path.endsWith(".sol")) {
return Promise.reject(__("This method is only supported for Solidity files"));
if (!this.path.endsWith('.sol')) {
return Promise.reject(__('This method is only supported for Solidity files'));
}
return prepareForCompilation(this, isCoverage);
}
@ -63,12 +63,12 @@ export class File {
return new Promise<string>((resolve) => {
switch (this.type) {
case Types.embarkInternal: {
const content = fs.readFileSync(embarkPath(path.join("dist", this.path)), "utf-8");
const content = fs.readFileSync(embarkPath(path.join('dist', this.path)), 'utf-8');
return resolve(content);
}
case Types.dappFile: {
const content = fs.readFileSync(this.path, "utf-8").toString();
const content = fs.readFileSync(this.path, 'utf-8').toString();
return resolve(content);
}
@ -81,7 +81,7 @@ export class File {
case Types.http: {
fs.ensureFileSync(this.path);
return downloadFile(this.externalUrl, this.path, () => {
const content = fs.readFileSync(this.path, "utf-8");
const content = fs.readFileSync(this.path, 'utf-8');
resolve(content);
});
}
@ -93,20 +93,20 @@ export class File {
export function getExternalContractUrl(file: string, providerUrl: string) {
let url;
const RAW_URL = "https://raw.githubusercontent.com/";
const DEFAULT_SWARM_GATEWAY = "https://swarm-gateways.net/";
const MALFORMED_SWARM_ERROR = "Malformed Swarm gateway URL for ";
const MALFORMED_ERROR = "Malformed Github URL for ";
const MALFORMED_IPFS_ERROR = "Malformed IPFS URL for ";
const IPFS_GETURL_NOTAVAILABLE = "IPFS getUrl is not available. Please set it in your storage config. For more info: https://embark.status.im/docs/storage_configuration.html";
if (file.startsWith("https://github")) {
const RAW_URL = 'https://raw.githubusercontent.com/';
const DEFAULT_SWARM_GATEWAY = 'https://swarm-gateways.net/';
const MALFORMED_SWARM_ERROR = 'Malformed Swarm gateway URL for ';
const MALFORMED_ERROR = 'Malformed Github URL for ';
const MALFORMED_IPFS_ERROR = 'Malformed IPFS URL for ';
const IPFS_GETURL_NOTAVAILABLE = 'IPFS getUrl is not available. Please set it in your storage config. For more info: https://embark.status.im/docs/storage_configuration.html';
if (file.startsWith('https://github')) {
const file_path = file.match(/https:\/\/github\.[a-z]+\/(.*)/);
if (!file_path) {
console.error(MALFORMED_ERROR + file);
return null;
}
url = `${RAW_URL}${file_path[1].replace("blob/", "")}`;
} else if (file.startsWith("ipfs")) {
url = `${RAW_URL}${file_path[1].replace('blob/', '')}`;
} else if (file.startsWith('ipfs')) {
if (!providerUrl) {
console.error(IPFS_GETURL_NOTAVAILABLE);
return null;
@ -121,14 +121,14 @@ export function getExternalContractUrl(file: string, providerUrl: string) {
}
let matchResult = file_path[1];
if (file_path[2]) {
matchResult += "/" + file_path[2];
matchResult += '/' + file_path[2];
}
url = `${providerUrl}${matchResult}`;
return {
filePath: HTTP_CONTRACTS_DIRECTORY + matchResult,
url,
};
} else if (file.startsWith("git")) {
} else if (file.startsWith('git')) {
// Match values
// [0] entire input
// [1] git://
@ -145,12 +145,12 @@ export function getExternalContractUrl(file: string, providerUrl: string) {
}
let branch = file_path[5];
if (!branch) {
branch = "master";
branch = 'master';
}
url = `${RAW_URL}${file_path[2]}/${file_path[3]}/${branch}/${file_path[4]}`;
} else if (file.startsWith("http")) {
} else if (file.startsWith('http')) {
url = file;
} else if (file.startsWith("bzz")) {
} else if (file.startsWith('bzz')) {
if (!providerUrl) {
url = DEFAULT_SWARM_GATEWAY + file;
} else {
@ -162,7 +162,7 @@ export function getExternalContractUrl(file: string, providerUrl: string) {
return null;
}
}
url = providerUrl + "/" + file;
url = providerUrl + '/' + file;
}
} else {
return null;
@ -171,7 +171,7 @@ export function getExternalContractUrl(file: string, providerUrl: string) {
/\.[a-z]+\/([-a-zA-Z0-9@:%_+.~#?&\/=]+)/,
);
return {
filePath: HTTP_CONTRACTS_DIRECTORY + (match !== null ? match[1] : ""),
filePath: HTTP_CONTRACTS_DIRECTORY + (match !== null ? match[1] : ''),
url,
};
}

View File

@ -1,17 +1,17 @@
const {execSync} = require("child_process");
const {hostname} = require("os");
const {execSync} = require('child_process');
const {hostname} = require('os');
const isDocker = (() => {
// assumption: an Embark container is always a Linux Docker container, though
// the Docker host may be Linux, macOS, or Windows
if (process.platform !== "linux") { return false; }
if (process.platform !== 'linux') { return false; }
try {
return (
new RegExp(`[0-9]+\:[a-z_-]+\:\/docker\/${hostname()}[0-9a-z]+`, "i")
new RegExp(`[0-9]+\:[a-z_-]+\:\/docker\/${hostname()}[0-9a-z]+`, 'i')
).test(
execSync(
"cat /proc/self/cgroup",
{stdio: ["ignore", "pipe", "ignore"]},
'cat /proc/self/cgroup',
{stdio: ['ignore', 'pipe', 'ignore']},
).toString(),
);
} catch (e) {
@ -19,18 +19,18 @@ const isDocker = (() => {
}
})();
const defaultHost = isDocker ? "0.0.0.0" : "localhost";
const defaultHost = isDocker ? '0.0.0.0' : 'localhost';
// when we're runing in Docker, we can expect (generally, in a development
// scenario) that the user would like to connect to the service in the
// container via the **host's** loopback address, so this helper can be used to
// swap 0.0.0.0 for localhost in code/messages that pertain to client-side
function canonicalHost(host: string): string {
return isDocker && host === "0.0.0.0" ? "localhost" : host;
return isDocker && host === '0.0.0.0' ? 'localhost' : host;
}
function dockerHostSwap(host: string): string {
return (isDocker && (host === "localhost" || host === "127.0.0.1")) ? defaultHost : host;
return (isDocker && (host === 'localhost' || host === '127.0.0.1')) ? defaultHost : host;
}
const defaultCorsHost = canonicalHost(defaultHost);

View File

@ -3,27 +3,36 @@ const https = require('follow-redirects').https;
const shelljs = require('shelljs');
const clipboardy = require('clipboardy');
const {canonicalHost, defaultCorsHost, defaultHost, dockerHostSwap, isDocker} = require('./host');
const {downloadFile, findNextPort, getJson, httpGet, httpsGet, httpGetJson, httpsGetJson, pingEndpoint} = require('./network');
import { canonicalHost } from './host';
export { canonicalHost, defaultCorsHost, defaultHost, dockerHostSwap, isDocker } from './host';
export { downloadFile, findNextPort, getJson, httpGet, httpsGet, httpGetJson, httpsGetJson, pingEndpoint } from './network';
const logUtils = require('./log-utils');
export const escapeHtml = logUtils.escapeHtml;
export const normalizeInput = logUtils.normalizeInput;
export { LogHandler } from './logHandler';
const toposortGraph = require('./toposort');
import { unitRegex } from './constants';
import * as AddressUtils from './addressUtils';
import {
getWeiBalanceFromString,
getHexBalanceFromString,
hexToNumber,
export { AddressUtils };
import { unitRegex } from './constants';
export { unitRegex } from './constants';
import { isHex, getWeiBalanceFromString } from './web3Utils';
export {
decodeParams,
isHex,
getHexBalanceFromString,
getWeiBalanceFromString,
hexToNumber,
sha3,
sha512,
isHex,
soliditySha3,
toChecksumAddress
} from './web3Utils';
import { getAddressToContract, getTransactionParams } from './transactionUtils';
export { getAddressToContract, getTransactionParams } from './transactionUtils';
import LongRunningProcessTimer from './longRunningProcessTimer';
export { LongRunningProcessTimer };
import AccountParser from './accountParser';
import {
export { AccountParser };
export {
anchoredValue,
dappPath,
diagramPath,
@ -42,15 +51,15 @@ import {
normalizePath,
toForwardSlashes
} from './pathUtils';
import { setUpEnv } from './env';
export { setUpEnv } from './env';
const { extendZeroAddressShorthand, replaceZeroAddressShorthand } = AddressUtils;
import { compact, last, recursiveMerge, groupBy } from './collections';
import { prepareForCompilation } from './solidity/remapImports';
import { File, getExternalContractUrl, Types } from './file';
export { compact, last, recursiveMerge, groupBy } from './collections';
export { prepareForCompilation } from './solidity/remapImports';
export { File, getExternalContractUrl, Types } from './file';
import {
export {
findMonorepoPackageFromRoot,
findMonorepoPackageFromRootSync,
isInsideMonorepo,
@ -59,25 +68,23 @@ import {
monorepoRootPathSync
} from './monorepo';
function timer(ms) {
export function timer(ms: number) {
const then = Date.now();
return new Promise(resolve => (
setTimeout(() => resolve(Date.now() - then), ms)
));
}
function checkIsAvailable(url, callback) {
export function checkIsAvailable(url: string, callback: (isAvailable: boolean) => void) {
const protocol = url.split(':')[0];
const httpObj = (protocol === 'https') ? https : http;
httpObj.get(url, function (_res) {
callback(true);
}).on('error', function (_res) {
callback(false);
});
httpObj
.get(url, (_res: any) => callback(true))
.on('error', (_res: any) => callback(false));
}
function hashTo32ByteHexString(hash) {
export function hashTo32ByteHexString(hash: string) {
if (isHex(hash)) {
if (!hash.startsWith('0x')) {
hash = '0x' + hash;
@ -85,84 +92,84 @@ function hashTo32ByteHexString(hash) {
return hash;
}
const multihash = require('multihashes');
let buf = multihash.fromB58String(hash);
let digest = multihash.decode(buf).digest;
const buf = multihash.fromB58String(hash);
const digest = multihash.decode(buf).digest;
return '0x' + multihash.toHexString(digest);
}
function exit(code) {
export function exit(code: number) {
process.exit(code);
}
function runCmd(cmd, options, callback) {
export function runCmd(cmd: string, options: any, callback: any) {
options = Object.assign({silent: true, exitOnError: true, async: true}, options || {});
const outputToConsole = !options.silent;
options.silent = true;
let result = shelljs.exec(cmd, options, function (code, stdout) {
if(code !== 0) {
const result = shelljs.exec(cmd, options, (code, stdout: string) => {
if (code !== 0) {
if (options.exitOnError) {
return exit();
return exit(code);
}
if(typeof callback === 'function') {
if (typeof callback === 'function') {
callback(`shell returned code ${code}`);
}
} else {
if(typeof callback === 'function') {
if (typeof callback === 'function') {
return callback(null, stdout);
}
}
});
result.stdout.on('data', function(data) {
if(outputToConsole) {
result.stdout.on('data', (data: any) => {
if (outputToConsole) {
console.log(data);
}
});
result.stderr.on('data', function(data) {
result.stderr.on('data', (data: any) => {
if (outputToConsole) {
console.log(data);
}
});
}
function copyToClipboard(text) {
export function copyToClipboard(text: string) {
clipboardy.writeSync(text);
}
function byName(a, b) {
export function byName(a, b) {
return a.name.localeCompare(b.name);
}
function isFolder(node) {
export function isFolder(node) {
return node.children && node.children.length;
}
function isNotFolder(node){
export function isNotFolder(node) {
return !isFolder(node);
}
function fileTreeSort(nodes){
export function fileTreeSort(nodes) {
const folders = nodes.filter(isFolder).sort(byName);
const files = nodes.filter(isNotFolder).sort(byName);
return folders.concat(files);
}
function proposeAlternative(word, _dictionary, _exceptions) {
export function proposeAlternative(word, _dictionary, _exceptions) {
const propose = require('propose');
let exceptions = _exceptions || [];
let dictionary = _dictionary.filter((entry) => {
const exceptions = _exceptions || [];
const dictionary = _dictionary.filter((entry) => {
return exceptions.indexOf(entry) < 0;
});
return propose(word, dictionary, {threshold: 0.3});
}
function toposort(graph) {
export function toposort(graph) {
return toposortGraph(graph);
}
function deconstructUrl(endpoint) {
export function deconstructUrl(endpoint) {
const matches = endpoint.match(/(wss?|https?):\/\/([a-zA-Z0-9_.\/-]*):?([0-9]*)?/);
return {
protocol: matches[1],
@ -172,7 +179,7 @@ function deconstructUrl(endpoint) {
};
}
function prepareContractsConfig(config) {
export function prepareContractsConfig(config) {
if (config.deploy) {
config.contracts = config.deploy;
delete config.deploy;
@ -213,7 +220,7 @@ function prepareContractsConfig(config) {
return config;
}
function jsonFunctionReplacer(_key, value) {
export function jsonFunctionReplacer(_key, value) {
if (typeof value === 'function') {
return value.toString();
}
@ -221,9 +228,11 @@ function jsonFunctionReplacer(_key, value) {
return value;
}
function fuzzySearch(text, list, filter) {
export function fuzzySearch(text, list, filter) {
const fuzzy = require('fuzzy');
return fuzzy.filter(text, list, {extract: (filter || function () {})});
return fuzzy.filter(text, list, {
extract: filter
});
}
/**
@ -239,10 +248,15 @@ function fuzzySearch(text, list, filter) {
* Type of connection
* @returns {string} the constructued URL, with defaults
*/
function buildUrl(protocol, host, port, type) {
if (!host) throw new Error('utils.buildUrl: parameter \'host\' is required');
if (port) port = ':' + port;
else port = '';
export function buildUrl(protocol, host, port, type) {
if (!host) {
throw new Error('utils.buildUrl: parameter \'host\' is required');
}
if (port) {
port = ':' + port;
} else {
port = '';
}
if (!protocol) {
protocol = type === 'ws' ? 'ws' : 'http';
}
@ -258,13 +272,17 @@ function buildUrl(protocol, host, port, type) {
* * port {String} (optional) The URL port, default to empty string.
* @returns {string} the constructued URL, with defaults
*/
function buildUrlFromConfig(configObj) {
if (!configObj) throw new Error('[utils.buildUrlFromConfig]: config object must cannot be null');
if (!configObj.host) throw new Error('[utils.buildUrlFromConfig]: object must contain a \'host\' property');
export function buildUrlFromConfig(configObj) {
if (!configObj) {
throw new Error('[utils.buildUrlFromConfig]: config object must cannot be null');
}
if (!configObj.host) {
throw new Error('[utils.buildUrlFromConfig]: object must contain a \'host\' property');
}
return buildUrl(configObj.protocol, canonicalHost(configObj.host), configObj.port, configObj.type);
}
function errorMessage(e) {
export function errorMessage(e) {
if (typeof e === 'string') {
return e;
} else if (e && e.message) {
@ -273,95 +291,10 @@ function errorMessage(e) {
return e;
}
function isConstructor(obj) {
export function isConstructor(obj) {
return !!obj.prototype && !!obj.prototype.constructor.name;
}
function isEs6Module(module) {
export function isEs6Module(module) {
return (typeof module === 'function' && isConstructor(module)) || (typeof module === 'object' && typeof module.default === 'function' && module.__esModule);
}
const Utils = {
anchoredValue,
buildUrl,
buildUrlFromConfig,
joinPath,
tmpDir,
ipcPath,
dappPath,
downloadFile,
embarkPath,
normalizePath,
toForwardSlashes,
jsonFunctionReplacer,
fuzzySearch,
canonicalHost,
compact,
copyToClipboard,
diagramPath,
deconstructUrl,
defaultCorsHost,
defaultHost,
decodeParams,
dockerHostSwap,
exit,
errorMessage,
getAddressToContract,
getTransactionParams,
isDocker,
isEs6Module,
checkIsAvailable,
File,
findNextPort,
fileTreeSort,
hashTo32ByteHexString,
hexToNumber,
isHex,
last,
soliditySha3,
recursiveMerge,
prepareContractsConfig,
findMonorepoPackageFromRoot,
findMonorepoPackageFromRootSync,
getWeiBalanceFromString,
getHexBalanceFromString,
getExternalContractUrl,
getJson,
groupBy,
httpGet,
httpsGet,
httpGetJson,
httpsGetJson,
isInsideMonorepo,
isInsideMonorepoSync,
monorepoRootPath,
monorepoRootPathSync,
pingEndpoint,
setUpEnv,
sha512,
sha3,
timer,
Types,
unitRegex,
urlJoin,
runCmd,
escapeHtml: logUtils.escapeHtml,
normalizeInput: logUtils.normalizeInput,
LogHandler: require('./logHandler'),
LongRunningProcessTimer,
pkgPath,
prepareForCompilation,
proposeAlternative,
toChecksumAddress,
toposort,
AddressUtils,
AccountParser,
PWD,
DAPP_PATH,
DIAGRAM_PATH,
EMBARK_PATH,
PKG_PATH,
NODE_PATH
};
module.exports = Utils;

View File

@ -7,7 +7,7 @@ const MAX_LOGS = 1500; // TODO use constants when it's put in a package or somet
/**
* Serves as a central point of log handling.
*/
class LogHandler {
export class LogHandler {
/**
* @param {Object} options Options object containing:
@ -97,5 +97,3 @@ class LogHandler {
});
}
}
module.exports = LogHandler;

View File

@ -1,5 +1,5 @@
import { red } from "colors";
import { Logger } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import { Logger } from 'embark-logger';
import { performance, PerformanceObserver } from "perf_hooks";
import prettyMs from "pretty-ms";
import { last, recursiveMerge } from "./collections";

View File

@ -194,26 +194,6 @@ class Cmd {
}
blockchain() {
// program
// .command('blockchain [environment]')
// .option('-c, --client [client]', __('Use a specific ethereum client [%s] (default: %s)', 'geth, parity', 'geth'))
// .option('--locale [locale]', __('language to use (default: en)'))
// .description(__('run blockchain server (default: %s)', 'development'))
// .action(function(env, options) {
// setOrDetectLocale(options.locale);
// embark.initConfig(env || 'development', {
// embarkConfig: 'embark.json',
// interceptLogs: false
// });
// if (embark.config.blockchainConfig.endpoint && !embark.config.blockchainConfig.isAutoEndpoint) {
// embark.logger.warn(__('You are starting the blockchain node, but have an `endpoint` specified. `embark run` is probably what you wanted to run'));
// }
// embark.blockchain(env || 'development', options.client);
// });
// TODO: fix me, re-add above
program
.command('blockchain [environment]')
.option('-p, --port [port]', __('port to run the dev webserver (default: %s)', '8000'))

View File

@ -1,20 +1,22 @@
import {__} from 'embark-i18n';
import {dappPath, embarkPath} from 'embark-utils';
import { Config, Engine, Events, fs, TemplateGenerator } from 'embark-core';
import { __ } from 'embark-i18n';
import { dappPath, embarkPath, joinPath, setUpEnv } from 'embark-utils';
import { Logger } from 'embark-logger';
let async = require('async');
const constants = require('embark-core/constants');
const Logger = require('embark-logger');
const {reset: embarkReset, paths: defaultResetPaths} = require('embark-reset');
const fs = require('../lib/core/fs.js');
const cloneDeep = require('clone-deep');
setUpEnv(joinPath(__dirname, '../../'));
require('colors');
let version = require('../../package.json').version;
let pkg = require('../../package.json');
class EmbarkController {
constructor(options) {
this.version = version;
this.version = pkg.version;
this.options = options || {};
// set a default context. should be overwritten by an action
@ -23,12 +25,10 @@ class EmbarkController {
}
initConfig(env, options) {
let Events = require('../lib/core/events.js');
let Config = require('../lib/core/config.js');
this.events = new Events();
this.logger = new Logger({logLevel: Logger.logLevels.debug, events: this.events, context: this.context});
this.logger.info('foo');
this.config = new Config({env: env, logger: this.logger, events: this.events, context: this.context, version: this.version});
this.config.loadConfigFiles(options);
this.plugins = this.config.plugins;
@ -38,7 +38,6 @@ class EmbarkController {
this.context = options.context || [constants.contexts.blockchain];
const webServerConfig = {};
const Engine = require('../lib/core/engine.js');
const engine = new Engine({
env: options.env,
client: options.client,
@ -52,7 +51,8 @@ class EmbarkController {
webServerConfig: webServerConfig,
webpackConfigName: options.webpackConfigName,
singleUseAuthToken: options.singleUseAuthToken,
ipcRole: 'server'
ipcRole: 'server',
package: pkg
});
engine.init({}, () => {
@ -87,7 +87,6 @@ class EmbarkController {
generateTemplate(templateName, destinationFolder, name, url) {
this.context = [constants.contexts.templateGeneration];
let TemplateGenerator = require('../lib/utils/template_generator.js');
let templateGenerator = new TemplateGenerator(templateName);
if (url) {
@ -119,7 +118,6 @@ class EmbarkController {
webServerConfig.openBrowser = options.openBrowser;
}
const Engine = require('../lib/core/engine.js');
const engine = new Engine({
env: options.env,
client: options.client,
@ -133,7 +131,8 @@ class EmbarkController {
webServerConfig: webServerConfig,
webpackConfigName: options.webpackConfigName,
singleUseAuthToken: options.singleUseAuthToken,
ipcRole: 'server'
ipcRole: 'server',
package: pkg
});
async.waterfall([
@ -240,7 +239,6 @@ class EmbarkController {
build(options) {
this.context = options.context || [constants.contexts.build];
const Engine = require('../lib/core/engine.js');
const engine = new Engine({
env: options.env,
client: options.client,
@ -253,7 +251,8 @@ class EmbarkController {
logger: options.logger,
config: options.config,
context: this.context,
webpackConfigName: options.webpackConfigName
webpackConfigName: options.webpackConfigName,
package: pkg
});
@ -340,7 +339,6 @@ class EmbarkController {
console(options) {
this.context = options.context || [constants.contexts.run, constants.contexts.console];
const REPL = require('./dashboard/repl.js');
const Engine = require('../lib/core/engine.js');
const engine = new Engine({
env: options.env,
client: options.client,
@ -351,7 +349,8 @@ class EmbarkController {
logLevel: options.logLevel,
context: this.context,
singleUseAuthToken: options.singleUseAuthToken,
webpackConfigName: options.webpackConfigName
webpackConfigName: options.webpackConfigName,
package: pkg
});
const isSecondaryProcess = (engine) => {return engine.ipc.connected && engine.ipc.isClient();};
@ -449,13 +448,13 @@ class EmbarkController {
this.context = options.context || [constants.contexts.graph];
options.onlyCompile = true;
const Engine = require('../lib/core/engine.js');
const engine = new Engine({
env: options.env,
version: this.version,
embarkConfig: options.embarkConfig || 'embark.json',
logFile: options.logFile,
context: this.context
context: this.context,
package: pkg
});
async.waterfall([
@ -545,7 +544,6 @@ class EmbarkController {
scaffold(options) {
this.context = options.context || [constants.contexts.scaffold];
const Engine = require('../lib/core/engine.js');
const engine = new Engine({
env: options.env,
client: options.client,
@ -560,7 +558,8 @@ class EmbarkController {
config: options.config,
plugins: options.plugins,
context: this.context,
webpackConfigName: options.webpackConfigName
webpackConfigName: options.webpackConfigName,
package: pkg
});
async.waterfall([
@ -617,7 +616,6 @@ class EmbarkController {
upload(options) {
this.context = options.context || [constants.contexts.upload, constants.contexts.build];
const Engine = require('../lib/core/engine.js');
const engine = new Engine({
env: options.env,
client: options.client,
@ -632,7 +630,8 @@ class EmbarkController {
config: options.config,
plugins: options.plugins,
context: this.context,
webpackConfigName: options.webpackConfigName
webpackConfigName: options.webpackConfigName,
package: pkg
});
let platform;
@ -714,7 +713,6 @@ class EmbarkController {
runTests(options) {
this.context = [constants.contexts.test];
const Engine = require('../lib/core/engine.js');
const engine = new Engine({
env: options.env,
client: options.client,
@ -727,7 +725,8 @@ class EmbarkController {
useDashboard: false,
webpackConfigName: options.webpackConfigName,
ipcRole: 'client',
interceptLogs: false
interceptLogs: false,
package: pkg
});
async.waterfall([
@ -768,6 +767,7 @@ class EmbarkController {
module.exports = EmbarkController;
async function compileAndDeploySmartContracts(engine) {
try {
let contractsFiles = await engine.events.request2("config:contractsFiles");
let compiledContracts = await engine.events.request2("compiler:contracts:compile", contractsFiles);
let _contractsConfig = await engine.events.request2("config:contractsConfig");
@ -776,6 +776,9 @@ async function compileAndDeploySmartContracts(engine) {
await engine.events.request2("deployment:contracts:deploy", contractsList, contractDependencies);
await engine.events.request2('pipeline:generateAll');
engine.events.emit('outputDone');
} catch (e) {
console.log(e);
}
}
async function setupCargoAndWatcher(engine) {

View File

@ -1,5 +1,12 @@
import { __ } from 'embark-i18n';
const { getWindowSize } = require('../../lib/utils/utils.js');
import windowSize from 'window-size';
function getWindowSize() {
if (windowSize) {
return windowSize.get();
}
return {width: 240, height: 75};
}
let Monitor = require('./monitor.js');

View File

@ -1,724 +0,0 @@
const fs = require('./fs.js');
const Plugins = require('./plugins.js');
const utils = require('../utils/utils.js');
const path = require('path');
const deepEqual = require('deep-equal');
const web3 = require('web3');
const constants = require('embark-core/constants');
import { __ } from 'embark-i18n';
import {
buildUrlFromConfig,
canonicalHost,
dappPath,
defaultHost,
File,
Types,
recursiveMerge,
AddressUtils,
unitRegex,
getWeiBalanceFromString,
prepareContractsConfig,
getExternalContractUrl
} from 'embark-utils';
const cloneDeep = require('lodash.clonedeep');
const { replaceZeroAddressShorthand } = AddressUtils;
import {getBlockchainDefaults, getContractDefaults} from './configDefaults';
const DEFAULT_CONFIG_PATH = 'config/';
const PACKAGE = require('../../../package.json');
const embark5ChangesUrl = 'https://embark.status.im/docs/migrating_from_3.x.html#Updating-to-v5';
var Config = function(options) {
this.env = options.env || 'default';
this.blockchainConfig = {};
this.contractsConfig = {};
this.pipelineConfig = {};
this.namesystemConfig = {};
this.communicationConfig = {};
this.webServerConfig = options.webServerConfig;
this.chainTracker = {};
this.assetFiles = {};
this.contractsFiles = [];
this.configDir = options.configDir || DEFAULT_CONFIG_PATH;
this.chainsFile = options.chainsFile || './chains.json';
this.plugins = options.plugins;
this.logger = options.logger;
this.package = PACKAGE;
this.events = options.events;
this.embarkConfig = {};
this.context = options.context || [constants.contexts.any];
this.version = options.version;
this.shownNoAccountConfigMsg = false; // flag to ensure "no account config" message is only displayed once to the user
this.corsParts = [];
this.providerUrl = null;
this.registerEvents();
};
Config.prototype.setConfig = function(configName, newConfig, cb) {
this[configName] = newConfig;
cb();
};
Config.prototype.registerEvents = function() {
this.events.setCommandHandler("config:cors:add", (url) => {
this.corsParts.push(url);
this._updateBlockchainCors();
});
this.events.setCommandHandler("config:contractsConfig", (cb) => {
cb(null, this.contractsConfig);
});
this.events.setCommandHandler("config:storageConfig", (cb) => {
cb(null, this.storageConfig);
});
this.events.setCommandHandler("config:contractsConfig:set", this.setConfig.bind(this, 'contractsConfig'));
this.events.setCommandHandler("config:blockchainConfig:set", this.setConfig.bind(this, 'blockchainConfig'));
this.events.setCommandHandler("config:storageConfig:set", this.setConfig.bind(this, 'storageConfig'));
this.events.setCommandHandler("config:namesystemConfig:set", this.setConfig.bind(this, 'namesystemConfig'));
this.events.setCommandHandler("config:communicationConfig:set", this.setConfig.bind(this, 'communicationConfig'));
this.events.setCommandHandler("config:contractsFiles", (cb) => {
cb(null, this.contractsFiles);
});
// TODO: refactor this so reading the file can be done with a normal resolver or something that takes advantage of the plugin api
this.events.setCommandHandler("config:contractsFiles:add", (filename, resolver) => {
resolver = resolver || function(callback) {
callback(fs.readFileSync(filename).toString());
};
this.contractsFiles.push(new File({path: filename, originalPath: filename, type: Types.custom, resolver}));
});
this.events.setCommandHandler("config:contractsFiles:reset", (cb) => {
this.contractsFiles.forEach((file) => {
if(file.path.includes(".embark")) {
fs.removeSync(file.path);
}
this.contractsFiles = this.contractsFiles.filter((contractFile) => contractFile.path !== file.path);
});
cb();
});
this.events.on('file-remove', (fileType, removedPath) => {
if(fileType !== 'contract') return;
const normalizedPath = path.normalize(removedPath);
this.contractsFiles = this.contractsFiles.filter(file => path.normalize(file.path) !== normalizedPath);
});
};
// TODO remove this at some point as it is now in plugin
Config.prototype.dappPath = dappPath;
Config.prototype.loadConfigFiles = function(options) {
var interceptLogs = options.interceptLogs;
if (options.interceptLogs === undefined) {
interceptLogs = true;
}
if (!fs.existsSync(options.embarkConfig)){
this.logger.error(__('Cannot find file %s Please ensure you are running this command inside the Dapp folder', options.embarkConfig));
process.exit(1);
}
this.embarkConfig = fs.readJSONSync(options.embarkConfig);
this.embarkConfig.plugins = this.embarkConfig.plugins || {};
this.plugins = new Plugins({
plugins: this.embarkConfig.plugins,
logger: this.logger,
interceptLogs: interceptLogs,
events: this.events,
config: this,
context: this.context,
env: this.env,
version: this.version
});
this.plugins.loadPlugins();
this.loadEmbarkConfigFile();
this.loadBlockchainConfigFile();
this.loadStorageConfigFile();
this.loadContractFiles();
this.loadCommunicationConfigFile();
this.loadNameSystemConfigFile();
this.loadPipelineConfigFile();
this.loadAssetFiles();
this.loadContractsConfigFile();
this.loadExternalContractsFiles();
this.loadWebServerConfigFile();
this.loadPluginContractFiles();
this._updateBlockchainCors();
};
Config.prototype.reloadConfig = function() {
this.loadEmbarkConfigFile();
this.loadBlockchainConfigFile();
this.loadStorageConfigFile();
this.loadContractFiles();
this.loadCommunicationConfigFile();
this.loadNameSystemConfigFile();
this.loadPipelineConfigFile();
this.loadAssetFiles();
this.loadContractsConfigFile();
this.loadExternalContractsFiles();
this._updateBlockchainCors();
};
Config.prototype.loadContractFiles = function() {
const loadedContractFiles = this.loadFiles(this.embarkConfig.contracts);
// `this.contractsFiles` could've been mutated at runtime using
// either `config:contractsFiles:add` event or through calls to
// `loadExternalContractsFiles()`, so we have to make sure we preserve
// those added files before we reset `this.contractsFiles`.
//
// We do that by determining the difference between `loadedContractFiles` and the ones
// already in memory in `this.contractsFiles`.
const addedContractFiles = this.contractsFiles.filter(existingFile => !loadedContractFiles.some(file => file.originalPath === existingFile.originalPath));
this.contractsFiles = loadedContractFiles.concat(addedContractFiles);
};
Config.prototype._updateBlockchainCors = function(){
let blockchainConfig = this.blockchainConfig;
let storageConfig = this.storageConfig;
let webServerConfig = this.webServerConfig;
let corsParts = cloneDeep(this.corsParts);
if (blockchainConfig.isDev) {
corsParts.push('*');
}
if(webServerConfig && webServerConfig.host) {
corsParts.push(buildUrlFromConfig(webServerConfig));
}
if(storageConfig && storageConfig.enabled) {
// if getUrl is specified in the config, that needs to be included in cors
// instead of the concatenated protocol://host:port
if(storageConfig.upload.getUrl) {
// remove /ipfs or /bzz: from getUrl if it's there
let getUrlParts = storageConfig.upload.getUrl.split('/');
getUrlParts = getUrlParts.slice(0, 3);
let host = canonicalHost(getUrlParts[2].split(':')[0]);
let port = getUrlParts[2].split(':')[1];
getUrlParts[2] = port ? [host, port].join(':') : host;
corsParts.push(getUrlParts.join('/'));
}
// use our modified getUrl or in case it wasn't specified, use a built url
else{
corsParts.push(buildUrlFromConfig(storageConfig.upload));
}
}
// Add cors for the proxy and whisper
corsParts.push(constants.embarkResourceOrigin);
corsParts = Array.from(new Set(corsParts));
this.corsParts = corsParts;
let cors = corsParts.join(',');
if (blockchainConfig.rpcCorsDomain === 'auto') {
blockchainConfig.rpcCorsDomain = cors;
} else if (typeof blockchainConfig.rpcCorsDomain === 'object') {
let tempCors = blockchainConfig.rpcCorsDomain.auto ? corsParts : [];
tempCors = tempCors.concat(blockchainConfig.rpcCorsDomain.additionalCors || []);
blockchainConfig.rpcCorsDomain = tempCors.join(',');
}
if (blockchainConfig.wsOrigins === 'auto') {
blockchainConfig.wsOrigins = cors;
} else if (typeof blockchainConfig.wsOrigins === 'object') {
let tempCors = blockchainConfig.wsOrigins.auto ? corsParts : [];
tempCors = tempCors.concat(blockchainConfig.wsOrigins.additionalCors || []);
blockchainConfig.wsOrigins = tempCors.join(',');
}
};
Config.prototype._loadConfigFile = function (configFilePath, defaultConfig, enabledByDefault) {
if (!configFilePath) {
const configToReturn = defaultConfig['default'] || {};
configToReturn.enabled = enabledByDefault || false;
return configToReturn;
}
configFilePath = configFilePath.replace('.json','').replace('.js', '');
let config;
if (fs.existsSync(configFilePath + '.js')) {
delete require.cache[configFilePath + '.js'];
config = require(configFilePath + '.js');
} else if (fs.existsSync(configFilePath + '.json')) {
config = fs.readJSONSync(configFilePath + '.json');
} else {
this.logger.warn(__("no config file found at %s using default config", configFilePath));
return defaultConfig['default'] || {};
}
return config;
};
Config.prototype._doMergeConfig = function(config, defaultConfig, env) {
let configObject = recursiveMerge(defaultConfig, config);
if (env) {
if (env === 'test' && !configObject[env]) {
// Disabled all configs in tests as they are opt in
return Object.assign({}, defaultConfig.default, {enabled: false});
}
return recursiveMerge(configObject.default || {}, configObject[env]);
} else if (env !== false) {
this.logger.info(__("No environment called %s found. Using defaults.", env));
}
return configObject;
};
Config.prototype._loadAndMergeConfig = function(configFilePath, defaultConfig, env, enabledByDefault) {
const config = this._loadConfigFile(configFilePath, defaultConfig, enabledByDefault);
return this._doMergeConfig(config, defaultConfig, env, enabledByDefault);
};
Config.prototype._getFileOrObject = function(object, filePath, property) {
if (typeof object === 'object') {
return object[property] ? dappPath(object[property]) : object[property];
}
return dappPath(object, filePath);
};
/*eslint complexity: ["error", 30]*/
Config.prototype.loadBlockchainConfigFile = function() {
const blockchainDefaults = getBlockchainDefaults(this.env);
const configFilePath = this._getFileOrObject(this.configDir, 'blockchain', 'blockchain');
const userConfig = this._loadConfigFile(configFilePath, blockchainDefaults, true);
const envConfig = userConfig[this.env];
if (envConfig) {
if (envConfig.ethereumClientName || envConfig.hasOwnProperty('isDev') || envConfig.hasOwnProperty('mineWhenNeeded')) {
this.logger.error(__('The blockchain config has changed quite a bit in Embark 5\nPlease visit %s to know what has to be changed', embark5ChangesUrl.underline));
process.exit(1);
}
if (envConfig.clientConfig) {
Object.assign(envConfig, envConfig.clientConfig);
delete envConfig.clientConfig;
}
switch (envConfig.miningMode) {
case 'dev': envConfig.isDev = true; break;
case 'auto': envConfig.isDev = false; envConfig.mineWhenNeeded = true; break;
case 'always': envConfig.isDev = false; envConfig.mineWhenNeeded = false; envConfig.mine = true; break;
case 'off': envConfig.isDev = false; envConfig.mineWhenNeeded = false; envConfig.mine = false; break;
default: envConfig.isDev = false;
}
if (envConfig.cors) {
const autoIndex = envConfig.cors.indexOf('auto');
envConfig.rpcCorsDomain = {};
envConfig.wsOrigins = {};
if (autoIndex > -1) {
envConfig.rpcCorsDomain.auto = true;
envConfig.wsOrigins.auto = true;
envConfig.cors.splice(autoIndex, 1);
} else {
envConfig.rpcCorsDomain.auto = false;
envConfig.wsOrigins.auto = false;
}
envConfig.rpcCorsDomain.additionalCors = envConfig.cors;
envConfig.wsOrigins.additionalCors = envConfig.cors;
delete envConfig.cors;
}
userConfig[this.env] = envConfig;
}
this.blockchainConfig = this._doMergeConfig(userConfig, blockchainDefaults, this.env);
if (!configFilePath) {
this.blockchainConfig.default = true;
}
if (this.blockchainConfig.targetGasLimit && this.blockchainConfig.targetGasLimit.toString().match(unitRegex)) {
this.blockchainConfig.targetGasLimit = getWeiBalanceFromString(this.blockchainConfig.targetGasLimit, web3);
}
if (this.blockchainConfig.gasPrice && this.blockchainConfig.gasPrice.toString().match(unitRegex)) {
this.blockchainConfig.gasPrice = getWeiBalanceFromString(this.blockchainConfig.gasPrice, web3);
}
if (this.blockchainConfig.accounts) {
this.blockchainConfig.accounts.forEach(acc => {
if (acc.balance && acc.balance.toString().match(unitRegex)) {
acc.balance = getWeiBalanceFromString(acc.balance, web3);
}
});
}
if (!this.blockchainConfig.endpoint) {
const urlConfig = (this.blockchainConfig.wsHost) ? {
host: this.blockchainConfig.wsHost,
port: this.blockchainConfig.wsPort,
type: 'ws'
} : {
host: this.blockchainConfig.rpcHost,
port: this.blockchainConfig.rpcPort,
type: 'rpc'
};
this.blockchainConfig.endpoint = buildUrlFromConfig(urlConfig);
this.blockchainConfig.isAutoEndpoint = true;
}
if (
!this.shownNoAccountConfigMsg &&
(/rinkeby|testnet|livenet/).test(this.blockchainConfig.networkType) &&
!(this.blockchainConfig.accounts && this.blockchainConfig.accounts.find(acc => acc.password)) &&
!this.blockchainConfig.isDev &&
this.env !== 'development' && this.env !== 'test') {
this.logger.warn((
'\n=== ' + __('Cannot unlock account - account config missing').bold + ' ===\n' +
__('Geth is configured to sync to a testnet/livenet and needs to unlock an account ' +
'to allow your dApp to interact with geth, however, the address and password must ' +
'be specified in your blockchain config. Please update your blockchain config with ' +
'a valid address and password: \n') +
` - config/blockchain.js > ${this.env} > account\n\n`.italic +
__('Please also make sure the keystore file for the account is located at: ') +
'\n - Mac: ' + `~/Library/Ethereum/${this.env}/keystore`.italic +
'\n - Linux: ' + `~/.ethereum/${this.env}/keystore`.italic +
'\n - Windows: ' + `%APPDATA%\\Ethereum\\${this.env}\\keystore`.italic) +
__('\n\nAlternatively, you could change ' +
`config/blockchain.js > ${this.env} > networkType`.italic +
__(' to ') +
'"custom"\n'.italic).yellow
);
this.shownNoAccountConfigMsg = true;
}
const accountDocsMessage = __('For more info, check the docs: %s', 'https://embark.status.im/docs/blockchain_accounts_configuration.html'.underline);
if (this.blockchainConfig.account) {
this.logger.error(__('The `account` config for the blockchain was removed. Please use `accounts` instead.'));
this.logger.error(accountDocsMessage);
process.exit(1);
}
if (this.blockchainConfig.simulatorMnemonic) {
this.logger.error(__('The `simulatorMnemonic` config for the blockchain was removed. Please use `accounts` instead.'));
this.logger.error(accountDocsMessage);
process.exit(1);
}
this.events.emit('config:load:blockchain', this.blockchainConfig);
};
Config.prototype.loadContractsConfigFile = function() {
let configObject = getContractDefaults(this.embarkConfig.versions);
const contractsConfigs = this.plugins.getPluginsProperty('contractsConfig', 'contractsConfigs');
contractsConfigs.forEach(function(pluginConfig) {
configObject = recursiveMerge(configObject, pluginConfig);
});
let configFilePath = this._getFileOrObject(this.configDir, 'contracts', 'contracts');
let newContractsConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
if (newContractsConfig.contracts) {
this.logger.error(__('`contracts` has been renamed `deploy` in contracts config\nFor more information: %s', embark5ChangesUrl.underline));
process.exit(1);
}
if (newContractsConfig.deployment) {
this.logger.error(__('`deployment` has been removed from contracts config and is now part of blockchain config\nFor more information: %s', embark5ChangesUrl.underline));
process.exit(1);
}
if (newContractsConfig.gas.match(unitRegex)) {
newContractsConfig.gas = getWeiBalanceFromString(newContractsConfig.gas, web3);
}
newContractsConfig = prepareContractsConfig(newContractsConfig);
const afterDeploy = newContractsConfig.afterDeploy;
if (Array.isArray(afterDeploy)) {
newContractsConfig.afterDeploy = afterDeploy.map(replaceZeroAddressShorthand);
}
if (!deepEqual(newContractsConfig, this.contractsConfig)) {
this.contractsConfig = newContractsConfig;
}
this.events.emit('config:load:contracts', this.contractsConfig);
};
Config.prototype.loadExternalContractsFiles = function() {
let contracts = this.contractsConfig.contracts;
let storageConfig = this.storageConfig;
if (storageConfig && storageConfig.upload && storageConfig.upload.getUrl) {
this.providerUrl = storageConfig.upload.getUrl;
}
for (let contractName in contracts) {
let contract = contracts[contractName];
if (!contract.file) {
continue;
}
let externalContractFile = null;
if (contract.file.startsWith('http') || contract.file.startsWith('git') || contract.file.startsWith('ipfs') || contract.file.startsWith('bzz')) {
const fileObj = getExternalContractUrl(contract.file, this.providerUrl);
if (!fileObj) {
return this.logger.error(__("HTTP contract file not found") + ": " + contract.file);
}
externalContractFile = new File({ path: fileObj.filePath, originalPath: fileObj.filePath, type: Types.http, basedir: '', externalUrl: fileObj.url, storageConfig });
} else if (fs.existsSync(contract.file)) {
externalContractFile = new File({ path: contract.file, originalPath: contract.file, type: Types.dappFile, basedir: '', storageConfig });
} else if (fs.existsSync(path.join('./node_modules/', contract.file))) {
const completePath = path.join('./node_modules/', contract.file);
externalContractFile = new File({ path: completePath, originalPath: completePath, type: Types.dappFile, basedir: '', storageConfig });
}
if (externalContractFile) {
const index = this.contractsFiles.findIndex(contractFile => contractFile.originalPath === externalContractFile.originalPath);
// It's important that we only add `externalContractFile` if it doesn't exist already
// within `contractsFiles`, otherwise we keep adding duplicates in subsequent
// compilation routines creating a memory leak.
if (index > -1) {
this.contractsFiles[index] = externalContractFile;
} else {
this.contractsFiles.push(externalContractFile);
}
} else {
this.logger.error(__("contract file not found") + ": " + contract.file);
}
}
};
Config.prototype.loadStorageConfigFile = function() {
var versions = recursiveMerge({"ipfs-api": "17.2.4"}, this.embarkConfig.versions || {});
var configObject = {
"default": {
"versions": versions,
"enabled": true,
"available_providers": ["ipfs", "swarm"],
"ipfs_bin": "ipfs",
"upload": {
"provider": "ipfs",
"protocol": "http",
"host" : defaultHost,
"port": 5001,
"getUrl": "http://localhost:8080/ipfs/"
},
"dappConnection": [{"provider": "ipfs", "host": "localhost", "port": 5001, "getUrl": "http://localhost:8080/ipfs/"}]
}
};
let configFilePath = this._getFileOrObject(this.configDir, 'storage', 'storage');
this.storageConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
this.events.emit('config:load:storage', this.storageConfig);
};
Config.prototype.loadNameSystemConfigFile = function() {
// todo: spec out names for registration in the file itself for a dev chain
var configObject = {
"default": {
"enabled": false
}
};
let configFilePath = this._getFileOrObject(this.configDir, 'namesystem', 'namesystem');
this.namesystemConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
};
Config.prototype.loadCommunicationConfigFile = function() {
var configObject = {
"default": {
"enabled": true,
"provider": "whisper",
"available_providers": ["whisper"],
"connection": {
"host": defaultHost,
"port": 8557,
"type": "ws"
}
}
};
let configFilePath = this._getFileOrObject(this.configDir, 'communication', 'communication');
this.communicationConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
this.events.emit('config:load:communication', this.communicationConfig);
};
Config.prototype.loadWebServerConfigFile = function() {
var configObject = {
"enabled": true,
"host": defaultHost,
"openBrowser": true,
"port": 8000,
"enableCatchAll": true,
"protocol": "http"
};
let configFilePath = this._getFileOrObject(this.configDir, 'webserver', 'webserver');
let webServerConfig = this._loadAndMergeConfig(configFilePath, configObject, false);
if (webServerConfig.https){
try {
webServerConfig.certOptions = {
key: fs.readFileSync(webServerConfig.key),
cert: fs.readFileSync(webServerConfig.cert)
};
webServerConfig.protocol = 'https';
} catch (e) {
this.logger.error(e.message);
this.logger.warn('Invalid path for key/cert in config/webserver.js. Using http instead.');
webServerConfig.certOptions = {};
webServerConfig.protocol = 'http';
}
}
if (configFilePath === false) {
this.webServerConfig = {enabled: false};
return;
}
if (this.webServerConfig) {
// cli flags to `embark run` should override configFile and defaults (configObject)
this.webServerConfig = recursiveMerge(webServerConfig, this.webServerConfig);
} else {
this.webServerConfig = webServerConfig;
}
if (!this.pipelineConfig.enabled) {
this.webServerConfig.enabled = false;
}
this.events.emit('config:load:webserver', this.webServerConfig);
};
Config.prototype.loadEmbarkConfigFile = function() {
var configObject = {
options: {
solc: {
"optimize": true,
"optimize-runs": 200
}
},
"generationDir": "embarkArtifacts"
};
this.embarkConfig = recursiveMerge(configObject, this.embarkConfig);
const contracts = this.embarkConfig.contracts;
// determine contract 'root' directories
this.contractDirectories = contracts.map((dir) => {
return dir.split("**")[0];
}).map((dir) => {
return dir.split("*.")[0];
});
this.contractDirectories.push(constants.httpContractsDirectory);
this.buildDir = this.embarkConfig.buildDir;
this.configDir = this.embarkConfig.config;
};
Config.prototype.loadPipelineConfigFile = function() {
const defaultPipelineConfig = {
typescript: false,
enabled: true
};
let pipelineConfigPath = this._getFileOrObject(this.configDir, 'pipeline', 'pipeline');
// Embark applications in "simple" mode that aren't aware of `pipeline.js` configuration capabilities
// won't have a pipeline config path so we need to perform this safety check here, otherwise the
// next expression is going to throw.
if (pipelineConfigPath !== undefined) {
// At this point, `pipelineConfigPath` could be either `config/pipeline` or a filepath including its extension.
// We need to make sure that we always have an extension.
pipelineConfigPath = `${dappPath(pipelineConfigPath)}${path.extname(pipelineConfigPath) === '.js' ? '' : '.js'}`;
}
let pipelineConfig = defaultPipelineConfig;
if (pipelineConfigPath && fs.existsSync(pipelineConfigPath)) {
delete require.cache[pipelineConfigPath];
pipelineConfig = recursiveMerge(
recursiveMerge(true, pipelineConfig),
require(pipelineConfigPath)
);
}
this.pipelineConfig = pipelineConfig;
this.events.emit('config:load:pipeline', this.pipelineConfig);
};
Config.prototype.loadAssetFiles = function () {
if(!this.embarkConfig.app) return;
Object.keys(this.embarkConfig.app).forEach(targetFile => {
this.assetFiles[targetFile] = this.loadFiles(this.embarkConfig.app[targetFile]);
});
};
function findMatchingExpression(filename, filesExpressions) {
for (let fileExpression of filesExpressions) {
var matchingFiles = utils.filesMatchingPattern(fileExpression);
for (let matchFile of matchingFiles) {
if (matchFile === filename) {
return path.dirname(fileExpression).replace(/\*/g, '');
}
}
}
return path.dirname(filename);
}
Config.prototype.loadFiles = function(files) {
var self = this;
var originalFiles = utils.filesMatchingPattern(files);
var readFiles = [];
let storageConfig = self.storageConfig;
originalFiles.filter(function(file) {
return (file[0] === '$' || file.indexOf('.') >= 0);
}).filter(function(file) {
let basedir = findMatchingExpression(file, files);
readFiles.push(new File({path: file, originalPath: file, type: Types.dappFile, basedir: basedir, storageConfig: storageConfig}));
});
var filesFromPlugins = [];
var filePlugins = self.plugins.getPluginsFor('pipelineFiles');
filePlugins.forEach(function(plugin) {
try {
var fileObjects = plugin.runFilePipeline();
for (var i=0; i < fileObjects.length; i++) {
var fileObject = fileObjects[i];
filesFromPlugins.push(fileObject);
}
}
catch(err) {
self.logger.error(err.message);
}
});
filesFromPlugins.filter(function(file) {
if ((file.intendedPath && utils.fileMatchesPattern(files, file.intendedPath)) || utils.fileMatchesPattern(files, file.file)) {
readFiles.push(file);
}
});
return readFiles;
};
// NOTE: this doesn't work for internal modules
Config.prototype.loadPluginContractFiles = function() {
var self = this;
let storageConfig = self.storageConfig;
var contractsPlugins = this.plugins.getPluginsFor('contractFiles');
contractsPlugins.forEach(function(plugin) {
plugin.contractsFiles.forEach(function(file) {
var filename = file.replace('./','');
self.contractsFiles.push(new File({ path: filename, originalPath: path.join(plugin.pluginPath, filename), pluginPath: plugin.pluginPath, type: Types.custom, storageConfig,
resolver: function(callback) {
callback(plugin.loadPluginFile(file));
}
}));
});
});
};
module.exports = Config;

View File

@ -1,127 +0,0 @@
/* global module process require */
const fs = require('fs-extra');
const parseJson = require('parse-json');
const path = require('path');
import { joinPath } from 'embark-utils';
import './env';
require('colors');
function mkdirpSync(...args) { return fs.mkdirpSync(...args); }
function mkdirp(...args) { return fs.mkdirp(...args); }
function readdir(...args) { return fs.readdir(...args); }
function stat(...args) { return fs.stat(...args); }
function remove(...args) { return fs.remove(...args); }
function copy(...args) { return fs.copy(...args); }
function copySync(...args) { return fs.copySync(...args); }
function move(...args) { return fs.move(...args); }
function moveSync(...args) { return fs.moveSync(...args); }
function symlink(...args) { return fs.symlink(...args); }
function appendFileSync(...args) { return fs.appendFileSync(...args); }
function writeFile(...args) { return fs.writeFile(...args); }
function writeFileSync(...args) { return fs.writeFileSync(...args); }
function readFile(...args) { return fs.readFile(...args); }
function readFileSync(...args) { return fs.readFileSync(...args); }
function readdirSync(...args) { return fs.readdirSync(...args); }
function statSync(...args) { return fs.statSync(...args); }
function readJSONSync(...args) {
let json;
try {
json = parseJson(readFileSync(...args));
} catch (e) {
console.error('error: '.red + args[0].green.underline + ' ' + e.message.green);
process.exit(1);
}
return json;
}
function writeJSONSync(...args) { return fs.writeJSONSync(...args); }
function outputJSONSync(...args) { return fs.outputJSONSync(...args); }
function writeJson(...args) { return fs.writeJson(...args); }
function existsSync(...args) { return fs.existsSync(...args); }
function ensureFileSync(...args) { return fs.ensureFileSync(...args); }
function ensureDirSync(...args) { return fs.ensureDirSync(...args); }
function access(...args) { return fs.access(...args); }
function removeSync(...args) { return fs.removeSync(...args); }
function createWriteStream(...args) { return fs.createWriteStream(...args); }
function copyPreserve(sourceFilePath, targetFilePath) {
const implementation = (sourceFilePath, targetFilePath) => {
let ext = 1;
let preserved = targetFilePath;
while (fs.existsSync(preserved)) {
const extname = path.extname(targetFilePath);
preserved = joinPath(
path.dirname(targetFilePath),
`${path.basename(targetFilePath, extname)}.${ext}${extname}`
);
ext++;
}
if (preserved !== targetFilePath) {
fs.copySync(targetFilePath, preserved);
}
fs.copySync(sourceFilePath, targetFilePath);
};
return implementation(sourceFilePath, targetFilePath);
}
function outputFileSync(...args) { return fs.outputFileSync(...args); }
module.exports = {
access,
appendFileSync,
copy,
copyPreserve,
copySync,
createWriteStream,
existsSync,
ensureFileSync,
ensureDirSync,
mkdirp,
mkdirpSync,
move,
moveSync,
outputFileSync,
outputJSONSync,
readFile,
readFileSync,
readJSONSync,
readdir,
readdirSync,
remove,
removeSync,
stat,
statSync,
symlink,
writeFile,
writeFileSync,
writeJSONSync,
writeJson
};

View File

@ -1,303 +0,0 @@
const utils = require('../utils/utils.js');
import { __ } from 'embark-i18n';
import { dappPath, embarkPath, isEs6Module, joinPath } from 'embark-utils';
const constants = require('embark-core/constants');
const fs = require('fs-extra');
const deepEqual = require('deep-equal');
// TODO: pass other params like blockchainConfig, contract files, etc..
var Plugin = function(options) {
this.name = options.name;
this.isInternal = options.isInternal;
this.pluginModule = options.pluginModule;
this.pluginPath = options.pluginPath;
this.pluginConfig = options.pluginConfig;
this.shouldInterceptLogs = options.interceptLogs;
this.clientWeb3Providers = [];
this.beforeDeploy = [];
this.contractsGenerators = [];
this.generateCustomContractCode = null;
this.testContractFactory = null;
this.pipeline = [];
this.pipelineFiles = [];
this.console = [];
this.contractsConfigs = [];
this.contractsFiles = [];
this.compilers = [];
this.serviceChecks = [];
this.dappGenerators = [];
this.pluginTypes = [];
this.uploadCmds = [];
this.apiCalls = [];
this.imports = [];
this.embarkjs_code = [];
this.generated_code = [];
this.embarkjs_init_code = {};
this.embarkjs_init_console_code = {};
this.fs = fs;
this.afterContractsDeployActions = [];
this.onDeployActions = [];
this.eventActions = {};
this._loggerObject = options.logger;
this.logger = this._loggerObject; // Might get changed if we do intercept
this.events = options.events;
this.config = options.config;
this.plugins = options.plugins;
this.env = options.env;
this.loaded = false;
this.currentContext = options.context;
this.acceptedContext = options.pluginConfig.context || [constants.contexts.any];
this.version = options.version;
this.constants = constants;
if (!Array.isArray(this.currentContext)) {
this.currentContext = [this.currentContext];
}
if (!Array.isArray(this.acceptedContext)) {
this.acceptedContext = [this.acceptedContext];
}
};
Plugin.prototype.dappPath = dappPath;
Plugin.prototype.embarkPath = embarkPath;
Plugin.prototype._log = function(type) {
this._loggerObject[type](this.name + ':', ...[].slice.call(arguments, 1));
};
Plugin.prototype.setUpLogger = function () {
this.logger = {
log: this._log.bind(this, 'log'),
warn: this._log.bind(this, 'warn'),
error: this._log.bind(this, 'error'),
info: this._log.bind(this, 'info'),
debug: this._log.bind(this, 'debug'),
trace: this._log.bind(this, 'trace'),
dir: this._log.bind(this, 'dir')
};
};
Plugin.prototype.isContextValid = function() {
if (this.currentContext.includes(constants.contexts.any) || this.acceptedContext.includes(constants.contexts.any)) {
return true;
}
return this.acceptedContext.some(context => {
return this.currentContext.includes(context);
});
};
Plugin.prototype.hasContext = function(context) {
return this.currentContext.includes(context);
};
Plugin.prototype.loadPlugin = function() {
if (!this.isContextValid()) {
this.logger.warn(__('Plugin {{name}} can only be loaded in the context of "{{contexts}}"', {name: this.name, contexts: this.acceptedContext.join(', ')}));
return false;
}
this.loaded = true;
if (this.shouldInterceptLogs) {
this.setUpLogger();
}
if (isEs6Module(this.pluginModule)) {
if (this.pluginModule.default) {
this.pluginModule = this.pluginModule.default;
}
return new this.pluginModule(this);
}
this.pluginModule.call(this, this);
};
Plugin.prototype.loadInternalPlugin = function() {
if (isEs6Module(this.pluginModule)) {
if (this.pluginModule.default) {
this.pluginModule = this.pluginModule.default;
}
}
return new this.pluginModule(this, this.pluginConfig); /*eslint no-new: "off"*/
};
Plugin.prototype.loadPluginFile = function(filename) {
return fs.readFileSync(this.pathToFile(filename)).toString();
};
Plugin.prototype.pathToFile = function(filename) {
if (!this.pluginPath) {
throw new Error('pluginPath not defined for plugin: ' + this.name);
}
return joinPath(this.pluginPath, filename);
};
// TODO: add deploy provider
Plugin.prototype.registerClientWeb3Provider = function(cb) {
this.clientWeb3Providers.push(cb);
this.addPluginType('clientWeb3Provider');
};
Plugin.prototype.registerContractsGeneration = function(cb) {
this.contractsGenerators.push(cb);
this.addPluginType('contractGeneration');
};
Plugin.prototype.registerCustomContractGenerator = function (cb) {
this.generateCustomContractCode = cb;
this.addPluginType('customContractGeneration');
};
Plugin.prototype.registerTestContractFactory = function(cb) {
this.testContractFactory = cb;
this.addPluginType('testContractFactory');
};
Plugin.prototype.registerPipeline = function(matcthingFiles, cb) {
// TODO: generate error for more than one pipeline per plugin
this.pipeline.push({matcthingFiles: matcthingFiles, cb: cb});
this.addPluginType('pipeline');
};
Plugin.prototype.registerDappGenerator = function(framework, cb){
this.dappGenerators.push({framework: framework, cb: cb});
this.pluginTypes.push('dappGenerator');
};
Plugin.prototype.registerCustomType = function(type){
this.pluginTypes.push(type);
};
Plugin.prototype.addFileToPipeline = function(file, intendedPath, options) {
this.pipelineFiles.push({file: file, intendedPath: intendedPath, options: options});
this.addPluginType('pipelineFiles');
};
Plugin.prototype.addContractFile = function(file) {
if (this.isInternal) {
throw new Error("this API cannot work for internal modules. please use an event command instead: config:contractsFiles:add");
}
this.contractsFiles.push(file);
this.addPluginType('contractFiles');
};
Plugin.prototype.registerConsoleCommand = function(optionsOrCb) {
if (typeof optionsOrCb === 'function') {
this.logger.warn(__('Registering console commands with function syntax is deprecated and will likely be removed in future versions of Embark'));
this.logger.info(__('You can find the new API documentation here: %s', 'https://embark.status.im/docs/plugin_reference.html#registerConsoleCommand-options'.underline));
}
this.console.push(optionsOrCb);
this.addPluginType('console');
};
// TODO: this only works for services done on startup
Plugin.prototype.registerServiceCheck = function(checkName, checkFn, time) {
this.serviceChecks.push({checkName: checkName, checkFn: checkFn, time: time});
this.addPluginType('serviceChecks');
};
Plugin.prototype.has = function(pluginType) {
return this.pluginTypes.indexOf(pluginType) >= 0;
};
Plugin.prototype.addPluginType = function(pluginType) {
this.pluginTypes.push(pluginType);
this.pluginTypes = Array.from(new Set(this.pluginTypes));
};
Plugin.prototype.generateProvider = function(args) {
return this.clientWeb3Providers.map(function(cb) {
return cb.call(this, args);
}).join("\n");
};
Plugin.prototype.generateContracts = function(args) {
return this.contractsGenerators.map(function(cb) {
return cb.call(this, args);
}).join("\n");
};
Plugin.prototype.registerContractConfiguration = function(config) {
this.contractsConfigs.push(config);
this.addPluginType('contractsConfig');
};
Plugin.prototype.registerCompiler = function(extension, cb) {
this.compilers.push({extension: extension, cb: cb});
this.addPluginType('compilers');
};
Plugin.prototype.registerUploadCommand = function(cmd, cb) {
this.uploadCmds.push({cmd: cmd, cb: cb});
this.addPluginType('uploadCmds');
};
Plugin.prototype.addCodeToEmbarkJS = function(code) {
this.addPluginType('embarkjsCode');
// TODO: what is this/why
if (!this.embarkjs_code.some((existingCode) => deepEqual(existingCode, code))) {
this.embarkjs_code.push(code);
}
};
Plugin.prototype.addGeneratedCode = function(codeCb) {
this.addPluginType('generatedCode');
this.generated_code.push(codeCb);
};
Plugin.prototype.addProviderInit = function(providerType, code, initCondition) {
this.embarkjs_init_code[providerType] = this.embarkjs_init_code[providerType] || [];
this.embarkjs_init_code[providerType].push([code, initCondition]);
this.addPluginType('initCode');
};
Plugin.prototype.addConsoleProviderInit = function(providerType, code, initCondition) {
this.embarkjs_init_console_code[providerType] = this.embarkjs_init_console_code[providerType] || [];
this.addPluginType('initConsoleCode');
const toAdd = [code, initCondition];
if (!this.embarkjs_init_console_code[providerType].some((initConsoleCode) => deepEqual(initConsoleCode, toAdd))) {
this.embarkjs_init_console_code[providerType].push(toAdd);
}
};
Plugin.prototype.registerImportFile = function(importName, importLocation) {
this.imports.push([importName, importLocation]);
this.addPluginType('imports');
};
Plugin.prototype.registerActionForEvent = function(eventName, cb) {
if (!this.eventActions[eventName]) {
this.eventActions[eventName] = [];
}
this.eventActions[eventName].push(cb);
this.addPluginType('eventActions');
};
Plugin.prototype.registerAPICall = function(method, endpoint, cb) {
this.apiCalls.push({method, endpoint, cb});
this.addPluginType('apiCalls');
this.events.emit('plugins:register:api', {method, endpoint, cb});
};
Plugin.prototype.runFilePipeline = function() {
var self = this;
return this.pipelineFiles.map(function(file) {
var obj = {};
obj.filename = file.file.replace('./','');
obj.content = self.loadPluginFile(file.file).toString();
obj.intendedPath = file.intendedPath;
obj.options = file.options;
obj.path = self.pathToFile(obj.filename);
return obj;
});
};
Plugin.prototype.runPipeline = function(args) {
// TODO: should iterate the pipelines
var pipeline = this.pipeline[0];
var shouldRunPipeline = utils.fileMatchesPattern(pipeline.matcthingFiles, args.targetFile);
if (shouldRunPipeline) {
return pipeline.cb.call(this, args);
}
return args.source;
};
module.exports = Plugin;

View File

@ -1,249 +0,0 @@
import { dappPath, embarkPath } from 'embark-utils';
const async = require('async');
var Plugin = require('./plugin.js');
var fs = require('../core/fs.js');
var Plugins = function(options) {
this.pluginList = options.plugins || [];
this.interceptLogs = options.interceptLogs;
this.plugins = [];
// TODO: need backup 'NullLogger'
this.logger = options.logger;
this.events = options.events;
this.config = options.config;
this.context = options.context;
this.fs = fs;
this.env = options.env;
this.version = options.version;
};
Plugins.deprecated = {
'embarkjs-connector-web3': '4.1.0'
};
Plugins.prototype.loadPlugins = function() {
Object.entries(Plugins.deprecated).forEach(([pluginName, embarkVersion]) => {
if (this.pluginList[pluginName]) {
delete this.pluginList[pluginName];
this.logger.warn(`${pluginName} plugin was not loaded because it has been deprecated as of embark v${embarkVersion}, please remove it from this project's embark.json and package.json`);
}
});
Object.entries(this.pluginList).forEach(([pluginName, pluginConfig]) => {
this.loadPlugin(pluginName, pluginConfig);
});
};
Plugins.prototype.listPlugins = function() {
return this.plugins.reduce((list, plugin) => {
if (plugin.loaded) {
list.push(plugin.name);
}
return list;
}, []);
};
// for services that act as a plugin but have core functionality
Plugins.prototype.createPlugin = function(pluginName, pluginConfig) {
let plugin = {};
let pluginPath = false;
var pluginWrapper = new Plugin({
name: pluginName,
pluginModule: plugin,
pluginConfig: pluginConfig,
logger: this.logger,
pluginPath: pluginPath,
interceptLogs: this.interceptLogs,
events: this.events,
config: this.config,
plugins: this.plugins,
fs: this.fs,
isInternal: true,
context: this.context
});
this.plugins.push(pluginWrapper);
return pluginWrapper;
};
Plugins.prototype.loadInternalPlugin = function(pluginName, pluginConfig, isPackage) {
let pluginPath, plugin;
if (isPackage) {
pluginPath = pluginName;
plugin = require(pluginName);
} else {
pluginPath = embarkPath('dist/lib/modules/' + pluginName);
plugin = require(pluginPath);
}
if (plugin.default) {
plugin = plugin.default;
}
const pluginWrapper = new Plugin({
name: pluginName,
pluginModule: plugin,
pluginConfig: pluginConfig || {},
logger: this.logger,
pluginPath: pluginPath,
interceptLogs: this.interceptLogs,
events: this.events,
config: this.config,
plugins: this.plugins,
fs: this.fs,
isInternal: true,
context: this.context,
env: this.env
});
const pluginInstance = pluginWrapper.loadInternalPlugin();
this.plugins.push(pluginWrapper);
return pluginInstance;
};
Plugins.prototype.loadPlugin = function(pluginName, pluginConfig) {
let pluginPath = dappPath('node_modules', pluginName);
let plugin = require(pluginPath);
if (plugin.default) {
plugin = plugin.default;
}
var pluginWrapper = new Plugin({
name: pluginName,
pluginModule: plugin,
pluginConfig: pluginConfig,
logger: this.logger,
pluginPath: pluginPath,
interceptLogs: this.interceptLogs,
events: this.events,
config: this.config,
plugins: this.plugins,
fs: this.fs,
isInternal: false,
context: this.context,
version: this.version
});
pluginWrapper.loadPlugin();
this.plugins.push(pluginWrapper);
};
Plugins.prototype.getPluginsFor = function(pluginType) {
return this.plugins.filter(function(plugin) {
return plugin.has(pluginType);
});
};
Plugins.prototype.getPluginsProperty = function(pluginType, property, sub_property) {
let matchingPlugins = this.plugins.filter(function(plugin) {
return plugin.has(pluginType);
});
// Sort internal plugins first
matchingPlugins.sort((a, b) => {
if (a.isInternal) {
return -1;
}
if (b.isInternal) {
return 1;
}
return 0;
});
let matchingProperties = matchingPlugins.map((plugin) => {
if (sub_property) {
return plugin[property][sub_property];
}
return plugin[property];
});
// Remove empty properties
matchingProperties = matchingProperties.filter((property) => property);
//return flattened list
if (matchingProperties.length === 0) return [];
return matchingProperties.reduce((a,b) => { return a.concat(b); }) || [];
};
Plugins.prototype.getPluginsPropertyAndPluginName = function(pluginType, property, sub_property) {
let matchingPlugins = this.plugins.filter(function(plugin) {
return plugin.has(pluginType);
});
// Sort internal plugins first
matchingPlugins.sort((a, b) => {
if (a.isInternal) {
return -1;
}
if (b.isInternal) {
return 1;
}
return 0;
});
let matchingProperties = [];
matchingPlugins.map((plugin) => {
if (sub_property) {
let newList = [];
for (let kall of (plugin[property][sub_property] || [])) {
matchingProperties.push([kall, plugin.name]);
}
return newList;
}
let newList = [];
for (let kall of (plugin[property] || [])) {
matchingProperties.push([kall, plugin.name]);
}
return newList;
});
// Remove empty properties
matchingProperties = matchingProperties.filter((property) => property[0]);
//return flattened list
if (matchingProperties.length === 0) return [];
// return matchingProperties.reduce((a,b) => { return a.concat(b); }) || [];
return matchingProperties;
};
// TODO: because this is potentially hanging, we should issue a trace warning if the event does not exists
Plugins.prototype.runActionsForEvent = function(eventName, args, cb) {
const self = this;
if (typeof (args) === 'function') {
cb = args;
args = [];
}
let actionPlugins = this.getPluginsPropertyAndPluginName('eventActions', 'eventActions', eventName);
if (actionPlugins.length === 0) {
return cb(null, args);
}
this.events.log("ACTION", eventName, "");
async.reduce(actionPlugins, args, function (current_args, pluginObj, nextEach) {
const [plugin, pluginName] = pluginObj;
self.events.log("== ACTION FOR " + eventName, plugin.name, pluginName);
if (typeof (args) === 'function') {
plugin.call(plugin, (...params) => {
nextEach(...params || current_args);
});
} else {
plugin.call(plugin, args, (...params) => {
nextEach(...params || current_args);
});
}
}, cb);
};
Plugins.prototype.emitAndRunActionsForEvent = function(eventName, args, cb) {
if (typeof (args) === 'function') {
cb = args;
args = [];
}
this.events.emit(eventName, args);
return this.runActionsForEvent(eventName, args, cb);
};
module.exports = Plugins;

View File

@ -1,92 +0,0 @@
import { __ } from 'embark-i18n';
class ServicesMonitor {
constructor(options) {
const self = this;
this.events = options.events;
this.logger = options.logger;
this.plugins = options.plugins;
this.checkList = {};
this.checkTimers = {};
this.checkState = {};
this.working = false;
self.events.setCommandHandler("services:register", (checkName, checkFn, time, initialStatus) => {
self.addCheck(checkName, checkFn, time, initialStatus);
});
}
}
ServicesMonitor.prototype.initCheck = function (checkName) {
let self = this;
let check = this.checkList[checkName];
if (!check) {
return false;
}
self.events.on('check:' + checkName, function (obj) {
if (check && check.status === 'off' && obj.status === 'on') {
self.events.emit('check:backOnline:' + checkName);
}
if (check && check.status === 'on' && obj.status === 'off') {
self.events.emit('check:wentOffline:' + checkName);
}
check.status = obj.status;
// const newState = {name: obj.name, status: obj.status, serviceName: checkName};
// if (!deepEqual(newState, self.checkState[checkName])) {
self.checkState[checkName] = {name: obj.name, status: obj.status, serviceName: checkName};
self.events.emit("servicesState", self.checkState);
// }
});
if (check.interval !== 0) {
self.checkTimers[checkName] = setInterval(function () {
check.fn.call(check.fn, function (obj) {
self.events.emit('check:' + checkName, obj);
});
}, check.interval);
}
check.fn.call(check.fn, function (obj) {
self.events.emit('check:' + checkName, obj);
});
};
ServicesMonitor.prototype.addCheck = function (checkName, checkFn, time, initialState) {
this.logger.trace('add check: ' + checkName);
this.checkList[checkName] = {fn: checkFn, interval: time || 5000, status: initialState};
if (this.working) {
this.initCheck(checkName);
}
};
ServicesMonitor.prototype.stopCheck = function (name) {
clearInterval(this.checkTimers[name]);
delete this.checkTimers[name];
delete this.checkList[name];
delete this.checkState[name];
};
ServicesMonitor.prototype.startMonitor = function () {
let self = this;
this.working = true;
this.logger.trace('startMonitor');
let servicePlugins = this.plugins.getPluginsProperty('serviceChecks', 'serviceChecks');
servicePlugins.forEach(function (pluginCheck) {
self.addCheck(pluginCheck.checkName, pluginCheck.checkFn, pluginCheck.time);
});
Object.keys(this.checkList).forEach(checkName => {
try {
self.initCheck(checkName);
} catch (err) {
self.logger.error(__("error running service check"));
self.logger.error(err.message);
}
});
};
module.exports = ServicesMonitor;

View File

@ -1,21 +1,26 @@
let version = require('../../package.json').version;
const Logger = require('embark-logger');
let pkg = require('../../package.json');
import { Config, Events } from 'embark-core';
import { Logger } from 'embark-logger';
class Embark {
constructor(options) {
this.version = version;
this.version = pkg.version;
this.options = options || {};
}
initConfig(env, options) {
let Events = require('./core/events.js');
let Config = require('./core/config.js');
this.events = new Events();
this.logger = new Logger({logLevel: 'debug', events: this.events, context: this.context});
this.config = new Config({env: env, logger: this.logger, events: this.events, context: this.context, version: this.version});
this.config = new Config({
env: env,
logger: this.logger,
events: this.events,
context: this.context,
version: this.version,
package: pkg
});
this.config.loadConfigFiles(options);
this.plugins = this.config.plugins;
}

View File

@ -1,116 +0,0 @@
import {normalizeInput} from 'embark-utils';
function dirname() {
const path = require('path');
return path.dirname.apply(path.dirname, arguments);
}
function filesMatchingPattern(files) {
const globule = require('globule');
return globule.find(files, {nonull: true});
}
function fileMatchesPattern(patterns, intendedPath) {
const globule = require('globule');
return globule.isMatch(patterns, intendedPath);
}
function cd(folder) {
const shelljs = require('shelljs');
shelljs.cd(folder);
}
function sed(file, pattern, replace) {
const shelljs = require('shelljs');
shelljs.sed('-i', pattern, replace, file);
}
function extractTar(filename, packageDirectory, cb) {
const o_fs = require('fs-extra');
const tar = require('tar');
o_fs.createReadStream(filename).pipe(
tar.x({
strip: 1,
C: packageDirectory
}).on('end', function () {
cb();
})
);
}
function extractZip(filename, packageDirectory, opts, cb) {
const decompress = require('decompress');
decompress(filename, packageDirectory, opts).then((_files) => {
cb();
});
}
function isValidDomain(v) {
// from: https://github.com/miguelmota/is-valid-domain
if (typeof v !== 'string') return false;
var parts = v.split('.');
if (parts.length <= 1) return false;
var tld = parts.pop();
var tldRegex = /^(?:xn--)?[a-zA-Z0-9]+$/gi;
if (!tldRegex.test(tld)) return false;
var isValid = parts.every(function(host) {
var hostRegex = /^(?!:\/\/)([a-zA-Z0-9]+|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])$/gi;
return hostRegex.test(host);
});
return isValid;
}
function interceptLogs(consoleContext, logger) {
let context = {};
context.console = consoleContext;
context.console.log = function () {
logger.info(normalizeInput(arguments));
};
context.console.warn = function () {
logger.warn(normalizeInput(arguments));
};
context.console.info = function () {
logger.info(normalizeInput(arguments));
};
context.console.debug = function () {
// TODO: ue JSON.stringify
logger.debug(normalizeInput(arguments));
};
context.console.trace = function () {
logger.trace(normalizeInput(arguments));
};
context.console.dir = function () {
logger.dir(normalizeInput(arguments));
};
}
function getWindowSize() {
const windowSize = require('window-size');
if (windowSize) {
return windowSize.get();
}
return {width: 240, height: 75};
}
module.exports = {
dirname,
filesMatchingPattern,
fileMatchesPattern,
isValidDomain,
cd,
sed,
extractTar,
extractZip,
normalizeInput,
interceptLogs,
getWindowSize
};

View File

@ -1,10 +1,19 @@
/*global __dirname, describe, it, before, after, require*/
import { TestLogger } from 'embark-core';
import * as i18n from 'embark-i18n';
const assert = require('assert');
const sinon = require('sinon');
let TestLogger = require('../lib/utils/test_logger');
const Web3 = require('web3');
import { dappPath, getWeiBalanceFromString, getHexBalanceFromString, AccountParser } from 'embark-utils';
import {
dappPath,
getWeiBalanceFromString,
getHexBalanceFromString,
AccountParser,
joinPath,
setUpEnv
} from 'embark-utils';
/* setUpEnv(joinPath(__dirname, '../../')); */
i18n.setOrDetectLocale('en');
describe('embark.AccountParser', function () {

View File

@ -1,10 +1,7 @@
/*global describe, it*/
import { Config, Events, Plugins, TestLogger } from 'embark-core';
const { dappPath } = require('embark-utils');
const Config = require('../lib/core/config.js');
const Plugins = require('../lib/core/plugins.js');
const assert = require('assert');
const TestLogger = require('../lib/utils/test_logger');
const Events = require('../lib/core/events');
describe('embark.Config', function () {
let config = new Config({

View File

@ -3,15 +3,10 @@ import { File, Types } from "embark-utils";
let ContractsManager = require('embark-contracts-manager');
let Compiler = require('embark-compiler');
let Logger = require('embark-logger');
import { IPC } from 'embark-core';
let TestLogger = require('../lib/utils/test_logger');
let Events = require('../lib/core/events');
const fs = require('../lib/core/fs');
import { Logger } from 'embark-logger';
import { Events, fs, IPC, TestLogger, Plugins } from 'embark-core';
let assert = require('assert');
let Plugins = require('../lib/core/plugins.js');
let readFile = function(file) {
return new File({filename: file, type: Types.dappFile, path: file});
};

View File

@ -1,9 +1,8 @@
/*globals describe, it, before, beforeEach*/
import { Events, fs } from 'embark-core';
import { File, Types } from 'embark-utils';
const Assert = require("assert");
const {expect} = require("chai");
const fs = require("../lib/core/fs");
const Events = require("../lib/core/events");
let events;
const testEventName = "testevent";

View File

@ -1,12 +1,10 @@
/*global describe, it, require*/
import { Events, Plugins, TestLogger } from 'embark-core';
import { File, Types } from "embark-utils";
const assert = require('assert');
const Compiler = require('embark-compiler');
const Plugins = require('../../../lib/core/plugins.js');
const TestLogger = require('../../../lib/utils/test_logger');
const Events = require('../../../lib/core/events');
const readFile = function(file) {
return new File({filename: file, type: Types.dappFile, path: file});

View File

@ -1,12 +1,10 @@
/*globals describe, it, beforeEach*/
const {expect} = require('chai');
const sinon = require('sinon');
const fs = require('../../lib/core/fs');
const Events = require('../../lib/core/events');
const Logger = require('embark-logger');
import { Logger } from 'embark-logger';
import { getAddressToContract } from 'embark-utils';
const ConsoleListener = require('embark-console-listener');
import { IPC } from 'embark-core';
import { Events, fs, IPC } from 'embark-core';
require('colors');
let events,

View File

@ -2,7 +2,6 @@
const { dappPath, File, Types, prepareForCompilation } = require('embark-utils');
const path = require("path");
const {expect} = require("chai");
const fs = require("../../../lib/core/fs");
const fsNode = require("fs");
let file, content;

View File

@ -1,9 +1,7 @@
/*global describe, it, require*/
const fs = require('../../../lib/core/fs');
import { IPC } from 'embark-core';
import { fs, IPC, TestLogger } from 'embark-core';
import { File, Types } from 'embark-utils';
let SolidityCompiler = require('embark-solidity');
let TestLogger = require('../../../lib/utils/test_logger');
let readFile = function(file) {
return new File({filename: file, type: Types.dappFile, path: file});

View File

@ -1,9 +1,8 @@
/*global describe, it, before, beforeEach*/
const assert = require('assert');
const sinon = require('sinon');
const TestLogger = require('../lib/utils/test_logger');
const path = require('path');
import { ProcessLauncher } from 'embark-core';
import { ProcessLauncher, TestLogger } from 'embark-core';
let logger = new TestLogger({});

View File

@ -1,6 +1,6 @@
/*globals describe, it, before*/
const assert = require('assert');
const TemplateGenerator = require('../lib/utils/template_generator');
import { TemplateGenerator } from 'embark-core';
const semver = require('semver');
const sinon = require('sinon');
const request = require('request');

View File

@ -1,5 +1,4 @@
/*global describe, it*/
const Utils = require('../lib/utils/utils');
import { getExternalContractUrl } from 'embark-utils';
const assert = require('assert');
const constants = require('embark-core/constants');

View File

@ -1,5 +1,5 @@
/*globals describe, it*/
const TestLogger = require('../lib/utils/test_logger');
import { TestLogger } from 'embark-core';
import { VM } from 'embark-code-runner';
const {expect} = require('chai');

View File

@ -51,6 +51,7 @@
"embark-core": "^5.0.0-alpha.1",
"embark-i18n": "^5.0.0-alpha.1",
"embark-utils": "^5.0.0-alpha.1",
"embark-logger": "^5.0.0-alpha.1",
"web3": "1.2.1"
},
"devDependencies": {

View File

@ -1,7 +1,8 @@
import async from "async";
import { Embark, Events, Logger } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import { Embark, Events } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import { __ } from "embark-i18n";
import { AccountParser, dappPath } from "embark-utils";
import { Logger } from 'embark-logger';
import Web3 from "web3";
const { blockchain: blockchainConstants } = require("embark-core/constants");

View File

@ -1,5 +1,5 @@
import async from "async";
import { CmdLine } from "remix-debug-debugtest";
import async from 'async';
import { CmdLine } from 'remix-debug-debugtest';
export default class DebuggerManager {
private nodeUrl: string;
@ -25,7 +25,7 @@ export default class DebuggerManager {
private debug(txHash: string, filename: string, cb: any) {
const cmdLine = new CmdLine();
cmdLine.connect("http", this.nodeUrl);
cmdLine.connect('http', this.nodeUrl);
cmdLine.loadCompilationData(this.inputJson, this.outputJson);
cmdLine.initDebugger(() => {
@ -48,7 +48,7 @@ export default class DebuggerManager {
async.waterfall([
function initDebugger(next: any) {
cmdLine = new CmdLine();
cmdLine.connect("http", self.nodeUrl);
cmdLine.connect('http', self.nodeUrl);
cmdLine.loadCompilationData(self.inputJson, self.outputJson);
cmdLine.initDebugger(() => {
// self.isDebugging = true
@ -57,19 +57,19 @@ export default class DebuggerManager {
},
function startDebug(next: any) {
const debuggerData: any = {};
cmdLine.events.on("locals", (data: any) => {
cmdLine.events.on('locals', (data: any) => {
debuggerData.locals = self.simplifyDebuggerVars(data);
});
cmdLine.events.on("globals", (data: any) => {
cmdLine.events.on('globals', (data: any) => {
debuggerData.contract = self.simplifyDebuggerVars(data);
});
cmdLine.startDebug(txHash, filename, () => {
cmdLine.events.on("source", () => {
cmdLine.events.on('source', () => {
const lines: string[] = cmdLine.getSource();
// TODO: this is a bit of a hack
const line: string = lines.filter((x) => x.indexOf("=>") === 0)[0];
const line: string = lines.filter((x) => x.indexOf('=>') === 0)[0];
outputCb(lines, line, debuggerData);
});

View File

@ -1,8 +1,8 @@
import "colors";
import { __ } from "embark-i18n";
import DebuggerManager from "./debugger_manager";
import 'colors';
import { __ } from 'embark-i18n';
import DebuggerManager from './debugger_manager';
const NO_DEBUG_SESSION = __("No debug session active. Activate one with `debug`");
const NO_DEBUG_SESSION = __('No debug session active. Activate one with `debug`');
interface Events {
on: any;
@ -31,28 +31,28 @@ class TransactionDebugger {
constructor(embark: EmbarkApi, options?: any) {
this.embark = embark;
this.debuggerManager = new DebuggerManager("http://localhost:8545");
embark.events.on("contracts:compile:solc", this.debuggerManager.setInputJson.bind(this.debuggerManager));
embark.events.on("contracts:compiled:solc", this.debuggerManager.setOutputJson.bind(this.debuggerManager));
this.debuggerManager = new DebuggerManager('http://localhost:8545');
embark.events.on('contracts:compile:solc', this.debuggerManager.setInputJson.bind(this.debuggerManager));
embark.events.on('contracts:compiled:solc', this.debuggerManager.setOutputJson.bind(this.debuggerManager));
this.txTracker = {};
this.lastTx = "";
this.lastTx = '';
this.isDebugging = false;
this.currentCmdTxHash = "";
this.currentCmdTxHash = '';
this.listenToEvents();
this.listenToCommands();
this.listentoAPI();
}
private listenToEvents() {
this.embark.events.on("blockchain:tx", (tx: any) => {
this.embark.events.request("contracts:contract", tx.name, (contract: any) => {
this.embark.events.on('blockchain:tx', (tx: any) => {
this.embark.events.request('contracts:contract', tx.name, (contract: any) => {
this.txTracker[tx.transactionHash] = {tx, contract};
this.lastTx = tx.transactionHash;
if (tx.status !== "0x0") { return; }
if (tx.status !== '0x0') { return; }
this.embark.logger.info("Transaction failed");
this.embark.logger.info('Transaction failed');
this.debuggerManager.getLastLine(tx.transactionHash, contract.filename, (lines: string[], line: string, knownVars: any) => {
lines.forEach((errorLine: string) => {
@ -60,7 +60,7 @@ class TransactionDebugger {
});
this.findVarsInLine(tx.transactionHash, line, knownVars, (foundVars: any) => {
if (!foundVars) { return; }
this.embark.logger.info("vars:");
this.embark.logger.info('vars:');
foundVars.forEach((variable: any) => {
this.embark.logger.info(`${variable.name}: ${variable.value}`);
});
@ -84,7 +84,7 @@ class TransactionDebugger {
for (const variable of Object.keys(knownVars.locals || {})) {
const value: any = knownVars.locals[variable];
const variableName: string = variable.split(" ")[0];
const variableName: string = variable.split(' ')[0];
if (line && line.indexOf(variableName) >= 0) {
foundVars.push({name: variable, value});
}
@ -92,7 +92,7 @@ class TransactionDebugger {
for (const variable of Object.keys(knownVars.contract || {})) {
const value: any = knownVars.contract[variable];
const variableName: string = variable.split(" ")[0];
const variableName: string = variable.split(' ')[0];
if (line && line.indexOf(variableName) >= 0) {
foundVars.push({name: variable, value});
}
@ -106,10 +106,10 @@ class TransactionDebugger {
this.debuggerData = {};
this.apiDebugger = false;
this.embark.registerAPICall("post", "/embark-api/debugger/start", (req: any, res: any) => {
this.embark.registerAPICall('post', '/embark-api/debugger/start', (req: any, res: any) => {
const txHash: string = req.body.params.txHash;
this.embark.events.request("contracts:contract:byTxHash", txHash, (err: any, contract: any) => {
this.embark.events.request('contracts:contract:byTxHash', txHash, (err: any, contract: any) => {
if (err) {
this.embark.logger.error(err);
return res.send({error: err});
@ -136,55 +136,55 @@ class TransactionDebugger {
});
});
this.embark.registerAPICall("post", "/embark-api/debugger/stop", (req: any, res: any) => {
this.embark.registerAPICall('post', '/embark-api/debugger/stop', (req: any, res: any) => {
this.apiDebugger.unload();
this.apiDebugger.events.emit("stop");
this.apiDebugger.events.emit('stop');
this.apiDebugger = false;
res.send({ok: true});
});
this.embark.registerAPICall("post", "/embark-api/debugger/JumpBack", (req: any, res: any) => {
this.embark.registerAPICall('post', '/embark-api/debugger/JumpBack', (req: any, res: any) => {
this.apiDebugger.stepJumpNextBreakpoint();
res.send({ok: true});
});
this.embark.registerAPICall("post", "/embark-api/debugger/JumpForward", (req: any, res: any) => {
this.embark.registerAPICall('post', '/embark-api/debugger/JumpForward', (req: any, res: any) => {
this.apiDebugger.stepJumpPreviousBreakpoint();
res.send({ok: true});
});
this.embark.registerAPICall("post", "/embark-api/debugger/StepOverForward", (req: any, res: any) => {
this.embark.registerAPICall('post', '/embark-api/debugger/StepOverForward', (req: any, res: any) => {
if (this.apiDebugger.canGoNext()) {
this.apiDebugger.stepOverForward(true);
}
res.send({ok: true});
});
this.embark.registerAPICall("post", "/embark-api/debugger/StepOverBackward", (req: any, res: any) => {
this.embark.registerAPICall('post', '/embark-api/debugger/StepOverBackward', (req: any, res: any) => {
if (this.apiDebugger.canGoPrevious()) {
this.apiDebugger.stepOverBack(true);
}
res.send({ok: true});
});
this.embark.registerAPICall("post", "/embark-api/debugger/StepIntoForward", (req: any, res: any) => {
this.embark.registerAPICall('post', '/embark-api/debugger/StepIntoForward', (req: any, res: any) => {
if (this.apiDebugger.canGoNext()) {
this.apiDebugger.stepIntoForward(true);
}
res.send({ok: true});
});
this.embark.registerAPICall("post", "/embark-api/debugger/StepIntoBackward", (req: any, res: any) => {
this.embark.registerAPICall('post', '/embark-api/debugger/StepIntoBackward', (req: any, res: any) => {
if (this.apiDebugger.canGoPrevious()) {
this.apiDebugger.stepIntoBack(true);
}
res.send({ok: true});
});
this.embark.registerAPICall("post", "/embark-api/debugger/breakpoint", (req: any, res: any) => {
this.embark.registerAPICall('post', '/embark-api/debugger/breakpoint', (req: any, res: any) => {
res.send({ok: true});
});
this.embark.registerAPICall("ws", "/embark-api/debugger", (ws: any, req: any) => {
this.embark.registerAPICall('ws', '/embark-api/debugger', (ws: any, req: any) => {
if (!this.apiDebugger) { return; }
this.apiDebugger.events.on("stop", () => { ws.close(1000); });
this.apiDebugger.events.on('stop', () => { ws.close(1000); });
this.apiDebugger.events.on("source", (lineColumnPos: any, rawLocation: any) => {
this.apiDebugger.events.on('source', (lineColumnPos: any, rawLocation: any) => {
this.debuggerData.sources = {lineColumnPos, rawLocation};
this.debuggerData.possibleSteps = {
canGoNext: this.apiDebugger.canGoNext(),
@ -193,7 +193,7 @@ class TransactionDebugger {
ws.send(JSON.stringify(this.debuggerData), () => {});
});
this.apiDebugger.events.on("locals", (data: any) => {
this.apiDebugger.events.on('locals', (data: any) => {
this.debuggerData.locals = this.simplifyDebuggerVars(data);
this.debuggerData.possibleSteps = {
canGoNext: this.apiDebugger.canGoNext(),
@ -202,7 +202,7 @@ class TransactionDebugger {
ws.send(JSON.stringify(this.debuggerData), () => {});
});
this.apiDebugger.events.on("globals", (data: any) => {
this.apiDebugger.events.on('globals', (data: any) => {
this.debuggerData.contract = this.simplifyDebuggerVars(data);
this.debuggerData.possibleSteps = {
canGoNext: this.apiDebugger.canGoNext(),
@ -227,27 +227,27 @@ class TransactionDebugger {
private listenToCommands() {
this.cmdDebugger = false;
this.currentCmdTxHash = "";
this.currentCmdTxHash = '';
const self = this;
function startDebug(txHash: string, filename: string, callback: (err?: string|object, output?: string) => void) {
self.currentCmdTxHash = txHash;
self.embark.logger.info("debugging tx " + txHash);
self.embark.logger.info('debugging tx ' + txHash);
self.cmdDebugger = self.debuggerManager.createDebuggerSession(txHash, filename, () => {
self.displayStepInfo(callback);
});
}
this.embark.registerConsoleCommand({
description: __("Start a debugging session using, the last transaction or the transaction specified by hash"),
description: __('Start a debugging session using, the last transaction or the transaction specified by hash'),
matches: (cmd: string) => {
const [cmdName] = cmd.split(" ");
return cmdName === "debug";
const [cmdName] = cmd.split(' ');
return cmdName === 'debug';
},
process: (cmd: string, callback: (err?: string|object, output?: string) => void) => {
const [_cmdName, txHash] = cmd.split(" ");
const [_cmdName, txHash] = cmd.split(' ');
if (txHash) {
this.embark.events.request("contracts:contract:byTxHash", txHash, (err: any, contract: any) => {
this.embark.events.request('contracts:contract:byTxHash', txHash, (err: any, contract: any) => {
if (err) {
this.embark.logger.error(err);
return callback();
@ -257,34 +257,34 @@ class TransactionDebugger {
});
return;
}
if (this.lastTx === "") {
return callback(undefined, __("No transaction to debug"));
if (this.lastTx === '') {
return callback(undefined, __('No transaction to debug'));
}
this.currentCmdTxHash = this.lastTx;
const filename: string = this.txTracker[this.lastTx].contract.filename;
startDebug(this.lastTx, filename, callback);
},
usage: "debug [txHash]",
usage: 'debug [txHash]',
});
this.embark.registerConsoleCommand({
description: __("Stops the active debugging session."),
matches: ["sd", "stop debugger"],
description: __('Stops the active debugging session.'),
matches: ['sd', 'stop debugger'],
process: (cmd: string, callback: (err?: string|object, output?: string) => void) => {
if (!this.cmdDebugger) {
this.embark.logger.warn(NO_DEBUG_SESSION);
return callback();
}
this.cmdDebugger = null;
this.embark.logger.info(__("The debug session has been stopped"));
this.embark.logger.info(__('The debug session has been stopped'));
this.cmdDebugger.unload();
},
usage: " stop debugger/sd",
usage: ' stop debugger/sd',
});
this.embark.registerConsoleCommand({
description: __("Step over forward on the current debugging session"),
matches: ["next", "n"],
description: __('Step over forward on the current debugging session'),
matches: ['next', 'n'],
process: (cmd: string, callback: (err?: string|object, output?: string) => void) => {
if (!this.cmdDebugger) {
this.embark.logger.warn(NO_DEBUG_SESSION);
@ -294,19 +294,19 @@ class TransactionDebugger {
return callback();
}
if (!this.cmdDebugger.currentStep()) {
this.embark.logger.info("end of execution reached");
this.embark.logger.info('end of execution reached');
this.cmdDebugger.unload();
return callback();
}
this.cmdDebugger.stepOverForward(true);
this.displayStepInfo(callback);
},
usage: " next/n",
usage: ' next/n',
});
this.embark.registerConsoleCommand({
description: __("Step over back on the current debugging session"),
matches: ["previous", "p"],
description: __('Step over back on the current debugging session'),
matches: ['previous', 'p'],
process: (cmd: string, callback: (err?: string|object, output?: string) => void) => {
if (!this.cmdDebugger) {
this.embark.logger.warn(NO_DEBUG_SESSION);
@ -316,54 +316,54 @@ class TransactionDebugger {
return callback();
}
if (!this.cmdDebugger.currentStep()) {
this.embark.logger.info("end of execution reached");
this.embark.logger.info('end of execution reached');
return this.cmdDebugger.unload();
}
this.cmdDebugger.stepOverBack(true);
this.displayStepInfo(callback);
},
usage: " previous/p",
usage: ' previous/p',
});
this.embark.registerConsoleCommand({
description: __("Display local variables of the current debugging session"),
matches: ["var local", "v l", "vl"],
description: __('Display local variables of the current debugging session'),
matches: ['var local', 'v l', 'vl'],
process: (cmd: string, callback: (err?: string|object, output?: string) => void) => {
if (!this.cmdDebugger) {
this.embark.logger.warn(NO_DEBUG_SESSION);
return callback();
}
this.embark.logger.info("Locals:");
this.embark.logger.info('Locals:');
const debugVars = this.simplifyDebuggerVars(this.cmdDebugger.solidityLocals);
for (const debugVar of Object.keys(debugVars)) {
this.embark.logger.info(`${debugVar}: ` + `${debugVars[debugVar]}`.white);
}
callback();
},
usage: " var local/v l/vl",
usage: ' var local/v l/vl',
});
this.embark.registerConsoleCommand({
description: __("Display global variables of the current debugging session"),
matches: ["var global", "v g", "vg"],
description: __('Display global variables of the current debugging session'),
matches: ['var global', 'v g', 'vg'],
process: (cmd: string, callback: (err?: string|object, output?: string) => void) => {
if (!this.cmdDebugger) {
this.embark.logger.warn(NO_DEBUG_SESSION);
return callback();
}
this.embark.logger.info("Globals:");
this.embark.logger.info('Globals:');
const debugVars = this.simplifyDebuggerVars(this.cmdDebugger.solidityState);
for (const debugVar of Object.keys(debugVars)) {
this.embark.logger.info(`${debugVar}: ` + `${debugVars[debugVar]}`.white);
}
callback();
},
usage: " var global/v g/vg",
usage: ' var global/v g/vg',
});
this.embark.registerConsoleCommand({
description: __("Display solidity global variables of the current debugging session"),
matches: ["var all", "v a", "va"],
description: __('Display solidity global variables of the current debugging session'),
matches: ['var all', 'v a', 'va'],
process: (cmd: string, callback: (err?: string|object, output?: string) => void) => {
if (!this.cmdDebugger) {
this.embark.logger.warn(NO_DEBUG_SESSION);
@ -374,37 +374,37 @@ class TransactionDebugger {
this.embark.logger.error(err);
return callback();
}
this.embark.logger.info("Solidity Global Variables:");
this.embark.logger.info('Solidity Global Variables:');
for (const debugVar of Object.keys(globals)) {
this.embark.logger.info(`${debugVar}: ` + `${globals[debugVar]}`.white);
}
callback();
});
},
usage: " var all/v a/va",
usage: ' var all/v a/va',
});
}
private getGlobals(txHash: string, cb: any) {
const globals: any = {};
this.embark.events.request("blockchain:getTransaction", txHash, (err: any, tx: any) => {
this.embark.events.request('blockchain:getTransaction', txHash, (err: any, tx: any) => {
if (err) { return cb(err); }
this.embark.events.request("blockchain:block:byHash", tx.blockHash, (errHash: any, block: any) => {
this.embark.events.request('blockchain:block:byHash', tx.blockHash, (errHash: any, block: any) => {
if (errHash) { return cb(errHash); }
/* tslint:disable:no-string-literal */
globals["block.blockHash"] = tx.blockHash;
globals["block.number"] = tx.blockNumber;
globals["block.coinbase"] = block.miner;
globals["block.difficulty"] = block.difficulty;
globals["block.gaslimit"] = block.gasLimit;
globals["block.timestamp"] = block.timestamp;
globals["msg.sender"] = tx.from;
globals["msg.gas"] = tx.gas;
globals["msg.gasPrice"] = tx.gasPrice;
globals["msg.value"] = tx.value;
globals["now"] = block.timestamp;
globals['block.blockHash'] = tx.blockHash;
globals['block.number'] = tx.blockNumber;
globals['block.coinbase'] = block.miner;
globals['block.difficulty'] = block.difficulty;
globals['block.gaslimit'] = block.gasLimit;
globals['block.timestamp'] = block.timestamp;
globals['msg.sender'] = tx.from;
globals['msg.gas'] = tx.gas;
globals['msg.gasPrice'] = tx.gasPrice;
globals['msg.value'] = tx.value;
globals['now'] = block.timestamp;
/* tslint:enable:no-string-literal */
cb(null, globals);
@ -414,24 +414,24 @@ class TransactionDebugger {
private displayPossibleActions() {
const actions: string[] = [];
actions.push("actions: ");
actions.push('actions: ');
if (this.cmdDebugger.canGoPrevious()) {
actions.push("(p)revious");
actions.push('(p)revious');
}
if (this.cmdDebugger.canGoNext()) {
actions.push("(n)ext");
actions.push('(n)ext');
}
actions.push("(vl) var local");
actions.push("(vg) var global");
actions.push("(va) var all");
actions.push("(sd) stop debugger");
actions.push('(vl) var local');
actions.push('(vg) var global');
actions.push('(va) var all');
actions.push('(sd) stop debugger');
if (actions.length === 1) { return; }
this.embark.logger.info("");
this.embark.logger.info(actions.join(" | "));
this.embark.logger.info('');
this.embark.logger.info(actions.join(' | '));
}
private displayVarsInLine(cb?: any) {
@ -450,7 +450,7 @@ class TransactionDebugger {
if (!foundVars) {
return cb ? cb() : null;
}
this.embark.logger.info("vars:");
this.embark.logger.info('vars:');
foundVars.forEach((variable: any) => {
this.embark.logger.info(`${variable.name}: ` + `${variable.value}`.white);
});

View File

@ -44,6 +44,7 @@
"dependencies": {
"colors": "1.3.2",
"embark-utils": "^5.0.0-alpha.1",
"embark-logger": "^5.0.0-alpha.1",
"fs-extra": "8.1.0",
"web3": "1.2.1"
},

View File

@ -5,7 +5,7 @@ const fs = require('fs-extra');
const sinon = require('sinon');
const expect = require('expect.js');
import {beforeEach, afterEach} from "mocha";
import Logger from "embark-logger";
import { Logger } from "embark-logger";
require("colors");
describe('embark.deploymentChecks', function () {

View File

@ -4,7 +4,7 @@ const fs = require('fs-extra');
const sinon = require('sinon');
const expect = require('expect.js');
import {beforeEach, afterEach} from "mocha";
import Logger from "embark-logger";
import { Logger } from "embark-logger";
import {dappPath} from 'embark-utils';
require("colors");

View File

@ -10,7 +10,7 @@ const WhisperGethClient = require('./whisperClient.js');
import { IPC } from 'embark-core';
import { compact, dappPath, defaultHost, dockerHostSwap, embarkPath} from 'embark-utils';
const Logger = require('embark-logger');
import { Logger } from 'embark-logger';
// time between IPC connection attempts (in ms)
const IPC_CONNECT_INTERVAL = 2000;

View File

@ -10,7 +10,7 @@ const ParityClient = require('./parityClient.js');
import {IPC} from 'embark-core';
import {compact, dappPath, defaultHost, dockerHostSwap, embarkPath/*, AccountParser*/} from 'embark-utils';
const Logger = require('embark-logger');
import { Logger } from 'embark-logger';
// time between IPC connection attempts (in ms)
const IPC_CONNECT_INTERVAL = 2000;

View File

@ -47,6 +47,7 @@
"core-js": "3.3.5",
"embark-i18n": "^5.0.0-alpha.1",
"embark-utils": "^5.0.0-alpha.1",
"embark-logger": "^5.0.0-alpha.1",
"handlebars": "4.2.0"
},
"devDependencies": {

View File

@ -1,6 +1,6 @@
import Ajv from "ajv";
import { Logger } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import { __ } from "embark-i18n";
import { Logger } from 'embark-logger';
export enum Framework {
React = "react",

View File

@ -1,5 +1,5 @@
import Ajv from "ajv";
import { Logger } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import { Logger } from 'embark-logger';
import { __ } from "embark-i18n";
import { schema } from "./schema";
const fs = require("fs");

View File

@ -48,7 +48,8 @@
"core-js": "3.3.5",
"embark-core": "^5.0.0-alpha.1",
"embark-i18n": "^5.0.0-alpha.1",
"embark-utils": "^5.0.0-alpha.1"
"embark-utils": "^5.0.0-alpha.1",
"embark-logger": "^5.0.0-alpha.1"
},
"devDependencies": {
"@babel/core": "7.6.4",

View File

@ -1,4 +1,5 @@
import { Embark, Events, Logger } from "embark";
import { Embark, Events } from "embark";
import { Logger } from 'embark-logger';
export default class BlockchainAPI {
private embark: Embark;
private logger: Logger;

View File

@ -53,6 +53,7 @@
"embark-core": "^5.0.0-alpha.1",
"embark-i18n": "^5.0.0-alpha.1",
"embark-utils": "^5.0.0-alpha.1",
"embark-logger": "^5.0.0-alpha.1",
"web3": "1.2.1"
},
"devDependencies": {

View File

@ -1,4 +1,5 @@
import { ContractConfig, Logger } from "embark";
import { ContractConfig } from "embark";
import { Logger } from 'embark-logger';
const { sha3 } = require("embark-utils");
import { ABIDefinition } from "web3/eth/abi";

View File

@ -51,6 +51,7 @@
"embark-core": "^5.0.0-alpha.1",
"embark-i18n": "^5.0.0-alpha.1",
"embark-utils": "^5.0.0-alpha.1",
"embark-logger": "^5.0.0-alpha.1",
"express": "4.17.1",
"express-ws": "4.0.0",
"web3-core-requestmanager": "1.2.1",

View File

@ -1,6 +1,7 @@
import { Embark, Events, Logger } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import { __ } from "embark-i18n";
import {Embark, Events } /* supplied by @types/embark in packages/embark-typings */ from "embark";
import {__} from "embark-i18n";
import { buildUrl, findNextPort } from "embark-utils";
import { Logger } from 'embark-logger';
import { Proxy } from "./proxy";
const constants = require("embark-core/constants");

View File

@ -44,6 +44,8 @@
"@babel/core": "7.6.4",
"@babel/plugin-proposal-class-properties": "7.5.5",
"@babel/plugin-proposal-decorators": "7.6.0",
"@babel/plugin-proposal-export-namespace-from": "7.5.2",
"@babel/plugin-proposal-export-default-from": "7.5.2",
"@babel/plugin-proposal-nullish-coalescing-operator": "7.4.4",
"@babel/plugin-proposal-optional-chaining": "7.6.0",
"@babel/plugin-syntax-dynamic-import": "7.2.0",

View File

@ -6,6 +6,7 @@
"module": "CommonJS",
"noEmit": true,
"noImplicitThis": false,
"noImplicitAny": false,
"strict": true,
"target": "ES2017",
"resolveJsonModule": true

View File

@ -5,13 +5,20 @@
],
"jsRules": {},
"rules": {
"arrow-parens": false,
"interface-name": [true, "never-prefix"],
"max-line-length": [true, 200],
"member-ordering": [false],
"member-access": false,
"no-empty": false,
"no-console": false,
"no-var-requires": false,
"variable-name": ["allow-leading-underscore"]
"variable-name": ["allow-leading-underscore"],
"object-literal-sort-keys": false,
"ordered-imports": false,
"quotemark": [false, "single"],
"trailing-comma": false,
"no-irregular-whitespace": false
},
"rulesDirectory": []
}

2645
yarn.lock

File diff suppressed because it is too large Load Diff