mirror of https://github.com/embarklabs/embark.git
refactor(@embark/core): move Engine into embark-core
This commit is contained in:
parent
8733ca911c
commit
d2556af8ba
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -0,0 +1,758 @@
|
|||
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 configObject = {
|
||||
default: {
|
||||
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);
|
||||
}
|
|
@ -39,22 +39,22 @@ export function getBlockchainDefaults(env) {
|
|||
|
||||
export function getContractDefaults(embarkConfigVersions) {
|
||||
const defaultVersions = {
|
||||
"solc": "0.5.0"
|
||||
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: {
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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));
|
||||
};
|
||||
}
|
|
@ -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;
|
|
@ -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) { return fs.statSync(args); }
|
||||
|
||||
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); }
|
|
@ -1,5 +0,0 @@
|
|||
export { ProcessLauncher } from './processes/processLauncher';
|
||||
export { ProcessManager } from './processes/processManager';
|
||||
export { ProcessWrapper } from './processes/processWrapper';
|
||||
|
||||
export { IPC } from './ipc';
|
|
@ -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 };
|
|
@ -0,0 +1,370 @@
|
|||
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');
|
||||
|
||||
// Default priority of actions with no specified priority. 1 => Highest
|
||||
const DEFAULT_ACTION_PRIORITY = 50;
|
||||
|
||||
// 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, options?, cb?) {
|
||||
if (typeof options === 'function') {
|
||||
cb = options;
|
||||
options = {};
|
||||
}
|
||||
if (!this.eventActions[eventName]) {
|
||||
this.eventActions[eventName] = [];
|
||||
}
|
||||
this.eventActions[eventName].push({action: cb, options: Object.assign({priority: DEFAULT_ACTION_PRIORITY}, options)});
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,284 @@
|
|||
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);
|
||||
}
|
||||
|
||||
actionPlugins.sort((a, b) => {
|
||||
const aPriority = a[0].options.priority;
|
||||
const bPriority = b[0].options.priority;
|
||||
if (aPriority < bPriority) {
|
||||
return -1;
|
||||
}
|
||||
if (aPriority > bPriority) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
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.action.name, pluginName);
|
||||
|
||||
if (typeof (args) === 'function') {
|
||||
plugin.action.call(plugin.action, (...params) => {
|
||||
nextEach(...params || current_args);
|
||||
});
|
||||
} else {
|
||||
plugin.action.call(plugin.action, 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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
});
|
||||
}
|
|
@ -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;
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": "../../../tslint.json"
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ABIDefinition } from "web3/eth/abi";
|
||||
import { ABIDefinition } from 'web3/eth/abi';
|
||||
|
||||
export interface Contract {
|
||||
abiDefinition: ABIDefinition[];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Logger } from "./logger";
|
||||
import { Plugins } from "./plugins";
|
||||
import { Logger } from './logger';
|
||||
import { Plugins } from './plugins';
|
||||
|
||||
type CommandCallback = (
|
||||
opt1?: any,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Callback} from "./callbacks";
|
||||
import {Callback} from './callbacks';
|
||||
|
||||
export interface Plugin {
|
||||
dappGenerators: any;
|
||||
|
|
|
@ -1 +1 @@
|
|||
declare module "prettier-plugin-solidity";
|
||||
declare module 'prettier-plugin-solidity';
|
||||
|
|
|
@ -1 +1 @@
|
|||
declare module "remix-debug-debugtest";
|
||||
declare module 'remix-debug-debugtest';
|
||||
|
|
|
@ -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;
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const merge = require("merge");
|
||||
const merge = require('merge');
|
||||
|
||||
export function last(array: any) {
|
||||
return array[array.length - 1];
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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'))
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -1,721 +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 configObject = {
|
||||
"default": {
|
||||
"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;
|
|
@ -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
|
||||
};
|
|
@ -1,310 +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');
|
||||
|
||||
// Default priority of actions with no specified priority. 1 => Highest
|
||||
const DEFAULT_ACTION_PRIORITY = 50;
|
||||
|
||||
// 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, options, cb) {
|
||||
if (typeof options === 'function') {
|
||||
cb = options;
|
||||
options = {};
|
||||
}
|
||||
if (!this.eventActions[eventName]) {
|
||||
this.eventActions[eventName] = [];
|
||||
}
|
||||
this.eventActions[eventName].push({action: cb, options: Object.assign({priority: DEFAULT_ACTION_PRIORITY}, options)});
|
||||
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;
|
|
@ -1,261 +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);
|
||||
}
|
||||
|
||||
actionPlugins.sort((a, b) => {
|
||||
const aPriority = a[0].options.priority;
|
||||
const bPriority = b[0].options.priority;
|
||||
if (aPriority < bPriority) {
|
||||
return -1;
|
||||
}
|
||||
if (aPriority > bPriority) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
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.action.name, pluginName);
|
||||
|
||||
if (typeof (args) === 'function') {
|
||||
plugin.action.call(plugin.action, (...params) => {
|
||||
nextEach(...params || current_args);
|
||||
});
|
||||
} else {
|
||||
plugin.action.call(plugin.action, 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;
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
|
@ -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 () {
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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});
|
||||
};
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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});
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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});
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*global __dirname, describe, it, beforeEach, afterEach, require*/
|
||||
import * as i18n from 'embark-i18n';
|
||||
import { Plugins } from 'embark-core';
|
||||
|
||||
const {fakeEmbark} = require('embark-testing');
|
||||
const assert = require('assert');
|
||||
const sinon = require('sinon');
|
||||
const Plugins = require('../lib/core/plugins');
|
||||
i18n.setOrDetectLocale('en');
|
||||
|
||||
describe('embark.plugins', function() {
|
||||
|
|
|
@ -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({});
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"module": "CommonJS",
|
||||
"noEmit": true,
|
||||
"noImplicitThis": false,
|
||||
"noImplicitAny": false,
|
||||
"strict": true,
|
||||
"target": "ES2017",
|
||||
"resolveJsonModule": true
|
||||
|
|
|
@ -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": []
|
||||
}
|
||||
|
|
31
yarn.lock
31
yarn.lock
|
@ -405,6 +405,22 @@
|
|||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
"@babel/plugin-syntax-dynamic-import" "^7.2.0"
|
||||
|
||||
"@babel/plugin-proposal-export-default-from@7.5.2":
|
||||
version "7.5.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.5.2.tgz#2c0ac2dcc36e3b2443fead2c3c5fc796fb1b5145"
|
||||
integrity sha512-wr9Itk05L1/wyyZKVEmXWCdcsp/e185WUNl6AfYZeEKYaUPPvHXRDqO5K1VH7/UamYqGJowFRuCv30aDYZawsg==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
"@babel/plugin-syntax-export-default-from" "^7.2.0"
|
||||
|
||||
"@babel/plugin-proposal-export-namespace-from@7.5.2":
|
||||
version "7.5.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.5.2.tgz#ccd5ed05b06d700688ff1db01a9dd27155e0d2a0"
|
||||
integrity sha512-TKUdOL07anjZEbR1iSxb5WFh810KyObdd29XLFLGo1IDsSuGrjH3ouWSbAxHNmrVKzr9X71UYl2dQ7oGGcRp0g==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
"@babel/plugin-syntax-export-namespace-from" "^7.2.0"
|
||||
|
||||
"@babel/plugin-proposal-json-strings@^7.2.0":
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317"
|
||||
|
@ -492,6 +508,20 @@
|
|||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-syntax-export-default-from@^7.2.0":
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.2.0.tgz#edd83b7adc2e0d059e2467ca96c650ab6d2f3820"
|
||||
integrity sha512-c7nqUnNST97BWPtoe+Ssi+fJukc9P9/JMZ71IOMNQWza2E+Psrd46N6AEvtw6pqK+gt7ChjXyrw4SPDO79f3Lw==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-syntax-export-namespace-from@^7.2.0":
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.2.0.tgz#8d257838c6b3b779db52c0224443459bd27fb039"
|
||||
integrity sha512-1zGA3UNch6A+A11nIzBVEaE3DDJbjfB+eLIcf0GGOh/BJr/8NxL3546MGhV/r0RhH4xADFIEso39TKCfEMlsGA==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-syntax-flow@^7.2.0":
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz#a765f061f803bc48f240c26f8747faf97c26bf7c"
|
||||
|
@ -17865,7 +17895,6 @@ scrypt-js@2.0.4:
|
|||
|
||||
"scrypt-shim@github:web3-js/scrypt-shim":
|
||||
version "0.1.0"
|
||||
uid be5e616323a8b5e568788bf94d03c1b8410eac54
|
||||
resolved "https://codeload.github.com/web3-js/scrypt-shim/tar.gz/be5e616323a8b5e568788bf94d03c1b8410eac54"
|
||||
dependencies:
|
||||
scryptsy "^2.1.0"
|
||||
|
|
Loading…
Reference in New Issue