feat: enable embark to be run with an external pipeline

This commit is contained in:
Jonathan Rainville 2019-02-20 11:19:39 -05:00
parent c1d08c667a
commit ebcc3c4a8d
17 changed files with 243 additions and 133 deletions

View File

@ -84,12 +84,13 @@
"xyz"
]
},
"dappConfig": {
"dappArtifacts": {
"dir": "config",
"blockchain": "blockchain.json",
"storage": "storage.json",
"communication": "communication.json",
"embarkjs": "embarkjs.js",
"contractsJs": "contracts"
"contractsJs": "contracts",
"symlinkDir": "modules"
}
}

View File

@ -139,6 +139,10 @@ Config.prototype._updateBlockchainCors = function(){
let webServerConfig = this.webServerConfig;
let corsParts = cloneDeep(this.corsParts);
if (blockchainConfig.isDev) {
corsParts.push('*');
}
if(webServerConfig && webServerConfig.host) {
corsParts.push(utils.buildUrlFromConfig(webServerConfig));
}
@ -162,6 +166,9 @@ Config.prototype._updateBlockchainCors = function(){
// 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;

View File

@ -8,9 +8,12 @@ require('colors');
function restrictPath(receiver, binding, count, args) {
const dapp = dappPath();
const embark = embarkPath();
let embark = embarkPath();
const pkg = pkgPath();
// In the monorepo, enable doing FS functions on all of embark (needed to access embark/node_modules)
embark = embark.replace(path.normalize('embark/packages/'), '');
const allowedRoots = [
dapp,
embark,
@ -66,6 +69,10 @@ function moveSync() {
return restrictPath(fs.moveSync, fs.moveSync, 2, arguments);
}
function symlink() {
return restrictPath(fs.symlink, fs.symlink, 2, arguments);
}
function appendFileSync() {
return restrictPath(fs.appendFileSync, fs.writeFileSync, 1, arguments);
}
@ -234,6 +241,7 @@ module.exports = {
removeSync,
stat,
statSync,
symlink,
tmpDir,
writeFile,
writeFileSync,

View File

@ -1,8 +1,6 @@
const VM = require('./vm');
const fs = require('../../core/fs');
const EmbarkJS = require('embarkjs');
const IpfsApi = require("ipfs-api");
const Web3 = require('web3');
class CodeRunner {
constructor(embark, options) {
@ -15,8 +13,6 @@ class CodeRunner {
this.ipc = options.ipc;
this.vm = new VM({
sandbox: {
IpfsApi,
Web3,
EmbarkJS
},
require: {
@ -56,7 +52,7 @@ class CodeRunner {
this.events.on("runcode:init-console-code:updated", (code, cb) => {
this.evalCode(code, (err, _result) => {
if(err) {
this.logger.error("Error running init console code: ", err);
this.logger.error("Error running init console code: ", err.message || err);
}
else if(code.includes("EmbarkJS.Blockchain.setProvider")) {
this.events.emit('runcode:blockchain:connected');
@ -69,7 +65,7 @@ class CodeRunner {
this.events.on("runcode:embarkjs-code:updated", (code, cb) => {
this.evalCode(code, (err, _result) => {
if(err) {
this.logger.error("Error running embarkjs code: ", err);
this.logger.error("Error running embarkjs code: ", err.message || err);
}
cb();
});
@ -124,7 +120,7 @@ class CodeRunner {
if (err) {
return cb(err);
}
cb(null, result);
});
}

View File

@ -3,6 +3,7 @@ import { Callback, Logger } from "embark";
import { NodeVM, NodeVMOptions } from "vm2";
const fs = require("../../core/fs");
const path = require("path");
const { recursiveMerge, isEs6Module, compact } = require("../../utils/utils");
const WEB3_INVALID_RESPONSE_ERROR: string = "Invalid JSON RPC response";

View File

@ -1,6 +1,7 @@
let async = require('async');
const utils = require('../../utils/utils.js');
const constants = require('../../constants');
const path = require('path');
require('ejs');
const Templates = {
@ -33,11 +34,7 @@ class CodeGenerator {
this.events = embark.events;
this.listenToCommands();
const self = this;
this.events.setCommandHandler("code-generator:embarkjs:build", (cb) => {
self.buildEmbarkJS(cb);
});
this.events.emit('code-generator:ready');
}
listenToCommands() {
@ -82,6 +79,14 @@ class CodeGenerator {
this.events.setCommandHandler('code-generator:embarkjs:init-provider-code', (cb) => {
cb(this.getInitProviderCode());
});
this.events.setCommandHandler('code-generator:symlink:generate', (...args) => {
this.generateSymlink(...args);
});
this.events.setCommandHandler("code-generator:embarkjs:build", (cb) => {
this.buildEmbarkJS(cb);
});
}
generateContracts(contractsList, useEmbarkJS, isDeployment, useLoader) {
@ -146,21 +151,21 @@ class CodeGenerator {
warnIfMetamask: this.blockchainConfig.isDev,
blockchainClient: this.blockchainConfig.ethereumClientName
};
this.generateArtifact(this.dappConfigs.blockchain, constants.dappConfig.blockchain, constants.dappConfig.dir);
this.generateArtifact(this.dappConfigs.blockchain, constants.dappArtifacts.blockchain, constants.dappArtifacts.dir);
}
generateStorageConfig(storageConfig) {
this.dappConfigs.storage = {
dappConnection: storageConfig.dappConnection
};
this.generateArtifact(this.dappConfigs.storage, constants.dappConfig.storage, constants.dappConfig.dir);
this.generateArtifact(this.dappConfigs.storage, constants.dappArtifacts.storage, constants.dappArtifacts.dir);
}
generateCommunicationConfig(communicationConfig) {
this.dappConfigs.communication = {
connection: communicationConfig.connection
};
this.generateArtifact(this.dappConfigs.communication, constants.dappConfig.communication, constants.dappConfig.dir);
this.generateArtifact(this.dappConfigs.communication, constants.dappArtifacts.communication, constants.dappArtifacts.dir);
}
generateArtifact(artifactInput, fileName, dirName, cb = () => {}) {
@ -198,6 +203,7 @@ class CodeGenerator {
return block;
}
generateCustomContractCode(contract) {
const customContractGeneratorPlugin = this.plugins.getPluginsFor('customContractGeneration').splice(-1)[0];
if (!customContractGeneratorPlugin) {
@ -290,16 +296,30 @@ class CodeGenerator {
buildEmbarkJS(cb) {
const self = this;
let embarkjsCode = "import EmbarkJS from 'embarkjs';";
embarkjsCode += "\nexport default EmbarkJS;";
embarkjsCode += "\nglobal.EmbarkJS = EmbarkJS";
let code = "";
let embarkjsCode = '';
let code = "/* eslint-disable */";
async.waterfall([
function getImports(next) {
code += "\nimport IpfsApi from 'ipfs-api';\n";
next();
function getEmbarkJsLocation(next) {
self.events.request('version:downloadIfNeeded', 'embarkjs', (err, location) => {
if (err) {
this.logger.error(__('Error downloading EmbarkJS'));
return next(err);
}
next(null, location);
});
},
function generateSymlink(location, next) {
self.generateSymlink(location, 'embarkjs', (err, symlinkDest) => {
if (err) {
this.logger.error(__('Error creating a symlink to EmbarkJS'));
return next(err);
}
embarkjsCode += `\nconst EmbarkJS = require("${symlinkDest}").default;`;
embarkjsCode += "\nexport default EmbarkJS;";
embarkjsCode += "\nglobal.EmbarkJS = EmbarkJS";
next();
});
},
function getJSCode(next) {
code += "\n" + embarkjsCode + "\n";
@ -309,11 +329,12 @@ class CodeGenerator {
code += self.generateStorageInitialization(true);
code += self.generateNamesInitialization(true);
code += self.getReloadPageCode();
code += '\n/* eslint-enable */';
next();
},
function writeFile(next) {
self.generateArtifact(code, constants.dappConfig.embarkjs, '', next);
self.generateArtifact(code, constants.dappArtifacts.embarkjs, '', next);
}
], function(_err, _result) {
cb();
@ -352,13 +373,34 @@ class CodeGenerator {
}
buildContractJS(contractName, contractJSON, cb) {
let contractCode = "import EmbarkJS from 'Embark/EmbarkJS';\n";
let contractCode = "import EmbarkJS from '../embarkjs';\n";
contractCode += `let ${contractName}JSONConfig = ${JSON.stringify(contractJSON)};\n`;
contractCode += `let ${contractName} = new EmbarkJS.Blockchain.Contract(${contractName}JSONConfig);\n`;
contractCode += "export default " + contractName + ";\n";
this.generateArtifact(contractCode, contractName + '.js', constants.dappConfig.contractsJs, cb);
this.generateArtifact(contractCode, contractName + '.js', constants.dappArtifacts.contractsJs, cb);
}
generateSymlink(target, name, callback) {
const symlinkDir = this.fs.dappPath(this.embarkConfig.generationDir, constants.dappArtifacts.symlinkDir);
this.fs.mkdirp(symlinkDir, (err) => {
if (err) {
return callback(err);
}
const symlinkDest = utils.joinPath(symlinkDir, name).replace(/\\/g, '/');
this.fs.remove(symlinkDest, (err) => {
if (err) {
return callback(err);
}
this.fs.symlink(path.dirname(target), symlinkDest, 'junction', (err) => {
if (err) {
return callback(err);
}
callback(null, symlinkDest);
});
});
});
}
}

View File

@ -1,4 +1,4 @@
const namehash = require('eth-ens-namehash');
/*global namehash*/
// Price of ENS registration contract functions
const ENS_GAS_PRICE = 700000;
@ -7,10 +7,11 @@ const reverseAddressSuffix = '.addr.reverse';
const NoDecodeAddrErr = 'Error: Couldn\'t decode address from ABI: 0x';
const NoDecodeStringErr = 'ERROR: The returned value is not a convertible string: 0x0';
function registerSubDomain(web3, ens, registrar, resolver, defaultAccount, subdomain, rootDomain, reverseNode, address, logger, secureSend, callback) {
const subnode = namehash.hash(subdomain);
const rootNode = namehash.hash(rootDomain);
const node = namehash.hash(`${subdomain}.${rootDomain}`);
function registerSubDomain(web3, ens, registrar, resolver, defaultAccount, subdomain, rootDomain, reverseNode, address, logger, secureSend, callback, _namehash) {
_namehash = _namehash || namehash;
const subnode = _namehash.hash(subdomain);
const rootNode = _namehash.hash(rootDomain);
const node = _namehash.hash(`${subdomain}.${rootDomain}`);
// FIXME Registrar calls a function in ENS and in privatenet it doesn't work for soem reason
// const toSend = registrar.methods.register(subnode, defaultAccount);
const toSend = ens.methods.setSubnodeOwner(rootNode, subnode, defaultAccount);
@ -75,8 +76,9 @@ function lookupAddress(address, ens, utils, createResolverContract, callback) {
});
}
function resolveName(name, ens, createResolverContract, callback) {
let node = namehash.hash(name);
function resolveName(name, ens, createResolverContract, callback, _namehash) {
_namehash = _namehash || namehash;
let node = _namehash.hash(name);
function cb(err, addr) {
if (err === NoDecodeAddrErr) {

View File

@ -1,7 +1,5 @@
/* global EmbarkJS Web3 namehash registerSubDomain require */
const {callbackify} = require('util');
const __embarkENS = {};
// resolver interface
@ -217,7 +215,10 @@ __embarkENS.resolve = function (name, callback) {
};
if (callback) {
return callbackify(resolve)(name, callback);
resolve(name).then((result) => {
callback(null, result);
}).catch(callback);
return;
}
return resolve(name);
};
@ -257,7 +258,10 @@ __embarkENS.lookup = function (address, callback) {
};
if (callback) {
return callbackify(lookup)(address, callback);
lookup(address).then((result) => {
callback(null, result);
}).catch(callback);
return;
}
return lookup(address);
};

View File

@ -294,7 +294,7 @@ class ENS {
registerSubDomain(defaultAccount, subDomainName, reverseNode, address, secureSend, cb) {
this.events.request("blockchain:get", (web3) => {
ENSFunctions.registerSubDomain(web3, this.ensContract, this.registrarContract, this.resolverContract, defaultAccount,
subDomainName, this.registration.rootDomain, reverseNode, address, this.logger, secureSend, cb);
subDomainName, this.registration.rootDomain, reverseNode, address, this.logger, secureSend, cb, namehash);
});
}
@ -320,7 +320,7 @@ class ENS {
(req, res) => {
async.waterfall([
function (callback) {
ENSFunctions.resolveName(req.query.name, self.ensContract, createInternalResolverContract.bind(self), callback);
ENSFunctions.resolveName(req.query.name, self.ensContract, createInternalResolverContract.bind(self), callback, namehash);
}
], function (error, address) {
if (error) {
@ -366,23 +366,29 @@ class ENS {
}
addENSToEmbarkJS() {
const self = this;
// get namehash, import it into file
self.events.request("version:get:eth-ens-namehash", function (EnsNamehashVersion) {
let currentEnsNamehashVersion = require('../../../../package.json').dependencies["eth-ens-namehash"];
if (EnsNamehashVersion !== currentEnsNamehashVersion) {
self.events.request("version:getPackageLocation", "eth-ens-namehash", EnsNamehashVersion, function (err, location) {
self.embark.registerImportFile("eth-ens-namehash", self.fs.dappPath(location));
});
this.events.request('version:downloadIfNeeded', 'eth-ens-namehash', (err, location) => {
if (err) {
this.logger.error(__('Error downloading NameHash'));
return this.logger.error(err.message || err);
}
this.events.once('code-generator:ready', () => {
this.events.request('code-generator:symlink:generate', location, 'eth-ens-namehash', (err, symlinkDest) => {
if (err) {
this.logger.error(__('Error creating a symlink to eth-ens-namehash'));
return this.logger.error(err.message || err);
}
this.events.emit('runcode:register', 'namehash', require('eth-ens-namehash'), () => {
let code = `\nconst namehash = global.namehash || require('${symlinkDest}');`;
code += this.fs.readFileSync(utils.joinPath(__dirname, 'ENSFunctions.js')).toString();
code += "\n" + this.fs.readFileSync(utils.joinPath(__dirname, 'embarkjs.js')).toString();
code += "\nEmbarkJS.Names.registerProvider('ens', __embarkENS);";
this.embark.addCodeToEmbarkJS(code);
});
});
});
});
let code = self.fs.readFileSync(utils.joinPath(__dirname, 'ENSFunctions.js')).toString();
code += "\n" + self.fs.readFileSync(utils.joinPath(__dirname, 'embarkjs.js')).toString();
code += "\nEmbarkJS.Names.registerProvider('ens', __embarkENS);";
this.embark.addCodeToEmbarkJS(code);
}
addSetProvider(config) {

View File

@ -11,6 +11,7 @@ class IPFS {
this.logger = embark.logger;
this.events = embark.events;
this.buildDir = options.buildDir;
this.embarkConfig = embark.config.embarkConfig;
this.storageConfig = embark.config.storageConfig;
this.namesystemConfig = embark.config.namesystemConfig;
this.embark = embark;
@ -20,7 +21,6 @@ class IPFS {
this.blockchainConfig = embark.config.blockchainConfig;
if (this.isIpfsStorageEnabledInTheConfig()) {
this.downloadIpfsApi();
this.setServiceCheck();
this.addStorageProviderToEmbarkJS();
this.addObjectToConsole();
@ -42,16 +42,17 @@ class IPFS {
}
}
downloadIpfsApi() {
const self = this;
self.events.request("version:get:ipfs-api", function(ipfsApiVersion) {
downloadIpfsApi(cb) {
this.events.request("version:get:ipfs-api", (ipfsApiVersion) => {
let currentIpfsApiVersion = require('../../../../package.json').dependencies["ipfs-api"];
if (ipfsApiVersion !== currentIpfsApiVersion) {
self.events.request("version:getPackageLocation", "ipfs-api", ipfsApiVersion, function(err, location) {
self.embark.registerImportFile("ipfs-api", self.fs.dappPath(location));
});
if (ipfsApiVersion === currentIpfsApiVersion) {
const nodePath = this.fs.embarkPath('node_modules');
const ipfsPath = require.resolve("ipfs-api", {paths: [nodePath]});
return cb(null, ipfsPath);
}
this.events.request("version:getPackageLocation", "ipfs-api", ipfsApiVersion, (err, location) => {
cb(err, this.fs.dappPath(location));
});
});
}
@ -100,11 +101,28 @@ class IPFS {
}
addStorageProviderToEmbarkJS() {
let code = "";
code += "\n" + this.fs.readFileSync(utils.joinPath(__dirname, 'embarkjs.js')).toString();
code += "\nEmbarkJS.Storage.registerProvider('ipfs', __embarkIPFS);";
this.events.request('version:downloadIfNeeded', 'ipfs-api', (err, location) => {
if (err) {
this.logger.error(__('Error downloading IPFS API'));
return this.logger.error(err.message || err);
}
this.events.once('code-generator:ready', () => {
this.events.request('code-generator:symlink:generate', location, 'ipfs-api', (err, symlinkDest) => {
if (err) {
this.logger.error(__('Error creating a symlink to IPFS API'));
return this.logger.error(err.message || err);
}
this.embark.addCodeToEmbarkJS(code);
this.events.emit('runcode:register', 'IpfsApi', require('ipfs-api'), () => {
let code = `\nconst IpfsApi = global.IpfsApi || require('${symlinkDest}');`;
code += "\n" + this.fs.readFileSync(utils.joinPath(__dirname, 'embarkjs.js')).toString();
code += "\nEmbarkJS.Storage.registerProvider('ipfs', __embarkIPFS);";
this.embark.addCodeToEmbarkJS(code);
});
});
});
});
}
addObjectToConsole() {

View File

@ -78,11 +78,28 @@ class LibraryManager {
}
}
downloadIfNeeded(packageName, cb) {
const wantedVersion = this.versions[packageName];
let installedVersion = require('../../../../package.json').dependencies[packageName];
if (!wantedVersion || wantedVersion === installedVersion) {
const nodePath = this.embark.fs.embarkPath('node_modules');
const packagePath = require.resolve(packageName, {paths: [nodePath]});
return cb(null, packagePath.replace(/\\/g, '/'));
}
// Download package
this.embark.events.request("version:getPackageLocation", packageName, wantedVersion, (err, location) => {
cb(err, this.embark.fs.dappPath(location).replace(/\\/g, '/'));
});
}
listenToCommandsToGetLibrary() {
let npm = new Npm({logger: this.embark.logger, useDashboard: this.useDashboard});
this.embark.events.setCommandHandler('version:getPackageLocation', (libName, version, cb) => {
npm.getPackageVersion(libName, version, cb);
});
this.embark.events.setCommandHandler('version:downloadIfNeeded', (libName, cb) => {
this.downloadIfNeeded(libName, cb);
});
this.embark.events.setCommandHandler('version:getPackagePath', (libName, version, cb) => {
cb(null, Npm.getPackagePath(libName, version));
});

View File

@ -25,7 +25,7 @@ class Pipeline {
this.useDashboard = options.useDashboard;
this.events.setCommandHandler('pipeline:build', (options, callback) => this.build(options, callback));
this.events.setCommandHandler('pipeline:build:contracts', callback => this.buildContracts(callback));
this.events.setCommandHandler('pipeline:build:contracts', callback => this.buildContracts([], callback));
this.fs.removeSync(this.buildDir);
let plugin = this.plugins.createPlugin('deployment', {});
@ -139,10 +139,10 @@ class Pipeline {
let self = this;
const importsList = {};
let placeholderPage;
const contractsDir = this.fs.dappPath(self.embarkConfig.generationDir, constants.dappConfig.contractsJs);
const contractsDir = this.fs.dappPath(self.embarkConfig.generationDir, constants.dappArtifacts.contractsJs);
if (!self.assetFiles || !Object.keys(self.assetFiles).length) {
return self.buildContracts(callback);
return self.buildContracts([], callback);
}
async.waterfall([
@ -153,9 +153,9 @@ class Pipeline {
}
self.events.request('placeholder:build', next);
},
(next) => self.buildContracts(next),
(next) => self.buildContracts(importsList, next),
function createImportList(next) {
importsList["Embark/EmbarkJS"] = self.fs.dappPath(self.embarkConfig.generationDir, constants.dappConfig.embarkjs);
importsList["Embark/EmbarkJS"] = self.fs.dappPath(self.embarkConfig.generationDir, constants.dappArtifacts.embarkjs);
importsList["Embark/contracts"] = contractsDir;
self.plugins.getPluginsProperty('imports', 'imports').forEach(importObject => {
@ -164,37 +164,6 @@ class Pipeline {
});
next();
},
function writeContracts(next) {
self.events.request('contracts:list', (_err, contracts) => {
self.fs.mkdirp(contractsDir, err => {
if (err) return next(err);
// Create a file index.js that requires all contract files
// Used to enable alternate import syntax:
// e.g. import {Token} from 'Embark/contracts'
// e.g. import * as Contracts from 'Embark/contracts'
let importsHelperFile = self.fs.createWriteStream(utils.joinPath(contractsDir, 'index.js'));
importsHelperFile.write('module.exports = {\n');
async.eachOf(contracts, (contract, idx, eachCb) => {
self.events.request('code-generator:contract', contract.className, (err, contractPath) => {
if (err) {
return eachCb(err);
}
importsList["Embark/contracts/" + contract.className] = contractPath;
// add the contract to the exports list to support alternate import syntax
importsHelperFile.write(`"${contract.className}": require('./${contract.className}').default`);
if (idx < contracts.length - 1) importsHelperFile.write(',\n'); // add a comma if we have more contracts to add
eachCb();
});
}, () => {
importsHelperFile.write('\n}'); // close the module.exports = {}
importsHelperFile.close(next); // close the write stream
});
});
});
},
function shouldRunWebpack(next) {
// assuming we got here because an asset was changed, let's check our webpack config
// to see if the changed asset requires webpack to run
@ -350,7 +319,7 @@ class Pipeline {
], callback);
}
buildContracts(cb) {
buildContracts(importsList, cb) {
const self = this;
async.waterfall([
function makeDirectory(next) {
@ -365,7 +334,37 @@ class Pipeline {
self.buildDir,
'contracts', contract.className + '.json'
), contract, {spaces: 2}, eachCb);
}, () => next());
}, () => next(null, contracts));
},
function writeContractJS(contracts, next) {
const contractsDir = self.fs.dappPath(self.embarkConfig.generationDir, constants.dappArtifacts.contractsJs);
self.fs.mkdirp(contractsDir, err => {
if (err) return next(err);
// Create a file index.js that requires all contract files
// Used to enable alternate import syntax:
// e.g. import {Token} from 'Embark/contracts'
// e.g. import * as Contracts from 'Embark/contracts'
let importsHelperFile = self.fs.createWriteStream(utils.joinPath(contractsDir, 'index.js'));
importsHelperFile.write('module.exports = {\n');
async.eachOf(contracts, (contract, idx, eachCb) => {
self.events.request('code-generator:contract', contract.className, (err, contractPath) => {
if (err) {
return eachCb(err);
}
importsList["Embark/contracts/" + contract.className] = contractPath;
// add the contract to the exports list to support alternate import syntax
importsHelperFile.write(`"${contract.className}": require('./${contract.className}').default`);
if (idx < contracts.length - 1) importsHelperFile.write(',\n'); // add a comma if we have more contracts to add
eachCb();
});
}, () => {
importsHelperFile.write('\n}'); // close the module.exports = {}
importsHelperFile.close(next); // close the write stream
});
});
}
], cb);
}

View File

@ -36,7 +36,8 @@ describe('embark.CodeGenerator', function() {
},
setCommandHandler: () => {
},
on: () => {}
on: () => {},
emit: () => {}
};
let generator = new CodeGenerator({config: {blockchainConfig: {}}, events: TestEvents}, {});

View File

@ -1,9 +1,7 @@
/*globals describe, it*/
const {File, Types} = require("../lib/core/file");
const path = require("path");
const {expect} = require("chai");
const fs = require("../lib/core/fs");
const fsNode = require("fs");
describe('embark.File', function () {
describe('Read file contents', function () {
@ -11,8 +9,7 @@ describe('embark.File', function () {
const file = new File({externalUrl: 'https://raw.githubusercontent.com/embark-framework/embark/master/test_dapps/test_app/app/contracts/simple_storage.sol', type: Types.http});
const content = await file.content;
const contentFromFileSystem = fsNode.readFileSync(path.join(fs.embarkPath(), "../../", "test_dapps/test_app/app/contracts/simple_storage.sol")).toString();
expect(content).to.equal(contentFromFileSystem);
expect(content).to.be.ok; //eslint-disable-line
});
it('should be able to read a file when type is "dappFile"', async () => {

View File

@ -43,8 +43,7 @@ describe('fs', () => {
const paths = [
'/etc',
'/home/testuser/src',
'/usr',
'../'
'/usr'
];
for(let func in fs) {

View File

@ -1,9 +1,6 @@
/* global ethereum */
import {reduce} from './async';
import nodeUtil from 'util';
const {callbackify} = nodeUtil;
let Blockchain = {
list: [],
@ -42,7 +39,10 @@ Blockchain.connect = function(options, callback) {
};
if (callback) {
return callbackify(connect)(options, callback);
connect(options).then((result) => {
callback(null, result);
}).catch(callback);
return;
}
return connect(options);
};

View File

@ -28,6 +28,17 @@ function getWeb3Location(embark) {
});
}
function generateSymlink(embark, location) {
return new Promise((resolve, reject) => {
embark.events.request('code-generator:symlink:generate', location, 'web3', (err, symlinkDest) => {
if (err) {
return reject(err);
}
resolve(symlinkDest);
});
});
}
module.exports = async (embark) => {
let blockchainConnectorReady = false;
await whenRuncodeReady(embark);
@ -52,26 +63,27 @@ module.exports = async (embark) => {
web3Location = web3Location.replace(/\\/g, '/');
embark.events.emit('runcode:register', '__Web3', require(web3Location), async () => {
const symlinkLocation = await generateSymlink(embark, web3Location);
embark.events.emit('runcode:register', '__Web3', require(web3Location));
let code = `\nconst Web3 = global.__Web3 || require('${symlinkLocation}');`;
code += `\nglobal.Web3 = Web3;`;
let code = `\nconst Web3 = global.__Web3 || require('${web3Location}');`;
code += `\nglobal.Web3 = Web3;`;
const connectorCode = fs.readFileSync(path.join(__dirname, 'web3Connector.js'), 'utf8');
code += connectorCode;
const connectorCode = fs.readFileSync(path.join(__dirname, 'web3Connector.js'), 'utf8');
code += connectorCode;
code += "\nEmbarkJS.Blockchain.registerProvider('web3', web3Connector);";
code += "\nEmbarkJS.Blockchain.registerProvider('web3', web3Connector);";
code += "\nEmbarkJS.Blockchain.setProvider('web3', {});";
code += "\nEmbarkJS.Blockchain.setProvider('web3', {});";
embark.addCodeToEmbarkJS(code);
embark.addCodeToEmbarkJS(code);
code = "EmbarkJS.Blockchain.setProvider('web3', {web3});";
code = "EmbarkJS.Blockchain.setProvider('web3', {web3});";
const shouldInit = (_config) => {
return true;
};
const shouldInit = (_config) => {
return true;
};
embark.addConsoleProviderInit('blockchain', code, shouldInit);
embark.addConsoleProviderInit('blockchain', code, shouldInit);
});
};