mirror of
https://github.com/embarklabs/embark.git
synced 2025-02-19 17:14:40 +00:00
refactor(@embark/core): move Engine
into embark-core
This also moves other modules and packages into `embark-core` which are affected by the move of `Engine`. It did some clean-up of some modules (e.g. `lib/utils/utils.js` had a lot of stuff that was not used anywhere). This is the first step to start typing our core inside out. For now we're just moving code into their dedicated package, after that we can address making use of TypeScript features as we see fit.
This commit is contained in:
parent
6afe1ace08
commit
96b6dd27c0
@ -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",
|
||||
|
761
packages/core/core/src/config.ts
Normal file
761
packages/core/core/src/config.ts
Normal file
@ -0,0 +1,761 @@
|
||||
import * as fs from './fs';
|
||||
import { Plugins } from './plugins';
|
||||
import { Plugin } from './plugin';
|
||||
import { EmbarkEmitter as Events } from './events';
|
||||
import { filesMatchingPattern, fileMatchesPattern } from './utils/utils';
|
||||
const path = require('path');
|
||||
const deepEqual = require('deep-equal');
|
||||
const web3 = require('web3');
|
||||
const constants = require('embark-core/constants');
|
||||
import { __ } from 'embark-i18n';
|
||||
import {
|
||||
buildUrlFromConfig,
|
||||
canonicalHost,
|
||||
dappPath,
|
||||
defaultHost,
|
||||
File,
|
||||
Types,
|
||||
recursiveMerge,
|
||||
AddressUtils,
|
||||
unitRegex,
|
||||
getWeiBalanceFromString,
|
||||
prepareContractsConfig,
|
||||
getExternalContractUrl
|
||||
} from 'embark-utils';
|
||||
import { Logger } from 'embark-logger';
|
||||
const cloneDeep = require('lodash.clonedeep');
|
||||
const { replaceZeroAddressShorthand } = AddressUtils;
|
||||
|
||||
import { getBlockchainDefaults, getContractDefaults } from './configDefaults';
|
||||
|
||||
const DEFAULT_CONFIG_PATH = 'config/';
|
||||
|
||||
const embark5ChangesUrl = 'https://embark.status.im/docs/migrating_from_3.x.html#Updating-to-v5';
|
||||
|
||||
export class Config {
|
||||
|
||||
env = 'default';
|
||||
|
||||
blockchainConfig: any = {};
|
||||
|
||||
contractsConfig: any = {};
|
||||
|
||||
pipelineConfig: any = {};
|
||||
|
||||
namesystemConfig: any = {};
|
||||
|
||||
communicationConfig: any = {};
|
||||
|
||||
webServerConfig: any;
|
||||
|
||||
storageConfig: any;
|
||||
|
||||
chainTracker: any = {};
|
||||
|
||||
assetFiles: any = {};
|
||||
|
||||
contractsFiles: File[] = [];
|
||||
|
||||
configDir: string;
|
||||
|
||||
chainsFile = './chains.json';
|
||||
|
||||
plugins: Plugins;
|
||||
|
||||
logger: Logger;
|
||||
|
||||
package: any;
|
||||
|
||||
events: Events;
|
||||
|
||||
embarkConfig: any = {};
|
||||
|
||||
context: any;
|
||||
|
||||
version: string;
|
||||
|
||||
shownNoAccountConfigMsg = false; // flag to ensure "no account config" message is only displayed once to the user
|
||||
|
||||
corsParts: string[] = [];
|
||||
|
||||
providerUrl = null;
|
||||
|
||||
contractDirectories: string[] = [];
|
||||
|
||||
buildDir: any;
|
||||
|
||||
dappPath = dappPath;
|
||||
|
||||
constructor(options) {
|
||||
this.env = options.env || 'default';
|
||||
this.webServerConfig = options.webServerConfig;
|
||||
this.configDir = options.configDir || DEFAULT_CONFIG_PATH;
|
||||
this.chainsFile = options.chainsFile;
|
||||
this.plugins = options.plugins;
|
||||
this.logger = options.logger;
|
||||
this.package = options.package;
|
||||
this.events = options.events;
|
||||
this.context = options.context || [constants.contexts.any];
|
||||
this.version = options.version;
|
||||
|
||||
this.registerEvents();
|
||||
}
|
||||
|
||||
setConfig(configName, newConfig, cb) {
|
||||
this[configName] = newConfig;
|
||||
cb();
|
||||
}
|
||||
|
||||
registerEvents() {
|
||||
this.events.setCommandHandler("config:cors:add", (url) => {
|
||||
this.corsParts.push(url);
|
||||
this._updateBlockchainCors();
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("config:contractsConfig", (cb) => {
|
||||
cb(null, this.contractsConfig);
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("config:storageConfig", (cb) => {
|
||||
cb(null, this.storageConfig);
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("config:contractsConfig:set", this.setConfig.bind(this, 'contractsConfig'));
|
||||
this.events.setCommandHandler("config:blockchainConfig:set", this.setConfig.bind(this, 'blockchainConfig'));
|
||||
this.events.setCommandHandler("config:storageConfig:set", this.setConfig.bind(this, 'storageConfig'));
|
||||
this.events.setCommandHandler("config:namesystemConfig:set", this.setConfig.bind(this, 'namesystemConfig'));
|
||||
this.events.setCommandHandler("config:communicationConfig:set", this.setConfig.bind(this, 'communicationConfig'));
|
||||
|
||||
this.events.setCommandHandler("config:contractsFiles", (cb) => {
|
||||
cb(null, this.contractsFiles);
|
||||
});
|
||||
|
||||
// TODO: refactor this so reading the file can be done with a normal resolver or something that takes advantage of the plugin api
|
||||
this.events.setCommandHandler("config:contractsFiles:add", (filename, resolver) => {
|
||||
resolver = resolver || function(callback) { callback(fs.readFileSync(filename).toString()); };
|
||||
this.contractsFiles.push(new File({path: filename, originalPath: filename, type: Types.custom, resolver}));
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("config:contractsFiles:reset", (cb) => {
|
||||
this.contractsFiles.forEach((file) => {
|
||||
if (file.path.includes(".embark")) {
|
||||
fs.removeSync(file.path);
|
||||
}
|
||||
this.contractsFiles = this.contractsFiles.filter((contractFile) => contractFile.path !== file.path);
|
||||
});
|
||||
cb();
|
||||
});
|
||||
|
||||
this.events.on('file-remove', (fileType, removedPath) => {
|
||||
if (fileType !== 'contract') {
|
||||
return;
|
||||
}
|
||||
const normalizedPath = path.normalize(removedPath);
|
||||
this.contractsFiles = this.contractsFiles.filter(file => path.normalize(file.path) !== normalizedPath);
|
||||
});
|
||||
}
|
||||
|
||||
loadConfigFiles(options) {
|
||||
let interceptLogs = options.interceptLogs;
|
||||
if (options.interceptLogs === undefined) {
|
||||
interceptLogs = true;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(options.embarkConfig)) {
|
||||
this.logger.error(__('Cannot find file %s Please ensure you are running this command inside the Dapp folder', options.embarkConfig));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
this.embarkConfig = fs.readJSONSync(options.embarkConfig);
|
||||
this.embarkConfig.plugins = this.embarkConfig.plugins || {};
|
||||
|
||||
this.plugins = new Plugins({
|
||||
plugins: this.embarkConfig.plugins,
|
||||
logger: this.logger,
|
||||
interceptLogs,
|
||||
events: this.events,
|
||||
config: this,
|
||||
context: this.context,
|
||||
env: this.env,
|
||||
version: this.version
|
||||
});
|
||||
this.plugins.loadPlugins();
|
||||
|
||||
this.loadEmbarkConfigFile();
|
||||
this.loadBlockchainConfigFile();
|
||||
this.loadStorageConfigFile();
|
||||
this.loadContractFiles();
|
||||
this.loadCommunicationConfigFile();
|
||||
this.loadNameSystemConfigFile();
|
||||
this.loadPipelineConfigFile();
|
||||
this.loadAssetFiles();
|
||||
this.loadContractsConfigFile();
|
||||
this.loadExternalContractsFiles();
|
||||
this.loadWebServerConfigFile();
|
||||
this.loadPluginContractFiles();
|
||||
|
||||
this._updateBlockchainCors();
|
||||
}
|
||||
|
||||
reloadConfig() {
|
||||
this.loadEmbarkConfigFile();
|
||||
this.loadBlockchainConfigFile();
|
||||
this.loadStorageConfigFile();
|
||||
this.loadContractFiles();
|
||||
this.loadCommunicationConfigFile();
|
||||
this.loadNameSystemConfigFile();
|
||||
this.loadPipelineConfigFile();
|
||||
this.loadAssetFiles();
|
||||
this.loadContractsConfigFile();
|
||||
this.loadExternalContractsFiles();
|
||||
|
||||
this._updateBlockchainCors();
|
||||
}
|
||||
|
||||
loadContractFiles() {
|
||||
const loadedContractFiles = this.loadFiles(this.embarkConfig.contracts);
|
||||
// `this.contractsFiles` could've been mutated at runtime using
|
||||
// either `config:contractsFiles:add` event or through calls to
|
||||
// `loadExternalContractsFiles()`, so we have to make sure we preserve
|
||||
// those added files before we reset `this.contractsFiles`.
|
||||
//
|
||||
// We do that by determining the difference between `loadedContractFiles` and the ones
|
||||
// already in memory in `this.contractsFiles`.
|
||||
const addedContractFiles = this.contractsFiles.filter(existingFile => !loadedContractFiles.some(file => file.originalPath === existingFile.originalPath));
|
||||
this.contractsFiles = loadedContractFiles.concat(addedContractFiles);
|
||||
}
|
||||
|
||||
_updateBlockchainCors() {
|
||||
const blockchainConfig = this.blockchainConfig;
|
||||
const storageConfig = this.storageConfig;
|
||||
const webServerConfig = this.webServerConfig;
|
||||
let corsParts = cloneDeep(this.corsParts);
|
||||
|
||||
if (blockchainConfig.isDev) {
|
||||
corsParts.push('*');
|
||||
}
|
||||
|
||||
if (webServerConfig && webServerConfig.host) {
|
||||
corsParts.push(buildUrlFromConfig(webServerConfig));
|
||||
}
|
||||
if (storageConfig && storageConfig.enabled) {
|
||||
// if getUrl is specified in the config, that needs to be included in cors
|
||||
// instead of the concatenated protocol://host:port
|
||||
if (storageConfig.upload.getUrl) {
|
||||
// remove /ipfs or /bzz: from getUrl if it's there
|
||||
let getUrlParts = storageConfig.upload.getUrl.split('/');
|
||||
getUrlParts = getUrlParts.slice(0, 3);
|
||||
const host = canonicalHost(getUrlParts[2].split(':')[0]);
|
||||
const port = getUrlParts[2].split(':')[1];
|
||||
getUrlParts[2] = port ? [host, port].join(':') : host;
|
||||
corsParts.push(getUrlParts.join('/'));
|
||||
} else {
|
||||
corsParts.push(buildUrlFromConfig(storageConfig.upload));
|
||||
}
|
||||
}
|
||||
// Add cors for the proxy and whisper
|
||||
corsParts.push(constants.embarkResourceOrigin);
|
||||
|
||||
corsParts = Array.from(new Set(corsParts));
|
||||
this.corsParts = corsParts;
|
||||
|
||||
const cors = corsParts.join(',');
|
||||
if (blockchainConfig.rpcCorsDomain === 'auto') {
|
||||
blockchainConfig.rpcCorsDomain = cors;
|
||||
} else if (typeof blockchainConfig.rpcCorsDomain === 'object') {
|
||||
let tempCors = blockchainConfig.rpcCorsDomain.auto ? corsParts : [];
|
||||
tempCors = tempCors.concat(blockchainConfig.rpcCorsDomain.additionalCors || []);
|
||||
blockchainConfig.rpcCorsDomain = tempCors.join(',');
|
||||
}
|
||||
if (blockchainConfig.wsOrigins === 'auto') {
|
||||
blockchainConfig.wsOrigins = cors;
|
||||
} else if (typeof blockchainConfig.wsOrigins === 'object') {
|
||||
let tempCors = blockchainConfig.wsOrigins.auto ? corsParts : [];
|
||||
tempCors = tempCors.concat(blockchainConfig.wsOrigins.additionalCors || []);
|
||||
blockchainConfig.wsOrigins = tempCors.join(',');
|
||||
}
|
||||
}
|
||||
|
||||
_loadConfigFile(configFilePath, defaultConfig, enabledByDefault = false) {
|
||||
if (!configFilePath) {
|
||||
const configToReturn = defaultConfig.default || {};
|
||||
configToReturn.enabled = enabledByDefault;
|
||||
return configToReturn;
|
||||
}
|
||||
configFilePath = configFilePath.replace('.json', '').replace('.js', '');
|
||||
let config;
|
||||
if (fs.existsSync(configFilePath + '.js')) {
|
||||
delete require.cache[configFilePath + '.js'];
|
||||
config = require(configFilePath + '.js');
|
||||
} else if (fs.existsSync(configFilePath + '.json')) {
|
||||
config = fs.readJSONSync(configFilePath + '.json');
|
||||
} else {
|
||||
this.logger.warn(__("no config file found at %s using default config", configFilePath));
|
||||
return defaultConfig.default || {};
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
_doMergeConfig(config, defaultConfig, env) {
|
||||
const configObject = recursiveMerge(defaultConfig, config);
|
||||
|
||||
if (env) {
|
||||
if (env === 'test' && !configObject[env]) {
|
||||
// Disabled all configs in tests as they are opt in
|
||||
return Object.assign({}, defaultConfig.default, {enabled: false});
|
||||
}
|
||||
return recursiveMerge(configObject.default || {}, configObject[env]);
|
||||
} else if (env !== false) {
|
||||
this.logger.info(__("No environment called %s found. Using defaults.", env));
|
||||
}
|
||||
return configObject;
|
||||
}
|
||||
|
||||
_loadAndMergeConfig(configFilePath, defaultConfig, env, enabledByDefault = false) {
|
||||
const config = this._loadConfigFile(configFilePath, defaultConfig, enabledByDefault);
|
||||
return this._doMergeConfig(config, defaultConfig, env);
|
||||
}
|
||||
|
||||
_getFileOrObject(object, filePath, property) {
|
||||
if (typeof object === 'object') {
|
||||
return object[property] ? dappPath(object[property]) : object[property];
|
||||
}
|
||||
return dappPath(object, filePath);
|
||||
}
|
||||
|
||||
/*eslint complexity: ["error", 30]*/
|
||||
loadBlockchainConfigFile() {
|
||||
const blockchainDefaults = getBlockchainDefaults(this.env);
|
||||
const configFilePath = this._getFileOrObject(this.configDir, 'blockchain', 'blockchain');
|
||||
|
||||
const userConfig = this._loadConfigFile(configFilePath, blockchainDefaults, true);
|
||||
const envConfig = userConfig[this.env];
|
||||
|
||||
if (envConfig) {
|
||||
if (envConfig.ethereumClientName || envConfig.hasOwnProperty('isDev') || envConfig.hasOwnProperty('mineWhenNeeded')) {
|
||||
this.logger.error(__('The blockchain config has changed quite a bit in Embark 5\nPlease visit %s to know what has to be changed', embark5ChangesUrl.underline));
|
||||
process.exit(1);
|
||||
}
|
||||
if (envConfig.clientConfig) {
|
||||
Object.assign(envConfig, envConfig.clientConfig);
|
||||
delete envConfig.clientConfig;
|
||||
}
|
||||
switch (envConfig.miningMode) {
|
||||
case 'dev': envConfig.isDev = true; break;
|
||||
case 'auto': envConfig.isDev = false; envConfig.mineWhenNeeded = true; break;
|
||||
case 'always': envConfig.isDev = false; envConfig.mineWhenNeeded = false; envConfig.mine = true; break;
|
||||
case 'off': envConfig.isDev = false; envConfig.mineWhenNeeded = false; envConfig.mine = false; break;
|
||||
default: envConfig.isDev = false;
|
||||
}
|
||||
if (envConfig.cors) {
|
||||
const autoIndex = envConfig.cors.indexOf('auto');
|
||||
envConfig.rpcCorsDomain = {};
|
||||
envConfig.wsOrigins = {};
|
||||
if (autoIndex > -1) {
|
||||
envConfig.rpcCorsDomain.auto = true;
|
||||
envConfig.wsOrigins.auto = true;
|
||||
envConfig.cors.splice(autoIndex, 1);
|
||||
} else {
|
||||
envConfig.rpcCorsDomain.auto = false;
|
||||
envConfig.wsOrigins.auto = false;
|
||||
}
|
||||
envConfig.rpcCorsDomain.additionalCors = envConfig.cors;
|
||||
envConfig.wsOrigins.additionalCors = envConfig.cors;
|
||||
delete envConfig.cors;
|
||||
}
|
||||
|
||||
userConfig[this.env] = envConfig;
|
||||
}
|
||||
|
||||
this.blockchainConfig = this._doMergeConfig(userConfig, blockchainDefaults, this.env);
|
||||
|
||||
if (!configFilePath) {
|
||||
this.blockchainConfig.default = true;
|
||||
}
|
||||
|
||||
if (this.blockchainConfig.targetGasLimit && this.blockchainConfig.targetGasLimit.toString().match(unitRegex)) {
|
||||
this.blockchainConfig.targetGasLimit = getWeiBalanceFromString(this.blockchainConfig.targetGasLimit, web3);
|
||||
}
|
||||
|
||||
if (this.blockchainConfig.gasPrice && this.blockchainConfig.gasPrice.toString().match(unitRegex)) {
|
||||
this.blockchainConfig.gasPrice = getWeiBalanceFromString(this.blockchainConfig.gasPrice, web3);
|
||||
}
|
||||
|
||||
if (this.blockchainConfig.accounts) {
|
||||
this.blockchainConfig.accounts.forEach(acc => {
|
||||
if (acc.balance && acc.balance.toString().match(unitRegex)) {
|
||||
acc.balance = getWeiBalanceFromString(acc.balance, web3);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.blockchainConfig.endpoint) {
|
||||
const urlConfig = (this.blockchainConfig.wsHost) ? {
|
||||
host: this.blockchainConfig.wsHost,
|
||||
port: this.blockchainConfig.wsPort,
|
||||
type: 'ws'
|
||||
} : {
|
||||
host: this.blockchainConfig.rpcHost,
|
||||
port: this.blockchainConfig.rpcPort,
|
||||
type: 'rpc'
|
||||
};
|
||||
this.blockchainConfig.endpoint = buildUrlFromConfig(urlConfig);
|
||||
this.blockchainConfig.isAutoEndpoint = true;
|
||||
}
|
||||
|
||||
if (
|
||||
!this.shownNoAccountConfigMsg &&
|
||||
(/rinkeby|testnet|livenet/).test(this.blockchainConfig.networkType) &&
|
||||
!(this.blockchainConfig.accounts && this.blockchainConfig.accounts.find(acc => acc.password)) &&
|
||||
!this.blockchainConfig.isDev &&
|
||||
this.env !== 'development' && this.env !== 'test') {
|
||||
this.logger.warn((
|
||||
'\n=== ' + __('Cannot unlock account - account config missing').bold + ' ===\n' +
|
||||
__('Geth is configured to sync to a testnet/livenet and needs to unlock an account ' +
|
||||
'to allow your dApp to interact with geth, however, the address and password must ' +
|
||||
'be specified in your blockchain config. Please update your blockchain config with ' +
|
||||
'a valid address and password: \n') +
|
||||
` - config/blockchain.js > ${this.env} > account\n\n`.italic +
|
||||
__('Please also make sure the keystore file for the account is located at: ') +
|
||||
'\n - Mac: ' + `~/Library/Ethereum/${this.env}/keystore`.italic +
|
||||
'\n - Linux: ' + `~/.ethereum/${this.env}/keystore`.italic +
|
||||
'\n - Windows: ' + `%APPDATA%\\Ethereum\\${this.env}\\keystore`.italic) +
|
||||
__('\n\nAlternatively, you could change ' +
|
||||
`config/blockchain.js > ${this.env} > networkType`.italic +
|
||||
__(' to ') +
|
||||
'"custom"\n'.italic).yellow
|
||||
);
|
||||
this.shownNoAccountConfigMsg = true;
|
||||
}
|
||||
|
||||
const accountDocsMessage = __('For more info, check the docs: %s', 'https://embark.status.im/docs/blockchain_accounts_configuration.html'.underline);
|
||||
if (this.blockchainConfig.account) {
|
||||
this.logger.error(__('The `account` config for the blockchain was removed. Please use `accounts` instead.'));
|
||||
this.logger.error(accountDocsMessage);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (this.blockchainConfig.simulatorMnemonic) {
|
||||
this.logger.error(__('The `simulatorMnemonic` config for the blockchain was removed. Please use `accounts` instead.'));
|
||||
this.logger.error(accountDocsMessage);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
this.events.emit('config:load:blockchain', this.blockchainConfig);
|
||||
}
|
||||
|
||||
loadContractsConfigFile() {
|
||||
let configObject = getContractDefaults(this.embarkConfig.versions);
|
||||
|
||||
const contractsConfigs = this.plugins.getPluginsProperty('contractsConfig', 'contractsConfigs');
|
||||
contractsConfigs.forEach(function(pluginConfig) {
|
||||
configObject = recursiveMerge(configObject, pluginConfig);
|
||||
});
|
||||
|
||||
const configFilePath = this._getFileOrObject(this.configDir, 'contracts', 'contracts');
|
||||
let newContractsConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
|
||||
if (newContractsConfig.contracts) {
|
||||
this.logger.error(__('`contracts` has been renamed `deploy` in contracts config\nFor more information: %s', embark5ChangesUrl.underline));
|
||||
process.exit(1);
|
||||
}
|
||||
if (newContractsConfig.deployment) {
|
||||
this.logger.error(__('`deployment` has been removed from contracts config and is now part of blockchain config\nFor more information: %s', embark5ChangesUrl.underline));
|
||||
process.exit(1);
|
||||
}
|
||||
if (newContractsConfig.gas.match(unitRegex)) {
|
||||
newContractsConfig.gas = getWeiBalanceFromString(newContractsConfig.gas, web3);
|
||||
}
|
||||
|
||||
newContractsConfig = prepareContractsConfig(newContractsConfig);
|
||||
|
||||
const afterDeploy = newContractsConfig.afterDeploy;
|
||||
|
||||
if (Array.isArray(afterDeploy)) {
|
||||
newContractsConfig.afterDeploy = afterDeploy.map(replaceZeroAddressShorthand);
|
||||
}
|
||||
|
||||
if (!deepEqual(newContractsConfig, this.contractsConfig)) {
|
||||
this.contractsConfig = newContractsConfig;
|
||||
}
|
||||
|
||||
this.events.emit('config:load:contracts', this.contractsConfig);
|
||||
}
|
||||
|
||||
loadExternalContractsFiles() {
|
||||
const contracts = this.contractsConfig.contracts;
|
||||
const storageConfig = this.storageConfig;
|
||||
if (storageConfig && storageConfig.upload && storageConfig.upload.getUrl) {
|
||||
this.providerUrl = storageConfig.upload.getUrl;
|
||||
}
|
||||
for (const contractName in contracts) {
|
||||
const contract = contracts[contractName];
|
||||
|
||||
if (!contract.file) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let externalContractFile;
|
||||
|
||||
if (contract.file.startsWith('http') || contract.file.startsWith('git') || contract.file.startsWith('ipfs') || contract.file.startsWith('bzz')) {
|
||||
const fileObj = getExternalContractUrl(contract.file, this.providerUrl);
|
||||
if (!fileObj) {
|
||||
return this.logger.error(__("HTTP contract file not found") + ": " + contract.file);
|
||||
}
|
||||
externalContractFile = new File({ path: fileObj.filePath, originalPath: fileObj.filePath, type: Types.http, basedir: '', externalUrl: fileObj.url, storageConfig });
|
||||
} else if (fs.existsSync(contract.file)) {
|
||||
externalContractFile = new File({ path: contract.file, originalPath: contract.file, type: Types.dappFile, basedir: '', storageConfig });
|
||||
} else if (fs.existsSync(path.join('./node_modules/', contract.file))) {
|
||||
const completePath = path.join('./node_modules/', contract.file);
|
||||
externalContractFile = new File({ path: completePath, originalPath: completePath, type: Types.dappFile, basedir: '', storageConfig });
|
||||
}
|
||||
|
||||
if (externalContractFile) {
|
||||
const index = this.contractsFiles.findIndex(contractFile => contractFile.originalPath === externalContractFile.originalPath);
|
||||
// It's important that we only add `externalContractFile` if it doesn't exist already
|
||||
// within `contractsFiles`, otherwise we keep adding duplicates in subsequent
|
||||
// compilation routines creating a memory leak.
|
||||
if (index > -1) {
|
||||
this.contractsFiles[index] = externalContractFile;
|
||||
} else {
|
||||
this.contractsFiles.push(externalContractFile);
|
||||
}
|
||||
} else {
|
||||
this.logger.error(__("contract file not found") + ": " + contract.file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadStorageConfigFile() {
|
||||
const versions = recursiveMerge({"ipfs-api": "17.2.4"}, this.embarkConfig.versions || {});
|
||||
|
||||
const configObject = {
|
||||
default: {
|
||||
versions,
|
||||
enabled: true,
|
||||
available_providers: ["ipfs", "swarm"],
|
||||
ipfs_bin: "ipfs",
|
||||
upload: {
|
||||
provider: "ipfs",
|
||||
protocol: "http",
|
||||
host : defaultHost,
|
||||
port: 5001,
|
||||
getUrl: "http://localhost:8080/ipfs/"
|
||||
},
|
||||
dappConnection: [{provider: "ipfs", host: "localhost", port: 5001, getUrl: "http://localhost:8080/ipfs/"}]
|
||||
}
|
||||
};
|
||||
|
||||
const configFilePath = this._getFileOrObject(this.configDir, 'storage', 'storage');
|
||||
|
||||
this.storageConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
|
||||
this.events.emit('config:load:storage', this.storageConfig);
|
||||
}
|
||||
|
||||
loadNameSystemConfigFile() {
|
||||
// todo: spec out names for registration in the file itself for a dev chain
|
||||
const configObject = {
|
||||
default: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
|
||||
const configFilePath = this._getFileOrObject(this.configDir, 'namesystem', 'namesystem');
|
||||
|
||||
this.namesystemConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
|
||||
}
|
||||
|
||||
loadCommunicationConfigFile() {
|
||||
const configObject = {
|
||||
default: {
|
||||
enabled: true,
|
||||
provider: "whisper",
|
||||
available_providers: ["whisper"],
|
||||
connection: {
|
||||
host: defaultHost,
|
||||
port: 8557,
|
||||
type: "ws"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const configFilePath = this._getFileOrObject(this.configDir, 'communication', 'communication');
|
||||
|
||||
this.communicationConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
|
||||
this.events.emit('config:load:communication', this.communicationConfig);
|
||||
}
|
||||
|
||||
loadWebServerConfigFile() {
|
||||
const configObject = {
|
||||
enabled: true,
|
||||
host: defaultHost,
|
||||
openBrowser: true,
|
||||
port: 8000,
|
||||
enableCatchAll: true,
|
||||
protocol: "http"
|
||||
};
|
||||
|
||||
const configFilePath = this._getFileOrObject(this.configDir, 'webserver', 'webserver');
|
||||
|
||||
const webServerConfig = this._loadAndMergeConfig(configFilePath, configObject, false);
|
||||
|
||||
if (webServerConfig.https) {
|
||||
try {
|
||||
webServerConfig.certOptions = {
|
||||
key: fs.readFileSync(webServerConfig.key),
|
||||
cert: fs.readFileSync(webServerConfig.cert)
|
||||
};
|
||||
webServerConfig.protocol = 'https';
|
||||
} catch (e) {
|
||||
this.logger.error(e.message);
|
||||
this.logger.warn('Invalid path for key/cert in config/webserver.js. Using http instead.');
|
||||
webServerConfig.certOptions = {};
|
||||
webServerConfig.protocol = 'http';
|
||||
}
|
||||
}
|
||||
if (configFilePath === false) {
|
||||
this.webServerConfig = {enabled: false};
|
||||
return;
|
||||
}
|
||||
if (this.webServerConfig) {
|
||||
// cli flags to `embark run` should override configFile and defaults (configObject)
|
||||
this.webServerConfig = recursiveMerge(webServerConfig, this.webServerConfig);
|
||||
} else {
|
||||
this.webServerConfig = webServerConfig;
|
||||
}
|
||||
|
||||
if (!this.pipelineConfig.enabled) {
|
||||
this.webServerConfig.enabled = false;
|
||||
}
|
||||
|
||||
this.events.emit('config:load:webserver', this.webServerConfig);
|
||||
}
|
||||
|
||||
loadEmbarkConfigFile() {
|
||||
const configObject = {
|
||||
options: {
|
||||
solc: {
|
||||
"optimize": true,
|
||||
"optimize-runs": 200
|
||||
}
|
||||
},
|
||||
generationDir: "embarkArtifacts"
|
||||
};
|
||||
|
||||
this.embarkConfig = recursiveMerge(configObject, this.embarkConfig);
|
||||
|
||||
const contracts = this.embarkConfig.contracts;
|
||||
// determine contract 'root' directories
|
||||
this.contractDirectories = contracts.map((dir) => {
|
||||
return dir.split("**")[0];
|
||||
}).map((dir) => {
|
||||
return dir.split("*.")[0];
|
||||
});
|
||||
this.contractDirectories.push(constants.httpContractsDirectory);
|
||||
|
||||
this.buildDir = this.embarkConfig.buildDir;
|
||||
this.configDir = this.embarkConfig.config;
|
||||
}
|
||||
|
||||
loadPipelineConfigFile() {
|
||||
|
||||
const defaultPipelineConfig = {
|
||||
typescript: false,
|
||||
enabled: true
|
||||
};
|
||||
|
||||
let pipelineConfigPath = this._getFileOrObject(this.configDir, 'pipeline', 'pipeline');
|
||||
|
||||
// Embark applications in "simple" mode that aren't aware of `pipeline.js` configuration capabilities
|
||||
// won't have a pipeline config path so we need to perform this safety check here, otherwise the
|
||||
// next expression is going to throw.
|
||||
if (pipelineConfigPath !== undefined) {
|
||||
// At this point, `pipelineConfigPath` could be either `config/pipeline` or a filepath including its extension.
|
||||
// We need to make sure that we always have an extension.
|
||||
pipelineConfigPath = `${dappPath(pipelineConfigPath)}${path.extname(pipelineConfigPath) === '.js' ? '' : '.js'}`;
|
||||
}
|
||||
|
||||
let pipelineConfig = defaultPipelineConfig;
|
||||
|
||||
if (pipelineConfigPath && fs.existsSync(pipelineConfigPath)) {
|
||||
delete require.cache[pipelineConfigPath];
|
||||
pipelineConfig = recursiveMerge(
|
||||
recursiveMerge(true, pipelineConfig),
|
||||
require(pipelineConfigPath)
|
||||
);
|
||||
}
|
||||
|
||||
this.pipelineConfig = pipelineConfig;
|
||||
this.events.emit('config:load:pipeline', this.pipelineConfig);
|
||||
}
|
||||
|
||||
loadAssetFiles() {
|
||||
if (!this.embarkConfig.app) { return; }
|
||||
Object.keys(this.embarkConfig.app).forEach(targetFile => {
|
||||
this.assetFiles[targetFile] = this.loadFiles(this.embarkConfig.app[targetFile]);
|
||||
});
|
||||
}
|
||||
|
||||
loadFiles(files) {
|
||||
const self = this;
|
||||
const originalFiles = filesMatchingPattern(files);
|
||||
const readFiles: File[] = [];
|
||||
const storageConfig = self.storageConfig;
|
||||
|
||||
originalFiles.filter(function(file) {
|
||||
return (file[0] === '$' || file.indexOf('.') >= 0);
|
||||
}).filter(function(file) {
|
||||
const basedir = findMatchingExpression(file, files);
|
||||
readFiles.push(new File({path: file, originalPath: file, type: Types.dappFile, basedir, storageConfig}));
|
||||
});
|
||||
|
||||
const filesFromPlugins: File[] = [];
|
||||
const filePlugins = self.plugins.getPluginsFor('pipelineFiles');
|
||||
filePlugins.forEach((plugin: Plugin) => {
|
||||
try {
|
||||
const fileObjects = plugin.runFilePipeline();
|
||||
for (let i = 0; i < fileObjects.length; i++) {
|
||||
const fileObject = fileObjects[i];
|
||||
filesFromPlugins.push(fileObject);
|
||||
}
|
||||
} catch (err) {
|
||||
self.logger.error(err.message);
|
||||
}
|
||||
});
|
||||
filesFromPlugins.filter(function(file) {
|
||||
if ((file.intendedPath && fileMatchesPattern(files, file.intendedPath)) || fileMatchesPattern(files, file.file)) {
|
||||
readFiles.push(file);
|
||||
}
|
||||
});
|
||||
|
||||
return readFiles;
|
||||
}
|
||||
|
||||
// NOTE: this doesn't work for internal modules
|
||||
loadPluginContractFiles() {
|
||||
const self = this;
|
||||
const storageConfig = self.storageConfig;
|
||||
const contractsPlugins = this.plugins.getPluginsFor('contractFiles');
|
||||
contractsPlugins.forEach((plugin: Plugin) => {
|
||||
plugin.contractsFiles.forEach(file => {
|
||||
const filename = file.replace('./', '');
|
||||
self.contractsFiles.push(new File({ path: filename, originalPath: path.join(plugin.pluginPath, filename), pluginPath: plugin.pluginPath, type: Types.custom, storageConfig,
|
||||
resolver(callback) {
|
||||
callback(plugin.loadPluginFile(file));
|
||||
}
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function findMatchingExpression(filename, filesExpressions) {
|
||||
for (const fileExpression of filesExpressions) {
|
||||
const matchingFiles = filesMatchingPattern(fileExpression);
|
||||
for (const matchFile of matchingFiles) {
|
||||
if (matchFile === filename) {
|
||||
return path.dirname(fileExpression).replace(/\*/g, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
return path.dirname(filename);
|
||||
}
|
@ -39,23 +39,23 @@ export function getBlockchainDefaults(env) {
|
||||
|
||||
export function getContractDefaults(embarkConfigVersions) {
|
||||
const defaultVersions = {
|
||||
"web3": "1.2.1",
|
||||
"solc": "0.5.0"
|
||||
web3: "1.2.1",
|
||||
solc: "0.5.0"
|
||||
};
|
||||
const versions = recursiveMerge(defaultVersions, embarkConfigVersions || {});
|
||||
|
||||
return {
|
||||
"default": {
|
||||
"versions": versions,
|
||||
"dappConnection": [
|
||||
default: {
|
||||
versions: versions,
|
||||
dappConnection: [
|
||||
"$WEB3",
|
||||
"ws://localhost:8546",
|
||||
"localhost:8545"
|
||||
],
|
||||
"dappAutoEnable": true,
|
||||
"strategy": constants.deploymentStrategy.implicit,
|
||||
"gas": "auto",
|
||||
"deploy": {
|
||||
dappAutoEnable: true,
|
||||
strategy: constants.deploymentStrategy.implicit,
|
||||
gas: "auto",
|
||||
deploy: {
|
||||
}
|
||||
}
|
||||
};
|
@ -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;
|
93
packages/core/core/src/fs.ts
Normal file
93
packages/core/core/src/fs.ts
Normal file
@ -0,0 +1,93 @@
|
||||
/* global module process require */
|
||||
/* tslint:disable */
|
||||
import { joinPath } from 'embark-utils';
|
||||
import * as fs from 'fs-extra';
|
||||
import parseJson from 'parse-json';
|
||||
import * as path from 'path';
|
||||
import 'colors';
|
||||
|
||||
export function mkdirpSync(args: any) { return fs.mkdirpSync(args); }
|
||||
|
||||
export function mkdirp(args: any, args2?: any) { return fs.mkdirp(args, args2); }
|
||||
|
||||
export function readdir(args: any, args2?: any) { return fs.readdir(args, args2); }
|
||||
|
||||
export function stat(args: any, args2?: any) { return fs.stat(args, args2); }
|
||||
|
||||
export function remove(args: any, args2: any) { return fs.remove(args, args2); }
|
||||
|
||||
export function copy(args: any, args2?: any, args3?: any, args4?: any) { return fs.copy(args, args2, args3, args4); }
|
||||
|
||||
export function copySync(args: any, args2?: any, args3?: any) { return fs.copySync(args, args2, args3); }
|
||||
|
||||
export function move(args: any, args2?: any, args3?: any, args4?: any) { return fs.move(args, args2, args3, args4); }
|
||||
|
||||
export function moveSync(args: any, args2?: any, args3?: any) { return fs.moveSync(args, args2, args3); }
|
||||
|
||||
export function symlink(args: any, args2?: any, args3?: any, args4?: any) { return fs.symlink(args, args2, args3, args4); }
|
||||
|
||||
export function appendFileSync(args: any, args2: any, args3?: any) { return fs.appendFileSync(args, args2, args3); }
|
||||
|
||||
export function writeFile(args: any, args2: any, args3?: any, args4?: any) { return fs.writeFile(args, args2, args3, args4); }
|
||||
|
||||
export function writeFileSync(args: any, args2: any, args3?: any) { return fs.writeFileSync(args, args2, args3); }
|
||||
|
||||
export function readFile(args: any, args2?: any, args3?: any) { return fs.readFile(args, args2, args3); }
|
||||
|
||||
export function readFileSync(args: any, args2?: any) { return fs.readFileSync(args, args2); }
|
||||
|
||||
export function readdirSync(args: any, args2?: any) { return fs.readdirSync(args, args2); }
|
||||
|
||||
export function statSync(args: any, args2?: any) { return fs.statSync(args, args2); }
|
||||
|
||||
export function readJSONSync(args: any, args2?: any) {
|
||||
let json;
|
||||
try {
|
||||
json = parseJson(readFileSync(args, args2));
|
||||
} catch (e) {
|
||||
console.error('error: '.red + args.green.underline + ' ' + e.message.green);
|
||||
process.exit(1);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
export function writeJSONSync(args: any, args2: any, args3?: any) { return fs.writeJSONSync(args, args2, args3); }
|
||||
|
||||
export function outputJSONSync(args: any, args2: any, args3?: any) { return fs.outputJSONSync(args, args2, args3); }
|
||||
|
||||
export function writeJson(args: any, args2: any, args3?: any, args4?: any) { return fs.writeJson(args, args2, args3, args4); }
|
||||
|
||||
export function existsSync(args: any) { return fs.existsSync(args); }
|
||||
|
||||
export function ensureFileSync(args: any) { return fs.ensureFileSync(args); }
|
||||
|
||||
export function ensureDirSync(args: any, args2?: any) { return fs.ensureDirSync(args, args2); }
|
||||
|
||||
export function access(args: any, args2?: any, args3?: any) { return fs.access(args, args2, args3); }
|
||||
|
||||
export function removeSync(args: any) { return fs.removeSync(args); }
|
||||
|
||||
export function createWriteStream(args: any, args2?: any) { return fs.createWriteStream(args, args2); }
|
||||
|
||||
export function copyPreserve(sourceFilePath, targetFilePath) {
|
||||
const implementation = (sourceFilePath, targetFilePath) => {
|
||||
let ext = 1;
|
||||
let preserved = targetFilePath;
|
||||
while (fs.existsSync(preserved)) {
|
||||
const extname = path.extname(targetFilePath);
|
||||
preserved = joinPath(
|
||||
path.dirname(targetFilePath),
|
||||
`${path.basename(targetFilePath, extname)}.${ext}${extname}`
|
||||
);
|
||||
ext++;
|
||||
}
|
||||
if (preserved !== targetFilePath) {
|
||||
fs.copySync(targetFilePath, preserved);
|
||||
}
|
||||
fs.copySync(sourceFilePath, targetFilePath);
|
||||
};
|
||||
|
||||
return implementation(sourceFilePath, targetFilePath);
|
||||
}
|
||||
|
||||
export function outputFileSync(args: any, args2: any, args3?: any) { return fs.outputFileSync(args, args2, args3); }
|
@ -1,5 +0,0 @@
|
||||
export { ProcessLauncher } from './processes/processLauncher';
|
||||
export { ProcessManager } from './processes/processManager';
|
||||
export { ProcessWrapper } from './processes/processWrapper';
|
||||
|
||||
export { IPC } from './ipc';
|
14
packages/core/core/src/index.ts
Normal file
14
packages/core/core/src/index.ts
Normal file
@ -0,0 +1,14 @@
|
||||
export { ProcessLauncher } from './processes/processLauncher';
|
||||
export { ProcessWrapper } from './processes/processWrapper';
|
||||
|
||||
export { Config } from './config';
|
||||
export { IPC } from './ipc';
|
||||
export { Engine } from './engine';
|
||||
import { EmbarkEmitter as Events } from './events';
|
||||
export { Events };
|
||||
export { Plugins } from './plugins';
|
||||
export { TestLogger } from './utils/test_logger';
|
||||
export { TemplateGenerator } from './utils/template_generator';
|
||||
|
||||
import * as fs from './fs';
|
||||
export { fs };
|
363
packages/core/core/src/plugin.ts
Normal file
363
packages/core/core/src/plugin.ts
Normal file
@ -0,0 +1,363 @@
|
||||
import { fileMatchesPattern } from './utils/utils';
|
||||
import { __ } from 'embark-i18n';
|
||||
import { dappPath, embarkPath, isEs6Module, joinPath } from 'embark-utils';
|
||||
import { Logger } from 'embark-logger';
|
||||
const constants = require('embark-core/constants');
|
||||
const fs = require('fs-extra');
|
||||
const deepEqual = require('deep-equal');
|
||||
|
||||
// TODO: pass other params like blockchainConfig, contract files, etc..
|
||||
export class Plugin {
|
||||
|
||||
dappPath = dappPath;
|
||||
|
||||
embarkPath = embarkPath;
|
||||
|
||||
name: string;
|
||||
|
||||
isInternal: boolean;
|
||||
|
||||
pluginModule: any;
|
||||
|
||||
pluginPath: string;
|
||||
|
||||
pluginConfig: any;
|
||||
|
||||
shouldInterceptLogs: boolean;
|
||||
|
||||
clientWeb3Providers: any[] = [];
|
||||
|
||||
beforeDeploy: any[] = [];
|
||||
|
||||
contractsGenerators: any[] = [];
|
||||
|
||||
generateCustomContractCode = null;
|
||||
|
||||
testContractFactory = null;
|
||||
|
||||
pipeline: any[] = [];
|
||||
|
||||
pipelineFiles: any[] = [];
|
||||
|
||||
console: any[] = [];
|
||||
|
||||
contractsConfigs: any[] = [];
|
||||
|
||||
contractsFiles: any[] = [];
|
||||
|
||||
compilers: any[] = [];
|
||||
|
||||
serviceChecks: any[] = [];
|
||||
|
||||
dappGenerators: any[] = [];
|
||||
|
||||
pluginTypes: string[] = [];
|
||||
|
||||
uploadCmds: any[] = [];
|
||||
|
||||
apiCalls: any[] = [];
|
||||
|
||||
imports: any[] = [];
|
||||
|
||||
embarkjs_code: any[] = [];
|
||||
|
||||
generated_code: any[] = [];
|
||||
|
||||
embarkjs_init_code: any[] = [];
|
||||
|
||||
embarkjs_init_console_code: any[] = [];
|
||||
|
||||
fs: any;
|
||||
|
||||
afterContractsDeployActions: any[] = [];
|
||||
|
||||
onDeployActions: any[] = [];
|
||||
|
||||
eventActions: any = {};
|
||||
|
||||
_loggerObject: Logger;
|
||||
|
||||
events: any;
|
||||
|
||||
config: any;
|
||||
|
||||
plugins: any;
|
||||
|
||||
env: any;
|
||||
|
||||
loaded = false;
|
||||
|
||||
currentContext: any;
|
||||
|
||||
acceptedContext: any;
|
||||
|
||||
version: string;
|
||||
|
||||
constants: any;
|
||||
|
||||
logger: Logger;
|
||||
|
||||
constructor(options) {
|
||||
this.name = options.name;
|
||||
this.isInternal = options.isInternal;
|
||||
this.pluginModule = options.pluginModule;
|
||||
this.pluginPath = options.pluginPath;
|
||||
this.pluginConfig = options.pluginConfig;
|
||||
this.shouldInterceptLogs = options.interceptLogs;
|
||||
this.fs = fs;
|
||||
this._loggerObject = options.logger;
|
||||
this.logger = this._loggerObject; // Might get changed if we do intercept
|
||||
this.events = options.events;
|
||||
this.config = options.config;
|
||||
this.plugins = options.plugins;
|
||||
this.env = options.env;
|
||||
this.currentContext = options.context;
|
||||
this.acceptedContext = options.pluginConfig.context || [constants.contexts.any];
|
||||
this.version = options.version;
|
||||
this.constants = constants;
|
||||
|
||||
if (!Array.isArray(this.currentContext)) {
|
||||
this.currentContext = [this.currentContext];
|
||||
}
|
||||
if (!Array.isArray(this.acceptedContext)) {
|
||||
this.acceptedContext = [this.acceptedContext];
|
||||
}
|
||||
}
|
||||
|
||||
_log(type) {
|
||||
this._loggerObject[type](this.name + ':', ...[].slice.call(arguments, 1));
|
||||
}
|
||||
|
||||
setUpLogger() {
|
||||
this.logger = {
|
||||
log: this._log.bind(this, 'log'),
|
||||
warn: this._log.bind(this, 'warn'),
|
||||
error: this._log.bind(this, 'error'),
|
||||
info: this._log.bind(this, 'info'),
|
||||
debug: this._log.bind(this, 'debug'),
|
||||
trace: this._log.bind(this, 'trace'),
|
||||
dir: this._log.bind(this, 'dir')
|
||||
};
|
||||
}
|
||||
|
||||
isContextValid() {
|
||||
if (this.currentContext.includes(constants.contexts.any) || this.acceptedContext.includes(constants.contexts.any)) {
|
||||
return true;
|
||||
}
|
||||
return this.acceptedContext.some(context => {
|
||||
return this.currentContext.includes(context);
|
||||
});
|
||||
}
|
||||
|
||||
hasContext(context) {
|
||||
return this.currentContext.includes(context);
|
||||
}
|
||||
|
||||
loadPlugin() {
|
||||
if (!this.isContextValid()) {
|
||||
this.logger.warn(__('Plugin {{name}} can only be loaded in the context of "{{contexts}}"', {name: this.name, contexts: this.acceptedContext.join(', ')}));
|
||||
return false;
|
||||
}
|
||||
this.loaded = true;
|
||||
if (this.shouldInterceptLogs) {
|
||||
this.setUpLogger();
|
||||
}
|
||||
if (isEs6Module(this.pluginModule)) {
|
||||
if (this.pluginModule.default) {
|
||||
this.pluginModule = this.pluginModule.default;
|
||||
}
|
||||
return new this.pluginModule(this);
|
||||
}
|
||||
this.pluginModule.call(this, this);
|
||||
}
|
||||
|
||||
loadInternalPlugin() {
|
||||
if (isEs6Module(this.pluginModule)) {
|
||||
if (this.pluginModule.default) {
|
||||
this.pluginModule = this.pluginModule.default;
|
||||
}
|
||||
}
|
||||
return new this.pluginModule(this, this.pluginConfig); /*eslint no-new: "off"*/
|
||||
}
|
||||
|
||||
loadPluginFile(filename) {
|
||||
return fs.readFileSync(this.pathToFile(filename)).toString();
|
||||
}
|
||||
|
||||
pathToFile(filename) {
|
||||
if (!this.pluginPath) {
|
||||
throw new Error('pluginPath not defined for plugin: ' + this.name);
|
||||
}
|
||||
return joinPath(this.pluginPath, filename);
|
||||
}
|
||||
|
||||
// TODO: add deploy provider
|
||||
registerClientWeb3Provider(cb) {
|
||||
this.clientWeb3Providers.push(cb);
|
||||
this.addPluginType('clientWeb3Provider');
|
||||
}
|
||||
|
||||
registerContractsGeneration(cb) {
|
||||
this.contractsGenerators.push(cb);
|
||||
this.addPluginType('contractGeneration');
|
||||
}
|
||||
|
||||
registerCustomContractGenerator(cb) {
|
||||
this.generateCustomContractCode = cb;
|
||||
this.addPluginType('customContractGeneration');
|
||||
}
|
||||
|
||||
registerTestContractFactory(cb) {
|
||||
this.testContractFactory = cb;
|
||||
this.addPluginType('testContractFactory');
|
||||
}
|
||||
|
||||
registerPipeline(matcthingFiles, cb) {
|
||||
// TODO: generate error for more than one pipeline per plugin
|
||||
this.pipeline.push({matcthingFiles, cb});
|
||||
this.addPluginType('pipeline');
|
||||
}
|
||||
|
||||
registerDappGenerator(framework, cb) {
|
||||
this.dappGenerators.push({framework, cb});
|
||||
this.pluginTypes.push('dappGenerator');
|
||||
}
|
||||
|
||||
registerCustomType(type) {
|
||||
this.pluginTypes.push(type);
|
||||
}
|
||||
|
||||
addFileToPipeline(file, intendedPath, options) {
|
||||
this.pipelineFiles.push({file, intendedPath, options});
|
||||
this.addPluginType('pipelineFiles');
|
||||
}
|
||||
|
||||
addContractFile(file) {
|
||||
if (this.isInternal) {
|
||||
throw new Error("this API cannot work for internal modules. please use an event command instead: config:contractsFiles:add");
|
||||
}
|
||||
this.contractsFiles.push(file);
|
||||
this.addPluginType('contractFiles');
|
||||
}
|
||||
|
||||
registerConsoleCommand(optionsOrCb) {
|
||||
if (typeof optionsOrCb === 'function') {
|
||||
this.logger.warn(__('Registering console commands with function syntax is deprecated and will likely be removed in future versions of Embark'));
|
||||
this.logger.info(__('You can find the new API documentation here: %s', 'https://embark.status.im/docs/plugin_reference.html#registerConsoleCommand-options'.underline));
|
||||
}
|
||||
this.console.push(optionsOrCb);
|
||||
this.addPluginType('console');
|
||||
}
|
||||
|
||||
// TODO: this only works for services done on startup
|
||||
registerServiceCheck(checkName, checkFn, time) {
|
||||
this.serviceChecks.push({checkName, checkFn, time});
|
||||
this.addPluginType('serviceChecks');
|
||||
}
|
||||
|
||||
has(pluginType) {
|
||||
return this.pluginTypes.indexOf(pluginType) >= 0;
|
||||
}
|
||||
|
||||
addPluginType(pluginType) {
|
||||
this.pluginTypes.push(pluginType);
|
||||
this.pluginTypes = Array.from(new Set(this.pluginTypes));
|
||||
}
|
||||
|
||||
generateProvider(args) {
|
||||
return this.clientWeb3Providers.map(function(cb) {
|
||||
return cb.call(this, args);
|
||||
}).join("\n");
|
||||
}
|
||||
|
||||
generateContracts(args) {
|
||||
return this.contractsGenerators.map(function(cb) {
|
||||
return cb.call(this, args);
|
||||
}).join("\n");
|
||||
}
|
||||
|
||||
registerContractConfiguration(config) {
|
||||
this.contractsConfigs.push(config);
|
||||
this.addPluginType('contractsConfig');
|
||||
}
|
||||
|
||||
registerCompiler(extension, cb) {
|
||||
this.compilers.push({extension, cb});
|
||||
this.addPluginType('compilers');
|
||||
}
|
||||
|
||||
registerUploadCommand(cmd, cb) {
|
||||
this.uploadCmds.push({cmd, cb});
|
||||
this.addPluginType('uploadCmds');
|
||||
}
|
||||
|
||||
addCodeToEmbarkJS(code) {
|
||||
this.addPluginType('embarkjsCode');
|
||||
// TODO: what is this/why
|
||||
if (!this.embarkjs_code.some((existingCode) => deepEqual(existingCode, code))) {
|
||||
this.embarkjs_code.push(code);
|
||||
}
|
||||
}
|
||||
|
||||
addGeneratedCode(codeCb) {
|
||||
this.addPluginType('generatedCode');
|
||||
this.generated_code.push(codeCb);
|
||||
}
|
||||
|
||||
addProviderInit(providerType, code, initCondition) {
|
||||
this.embarkjs_init_code[providerType] = this.embarkjs_init_code[providerType] || [];
|
||||
this.embarkjs_init_code[providerType].push([code, initCondition]);
|
||||
this.addPluginType('initCode');
|
||||
}
|
||||
|
||||
addConsoleProviderInit(providerType, code, initCondition) {
|
||||
this.embarkjs_init_console_code[providerType] = this.embarkjs_init_console_code[providerType] || [];
|
||||
this.addPluginType('initConsoleCode');
|
||||
const toAdd = [code, initCondition];
|
||||
if (!this.embarkjs_init_console_code[providerType].some((initConsoleCode) => deepEqual(initConsoleCode, toAdd))) {
|
||||
this.embarkjs_init_console_code[providerType].push(toAdd);
|
||||
}
|
||||
}
|
||||
|
||||
registerImportFile(importName, importLocation) {
|
||||
this.imports.push([importName, importLocation]);
|
||||
this.addPluginType('imports');
|
||||
}
|
||||
|
||||
registerActionForEvent(eventName, cb) {
|
||||
if (!this.eventActions[eventName]) {
|
||||
this.eventActions[eventName] = [];
|
||||
}
|
||||
this.eventActions[eventName].push(cb);
|
||||
this.addPluginType('eventActions');
|
||||
}
|
||||
|
||||
registerAPICall(method, endpoint, cb) {
|
||||
this.apiCalls.push({method, endpoint, cb});
|
||||
this.addPluginType('apiCalls');
|
||||
this.events.emit('plugins:register:api', {method, endpoint, cb});
|
||||
}
|
||||
|
||||
runFilePipeline() {
|
||||
return this.pipelineFiles.map(file => {
|
||||
let obj: any = {};
|
||||
obj.filename = file.file.replace('./', '');
|
||||
obj.content = this.loadPluginFile(file.file).toString();
|
||||
obj.intendedPath = file.intendedPath;
|
||||
obj.options = file.options;
|
||||
obj.path = this.pathToFile(obj.filename);
|
||||
|
||||
return obj;
|
||||
});
|
||||
}
|
||||
|
||||
runPipeline(args) {
|
||||
// TODO: should iterate the pipelines
|
||||
let pipeline = this.pipeline[0];
|
||||
let shouldRunPipeline = fileMatchesPattern(pipeline.matcthingFiles, args.targetFile);
|
||||
if (shouldRunPipeline) {
|
||||
return pipeline.cb.call(this, args);
|
||||
}
|
||||
return args.source;
|
||||
}
|
||||
}
|
272
packages/core/core/src/plugins.ts
Normal file
272
packages/core/core/src/plugins.ts
Normal file
@ -0,0 +1,272 @@
|
||||
import * as fs from './fs';
|
||||
import { Plugin } from './plugin';
|
||||
import { EmbarkEmitter as Events } from './events';
|
||||
import { Config } from './config';
|
||||
|
||||
import * as async from 'async';
|
||||
import { dappPath, embarkPath } from 'embark-utils';
|
||||
import { Logger } from 'embark-logger';
|
||||
|
||||
export class Plugins {
|
||||
|
||||
pluginList = [];
|
||||
|
||||
interceptLogs: boolean;
|
||||
|
||||
plugins: Plugin[] = [];
|
||||
|
||||
logger: Logger;
|
||||
|
||||
events: Events;
|
||||
|
||||
config: Config;
|
||||
|
||||
context: any;
|
||||
|
||||
fs: any;
|
||||
|
||||
env: string;
|
||||
|
||||
version: string;
|
||||
|
||||
static deprecated = {
|
||||
'embarkjs-connector-web3': '4.1.0'
|
||||
};
|
||||
|
||||
constructor(options) {
|
||||
this.pluginList = options.plugins || [];
|
||||
this.interceptLogs = options.interceptLogs;
|
||||
// TODO: need backup 'NullLogger'
|
||||
this.logger = options.logger;
|
||||
this.events = options.events;
|
||||
this.config = options.config;
|
||||
this.context = options.context;
|
||||
this.fs = fs;
|
||||
this.env = options.env;
|
||||
this.version = options.version;
|
||||
}
|
||||
|
||||
loadPlugins() {
|
||||
Object.entries(Plugins.deprecated).forEach(([pluginName, embarkVersion]) => {
|
||||
if (this.pluginList[pluginName]) {
|
||||
delete this.pluginList[pluginName];
|
||||
this.logger.warn(`${pluginName} plugin was not loaded because it has been deprecated as of embark v${embarkVersion}, please remove it from this project's embark.json and package.json`);
|
||||
}
|
||||
});
|
||||
Object.entries(this.pluginList).forEach(([pluginName, pluginConfig]) => {
|
||||
this.loadPlugin(pluginName, pluginConfig);
|
||||
});
|
||||
}
|
||||
|
||||
listPlugins() {
|
||||
return this.plugins.reduce((list: string[], plugin) => {
|
||||
if (plugin.loaded) {
|
||||
list.push(plugin.name);
|
||||
}
|
||||
return list;
|
||||
}, []);
|
||||
}
|
||||
|
||||
// for services that act as a plugin but have core functionality
|
||||
createPlugin(pluginName, pluginConfig) {
|
||||
const plugin = {};
|
||||
const pluginPath = false;
|
||||
const pluginWrapper = new Plugin({
|
||||
name: pluginName,
|
||||
pluginModule: plugin,
|
||||
pluginConfig,
|
||||
logger: this.logger,
|
||||
pluginPath,
|
||||
interceptLogs: this.interceptLogs,
|
||||
events: this.events,
|
||||
config: this.config,
|
||||
plugins: this.plugins,
|
||||
fs: this.fs,
|
||||
isInternal: true,
|
||||
context: this.context
|
||||
});
|
||||
this.plugins.push(pluginWrapper);
|
||||
return pluginWrapper;
|
||||
}
|
||||
|
||||
loadInternalPlugin(pluginName, pluginConfig, isPackage?: boolean) {
|
||||
let pluginPath, plugin;
|
||||
if (isPackage) {
|
||||
pluginPath = pluginName;
|
||||
plugin = require(pluginName);
|
||||
} else {
|
||||
pluginPath = embarkPath('dist/lib/modules/' + pluginName);
|
||||
plugin = require(pluginPath);
|
||||
}
|
||||
|
||||
if (plugin.default) {
|
||||
plugin = plugin.default;
|
||||
}
|
||||
|
||||
const pluginWrapper = new Plugin({
|
||||
name: pluginName,
|
||||
pluginModule: plugin,
|
||||
pluginConfig: pluginConfig || {},
|
||||
logger: this.logger,
|
||||
pluginPath,
|
||||
interceptLogs: this.interceptLogs,
|
||||
events: this.events,
|
||||
config: this.config,
|
||||
plugins: this.plugins,
|
||||
fs: this.fs,
|
||||
isInternal: true,
|
||||
context: this.context,
|
||||
env: this.env
|
||||
});
|
||||
const pluginInstance = pluginWrapper.loadInternalPlugin();
|
||||
this.plugins.push(pluginWrapper);
|
||||
return pluginInstance;
|
||||
}
|
||||
|
||||
loadPlugin(pluginName, pluginConfig) {
|
||||
const pluginPath = dappPath('node_modules', pluginName);
|
||||
let plugin = require(pluginPath);
|
||||
|
||||
if (plugin.default) {
|
||||
plugin = plugin.default;
|
||||
}
|
||||
|
||||
const pluginWrapper = new Plugin({
|
||||
name: pluginName,
|
||||
pluginModule: plugin,
|
||||
pluginConfig,
|
||||
logger: this.logger,
|
||||
pluginPath,
|
||||
interceptLogs: this.interceptLogs,
|
||||
events: this.events,
|
||||
config: this.config,
|
||||
plugins: this.plugins,
|
||||
fs: this.fs,
|
||||
isInternal: false,
|
||||
context: this.context,
|
||||
version: this.version
|
||||
});
|
||||
pluginWrapper.loadPlugin();
|
||||
this.plugins.push(pluginWrapper);
|
||||
}
|
||||
|
||||
getPluginsFor(pluginType) {
|
||||
return this.plugins.filter(function(plugin) {
|
||||
return plugin.has(pluginType);
|
||||
});
|
||||
}
|
||||
|
||||
getPluginsProperty(pluginType, property, sub_property?: any) {
|
||||
const matchingPlugins = this.plugins.filter(function(plugin) {
|
||||
return plugin.has(pluginType);
|
||||
});
|
||||
|
||||
// Sort internal plugins first
|
||||
matchingPlugins.sort((a, b) => {
|
||||
if (a.isInternal) {
|
||||
return -1;
|
||||
}
|
||||
if (b.isInternal) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
let matchingProperties = matchingPlugins.map((plugin) => {
|
||||
if (sub_property) {
|
||||
return plugin[property][sub_property];
|
||||
}
|
||||
return plugin[property];
|
||||
});
|
||||
|
||||
// Remove empty properties
|
||||
matchingProperties = matchingProperties.filter((property) => property);
|
||||
|
||||
// return flattened list
|
||||
if (matchingProperties.length === 0) { return []; }
|
||||
return matchingProperties.reduce((a, b) => a.concat(b)) || [];
|
||||
}
|
||||
|
||||
getPluginsPropertyAndPluginName(pluginType, property, sub_property) {
|
||||
const matchingPlugins = this.plugins.filter(function(plugin) {
|
||||
return plugin.has(pluginType);
|
||||
});
|
||||
|
||||
// Sort internal plugins first
|
||||
matchingPlugins.sort((a, b) => {
|
||||
if (a.isInternal) {
|
||||
return -1;
|
||||
}
|
||||
if (b.isInternal) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
let matchingProperties: any[] = [];
|
||||
matchingPlugins.map((plugin) => {
|
||||
if (sub_property) {
|
||||
const newList = [];
|
||||
for (const kall of (plugin[property][sub_property] || [])) {
|
||||
matchingProperties.push([kall, plugin.name]);
|
||||
}
|
||||
return newList;
|
||||
}
|
||||
|
||||
const newList = [];
|
||||
for (const kall of (plugin[property] || [])) {
|
||||
matchingProperties.push([kall, plugin.name]);
|
||||
}
|
||||
return newList;
|
||||
});
|
||||
|
||||
// Remove empty properties
|
||||
matchingProperties = matchingProperties.filter((property) => property[0]);
|
||||
|
||||
// return flattened list
|
||||
if (matchingProperties.length === 0) { return []; }
|
||||
// return matchingProperties.reduce((a,b) => { return a.concat(b); }) || [];
|
||||
return matchingProperties;
|
||||
}
|
||||
|
||||
// TODO: because this is potentially hanging, we should issue a trace warning if the event does not exists
|
||||
runActionsForEvent(eventName, args, cb) {
|
||||
const self = this;
|
||||
if (typeof (args) === 'function') {
|
||||
cb = args;
|
||||
args = [];
|
||||
}
|
||||
const actionPlugins = this.getPluginsPropertyAndPluginName('eventActions', 'eventActions', eventName);
|
||||
|
||||
if (actionPlugins.length === 0) {
|
||||
return cb(null, args);
|
||||
}
|
||||
|
||||
this.events.log("ACTION", eventName, "");
|
||||
|
||||
async.reduce(actionPlugins, args, function(current_args, pluginObj: any, nextEach) {
|
||||
const [plugin, pluginName] = pluginObj;
|
||||
|
||||
self.events.log("== ACTION FOR " + eventName, plugin.name, pluginName);
|
||||
|
||||
if (typeof (args) === 'function') {
|
||||
plugin.call(plugin, (...params) => {
|
||||
nextEach(...params || current_args);
|
||||
});
|
||||
} else {
|
||||
plugin.call(plugin, args, (...params) => {
|
||||
nextEach(...params || current_args);
|
||||
});
|
||||
}
|
||||
}, cb);
|
||||
}
|
||||
|
||||
emitAndRunActionsForEvent(eventName, args, cb) {
|
||||
if (typeof (args) === 'function') {
|
||||
cb = args;
|
||||
args = [];
|
||||
}
|
||||
this.events.emit(eventName, args);
|
||||
return this.runActionsForEvent(eventName, args, cb);
|
||||
}
|
||||
}
|
103
packages/core/core/src/services_monitor.ts
Normal file
103
packages/core/core/src/services_monitor.ts
Normal file
@ -0,0 +1,103 @@
|
||||
import { EmbarkEmitter as Events } from './events';
|
||||
import { Plugins } from './plugins';
|
||||
|
||||
import { __ } from 'embark-i18n';
|
||||
import { Logger } from 'embark-logger';
|
||||
|
||||
export class ServicesMonitor {
|
||||
|
||||
events: Events;
|
||||
|
||||
logger: Logger;
|
||||
|
||||
plugins: Plugins;
|
||||
|
||||
checkList: any = {};
|
||||
|
||||
checkTimers: any = {};
|
||||
|
||||
checkState: any = {};
|
||||
|
||||
working = false;
|
||||
|
||||
constructor(options) {
|
||||
this.events = options.events;
|
||||
this.logger = options.logger;
|
||||
this.plugins = options.plugins;
|
||||
this.events.setCommandHandler("services:register", (checkName, checkFn, time, initialStatus) => {
|
||||
this.addCheck(checkName, checkFn, time, initialStatus);
|
||||
});
|
||||
}
|
||||
|
||||
initCheck(checkName) {
|
||||
const self = this;
|
||||
const check = this.checkList[checkName];
|
||||
|
||||
if (!check) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.events.on('check:' + checkName, function(obj) {
|
||||
if (check && check.status === 'off' && obj.status === 'on') {
|
||||
self.events.emit('check:backOnline:' + checkName);
|
||||
}
|
||||
if (check && check.status === 'on' && obj.status === 'off') {
|
||||
self.events.emit('check:wentOffline:' + checkName);
|
||||
}
|
||||
check.status = obj.status;
|
||||
// const newState = {name: obj.name, status: obj.status, serviceName: checkName};
|
||||
// if (!deepEqual(newState, self.checkState[checkName])) {
|
||||
self.checkState[checkName] = {name: obj.name, status: obj.status, serviceName: checkName};
|
||||
self.events.emit("servicesState", self.checkState);
|
||||
// }
|
||||
});
|
||||
|
||||
if (check.interval !== 0) {
|
||||
self.checkTimers[checkName] = setInterval(function() {
|
||||
check.fn.call(check.fn, function(obj) {
|
||||
self.events.emit('check:' + checkName, obj);
|
||||
});
|
||||
}, check.interval);
|
||||
}
|
||||
|
||||
check.fn.call(check.fn, function(obj) {
|
||||
self.events.emit('check:' + checkName, obj);
|
||||
});
|
||||
}
|
||||
|
||||
addCheck(checkName, checkFn, time, initialState?: any) {
|
||||
this.logger.trace('add check: ' + checkName);
|
||||
this.checkList[checkName] = {fn: checkFn, interval: time || 5000, status: initialState};
|
||||
|
||||
if (this.working) {
|
||||
this.initCheck(checkName);
|
||||
}
|
||||
}
|
||||
|
||||
stopCheck(name) {
|
||||
clearInterval(this.checkTimers[name]);
|
||||
delete this.checkTimers[name];
|
||||
delete this.checkList[name];
|
||||
delete this.checkState[name];
|
||||
}
|
||||
|
||||
startMonitor() {
|
||||
const self = this;
|
||||
this.working = true;
|
||||
this.logger.trace('startMonitor');
|
||||
|
||||
const servicePlugins = this.plugins.getPluginsProperty('serviceChecks', 'serviceChecks');
|
||||
servicePlugins.forEach(function(pluginCheck) {
|
||||
self.addCheck(pluginCheck.checkName, pluginCheck.checkFn, pluginCheck.time);
|
||||
});
|
||||
|
||||
Object.keys(this.checkList).forEach(checkName => {
|
||||
try {
|
||||
self.initCheck(checkName);
|
||||
} catch (err) {
|
||||
self.logger.error(__("error running service check"));
|
||||
self.logger.error(err.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -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;
|
9
packages/core/core/src/utils/utils.js
Normal file
9
packages/core/core/src/utils/utils.js
Normal file
@ -0,0 +1,9 @@
|
||||
export function filesMatchingPattern(files) {
|
||||
const globule = require('globule');
|
||||
return globule.find(files, {nonull: true});
|
||||
}
|
||||
|
||||
export function fileMatchesPattern(patterns, intendedPath) {
|
||||
const globule = require('globule');
|
||||
return globule.isMatch(patterns, intendedPath);
|
||||
}
|
5
packages/core/core/tsconfig.json
Normal file
5
packages/core/core/tsconfig.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
|
4
packages/core/core/tslint.json
Normal file
4
packages/core/core/tslint.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../../tslint.json"
|
||||
}
|
||||
|
6
packages/core/i18n/index.d.ts
vendored
6
packages/core/i18n/index.d.ts
vendored
@ -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;
|
||||
|
20
packages/core/typings/index.d.ts
vendored
20
packages/core/typings/index.d.ts
vendored
@ -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';
|
||||
|
2
packages/core/typings/src/contract.d.ts
vendored
2
packages/core/typings/src/contract.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { ABIDefinition } from "web3/eth/abi";
|
||||
import { ABIDefinition } from 'web3/eth/abi';
|
||||
|
||||
export interface Contract {
|
||||
abiDefinition: ABIDefinition[];
|
||||
|
4
packages/core/typings/src/embark.d.ts
vendored
4
packages/core/typings/src/embark.d.ts
vendored
@ -1,5 +1,5 @@
|
||||
import { Logger } from "./logger";
|
||||
import { Plugins } from "./plugins";
|
||||
import { Logger } from './logger';
|
||||
import { Plugins } from './plugins';
|
||||
|
||||
type CommandCallback = (
|
||||
opt1?: any,
|
||||
|
2
packages/core/typings/src/plugins.d.ts
vendored
2
packages/core/typings/src/plugins.d.ts
vendored
@ -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,724 +0,0 @@
|
||||
const fs = require('./fs.js');
|
||||
const Plugins = require('./plugins.js');
|
||||
const utils = require('../utils/utils.js');
|
||||
const path = require('path');
|
||||
const deepEqual = require('deep-equal');
|
||||
const web3 = require('web3');
|
||||
const constants = require('embark-core/constants');
|
||||
import { __ } from 'embark-i18n';
|
||||
import {
|
||||
buildUrlFromConfig,
|
||||
canonicalHost,
|
||||
dappPath,
|
||||
defaultHost,
|
||||
File,
|
||||
Types,
|
||||
recursiveMerge,
|
||||
AddressUtils,
|
||||
unitRegex,
|
||||
getWeiBalanceFromString,
|
||||
prepareContractsConfig,
|
||||
getExternalContractUrl
|
||||
} from 'embark-utils';
|
||||
const cloneDeep = require('lodash.clonedeep');
|
||||
const { replaceZeroAddressShorthand } = AddressUtils;
|
||||
|
||||
import {getBlockchainDefaults, getContractDefaults} from './configDefaults';
|
||||
|
||||
const DEFAULT_CONFIG_PATH = 'config/';
|
||||
const PACKAGE = require('../../../package.json');
|
||||
|
||||
const embark5ChangesUrl = 'https://embark.status.im/docs/migrating_from_3.x.html#Updating-to-v5';
|
||||
|
||||
var Config = function(options) {
|
||||
this.env = options.env || 'default';
|
||||
this.blockchainConfig = {};
|
||||
this.contractsConfig = {};
|
||||
this.pipelineConfig = {};
|
||||
this.namesystemConfig = {};
|
||||
this.communicationConfig = {};
|
||||
this.webServerConfig = options.webServerConfig;
|
||||
this.chainTracker = {};
|
||||
this.assetFiles = {};
|
||||
this.contractsFiles = [];
|
||||
this.configDir = options.configDir || DEFAULT_CONFIG_PATH;
|
||||
this.chainsFile = options.chainsFile || './chains.json';
|
||||
this.plugins = options.plugins;
|
||||
this.logger = options.logger;
|
||||
this.package = PACKAGE;
|
||||
this.events = options.events;
|
||||
this.embarkConfig = {};
|
||||
this.context = options.context || [constants.contexts.any];
|
||||
this.version = options.version;
|
||||
this.shownNoAccountConfigMsg = false; // flag to ensure "no account config" message is only displayed once to the user
|
||||
this.corsParts = [];
|
||||
this.providerUrl = null;
|
||||
|
||||
this.registerEvents();
|
||||
};
|
||||
|
||||
Config.prototype.setConfig = function(configName, newConfig, cb) {
|
||||
this[configName] = newConfig;
|
||||
cb();
|
||||
};
|
||||
|
||||
Config.prototype.registerEvents = function() {
|
||||
this.events.setCommandHandler("config:cors:add", (url) => {
|
||||
this.corsParts.push(url);
|
||||
this._updateBlockchainCors();
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("config:contractsConfig", (cb) => {
|
||||
cb(null, this.contractsConfig);
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("config:storageConfig", (cb) => {
|
||||
cb(null, this.storageConfig);
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("config:contractsConfig:set", this.setConfig.bind(this, 'contractsConfig'));
|
||||
this.events.setCommandHandler("config:blockchainConfig:set", this.setConfig.bind(this, 'blockchainConfig'));
|
||||
this.events.setCommandHandler("config:storageConfig:set", this.setConfig.bind(this, 'storageConfig'));
|
||||
this.events.setCommandHandler("config:namesystemConfig:set", this.setConfig.bind(this, 'namesystemConfig'));
|
||||
this.events.setCommandHandler("config:communicationConfig:set", this.setConfig.bind(this, 'communicationConfig'));
|
||||
|
||||
this.events.setCommandHandler("config:contractsFiles", (cb) => {
|
||||
cb(null, this.contractsFiles);
|
||||
});
|
||||
|
||||
// TODO: refactor this so reading the file can be done with a normal resolver or something that takes advantage of the plugin api
|
||||
this.events.setCommandHandler("config:contractsFiles:add", (filename, resolver) => {
|
||||
resolver = resolver || function(callback) {
|
||||
callback(fs.readFileSync(filename).toString());
|
||||
};
|
||||
this.contractsFiles.push(new File({path: filename, originalPath: filename, type: Types.custom, resolver}));
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("config:contractsFiles:reset", (cb) => {
|
||||
this.contractsFiles.forEach((file) => {
|
||||
if(file.path.includes(".embark")) {
|
||||
fs.removeSync(file.path);
|
||||
}
|
||||
this.contractsFiles = this.contractsFiles.filter((contractFile) => contractFile.path !== file.path);
|
||||
});
|
||||
cb();
|
||||
});
|
||||
|
||||
this.events.on('file-remove', (fileType, removedPath) => {
|
||||
if(fileType !== 'contract') return;
|
||||
const normalizedPath = path.normalize(removedPath);
|
||||
this.contractsFiles = this.contractsFiles.filter(file => path.normalize(file.path) !== normalizedPath);
|
||||
});
|
||||
};
|
||||
|
||||
// TODO remove this at some point as it is now in plugin
|
||||
Config.prototype.dappPath = dappPath;
|
||||
|
||||
Config.prototype.loadConfigFiles = function(options) {
|
||||
var interceptLogs = options.interceptLogs;
|
||||
if (options.interceptLogs === undefined) {
|
||||
interceptLogs = true;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(options.embarkConfig)){
|
||||
this.logger.error(__('Cannot find file %s Please ensure you are running this command inside the Dapp folder', options.embarkConfig));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
this.embarkConfig = fs.readJSONSync(options.embarkConfig);
|
||||
this.embarkConfig.plugins = this.embarkConfig.plugins || {};
|
||||
|
||||
this.plugins = new Plugins({
|
||||
plugins: this.embarkConfig.plugins,
|
||||
logger: this.logger,
|
||||
interceptLogs: interceptLogs,
|
||||
events: this.events,
|
||||
config: this,
|
||||
context: this.context,
|
||||
env: this.env,
|
||||
version: this.version
|
||||
});
|
||||
this.plugins.loadPlugins();
|
||||
|
||||
this.loadEmbarkConfigFile();
|
||||
this.loadBlockchainConfigFile();
|
||||
this.loadStorageConfigFile();
|
||||
this.loadContractFiles();
|
||||
this.loadCommunicationConfigFile();
|
||||
this.loadNameSystemConfigFile();
|
||||
this.loadPipelineConfigFile();
|
||||
this.loadAssetFiles();
|
||||
this.loadContractsConfigFile();
|
||||
this.loadExternalContractsFiles();
|
||||
this.loadWebServerConfigFile();
|
||||
this.loadPluginContractFiles();
|
||||
|
||||
this._updateBlockchainCors();
|
||||
};
|
||||
|
||||
Config.prototype.reloadConfig = function() {
|
||||
this.loadEmbarkConfigFile();
|
||||
this.loadBlockchainConfigFile();
|
||||
this.loadStorageConfigFile();
|
||||
this.loadContractFiles();
|
||||
this.loadCommunicationConfigFile();
|
||||
this.loadNameSystemConfigFile();
|
||||
this.loadPipelineConfigFile();
|
||||
this.loadAssetFiles();
|
||||
this.loadContractsConfigFile();
|
||||
this.loadExternalContractsFiles();
|
||||
|
||||
this._updateBlockchainCors();
|
||||
};
|
||||
|
||||
Config.prototype.loadContractFiles = function() {
|
||||
const loadedContractFiles = this.loadFiles(this.embarkConfig.contracts);
|
||||
// `this.contractsFiles` could've been mutated at runtime using
|
||||
// either `config:contractsFiles:add` event or through calls to
|
||||
// `loadExternalContractsFiles()`, so we have to make sure we preserve
|
||||
// those added files before we reset `this.contractsFiles`.
|
||||
//
|
||||
// We do that by determining the difference between `loadedContractFiles` and the ones
|
||||
// already in memory in `this.contractsFiles`.
|
||||
const addedContractFiles = this.contractsFiles.filter(existingFile => !loadedContractFiles.some(file => file.originalPath === existingFile.originalPath));
|
||||
this.contractsFiles = loadedContractFiles.concat(addedContractFiles);
|
||||
};
|
||||
|
||||
Config.prototype._updateBlockchainCors = function(){
|
||||
let blockchainConfig = this.blockchainConfig;
|
||||
let storageConfig = this.storageConfig;
|
||||
let webServerConfig = this.webServerConfig;
|
||||
let corsParts = cloneDeep(this.corsParts);
|
||||
|
||||
if (blockchainConfig.isDev) {
|
||||
corsParts.push('*');
|
||||
}
|
||||
|
||||
if(webServerConfig && webServerConfig.host) {
|
||||
corsParts.push(buildUrlFromConfig(webServerConfig));
|
||||
}
|
||||
if(storageConfig && storageConfig.enabled) {
|
||||
// if getUrl is specified in the config, that needs to be included in cors
|
||||
// instead of the concatenated protocol://host:port
|
||||
if(storageConfig.upload.getUrl) {
|
||||
// remove /ipfs or /bzz: from getUrl if it's there
|
||||
let getUrlParts = storageConfig.upload.getUrl.split('/');
|
||||
getUrlParts = getUrlParts.slice(0, 3);
|
||||
let host = canonicalHost(getUrlParts[2].split(':')[0]);
|
||||
let port = getUrlParts[2].split(':')[1];
|
||||
getUrlParts[2] = port ? [host, port].join(':') : host;
|
||||
corsParts.push(getUrlParts.join('/'));
|
||||
}
|
||||
// use our modified getUrl or in case it wasn't specified, use a built url
|
||||
else{
|
||||
corsParts.push(buildUrlFromConfig(storageConfig.upload));
|
||||
}
|
||||
}
|
||||
// Add cors for the proxy and whisper
|
||||
corsParts.push(constants.embarkResourceOrigin);
|
||||
|
||||
corsParts = Array.from(new Set(corsParts));
|
||||
this.corsParts = corsParts;
|
||||
|
||||
let cors = corsParts.join(',');
|
||||
if (blockchainConfig.rpcCorsDomain === 'auto') {
|
||||
blockchainConfig.rpcCorsDomain = cors;
|
||||
} else if (typeof blockchainConfig.rpcCorsDomain === 'object') {
|
||||
let tempCors = blockchainConfig.rpcCorsDomain.auto ? corsParts : [];
|
||||
tempCors = tempCors.concat(blockchainConfig.rpcCorsDomain.additionalCors || []);
|
||||
blockchainConfig.rpcCorsDomain = tempCors.join(',');
|
||||
}
|
||||
if (blockchainConfig.wsOrigins === 'auto') {
|
||||
blockchainConfig.wsOrigins = cors;
|
||||
} else if (typeof blockchainConfig.wsOrigins === 'object') {
|
||||
let tempCors = blockchainConfig.wsOrigins.auto ? corsParts : [];
|
||||
tempCors = tempCors.concat(blockchainConfig.wsOrigins.additionalCors || []);
|
||||
blockchainConfig.wsOrigins = tempCors.join(',');
|
||||
}
|
||||
};
|
||||
|
||||
Config.prototype._loadConfigFile = function (configFilePath, defaultConfig, enabledByDefault) {
|
||||
if (!configFilePath) {
|
||||
const configToReturn = defaultConfig['default'] || {};
|
||||
configToReturn.enabled = enabledByDefault || false;
|
||||
return configToReturn;
|
||||
}
|
||||
configFilePath = configFilePath.replace('.json','').replace('.js', '');
|
||||
let config;
|
||||
if (fs.existsSync(configFilePath + '.js')) {
|
||||
delete require.cache[configFilePath + '.js'];
|
||||
config = require(configFilePath + '.js');
|
||||
} else if (fs.existsSync(configFilePath + '.json')) {
|
||||
config = fs.readJSONSync(configFilePath + '.json');
|
||||
} else {
|
||||
this.logger.warn(__("no config file found at %s using default config", configFilePath));
|
||||
return defaultConfig['default'] || {};
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
Config.prototype._doMergeConfig = function(config, defaultConfig, env) {
|
||||
let configObject = recursiveMerge(defaultConfig, config);
|
||||
|
||||
if (env) {
|
||||
if (env === 'test' && !configObject[env]) {
|
||||
// Disabled all configs in tests as they are opt in
|
||||
return Object.assign({}, defaultConfig.default, {enabled: false});
|
||||
}
|
||||
return recursiveMerge(configObject.default || {}, configObject[env]);
|
||||
} else if (env !== false) {
|
||||
this.logger.info(__("No environment called %s found. Using defaults.", env));
|
||||
}
|
||||
return configObject;
|
||||
};
|
||||
|
||||
Config.prototype._loadAndMergeConfig = function(configFilePath, defaultConfig, env, enabledByDefault) {
|
||||
const config = this._loadConfigFile(configFilePath, defaultConfig, enabledByDefault);
|
||||
return this._doMergeConfig(config, defaultConfig, env, enabledByDefault);
|
||||
};
|
||||
|
||||
Config.prototype._getFileOrObject = function(object, filePath, property) {
|
||||
if (typeof object === 'object') {
|
||||
return object[property] ? dappPath(object[property]) : object[property];
|
||||
}
|
||||
return dappPath(object, filePath);
|
||||
};
|
||||
|
||||
/*eslint complexity: ["error", 30]*/
|
||||
Config.prototype.loadBlockchainConfigFile = function() {
|
||||
const blockchainDefaults = getBlockchainDefaults(this.env);
|
||||
const configFilePath = this._getFileOrObject(this.configDir, 'blockchain', 'blockchain');
|
||||
|
||||
const userConfig = this._loadConfigFile(configFilePath, blockchainDefaults, true);
|
||||
const envConfig = userConfig[this.env];
|
||||
|
||||
if (envConfig) {
|
||||
if (envConfig.ethereumClientName || envConfig.hasOwnProperty('isDev') || envConfig.hasOwnProperty('mineWhenNeeded')) {
|
||||
this.logger.error(__('The blockchain config has changed quite a bit in Embark 5\nPlease visit %s to know what has to be changed', embark5ChangesUrl.underline));
|
||||
process.exit(1);
|
||||
}
|
||||
if (envConfig.clientConfig) {
|
||||
Object.assign(envConfig, envConfig.clientConfig);
|
||||
delete envConfig.clientConfig;
|
||||
}
|
||||
switch (envConfig.miningMode) {
|
||||
case 'dev': envConfig.isDev = true; break;
|
||||
case 'auto': envConfig.isDev = false; envConfig.mineWhenNeeded = true; break;
|
||||
case 'always': envConfig.isDev = false; envConfig.mineWhenNeeded = false; envConfig.mine = true; break;
|
||||
case 'off': envConfig.isDev = false; envConfig.mineWhenNeeded = false; envConfig.mine = false; break;
|
||||
default: envConfig.isDev = false;
|
||||
}
|
||||
if (envConfig.cors) {
|
||||
const autoIndex = envConfig.cors.indexOf('auto');
|
||||
envConfig.rpcCorsDomain = {};
|
||||
envConfig.wsOrigins = {};
|
||||
if (autoIndex > -1) {
|
||||
envConfig.rpcCorsDomain.auto = true;
|
||||
envConfig.wsOrigins.auto = true;
|
||||
envConfig.cors.splice(autoIndex, 1);
|
||||
} else {
|
||||
envConfig.rpcCorsDomain.auto = false;
|
||||
envConfig.wsOrigins.auto = false;
|
||||
}
|
||||
envConfig.rpcCorsDomain.additionalCors = envConfig.cors;
|
||||
envConfig.wsOrigins.additionalCors = envConfig.cors;
|
||||
delete envConfig.cors;
|
||||
}
|
||||
|
||||
userConfig[this.env] = envConfig;
|
||||
}
|
||||
|
||||
this.blockchainConfig = this._doMergeConfig(userConfig, blockchainDefaults, this.env);
|
||||
|
||||
if (!configFilePath) {
|
||||
this.blockchainConfig.default = true;
|
||||
}
|
||||
|
||||
if (this.blockchainConfig.targetGasLimit && this.blockchainConfig.targetGasLimit.toString().match(unitRegex)) {
|
||||
this.blockchainConfig.targetGasLimit = getWeiBalanceFromString(this.blockchainConfig.targetGasLimit, web3);
|
||||
}
|
||||
|
||||
if (this.blockchainConfig.gasPrice && this.blockchainConfig.gasPrice.toString().match(unitRegex)) {
|
||||
this.blockchainConfig.gasPrice = getWeiBalanceFromString(this.blockchainConfig.gasPrice, web3);
|
||||
}
|
||||
|
||||
if (this.blockchainConfig.accounts) {
|
||||
this.blockchainConfig.accounts.forEach(acc => {
|
||||
if (acc.balance && acc.balance.toString().match(unitRegex)) {
|
||||
acc.balance = getWeiBalanceFromString(acc.balance, web3);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.blockchainConfig.endpoint) {
|
||||
const urlConfig = (this.blockchainConfig.wsHost) ? {
|
||||
host: this.blockchainConfig.wsHost,
|
||||
port: this.blockchainConfig.wsPort,
|
||||
type: 'ws'
|
||||
} : {
|
||||
host: this.blockchainConfig.rpcHost,
|
||||
port: this.blockchainConfig.rpcPort,
|
||||
type: 'rpc'
|
||||
};
|
||||
this.blockchainConfig.endpoint = buildUrlFromConfig(urlConfig);
|
||||
this.blockchainConfig.isAutoEndpoint = true;
|
||||
}
|
||||
|
||||
if (
|
||||
!this.shownNoAccountConfigMsg &&
|
||||
(/rinkeby|testnet|livenet/).test(this.blockchainConfig.networkType) &&
|
||||
!(this.blockchainConfig.accounts && this.blockchainConfig.accounts.find(acc => acc.password)) &&
|
||||
!this.blockchainConfig.isDev &&
|
||||
this.env !== 'development' && this.env !== 'test') {
|
||||
this.logger.warn((
|
||||
'\n=== ' + __('Cannot unlock account - account config missing').bold + ' ===\n' +
|
||||
__('Geth is configured to sync to a testnet/livenet and needs to unlock an account ' +
|
||||
'to allow your dApp to interact with geth, however, the address and password must ' +
|
||||
'be specified in your blockchain config. Please update your blockchain config with ' +
|
||||
'a valid address and password: \n') +
|
||||
` - config/blockchain.js > ${this.env} > account\n\n`.italic +
|
||||
__('Please also make sure the keystore file for the account is located at: ') +
|
||||
'\n - Mac: ' + `~/Library/Ethereum/${this.env}/keystore`.italic +
|
||||
'\n - Linux: ' + `~/.ethereum/${this.env}/keystore`.italic +
|
||||
'\n - Windows: ' + `%APPDATA%\\Ethereum\\${this.env}\\keystore`.italic) +
|
||||
__('\n\nAlternatively, you could change ' +
|
||||
`config/blockchain.js > ${this.env} > networkType`.italic +
|
||||
__(' to ') +
|
||||
'"custom"\n'.italic).yellow
|
||||
);
|
||||
this.shownNoAccountConfigMsg = true;
|
||||
}
|
||||
|
||||
const accountDocsMessage = __('For more info, check the docs: %s', 'https://embark.status.im/docs/blockchain_accounts_configuration.html'.underline);
|
||||
if (this.blockchainConfig.account) {
|
||||
this.logger.error(__('The `account` config for the blockchain was removed. Please use `accounts` instead.'));
|
||||
this.logger.error(accountDocsMessage);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (this.blockchainConfig.simulatorMnemonic) {
|
||||
this.logger.error(__('The `simulatorMnemonic` config for the blockchain was removed. Please use `accounts` instead.'));
|
||||
this.logger.error(accountDocsMessage);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
this.events.emit('config:load:blockchain', this.blockchainConfig);
|
||||
};
|
||||
|
||||
Config.prototype.loadContractsConfigFile = function() {
|
||||
let configObject = getContractDefaults(this.embarkConfig.versions);
|
||||
|
||||
const contractsConfigs = this.plugins.getPluginsProperty('contractsConfig', 'contractsConfigs');
|
||||
contractsConfigs.forEach(function(pluginConfig) {
|
||||
configObject = recursiveMerge(configObject, pluginConfig);
|
||||
});
|
||||
|
||||
let configFilePath = this._getFileOrObject(this.configDir, 'contracts', 'contracts');
|
||||
let newContractsConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
|
||||
if (newContractsConfig.contracts) {
|
||||
this.logger.error(__('`contracts` has been renamed `deploy` in contracts config\nFor more information: %s', embark5ChangesUrl.underline));
|
||||
process.exit(1);
|
||||
}
|
||||
if (newContractsConfig.deployment) {
|
||||
this.logger.error(__('`deployment` has been removed from contracts config and is now part of blockchain config\nFor more information: %s', embark5ChangesUrl.underline));
|
||||
process.exit(1);
|
||||
}
|
||||
if (newContractsConfig.gas.match(unitRegex)) {
|
||||
newContractsConfig.gas = getWeiBalanceFromString(newContractsConfig.gas, web3);
|
||||
}
|
||||
|
||||
newContractsConfig = prepareContractsConfig(newContractsConfig);
|
||||
|
||||
const afterDeploy = newContractsConfig.afterDeploy;
|
||||
|
||||
if (Array.isArray(afterDeploy)) {
|
||||
newContractsConfig.afterDeploy = afterDeploy.map(replaceZeroAddressShorthand);
|
||||
}
|
||||
|
||||
if (!deepEqual(newContractsConfig, this.contractsConfig)) {
|
||||
this.contractsConfig = newContractsConfig;
|
||||
}
|
||||
|
||||
this.events.emit('config:load:contracts', this.contractsConfig);
|
||||
};
|
||||
|
||||
Config.prototype.loadExternalContractsFiles = function() {
|
||||
let contracts = this.contractsConfig.contracts;
|
||||
let storageConfig = this.storageConfig;
|
||||
if (storageConfig && storageConfig.upload && storageConfig.upload.getUrl) {
|
||||
this.providerUrl = storageConfig.upload.getUrl;
|
||||
}
|
||||
for (let contractName in contracts) {
|
||||
let contract = contracts[contractName];
|
||||
|
||||
if (!contract.file) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let externalContractFile = null;
|
||||
|
||||
if (contract.file.startsWith('http') || contract.file.startsWith('git') || contract.file.startsWith('ipfs') || contract.file.startsWith('bzz')) {
|
||||
const fileObj = getExternalContractUrl(contract.file, this.providerUrl);
|
||||
if (!fileObj) {
|
||||
return this.logger.error(__("HTTP contract file not found") + ": " + contract.file);
|
||||
}
|
||||
externalContractFile = new File({ path: fileObj.filePath, originalPath: fileObj.filePath, type: Types.http, basedir: '', externalUrl: fileObj.url, storageConfig });
|
||||
} else if (fs.existsSync(contract.file)) {
|
||||
externalContractFile = new File({ path: contract.file, originalPath: contract.file, type: Types.dappFile, basedir: '', storageConfig });
|
||||
} else if (fs.existsSync(path.join('./node_modules/', contract.file))) {
|
||||
const completePath = path.join('./node_modules/', contract.file);
|
||||
externalContractFile = new File({ path: completePath, originalPath: completePath, type: Types.dappFile, basedir: '', storageConfig });
|
||||
}
|
||||
|
||||
if (externalContractFile) {
|
||||
const index = this.contractsFiles.findIndex(contractFile => contractFile.originalPath === externalContractFile.originalPath);
|
||||
// It's important that we only add `externalContractFile` if it doesn't exist already
|
||||
// within `contractsFiles`, otherwise we keep adding duplicates in subsequent
|
||||
// compilation routines creating a memory leak.
|
||||
if (index > -1) {
|
||||
this.contractsFiles[index] = externalContractFile;
|
||||
} else {
|
||||
this.contractsFiles.push(externalContractFile);
|
||||
}
|
||||
} else {
|
||||
this.logger.error(__("contract file not found") + ": " + contract.file);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Config.prototype.loadStorageConfigFile = function() {
|
||||
var versions = recursiveMerge({"ipfs-api": "17.2.4"}, this.embarkConfig.versions || {});
|
||||
|
||||
var configObject = {
|
||||
"default": {
|
||||
"versions": versions,
|
||||
"enabled": true,
|
||||
"available_providers": ["ipfs", "swarm"],
|
||||
"ipfs_bin": "ipfs",
|
||||
"upload": {
|
||||
"provider": "ipfs",
|
||||
"protocol": "http",
|
||||
"host" : defaultHost,
|
||||
"port": 5001,
|
||||
"getUrl": "http://localhost:8080/ipfs/"
|
||||
},
|
||||
"dappConnection": [{"provider": "ipfs", "host": "localhost", "port": 5001, "getUrl": "http://localhost:8080/ipfs/"}]
|
||||
}
|
||||
};
|
||||
|
||||
let configFilePath = this._getFileOrObject(this.configDir, 'storage', 'storage');
|
||||
|
||||
this.storageConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
|
||||
this.events.emit('config:load:storage', this.storageConfig);
|
||||
};
|
||||
|
||||
Config.prototype.loadNameSystemConfigFile = function() {
|
||||
// todo: spec out names for registration in the file itself for a dev chain
|
||||
var configObject = {
|
||||
"default": {
|
||||
"enabled": false
|
||||
}
|
||||
};
|
||||
|
||||
let configFilePath = this._getFileOrObject(this.configDir, 'namesystem', 'namesystem');
|
||||
|
||||
this.namesystemConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
|
||||
};
|
||||
|
||||
Config.prototype.loadCommunicationConfigFile = function() {
|
||||
var configObject = {
|
||||
"default": {
|
||||
"enabled": true,
|
||||
"provider": "whisper",
|
||||
"available_providers": ["whisper"],
|
||||
"connection": {
|
||||
"host": defaultHost,
|
||||
"port": 8557,
|
||||
"type": "ws"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let configFilePath = this._getFileOrObject(this.configDir, 'communication', 'communication');
|
||||
|
||||
this.communicationConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
|
||||
this.events.emit('config:load:communication', this.communicationConfig);
|
||||
};
|
||||
|
||||
Config.prototype.loadWebServerConfigFile = function() {
|
||||
var configObject = {
|
||||
"enabled": true,
|
||||
"host": defaultHost,
|
||||
"openBrowser": true,
|
||||
"port": 8000,
|
||||
"enableCatchAll": true,
|
||||
"protocol": "http"
|
||||
};
|
||||
|
||||
let configFilePath = this._getFileOrObject(this.configDir, 'webserver', 'webserver');
|
||||
|
||||
let webServerConfig = this._loadAndMergeConfig(configFilePath, configObject, false);
|
||||
|
||||
if (webServerConfig.https){
|
||||
try {
|
||||
webServerConfig.certOptions = {
|
||||
key: fs.readFileSync(webServerConfig.key),
|
||||
cert: fs.readFileSync(webServerConfig.cert)
|
||||
};
|
||||
webServerConfig.protocol = 'https';
|
||||
} catch (e) {
|
||||
this.logger.error(e.message);
|
||||
this.logger.warn('Invalid path for key/cert in config/webserver.js. Using http instead.');
|
||||
webServerConfig.certOptions = {};
|
||||
webServerConfig.protocol = 'http';
|
||||
}
|
||||
}
|
||||
if (configFilePath === false) {
|
||||
this.webServerConfig = {enabled: false};
|
||||
return;
|
||||
}
|
||||
if (this.webServerConfig) {
|
||||
// cli flags to `embark run` should override configFile and defaults (configObject)
|
||||
this.webServerConfig = recursiveMerge(webServerConfig, this.webServerConfig);
|
||||
} else {
|
||||
this.webServerConfig = webServerConfig;
|
||||
}
|
||||
|
||||
if (!this.pipelineConfig.enabled) {
|
||||
this.webServerConfig.enabled = false;
|
||||
}
|
||||
|
||||
this.events.emit('config:load:webserver', this.webServerConfig);
|
||||
};
|
||||
|
||||
Config.prototype.loadEmbarkConfigFile = function() {
|
||||
var configObject = {
|
||||
options: {
|
||||
solc: {
|
||||
"optimize": true,
|
||||
"optimize-runs": 200
|
||||
}
|
||||
},
|
||||
"generationDir": "embarkArtifacts"
|
||||
};
|
||||
|
||||
this.embarkConfig = recursiveMerge(configObject, this.embarkConfig);
|
||||
|
||||
const contracts = this.embarkConfig.contracts;
|
||||
// determine contract 'root' directories
|
||||
this.contractDirectories = contracts.map((dir) => {
|
||||
return dir.split("**")[0];
|
||||
}).map((dir) => {
|
||||
return dir.split("*.")[0];
|
||||
});
|
||||
this.contractDirectories.push(constants.httpContractsDirectory);
|
||||
|
||||
this.buildDir = this.embarkConfig.buildDir;
|
||||
this.configDir = this.embarkConfig.config;
|
||||
};
|
||||
|
||||
Config.prototype.loadPipelineConfigFile = function() {
|
||||
|
||||
const defaultPipelineConfig = {
|
||||
typescript: false,
|
||||
enabled: true
|
||||
};
|
||||
|
||||
let pipelineConfigPath = this._getFileOrObject(this.configDir, 'pipeline', 'pipeline');
|
||||
|
||||
// Embark applications in "simple" mode that aren't aware of `pipeline.js` configuration capabilities
|
||||
// won't have a pipeline config path so we need to perform this safety check here, otherwise the
|
||||
// next expression is going to throw.
|
||||
if (pipelineConfigPath !== undefined) {
|
||||
// At this point, `pipelineConfigPath` could be either `config/pipeline` or a filepath including its extension.
|
||||
// We need to make sure that we always have an extension.
|
||||
pipelineConfigPath = `${dappPath(pipelineConfigPath)}${path.extname(pipelineConfigPath) === '.js' ? '' : '.js'}`;
|
||||
}
|
||||
|
||||
let pipelineConfig = defaultPipelineConfig;
|
||||
|
||||
if (pipelineConfigPath && fs.existsSync(pipelineConfigPath)) {
|
||||
delete require.cache[pipelineConfigPath];
|
||||
pipelineConfig = recursiveMerge(
|
||||
recursiveMerge(true, pipelineConfig),
|
||||
require(pipelineConfigPath)
|
||||
);
|
||||
}
|
||||
|
||||
this.pipelineConfig = pipelineConfig;
|
||||
this.events.emit('config:load:pipeline', this.pipelineConfig);
|
||||
};
|
||||
|
||||
Config.prototype.loadAssetFiles = function () {
|
||||
if(!this.embarkConfig.app) return;
|
||||
Object.keys(this.embarkConfig.app).forEach(targetFile => {
|
||||
this.assetFiles[targetFile] = this.loadFiles(this.embarkConfig.app[targetFile]);
|
||||
});
|
||||
};
|
||||
|
||||
function findMatchingExpression(filename, filesExpressions) {
|
||||
for (let fileExpression of filesExpressions) {
|
||||
var matchingFiles = utils.filesMatchingPattern(fileExpression);
|
||||
for (let matchFile of matchingFiles) {
|
||||
if (matchFile === filename) {
|
||||
return path.dirname(fileExpression).replace(/\*/g, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
return path.dirname(filename);
|
||||
}
|
||||
|
||||
Config.prototype.loadFiles = function(files) {
|
||||
var self = this;
|
||||
var originalFiles = utils.filesMatchingPattern(files);
|
||||
var readFiles = [];
|
||||
let storageConfig = self.storageConfig;
|
||||
|
||||
originalFiles.filter(function(file) {
|
||||
return (file[0] === '$' || file.indexOf('.') >= 0);
|
||||
}).filter(function(file) {
|
||||
let basedir = findMatchingExpression(file, files);
|
||||
readFiles.push(new File({path: file, originalPath: file, type: Types.dappFile, basedir: basedir, storageConfig: storageConfig}));
|
||||
});
|
||||
|
||||
var filesFromPlugins = [];
|
||||
var filePlugins = self.plugins.getPluginsFor('pipelineFiles');
|
||||
filePlugins.forEach(function(plugin) {
|
||||
try {
|
||||
var fileObjects = plugin.runFilePipeline();
|
||||
for (var i=0; i < fileObjects.length; i++) {
|
||||
var fileObject = fileObjects[i];
|
||||
filesFromPlugins.push(fileObject);
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
self.logger.error(err.message);
|
||||
}
|
||||
});
|
||||
filesFromPlugins.filter(function(file) {
|
||||
if ((file.intendedPath && utils.fileMatchesPattern(files, file.intendedPath)) || utils.fileMatchesPattern(files, file.file)) {
|
||||
readFiles.push(file);
|
||||
}
|
||||
});
|
||||
|
||||
return readFiles;
|
||||
};
|
||||
|
||||
// NOTE: this doesn't work for internal modules
|
||||
Config.prototype.loadPluginContractFiles = function() {
|
||||
var self = this;
|
||||
let storageConfig = self.storageConfig;
|
||||
var contractsPlugins = this.plugins.getPluginsFor('contractFiles');
|
||||
contractsPlugins.forEach(function(plugin) {
|
||||
plugin.contractsFiles.forEach(function(file) {
|
||||
var filename = file.replace('./','');
|
||||
self.contractsFiles.push(new File({ path: filename, originalPath: path.join(plugin.pluginPath, filename), pluginPath: plugin.pluginPath, type: Types.custom, storageConfig,
|
||||
resolver: function(callback) {
|
||||
callback(plugin.loadPluginFile(file));
|
||||
}
|
||||
}));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = Config;
|
@ -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,303 +0,0 @@
|
||||
const utils = require('../utils/utils.js');
|
||||
import { __ } from 'embark-i18n';
|
||||
import { dappPath, embarkPath, isEs6Module, joinPath } from 'embark-utils';
|
||||
const constants = require('embark-core/constants');
|
||||
const fs = require('fs-extra');
|
||||
const deepEqual = require('deep-equal');
|
||||
|
||||
// TODO: pass other params like blockchainConfig, contract files, etc..
|
||||
var Plugin = function(options) {
|
||||
this.name = options.name;
|
||||
this.isInternal = options.isInternal;
|
||||
this.pluginModule = options.pluginModule;
|
||||
this.pluginPath = options.pluginPath;
|
||||
this.pluginConfig = options.pluginConfig;
|
||||
this.shouldInterceptLogs = options.interceptLogs;
|
||||
this.clientWeb3Providers = [];
|
||||
this.beforeDeploy = [];
|
||||
this.contractsGenerators = [];
|
||||
this.generateCustomContractCode = null;
|
||||
this.testContractFactory = null;
|
||||
this.pipeline = [];
|
||||
this.pipelineFiles = [];
|
||||
this.console = [];
|
||||
this.contractsConfigs = [];
|
||||
this.contractsFiles = [];
|
||||
this.compilers = [];
|
||||
this.serviceChecks = [];
|
||||
this.dappGenerators = [];
|
||||
this.pluginTypes = [];
|
||||
this.uploadCmds = [];
|
||||
this.apiCalls = [];
|
||||
this.imports = [];
|
||||
this.embarkjs_code = [];
|
||||
this.generated_code = [];
|
||||
this.embarkjs_init_code = {};
|
||||
this.embarkjs_init_console_code = {};
|
||||
this.fs = fs;
|
||||
this.afterContractsDeployActions = [];
|
||||
this.onDeployActions = [];
|
||||
this.eventActions = {};
|
||||
this._loggerObject = options.logger;
|
||||
this.logger = this._loggerObject; // Might get changed if we do intercept
|
||||
this.events = options.events;
|
||||
this.config = options.config;
|
||||
this.plugins = options.plugins;
|
||||
this.env = options.env;
|
||||
this.loaded = false;
|
||||
this.currentContext = options.context;
|
||||
this.acceptedContext = options.pluginConfig.context || [constants.contexts.any];
|
||||
this.version = options.version;
|
||||
this.constants = constants;
|
||||
|
||||
if (!Array.isArray(this.currentContext)) {
|
||||
this.currentContext = [this.currentContext];
|
||||
}
|
||||
if (!Array.isArray(this.acceptedContext)) {
|
||||
this.acceptedContext = [this.acceptedContext];
|
||||
}
|
||||
};
|
||||
|
||||
Plugin.prototype.dappPath = dappPath;
|
||||
Plugin.prototype.embarkPath = embarkPath;
|
||||
|
||||
Plugin.prototype._log = function(type) {
|
||||
this._loggerObject[type](this.name + ':', ...[].slice.call(arguments, 1));
|
||||
};
|
||||
|
||||
Plugin.prototype.setUpLogger = function () {
|
||||
this.logger = {
|
||||
log: this._log.bind(this, 'log'),
|
||||
warn: this._log.bind(this, 'warn'),
|
||||
error: this._log.bind(this, 'error'),
|
||||
info: this._log.bind(this, 'info'),
|
||||
debug: this._log.bind(this, 'debug'),
|
||||
trace: this._log.bind(this, 'trace'),
|
||||
dir: this._log.bind(this, 'dir')
|
||||
};
|
||||
};
|
||||
|
||||
Plugin.prototype.isContextValid = function() {
|
||||
if (this.currentContext.includes(constants.contexts.any) || this.acceptedContext.includes(constants.contexts.any)) {
|
||||
return true;
|
||||
}
|
||||
return this.acceptedContext.some(context => {
|
||||
return this.currentContext.includes(context);
|
||||
});
|
||||
};
|
||||
|
||||
Plugin.prototype.hasContext = function(context) {
|
||||
return this.currentContext.includes(context);
|
||||
};
|
||||
|
||||
Plugin.prototype.loadPlugin = function() {
|
||||
if (!this.isContextValid()) {
|
||||
this.logger.warn(__('Plugin {{name}} can only be loaded in the context of "{{contexts}}"', {name: this.name, contexts: this.acceptedContext.join(', ')}));
|
||||
return false;
|
||||
}
|
||||
this.loaded = true;
|
||||
if (this.shouldInterceptLogs) {
|
||||
this.setUpLogger();
|
||||
}
|
||||
if (isEs6Module(this.pluginModule)) {
|
||||
if (this.pluginModule.default) {
|
||||
this.pluginModule = this.pluginModule.default;
|
||||
}
|
||||
return new this.pluginModule(this);
|
||||
}
|
||||
this.pluginModule.call(this, this);
|
||||
};
|
||||
|
||||
Plugin.prototype.loadInternalPlugin = function() {
|
||||
if (isEs6Module(this.pluginModule)) {
|
||||
if (this.pluginModule.default) {
|
||||
this.pluginModule = this.pluginModule.default;
|
||||
}
|
||||
}
|
||||
return new this.pluginModule(this, this.pluginConfig); /*eslint no-new: "off"*/
|
||||
};
|
||||
|
||||
Plugin.prototype.loadPluginFile = function(filename) {
|
||||
return fs.readFileSync(this.pathToFile(filename)).toString();
|
||||
};
|
||||
|
||||
Plugin.prototype.pathToFile = function(filename) {
|
||||
if (!this.pluginPath) {
|
||||
throw new Error('pluginPath not defined for plugin: ' + this.name);
|
||||
}
|
||||
return joinPath(this.pluginPath, filename);
|
||||
};
|
||||
|
||||
// TODO: add deploy provider
|
||||
Plugin.prototype.registerClientWeb3Provider = function(cb) {
|
||||
this.clientWeb3Providers.push(cb);
|
||||
this.addPluginType('clientWeb3Provider');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerContractsGeneration = function(cb) {
|
||||
this.contractsGenerators.push(cb);
|
||||
this.addPluginType('contractGeneration');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerCustomContractGenerator = function (cb) {
|
||||
this.generateCustomContractCode = cb;
|
||||
this.addPluginType('customContractGeneration');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerTestContractFactory = function(cb) {
|
||||
this.testContractFactory = cb;
|
||||
this.addPluginType('testContractFactory');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerPipeline = function(matcthingFiles, cb) {
|
||||
// TODO: generate error for more than one pipeline per plugin
|
||||
this.pipeline.push({matcthingFiles: matcthingFiles, cb: cb});
|
||||
this.addPluginType('pipeline');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerDappGenerator = function(framework, cb){
|
||||
this.dappGenerators.push({framework: framework, cb: cb});
|
||||
this.pluginTypes.push('dappGenerator');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerCustomType = function(type){
|
||||
this.pluginTypes.push(type);
|
||||
};
|
||||
|
||||
Plugin.prototype.addFileToPipeline = function(file, intendedPath, options) {
|
||||
this.pipelineFiles.push({file: file, intendedPath: intendedPath, options: options});
|
||||
this.addPluginType('pipelineFiles');
|
||||
};
|
||||
|
||||
Plugin.prototype.addContractFile = function(file) {
|
||||
if (this.isInternal) {
|
||||
throw new Error("this API cannot work for internal modules. please use an event command instead: config:contractsFiles:add");
|
||||
}
|
||||
this.contractsFiles.push(file);
|
||||
this.addPluginType('contractFiles');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerConsoleCommand = function(optionsOrCb) {
|
||||
if (typeof optionsOrCb === 'function') {
|
||||
this.logger.warn(__('Registering console commands with function syntax is deprecated and will likely be removed in future versions of Embark'));
|
||||
this.logger.info(__('You can find the new API documentation here: %s', 'https://embark.status.im/docs/plugin_reference.html#registerConsoleCommand-options'.underline));
|
||||
}
|
||||
this.console.push(optionsOrCb);
|
||||
this.addPluginType('console');
|
||||
};
|
||||
|
||||
// TODO: this only works for services done on startup
|
||||
Plugin.prototype.registerServiceCheck = function(checkName, checkFn, time) {
|
||||
this.serviceChecks.push({checkName: checkName, checkFn: checkFn, time: time});
|
||||
this.addPluginType('serviceChecks');
|
||||
};
|
||||
|
||||
Plugin.prototype.has = function(pluginType) {
|
||||
return this.pluginTypes.indexOf(pluginType) >= 0;
|
||||
};
|
||||
|
||||
Plugin.prototype.addPluginType = function(pluginType) {
|
||||
this.pluginTypes.push(pluginType);
|
||||
this.pluginTypes = Array.from(new Set(this.pluginTypes));
|
||||
};
|
||||
|
||||
Plugin.prototype.generateProvider = function(args) {
|
||||
return this.clientWeb3Providers.map(function(cb) {
|
||||
return cb.call(this, args);
|
||||
}).join("\n");
|
||||
};
|
||||
|
||||
Plugin.prototype.generateContracts = function(args) {
|
||||
return this.contractsGenerators.map(function(cb) {
|
||||
return cb.call(this, args);
|
||||
}).join("\n");
|
||||
};
|
||||
|
||||
Plugin.prototype.registerContractConfiguration = function(config) {
|
||||
this.contractsConfigs.push(config);
|
||||
this.addPluginType('contractsConfig');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerCompiler = function(extension, cb) {
|
||||
this.compilers.push({extension: extension, cb: cb});
|
||||
this.addPluginType('compilers');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerUploadCommand = function(cmd, cb) {
|
||||
this.uploadCmds.push({cmd: cmd, cb: cb});
|
||||
this.addPluginType('uploadCmds');
|
||||
};
|
||||
|
||||
Plugin.prototype.addCodeToEmbarkJS = function(code) {
|
||||
this.addPluginType('embarkjsCode');
|
||||
// TODO: what is this/why
|
||||
if (!this.embarkjs_code.some((existingCode) => deepEqual(existingCode, code))) {
|
||||
this.embarkjs_code.push(code);
|
||||
}
|
||||
};
|
||||
|
||||
Plugin.prototype.addGeneratedCode = function(codeCb) {
|
||||
this.addPluginType('generatedCode');
|
||||
this.generated_code.push(codeCb);
|
||||
};
|
||||
|
||||
Plugin.prototype.addProviderInit = function(providerType, code, initCondition) {
|
||||
this.embarkjs_init_code[providerType] = this.embarkjs_init_code[providerType] || [];
|
||||
this.embarkjs_init_code[providerType].push([code, initCondition]);
|
||||
this.addPluginType('initCode');
|
||||
};
|
||||
|
||||
Plugin.prototype.addConsoleProviderInit = function(providerType, code, initCondition) {
|
||||
this.embarkjs_init_console_code[providerType] = this.embarkjs_init_console_code[providerType] || [];
|
||||
this.addPluginType('initConsoleCode');
|
||||
const toAdd = [code, initCondition];
|
||||
if (!this.embarkjs_init_console_code[providerType].some((initConsoleCode) => deepEqual(initConsoleCode, toAdd))) {
|
||||
this.embarkjs_init_console_code[providerType].push(toAdd);
|
||||
}
|
||||
};
|
||||
|
||||
Plugin.prototype.registerImportFile = function(importName, importLocation) {
|
||||
this.imports.push([importName, importLocation]);
|
||||
this.addPluginType('imports');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerActionForEvent = function(eventName, cb) {
|
||||
if (!this.eventActions[eventName]) {
|
||||
this.eventActions[eventName] = [];
|
||||
}
|
||||
this.eventActions[eventName].push(cb);
|
||||
this.addPluginType('eventActions');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerAPICall = function(method, endpoint, cb) {
|
||||
this.apiCalls.push({method, endpoint, cb});
|
||||
this.addPluginType('apiCalls');
|
||||
this.events.emit('plugins:register:api', {method, endpoint, cb});
|
||||
};
|
||||
|
||||
Plugin.prototype.runFilePipeline = function() {
|
||||
var self = this;
|
||||
|
||||
return this.pipelineFiles.map(function(file) {
|
||||
var obj = {};
|
||||
obj.filename = file.file.replace('./','');
|
||||
obj.content = self.loadPluginFile(file.file).toString();
|
||||
obj.intendedPath = file.intendedPath;
|
||||
obj.options = file.options;
|
||||
obj.path = self.pathToFile(obj.filename);
|
||||
|
||||
return obj;
|
||||
});
|
||||
};
|
||||
|
||||
Plugin.prototype.runPipeline = function(args) {
|
||||
// TODO: should iterate the pipelines
|
||||
var pipeline = this.pipeline[0];
|
||||
var shouldRunPipeline = utils.fileMatchesPattern(pipeline.matcthingFiles, args.targetFile);
|
||||
if (shouldRunPipeline) {
|
||||
return pipeline.cb.call(this, args);
|
||||
}
|
||||
return args.source;
|
||||
};
|
||||
|
||||
module.exports = Plugin;
|
@ -1,249 +0,0 @@
|
||||
import { dappPath, embarkPath } from 'embark-utils';
|
||||
const async = require('async');
|
||||
var Plugin = require('./plugin.js');
|
||||
var fs = require('../core/fs.js');
|
||||
|
||||
var Plugins = function(options) {
|
||||
this.pluginList = options.plugins || [];
|
||||
this.interceptLogs = options.interceptLogs;
|
||||
this.plugins = [];
|
||||
// TODO: need backup 'NullLogger'
|
||||
this.logger = options.logger;
|
||||
this.events = options.events;
|
||||
this.config = options.config;
|
||||
this.context = options.context;
|
||||
this.fs = fs;
|
||||
this.env = options.env;
|
||||
this.version = options.version;
|
||||
};
|
||||
|
||||
Plugins.deprecated = {
|
||||
'embarkjs-connector-web3': '4.1.0'
|
||||
};
|
||||
|
||||
Plugins.prototype.loadPlugins = function() {
|
||||
Object.entries(Plugins.deprecated).forEach(([pluginName, embarkVersion]) => {
|
||||
if (this.pluginList[pluginName]) {
|
||||
delete this.pluginList[pluginName];
|
||||
this.logger.warn(`${pluginName} plugin was not loaded because it has been deprecated as of embark v${embarkVersion}, please remove it from this project's embark.json and package.json`);
|
||||
}
|
||||
});
|
||||
Object.entries(this.pluginList).forEach(([pluginName, pluginConfig]) => {
|
||||
this.loadPlugin(pluginName, pluginConfig);
|
||||
});
|
||||
};
|
||||
|
||||
Plugins.prototype.listPlugins = function() {
|
||||
return this.plugins.reduce((list, plugin) => {
|
||||
if (plugin.loaded) {
|
||||
list.push(plugin.name);
|
||||
}
|
||||
return list;
|
||||
}, []);
|
||||
};
|
||||
|
||||
// for services that act as a plugin but have core functionality
|
||||
Plugins.prototype.createPlugin = function(pluginName, pluginConfig) {
|
||||
let plugin = {};
|
||||
let pluginPath = false;
|
||||
var pluginWrapper = new Plugin({
|
||||
name: pluginName,
|
||||
pluginModule: plugin,
|
||||
pluginConfig: pluginConfig,
|
||||
logger: this.logger,
|
||||
pluginPath: pluginPath,
|
||||
interceptLogs: this.interceptLogs,
|
||||
events: this.events,
|
||||
config: this.config,
|
||||
plugins: this.plugins,
|
||||
fs: this.fs,
|
||||
isInternal: true,
|
||||
context: this.context
|
||||
});
|
||||
this.plugins.push(pluginWrapper);
|
||||
return pluginWrapper;
|
||||
};
|
||||
|
||||
Plugins.prototype.loadInternalPlugin = function(pluginName, pluginConfig, isPackage) {
|
||||
let pluginPath, plugin;
|
||||
if (isPackage) {
|
||||
pluginPath = pluginName;
|
||||
plugin = require(pluginName);
|
||||
} else {
|
||||
pluginPath = embarkPath('dist/lib/modules/' + pluginName);
|
||||
plugin = require(pluginPath);
|
||||
}
|
||||
|
||||
if (plugin.default) {
|
||||
plugin = plugin.default;
|
||||
}
|
||||
|
||||
const pluginWrapper = new Plugin({
|
||||
name: pluginName,
|
||||
pluginModule: plugin,
|
||||
pluginConfig: pluginConfig || {},
|
||||
logger: this.logger,
|
||||
pluginPath: pluginPath,
|
||||
interceptLogs: this.interceptLogs,
|
||||
events: this.events,
|
||||
config: this.config,
|
||||
plugins: this.plugins,
|
||||
fs: this.fs,
|
||||
isInternal: true,
|
||||
context: this.context,
|
||||
env: this.env
|
||||
});
|
||||
const pluginInstance = pluginWrapper.loadInternalPlugin();
|
||||
this.plugins.push(pluginWrapper);
|
||||
return pluginInstance;
|
||||
};
|
||||
|
||||
Plugins.prototype.loadPlugin = function(pluginName, pluginConfig) {
|
||||
let pluginPath = dappPath('node_modules', pluginName);
|
||||
let plugin = require(pluginPath);
|
||||
|
||||
if (plugin.default) {
|
||||
plugin = plugin.default;
|
||||
}
|
||||
|
||||
var pluginWrapper = new Plugin({
|
||||
name: pluginName,
|
||||
pluginModule: plugin,
|
||||
pluginConfig: pluginConfig,
|
||||
logger: this.logger,
|
||||
pluginPath: pluginPath,
|
||||
interceptLogs: this.interceptLogs,
|
||||
events: this.events,
|
||||
config: this.config,
|
||||
plugins: this.plugins,
|
||||
fs: this.fs,
|
||||
isInternal: false,
|
||||
context: this.context,
|
||||
version: this.version
|
||||
});
|
||||
pluginWrapper.loadPlugin();
|
||||
this.plugins.push(pluginWrapper);
|
||||
};
|
||||
|
||||
Plugins.prototype.getPluginsFor = function(pluginType) {
|
||||
return this.plugins.filter(function(plugin) {
|
||||
return plugin.has(pluginType);
|
||||
});
|
||||
};
|
||||
|
||||
Plugins.prototype.getPluginsProperty = function(pluginType, property, sub_property) {
|
||||
let matchingPlugins = this.plugins.filter(function(plugin) {
|
||||
return plugin.has(pluginType);
|
||||
});
|
||||
|
||||
// Sort internal plugins first
|
||||
matchingPlugins.sort((a, b) => {
|
||||
if (a.isInternal) {
|
||||
return -1;
|
||||
}
|
||||
if (b.isInternal) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
let matchingProperties = matchingPlugins.map((plugin) => {
|
||||
if (sub_property) {
|
||||
return plugin[property][sub_property];
|
||||
}
|
||||
return plugin[property];
|
||||
});
|
||||
|
||||
// Remove empty properties
|
||||
matchingProperties = matchingProperties.filter((property) => property);
|
||||
|
||||
//return flattened list
|
||||
if (matchingProperties.length === 0) return [];
|
||||
return matchingProperties.reduce((a,b) => { return a.concat(b); }) || [];
|
||||
};
|
||||
|
||||
Plugins.prototype.getPluginsPropertyAndPluginName = function(pluginType, property, sub_property) {
|
||||
let matchingPlugins = this.plugins.filter(function(plugin) {
|
||||
return plugin.has(pluginType);
|
||||
});
|
||||
|
||||
// Sort internal plugins first
|
||||
matchingPlugins.sort((a, b) => {
|
||||
if (a.isInternal) {
|
||||
return -1;
|
||||
}
|
||||
if (b.isInternal) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
let matchingProperties = [];
|
||||
matchingPlugins.map((plugin) => {
|
||||
if (sub_property) {
|
||||
let newList = [];
|
||||
for (let kall of (plugin[property][sub_property] || [])) {
|
||||
matchingProperties.push([kall, plugin.name]);
|
||||
}
|
||||
return newList;
|
||||
}
|
||||
|
||||
let newList = [];
|
||||
for (let kall of (plugin[property] || [])) {
|
||||
matchingProperties.push([kall, plugin.name]);
|
||||
}
|
||||
return newList;
|
||||
});
|
||||
|
||||
// Remove empty properties
|
||||
matchingProperties = matchingProperties.filter((property) => property[0]);
|
||||
|
||||
//return flattened list
|
||||
if (matchingProperties.length === 0) return [];
|
||||
// return matchingProperties.reduce((a,b) => { return a.concat(b); }) || [];
|
||||
return matchingProperties;
|
||||
};
|
||||
|
||||
|
||||
// TODO: because this is potentially hanging, we should issue a trace warning if the event does not exists
|
||||
Plugins.prototype.runActionsForEvent = function(eventName, args, cb) {
|
||||
const self = this;
|
||||
if (typeof (args) === 'function') {
|
||||
cb = args;
|
||||
args = [];
|
||||
}
|
||||
let actionPlugins = this.getPluginsPropertyAndPluginName('eventActions', 'eventActions', eventName);
|
||||
|
||||
if (actionPlugins.length === 0) {
|
||||
return cb(null, args);
|
||||
}
|
||||
|
||||
this.events.log("ACTION", eventName, "");
|
||||
|
||||
async.reduce(actionPlugins, args, function (current_args, pluginObj, nextEach) {
|
||||
const [plugin, pluginName] = pluginObj;
|
||||
|
||||
self.events.log("== ACTION FOR " + eventName, plugin.name, pluginName);
|
||||
|
||||
if (typeof (args) === 'function') {
|
||||
plugin.call(plugin, (...params) => {
|
||||
nextEach(...params || current_args);
|
||||
});
|
||||
} else {
|
||||
plugin.call(plugin, args, (...params) => {
|
||||
nextEach(...params || current_args);
|
||||
});
|
||||
}
|
||||
}, cb);
|
||||
};
|
||||
|
||||
Plugins.prototype.emitAndRunActionsForEvent = function(eventName, args, cb) {
|
||||
if (typeof (args) === 'function') {
|
||||
cb = args;
|
||||
args = [];
|
||||
}
|
||||
this.events.emit(eventName, args);
|
||||
return this.runActionsForEvent(eventName, args, cb);
|
||||
};
|
||||
|
||||
module.exports = Plugins;
|
@ -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,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": []
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user