diff --git a/packages/colony-js-adapter-ethers/src/EthersAdapter.js b/packages/colony-js-adapter-ethers/src/EthersAdapter.js index a129eba7a..7d0df7c7f 100644 --- a/packages/colony-js-adapter-ethers/src/EthersAdapter.js +++ b/packages/colony-js-adapter-ethers/src/EthersAdapter.js @@ -13,13 +13,15 @@ import type { Signature, Transaction, } from '@colony/colony-js-adapter'; -import type { IContractLoader, Query } from '@colony/colony-js-contract-loader'; +import type { Query } from '@colony/colony-js-contract-loader'; + +import ContractLoader from '@colony/colony-js-contract-loader'; -import EthersContract from './EthersContract'; import type { ConstructorArgs } from './flowtypes'; +import EthersContract from './EthersContract'; export default class EthersAdapter implements IAdapter { - loader: IContractLoader; + loader: ContractLoader; provider: IProvider; wallet: IWallet; static getEventPromises({ diff --git a/packages/colony-js-adapter-ethers/src/flowtypes.js b/packages/colony-js-adapter-ethers/src/flowtypes.js index fd159ec3a..e7d902995 100644 --- a/packages/colony-js-adapter-ethers/src/flowtypes.js +++ b/packages/colony-js-adapter-ethers/src/flowtypes.js @@ -1,10 +1,10 @@ /* @flow */ import type { Event, IProvider, IWallet } from '@colony/colony-js-adapter'; -import type { IContractLoader } from '@colony/colony-js-contract-loader'; +import ContractLoader from '@colony/colony-js-contract-loader'; export type ConstructorArgs = { - loader: IContractLoader, + loader: ContractLoader, provider: IProvider, wallet: IWallet, }; diff --git a/packages/colony-js-adapter/interface/Adapter.js b/packages/colony-js-adapter/interface/Adapter.js index 0d7524671..92780c1fd 100644 --- a/packages/colony-js-adapter/interface/Adapter.js +++ b/packages/colony-js-adapter/interface/Adapter.js @@ -1,7 +1,6 @@ /* @flow */ -import type { IContractLoader, Query } from '@colony/colony-js-contract-loader'; - +import type { Query } from '@colony/colony-js-contract-loader'; import type { Contract } from './Contract'; import type { EventHandlers } from './EventHandlers'; import type { Provider } from './Provider'; @@ -10,8 +9,10 @@ import type { Transaction } from './Transaction'; import type { TransactionReceipt } from './TransactionReceipt'; import type { Wallet } from './Wallet'; +import ContractLoader from '@colony/colony-js-contract-loader'; + export interface Adapter { - loader: IContractLoader; + loader: ContractLoader; provider: Provider; wallet: Wallet; ecRecover(digest: Array, signature: Signature): string; diff --git a/packages/colony-js-client/package.json b/packages/colony-js-client/package.json index 88a055f09..88df4a6b1 100644 --- a/packages/colony-js-client/package.json +++ b/packages/colony-js-client/package.json @@ -46,9 +46,9 @@ "@colony/colony-js-contract-client": "^1.2.1", "@colony/colony-js-contract-loader": "^1.2.1", "@colony/colony-js-utils": "^1.2.1", + "assert": "^1.4.1", "babel-runtime": "^6.26.0", "bn.js": "^4.11.6", - "browser-assert": "^1.2.1", "web3-utils": "^1.0.0-beta.34" }, "engines": { diff --git a/packages/colony-js-client/src/ColonyClient/callers/GetTask.js b/packages/colony-js-client/src/ColonyClient/callers/GetTask.js index 8464adc08..132eb14c5 100644 --- a/packages/colony-js-client/src/ColonyClient/callers/GetTask.js +++ b/packages/colony-js-client/src/ColonyClient/callers/GetTask.js @@ -1,7 +1,7 @@ /* @flow */ /* eslint-disable no-underscore-dangle */ -import assert from 'browser-assert'; +import assert from 'assert'; import BigNumber from 'bn.js'; import ContractClient from '@colony/colony-js-contract-client'; import { isBigNumber } from '@colony/colony-js-utils'; diff --git a/packages/colony-js-client/src/ColonyClient/index.js b/packages/colony-js-client/src/ColonyClient/index.js index c8b74cb43..fa771180c 100644 --- a/packages/colony-js-client/src/ColonyClient/index.js +++ b/packages/colony-js-client/src/ColonyClient/index.js @@ -1,6 +1,6 @@ /* @flow */ -import assert from 'browser-assert'; +import assert from 'assert'; import type BigNumber from 'bn.js'; diff --git a/packages/colony-js-client/src/ColonyNetworkClient/index.js b/packages/colony-js-client/src/ColonyNetworkClient/index.js index d8022214c..0a8655edc 100644 --- a/packages/colony-js-client/src/ColonyNetworkClient/index.js +++ b/packages/colony-js-client/src/ColonyNetworkClient/index.js @@ -1,6 +1,6 @@ /* @flow */ -import assert from 'browser-assert'; +import assert from 'assert'; import { utf8ToHex } from 'web3-utils'; import { isValidAddress } from '@colony/colony-js-utils'; import BigNumber from 'bn.js'; diff --git a/packages/colony-js-contract-client/package.json b/packages/colony-js-contract-client/package.json index 554856030..2f4600363 100644 --- a/packages/colony-js-contract-client/package.json +++ b/packages/colony-js-contract-client/package.json @@ -44,9 +44,9 @@ "@colony/colony-js-adapter": "^1.2.1", "@colony/colony-js-contract-loader": "^1.2.1", "@colony/colony-js-utils": "^1.2.1", + "assert": "^1.4.1", "babel-runtime": "^6.26.0", "bn.js": "^4.11.6", - "browser-assert": "^1.2.1", "bs58": "^4.0.1", "lodash.isequal": "^4.5.0", "lodash.isplainobject": "^4.0.6", diff --git a/packages/colony-js-contract-client/src/__tests__/MultisigOperation.js b/packages/colony-js-contract-client/src/__tests__/MultisigOperation.js index 1049be739..7aed83d1b 100644 --- a/packages/colony-js-contract-client/src/__tests__/MultisigOperation.js +++ b/packages/colony-js-contract-client/src/__tests__/MultisigOperation.js @@ -2,7 +2,7 @@ /* eslint-disable no-underscore-dangle */ import createSandbox from 'jest-sandbox'; -import assert from 'browser-assert'; +import assert from 'assert'; import { hexToBytes, isAddress, @@ -16,7 +16,7 @@ import isEqual from 'lodash.isequal'; import MultisigOperation from '../classes/MultisigOperation'; -jest.mock('browser-assert', () => jest.fn().mockReturnValue(true)); +jest.mock('assert', () => jest.fn().mockReturnValue(true)); jest.mock('lodash.isplainobject', () => jest.fn().mockReturnValue(true)); diff --git a/packages/colony-js-contract-client/src/classes/ContractMethodMultisigSender.js b/packages/colony-js-contract-client/src/classes/ContractMethodMultisigSender.js index 1c6b4eb57..a2ec5d02e 100644 --- a/packages/colony-js-contract-client/src/classes/ContractMethodMultisigSender.js +++ b/packages/colony-js-contract-client/src/classes/ContractMethodMultisigSender.js @@ -1,6 +1,6 @@ /* @flow */ -import assert from 'browser-assert'; +import assert from 'assert'; import { isBigNumber, isValidAddress } from '@colony/colony-js-utils'; import type { TransactionOptions } from '@colony/colony-js-adapter'; diff --git a/packages/colony-js-contract-client/src/classes/MultisigOperation.js b/packages/colony-js-contract-client/src/classes/MultisigOperation.js index 8af84b6d6..3503af0be 100644 --- a/packages/colony-js-contract-client/src/classes/MultisigOperation.js +++ b/packages/colony-js-contract-client/src/classes/MultisigOperation.js @@ -2,7 +2,7 @@ /* eslint-disable no-underscore-dangle */ import { padLeft, soliditySha3, isHexStrict, hexToBytes } from 'web3-utils'; -import defaultAssert from 'browser-assert'; +import defaultAssert from 'assert'; import { isValidAddress, makeAssert } from '@colony/colony-js-utils'; import isPlainObject from 'lodash.isplainobject'; import isEqual from 'lodash.isequal'; diff --git a/packages/colony-js-contract-loader-fs/README.md b/packages/colony-js-contract-loader-fs/README.md new file mode 100644 index 000000000..c7fd982b8 --- /dev/null +++ b/packages/colony-js-contract-loader-fs/README.md @@ -0,0 +1,23 @@ +# colonyJS Contract Loader for Node.js using the filesystem + +This package provides a means to load Ethereum smart contracts simply via +the node `fs` module, for local testing and in dev environments + +## Installation + +``` +yarn add @colony/colony-js-contract-loader-fs +``` + + +## Usage + +// TODO DOCS +Please see [the full documentation](https://joincolony.github.io/colonyjs/api-loaders/#INSERTCORRECTANCHORHERE). + + +## Contributing + +This package is part of the [colonyJS monorepo](https://github.com/JoinColony/colonyJS). + +Please read our [contributing guidelines](https://github.com/JoinColony/colonyJS/blob/master/CONTRIBUTING.md). diff --git a/packages/colony-js-contract-loader-fs/jest.conf.json b/packages/colony-js-contract-loader-fs/jest.conf.json new file mode 100644 index 000000000..a4aa067b4 --- /dev/null +++ b/packages/colony-js-contract-loader-fs/jest.conf.json @@ -0,0 +1,10 @@ +{ + "rootDir": "src", + "collectCoverageFrom" : ["*.{js}", "**/*.{js}"], + "coverageDirectory": "../coverage", + "coverageThreshold": { + "global": { + "branches": 0 + } + } + } diff --git a/packages/colony-js-contract-loader-fs/package.json b/packages/colony-js-contract-loader-fs/package.json new file mode 100644 index 000000000..52257eda5 --- /dev/null +++ b/packages/colony-js-contract-loader-fs/package.json @@ -0,0 +1,59 @@ +{ + "name": "@colony/colony-js-contract-loader-fs", + "version": "1.0.0", + "description": "Load Ethereum smart contract definitions/metadata from the filesystem (in node.js)", + "main": "lib/index.js", + "files": [ + "lib", + "README.md" + ], + "scripts": { + "build": "yarn run build:flow && yarn run build:lib", + "build:flow": "flow-copy-source src lib --ignore '__tests__/*.js'", + "build:lib": "flow-remove-types --out-dir lib/ src/", + "dev": "nodemon", + "flow": "flow check", + "lint": "eslint src", + "precommit": "lint-staged", + "test": "yarn run flow && yarn run lint && yarn run test:unit", + "test:unit": "jest --coverage --config=jest.conf.json" + }, + "lint-staged": { + "src/{,**/}*.js": [ + "lint --fix", + "git add" + ] + }, + "repository": { + "type": "git", + "url": "git+https://github.com/JoinColony/colonyJS.git" + }, + "contributors": [ + "Christian Maniewski ", + "Griffin Hotchkiss ", + "James Lefrère ", + "Jan Kaßel ", + "Raul Glogovetan " + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/JoinColony/colonyJS/issues" + }, + "homepage": "https://github.com/JoinColony/colonyJS#readme", + "dependencies": { + "@colony/colony-js-contract-loader": "^1.2.0", + "jsonfile": "^4.0.0" + }, + "devDependencies": { + "flow-bin": "^0.72.0", + "flow-copy-source": "^2.0.0", + "flow-remove-types": "^1.2.3", + "jest": "^22.4.0", + "jest-sandbox": "^1.1.2", + "nodemon": "^1.17.5" + }, + "engines": { + "node": ">=8.2.1", + "yarn": ">=1.3.2" + } +} diff --git a/packages/colony-js-contract-loader-fs/src/__tests__/index.js b/packages/colony-js-contract-loader-fs/src/__tests__/index.js new file mode 100644 index 000000000..3793e36d6 --- /dev/null +++ b/packages/colony-js-contract-loader-fs/src/__tests__/index.js @@ -0,0 +1,44 @@ +/* eslint-env jest */ +/* eslint no-underscore-dangle: 0 */ + +import createSandbox from 'jest-sandbox'; +import FSLoader from '../loaders/FSLoader'; + +jest.mock('jsonfile', () => ({ + readFile: jest.fn((file, cb) => + cb(null, { + address: '0x123', + abi: [{ myData: 123 }], + }), + ), +})); + +describe('ContractFsLoader', () => { + const sandbox = createSandbox(); + const setupLoader = () => new FSLoader({ contractDir: '/tmp' }); + + const requiredProps = { + address: true, + abi: true, + bytecode: false, + }; + + beforeEach(() => { + sandbox.clear(); + }); + + test('Default implementation', async () => { + const loader = setupLoader(); + + const query = { contractName: 'MyCoolContract' }; + const { address, abi } = await loader.load(query, requiredProps); + expect(address).toEqual('0x123'); + expect(abi).toEqual([{ myData: 123 }]); + }); + + test('Throws if contract name not given', async () => { + const loader = setupLoader(); + const query = { contractAddress: '0xdeafbeef' }; + expect(loader.load(query, requiredProps)).rejects.toThrow(); + }); +}); diff --git a/packages/colony-js-contract-loader-fs/src/flowtypes.js b/packages/colony-js-contract-loader-fs/src/flowtypes.js new file mode 100644 index 000000000..32230d2ff --- /dev/null +++ b/packages/colony-js-contract-loader-fs/src/flowtypes.js @@ -0,0 +1,18 @@ +/* @flow */ + +import type { Transform } from '@colony/colony-js-contract-loader'; + +export type ConstructorArgs = { + contractDir: string, + transform: Transform, +}; + +export type TruffleArtifact = { + abi: Array<{}>, + bytecode: string, + networks: { + [networkId: number]: { + address: string, + }, + }, +}; diff --git a/packages/colony-js-contract-loader-fs/src/index.js b/packages/colony-js-contract-loader-fs/src/index.js new file mode 100644 index 000000000..2c24f9b79 --- /dev/null +++ b/packages/colony-js-contract-loader-fs/src/index.js @@ -0,0 +1,7 @@ +/* @flow */ + +const TruffleLoader = require('./loaders/TruffleLoader'); +const FSLoader = require('./loaders/FSLoader'); + +exports.TruffleLoader = TruffleLoader; +exports.FSLoader = FSLoader; diff --git a/packages/colony-js-contract-loader-fs/src/loaders/FSLoader.js b/packages/colony-js-contract-loader-fs/src/loaders/FSLoader.js new file mode 100644 index 000000000..22a2315c9 --- /dev/null +++ b/packages/colony-js-contract-loader-fs/src/loaders/FSLoader.js @@ -0,0 +1,53 @@ +/* @flow */ + +import type { + ContractDefinition, + IContractLoader, + RequiredContractProps, + Query, +} from '@colony/colony-js-contract-loader'; + +import type { ConstructorArgs } from '../flowtypes'; + +const assert = require('assert'); +const path = require('path'); +const jsonfile = require('jsonfile'); + +const ContractLoader = require('@colony/colony-js-contract-loader').default; + +class FSLoader extends ContractLoader implements IContractLoader { + _contractDir: string; + + constructor({ contractDir, transform }: ConstructorArgs = {}) { + super({ transform }); + assert( + typeof contractDir === 'string' && contractDir, + 'A `contractDir` option must be provided', + ); + this._contractDir = contractDir; + } + async _load( + query: Query = {}, + requiredProps?: RequiredContractProps, + ): Promise { + const { contractName = '' } = query; + + assert(!!contractName, 'A `contractName` option must be provided'); + + const file = path.resolve(this._contractDir, `${contractName}.json`); + return new Promise((resolve, reject) => { + jsonfile.readFile(file, (error, contents) => { + let transformed; + if (error) return reject(error); + try { + transformed = this._transform(contents, query, requiredProps); + } catch (transformError) { + return reject(transformError); + } + return resolve(transformed); + }); + }); + } +} + +module.exports = FSLoader; diff --git a/packages/colony-js-contract-loader-fs/src/loaders/TruffleLoader.js b/packages/colony-js-contract-loader-fs/src/loaders/TruffleLoader.js new file mode 100644 index 000000000..32c4c4133 --- /dev/null +++ b/packages/colony-js-contract-loader-fs/src/loaders/TruffleLoader.js @@ -0,0 +1,15 @@ +/* @flow */ + +import type { ConstructorArgs } from '../flowtypes'; + +const FSLoader = require('./FSLoader'); + +const { truffleTransform } = require('@colony/colony-js-contract-loader'); + +class TruffleLoader extends FSLoader { + constructor({ contractDir }: ConstructorArgs = {}) { + super({ transform: truffleTransform, contractDir }); + } +} + +module.exports = TruffleLoader; diff --git a/packages/colony-js-contract-loader-http/package.json b/packages/colony-js-contract-loader-http/package.json index 28a30f4ea..824da9320 100644 --- a/packages/colony-js-contract-loader-http/package.json +++ b/packages/colony-js-contract-loader-http/package.json @@ -44,8 +44,8 @@ "homepage": "https://github.com/JoinColony/colonyJS#readme", "dependencies": { "@colony/colony-js-contract-loader": "^1.2.1", + "assert": "^1.4.1", "babel-runtime": "^6.26.0", - "browser-assert": "^1.2.1", "isomorphic-fetch": "^2.2.1" }, "devDependencies": { diff --git a/packages/colony-js-contract-loader-http/src/__tests__/index.js b/packages/colony-js-contract-loader-http/src/__tests__/index.js index dfca79040..b83a1c9b3 100644 --- a/packages/colony-js-contract-loader-http/src/__tests__/index.js +++ b/packages/colony-js-contract-loader-http/src/__tests__/index.js @@ -2,7 +2,7 @@ /* eslint no-underscore-dangle: 0 */ import createSandbox from 'jest-sandbox'; -import ContractHttpLoader from '../loaders/ContractHttpLoader'; +import ContractHttpLoader from '../loaders/HttpLoader'; import TrufflepigLoader from '../loaders/TrufflepigLoader'; import EtherscanLoader from '../loaders/EtherscanLoader'; import MetaCoin from '../__mocks__/MetaCoin.json'; diff --git a/packages/colony-js-contract-loader-http/src/flowtypes.js b/packages/colony-js-contract-loader-http/src/flowtypes.js index fc2554e90..d9a2cee19 100644 --- a/packages/colony-js-contract-loader-http/src/flowtypes.js +++ b/packages/colony-js-contract-loader-http/src/flowtypes.js @@ -6,13 +6,3 @@ export type ConstructorArgs = { endpoint: string, transform: Transform, }; - -export type TruffleArtifact = { - abi: Array<{}>, - bytecode: string, - networks: { - [networkId: number]: { - address: string, - }, - }, -}; diff --git a/packages/colony-js-contract-loader-http/src/index.js b/packages/colony-js-contract-loader-http/src/index.js index 14d53d7f2..c367fe3b0 100644 --- a/packages/colony-js-contract-loader-http/src/index.js +++ b/packages/colony-js-contract-loader-http/src/index.js @@ -1,8 +1,5 @@ /* @flow */ -import ContractHttpLoader from './loaders/ContractHttpLoader'; -import EtherscanLoader from './loaders/EtherscanLoader'; -import TrufflepigLoader from './loaders/TrufflepigLoader'; - -export default ContractHttpLoader; -export { ContractHttpLoader, EtherscanLoader, TrufflepigLoader }; +export { default as HttpLoader } from './loaders/HttpLoader'; +export { default as EtherscanLoader } from './loaders/EtherscanLoader'; +export { default as TrufflepigLoader } from './loaders/TrufflepigLoader'; diff --git a/packages/colony-js-contract-loader-http/src/loaders/EtherscanLoader.js b/packages/colony-js-contract-loader-http/src/loaders/EtherscanLoader.js index af83e5b08..0bc743313 100644 --- a/packages/colony-js-contract-loader-http/src/loaders/EtherscanLoader.js +++ b/packages/colony-js-contract-loader-http/src/loaders/EtherscanLoader.js @@ -2,7 +2,7 @@ import type { Query } from '@colony/colony-js-contract-loader'; -import ContractHttpLoader from './ContractHttpLoader'; +import HttpLoader from './HttpLoader'; import type { ConstructorArgs } from '../flowtypes'; @@ -44,7 +44,7 @@ function etherscanTransform(response: any, query?: Query = {}) { return parsed; } -export default class EtherscanLoader extends ContractHttpLoader { +export default class EtherscanLoader extends HttpLoader { constructor({ transform = etherscanTransform, endpoint = DEFAULT_ENDPOINT, diff --git a/packages/colony-js-contract-loader-http/src/loaders/HttpLoader.js b/packages/colony-js-contract-loader-http/src/loaders/HttpLoader.js new file mode 100644 index 000000000..a3a0d1ae2 --- /dev/null +++ b/packages/colony-js-contract-loader-http/src/loaders/HttpLoader.js @@ -0,0 +1,83 @@ +/* @flow */ + +import assert from 'assert'; +import 'isomorphic-fetch'; +import ContractLoader from '@colony/colony-js-contract-loader'; + +import type { + ContractDefinition, + IContractLoader, + RequiredContractProps, + Query, +} from '@colony/colony-js-contract-loader'; + +import type { ConstructorArgs } from '../flowtypes'; + +export default class HttpLoader extends ContractLoader + implements IContractLoader { + _endpoint: string; + + constructor({ endpoint, transform }: ConstructorArgs = {}) { + super({ transform }); + assert( + typeof endpoint === 'string' && endpoint, + 'An `endpoint` option must be provided', + ); + this._endpoint = endpoint; + } + resolveEndpointResource({ + contractName, + contractAddress, + version, + }: Query): string { + return ( + this._endpoint + .replace('%%NAME%%', contractName || '') + .replace('%%ADDRESS%%', contractAddress || '') + // `version` can be a string or an integer + .replace( + '%%VERSION%%', + version != null && + (typeof version === 'string' || + Number(parseInt(version, 10)) === version) + ? version.toString() + : '', + ) + ); + } + async _load( + query: Query = {}, + requiredProps?: RequiredContractProps, + ): Promise { + // Provide some context for errors thrown by lower-level functions + const throwError = (action: string, error: any) => { + throw new Error( + `Unable to ${action} for contract ${query.contractName || + query.contractAddress || + ''}: ${error.message || error}`, + ); + }; + + let response; + try { + response = await fetch(this.resolveEndpointResource(query)); + } catch (error) { + throwError('fetch resource', error); + } + + let json; + try { + json = response && response.json && (await response.json()); + } catch (error) { + throwError('get JSON', error); + } + + let contractDef; + try { + contractDef = this._transform(json, query, requiredProps); + } catch (error) { + throwError('transform contract definition', error); + } + return contractDef; + } +} diff --git a/packages/colony-js-contract-loader-http/src/loaders/TrufflepigLoader.js b/packages/colony-js-contract-loader-http/src/loaders/TrufflepigLoader.js index 108b51f4f..84920d253 100644 --- a/packages/colony-js-contract-loader-http/src/loaders/TrufflepigLoader.js +++ b/packages/colony-js-contract-loader-http/src/loaders/TrufflepigLoader.js @@ -1,50 +1,21 @@ /* @flow */ import 'isomorphic-fetch'; -import type { Query } from '@colony/colony-js-contract-loader'; +import { truffleTransform } from '@colony/colony-js-contract-loader'; -import ContractHttpLoader from './ContractHttpLoader'; +import type { ConstructorArgs } from '../flowtypes'; -import type { TruffleArtifact, ConstructorArgs } from '../flowtypes'; +import HttpLoader from './HttpLoader'; const DEFAULT_HOST = 'http://127.0.0.1:3030'; const DEFAULT_ENDPOINT = `${DEFAULT_HOST}/contracts?name=%%NAME%%&address=%%ADDRESS%%&version=%%VERSION%%`; // eslint-disable-line max-len -function trufflepigTransform( - { abi = [], bytecode, networks = {} }: TruffleArtifact = {}, - { networkId }: Query = {}, -) { - let address; - - const networkIds = Object.keys(networks); - - if (networkId && networkIds.length) { - if (!networks[networkId]) - throw new Error(`Network ID ${networkId} not found in contract`); - ({ address } = networks[networkId]); - } else { - // Pick the last network (assumed to be the most recent) - ({ address } = - networks[parseInt(networkIds[networkIds.length - 1], 10)] || {}); - } - - return { - abi, - address, - bytecode, - }; -} - -export default class TrufflepigLoader extends ContractHttpLoader { +export default class TrufflepigLoader extends HttpLoader { _host: string; - constructor({ - transform = trufflepigTransform, - endpoint = DEFAULT_ENDPOINT, - ...rest - }: ConstructorArgs = {}) { - super({ transform, endpoint, ...rest }); + constructor({ endpoint = DEFAULT_ENDPOINT }: ConstructorArgs = {}) { + super({ transform: truffleTransform, endpoint }); const [host] = this._endpoint.split('/contracts'); this._host = host; } diff --git a/packages/colony-js-contract-loader/package.json b/packages/colony-js-contract-loader/package.json index 18bd53b46..f7385b63d 100644 --- a/packages/colony-js-contract-loader/package.json +++ b/packages/colony-js-contract-loader/package.json @@ -2,10 +2,9 @@ "name": "@colony/colony-js-contract-loader", "version": "1.2.1", "description": "Contract loader interfaces", - "main": "index.js", + "main": "lib/index.js", "files": [ - "interface", - "index.js", + "lib", "README.md" ], "repository": { @@ -13,9 +12,13 @@ "url": "git+https://github.com/JoinColony/colonyJS.git" }, "scripts": { - "lint": "eslint ./{,interface/}*.js", - "precommit": "lint-staged", - "prepublish": "yarn run precommit" + "build": "yarn run clean && yarn run build:lib && yarn run build:flow", + "build:flow": "flow-copy-source src lib --ignore '__tests__/*.js'", + "build:lib": "babel src --out-dir lib --ignore __tests__ --source-maps", + "clean": "shx rm -rf lib", + "flow": "flow check", + "lint": "eslint src/{,**/}*.js", + "precommit": "lint-staged" }, "lint-staged": { "./{,interface/}*": [ @@ -33,10 +36,15 @@ }, "homepage": "https://github.com/JoinColony/colonyJS#readme", "devDependencies": { - "flow-bin": "^0.72.0" + "flow-bin": "^0.73.0", + "flow-copy-source": "^2.0.0" }, "engines": { "node": ">=8.2.1", "yarn": ">=1.3.2" + }, + "dependencies": { + "assert": "^1.4.1", + "babel-runtime": "^6.26.0" } } diff --git a/packages/colony-js-contract-loader-http/src/loaders/ContractHttpLoader.js b/packages/colony-js-contract-loader/src/ContractLoader.js similarity index 54% rename from packages/colony-js-contract-loader-http/src/loaders/ContractHttpLoader.js rename to packages/colony-js-contract-loader/src/ContractLoader.js index 8208db99b..348ce77d6 100644 --- a/packages/colony-js-contract-loader-http/src/loaders/ContractHttpLoader.js +++ b/packages/colony-js-contract-loader/src/ContractLoader.js @@ -1,18 +1,16 @@ /* @flow */ -import assert from 'browser-assert'; -import 'isomorphic-fetch'; - import type { ContractDefinition, - IContractLoader, + ConstructorArgs, Transform, RequiredContractProps, Query, -} from '@colony/colony-js-contract-loader'; +} from './interface/ContractLoader'; + +import { DEFAULT_REQUIRED_CONTRACT_PROPS } from './defaults'; -import type { ConstructorArgs } from '../flowtypes'; -import { DEFAULT_REQUIRED_CONTRACT_PROPS } from '../defaults'; +const assert = require('assert'); const validateField = (assertion, field) => assert( @@ -20,21 +18,20 @@ const validateField = (assertion, field) => `Invalid contract definition: ${field} is missing or invalid`, ); -export default class ContractHttpLoader implements IContractLoader { - _endpoint: string; +export default class ContractLoader { _transform: Transform; /** - * The default `transform` function is simply returns the JSON object as the + * The default `transform` function is simply returns the input object as the * default behaviour. */ static defaultTransform(): Transform { /* eslint-disable no-unused-vars */ return ( - jsonObj: any, + inputObj: any, query?: Query, requiredProps?: RequiredContractProps, - ) => jsonObj; + ) => inputObj; /* eslint-enable no-unused-vars */ } @@ -68,74 +65,22 @@ export default class ContractHttpLoader implements IContractLoader { return true; } constructor({ - endpoint, transform = this.constructor.defaultTransform(), }: ConstructorArgs = {}) { - assert( - typeof endpoint === 'string', - 'An `endpoint` option must be provided', - ); assert( typeof transform === 'function', 'A `transform` function must be provided', ); - this._endpoint = endpoint; this._transform = transform; } - resolveEndpointResource({ - contractName, - contractAddress, - version, - }: Query): string { - return ( - this._endpoint - .replace('%%NAME%%', contractName || '') - .replace('%%ADDRESS%%', contractAddress || '') - // `version` can be a string or an integer - .replace( - '%%VERSION%%', - version != null && - (typeof version === 'string' || - Number(parseInt(version, 10)) === version) - ? version.toString() - : '', - ) - ); - } + // eslint-disable-next-line class-methods-use-this async _load( - query: Query = {}, - requiredProps: RequiredContractProps, - ): Promise { - // Provide some context for errors thrown by lower-level functions - const throwError = (action: string, error: any) => { - throw new Error( - `Unable to ${action} for contract ${query.contractName || - query.contractAddress || - ''}: ${error.message || error}`, - ); - }; - - let response; - try { - response = await fetch(this.resolveEndpointResource(query)); - } catch (error) { - throwError('fetch resource', error); - } - - let json; - try { - json = response && response.json && (await response.json()); - } catch (error) { - throwError('get JSON', error); - } - - let contractDef = { abi: [], bytecode: '' }; - try { - contractDef = this._transform(json, query, requiredProps); - } catch (error) { - throwError('transform contract definition', error); - } - return contractDef; + query: Query, + requiredProps?: RequiredContractProps, // eslint-disable-line no-unused-vars + ): Promise { + throw new Error( + 'ContractLoader._load() is expected to be defined in a derived class', + ); } async load( query: Query, @@ -155,13 +100,16 @@ export default class ContractHttpLoader implements IContractLoader { ); // Load the contract definition by either the contract name or address - const result = await this._load( - { - ...(contractName ? { contractName } : { contractAddress }), - ...otherQuery, - }, - requiredProps, - ); + const firstQuery = { + ...(contractName ? { contractName } : { contractAddress }), + ...otherQuery, + }; + const result = await this._load(firstQuery, requiredProps); + + if (result == null) + throw new Error( + `Unable to load contract definition (${JSON.stringify(firstQuery)})`, + ); if (contractAddress) { // If we have a specific contractAddress, set it directly. @@ -178,7 +126,7 @@ export default class ContractHttpLoader implements IContractLoader { }, requiredProps, ); - result.address = routerContract.address; + if (routerContract != null) result.address = routerContract.address; } this.constructor.validateContractDefinition(result, requiredProps); diff --git a/packages/colony-js-contract-loader-http/src/defaults.js b/packages/colony-js-contract-loader/src/defaults.js similarity index 100% rename from packages/colony-js-contract-loader-http/src/defaults.js rename to packages/colony-js-contract-loader/src/defaults.js diff --git a/packages/colony-js-contract-loader/index.js b/packages/colony-js-contract-loader/src/index.js similarity index 58% rename from packages/colony-js-contract-loader/index.js rename to packages/colony-js-contract-loader/src/index.js index b4b684f03..982b3de5d 100644 --- a/packages/colony-js-contract-loader/index.js +++ b/packages/colony-js-contract-loader/src/index.js @@ -7,3 +7,6 @@ export type { RequiredContractProps, Query, } from './interface/ContractLoader'; + +export { default } from './ContractLoader'; +export { default as truffleTransform } from './transforms/truffleTransform'; diff --git a/packages/colony-js-contract-loader/interface/ContractLoader.js b/packages/colony-js-contract-loader/src/interface/ContractLoader.js similarity index 85% rename from packages/colony-js-contract-loader/interface/ContractLoader.js rename to packages/colony-js-contract-loader/src/interface/ContractLoader.js index 7fea6d48c..43723e2ff 100644 --- a/packages/colony-js-contract-loader/interface/ContractLoader.js +++ b/packages/colony-js-contract-loader/src/interface/ContractLoader.js @@ -27,9 +27,13 @@ export type Transform = ( requiredProps?: RequiredContractProps, ) => ContractDefinition; +export type ConstructorArgs = { + transform: Transform, +}; + export interface ContractLoader { - load( + _load( query: Query, requiredProps?: RequiredContractProps, - ): Promise; + ): Promise; } diff --git a/packages/colony-js-contract-loader/src/transforms/truffleTransform.js b/packages/colony-js-contract-loader/src/transforms/truffleTransform.js new file mode 100644 index 000000000..80070f50a --- /dev/null +++ b/packages/colony-js-contract-loader/src/transforms/truffleTransform.js @@ -0,0 +1,38 @@ +/* @flow */ + +import type { Query } from '../interface/ContractLoader'; + +type TruffleArtifact = { + abi: Array<{}>, + bytecode: string, + networks: { + [networkId: number]: { + address: string, + }, + }, +}; + +export default function truffleTransform( + { abi = [], bytecode, networks = {} }: TruffleArtifact = {}, + { networkId }: Query = {}, +) { + let address; + + const networkIds = Object.keys(networks); + + if (networkId && networkIds.length) { + if (!networks[networkId]) + throw new Error(`Network ID ${networkId} not found in contract`); + ({ address } = networks[networkId]); + } else { + // Pick the last network (assumed to be the most recent) + ({ address } = + networks[parseInt(networkIds[networkIds.length - 1], 10)] || {}); + } + + return { + abi, + address, + bytecode, + }; +} diff --git a/packages/colony-js-utils/package.json b/packages/colony-js-utils/package.json index d41beaeec..d41cf943e 100644 --- a/packages/colony-js-utils/package.json +++ b/packages/colony-js-utils/package.json @@ -55,9 +55,9 @@ "webpack-cli": "^2.0.14" }, "dependencies": { + "assert": "^1.4.1", "babel-runtime": "^6.26.0", "bn.js": "^4.11.6", - "browser-assert": "^1.2.1", "web3-utils": "^1.0.0-beta.34" }, "engines": { diff --git a/packages/colony-js-utils/src/checkValidAddress.js b/packages/colony-js-utils/src/checkValidAddress.js index 9e375cc1e..69bd36e2c 100644 --- a/packages/colony-js-utils/src/checkValidAddress.js +++ b/packages/colony-js-utils/src/checkValidAddress.js @@ -1,6 +1,6 @@ /* @flow */ -import assert from 'browser-assert'; +import assert from 'assert'; import { isAddress } from 'web3-utils'; import isEmptyHexString from './isEmptyHexString'; diff --git a/packages/colony-js-utils/src/makeAssert.js b/packages/colony-js-utils/src/makeAssert.js index 8e4d15edd..60e976e40 100644 --- a/packages/colony-js-utils/src/makeAssert.js +++ b/packages/colony-js-utils/src/makeAssert.js @@ -1,6 +1,6 @@ /* @flow */ -import assert from 'browser-assert'; +import assert from 'assert'; /** * Given a message string (e.g. 'Validation failed'), return an assert function diff --git a/yarn.lock b/yarn.lock index 20f171305..fd6a3942f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -187,6 +187,12 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + dependencies: + string-width "^2.0.0" + ansi-escapes@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -342,7 +348,7 @@ assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" -assert@^1.1.1: +assert@^1.1.1, assert@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" dependencies: @@ -1126,7 +1132,7 @@ babylon@7.0.0-beta.44, babylon@^7.0.0-beta.30, babylon@^7.0.0-beta.40: version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" -babylon@^6.17.3, babylon@^6.18.0: +babylon@^6.15.0, babylon@^6.17.3, babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" @@ -1225,6 +1231,18 @@ boom@5.x.x: dependencies: hoek "4.x.x" +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1259,10 +1277,6 @@ brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" -browser-assert@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" - browser-process-hrtime@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" @@ -1467,7 +1481,7 @@ camelcase@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" -camelcase@^4.1.0: +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -1585,6 +1599,10 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + cli-cursor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" @@ -1773,6 +1791,17 @@ concat-stream@^1.4.10, concat-stream@^1.5.0, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" +configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + console-browserify@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" @@ -2080,6 +2109,10 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.2" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" @@ -2325,11 +2358,17 @@ dot-prop@^3.0.0: dependencies: is-obj "^1.0.0" +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + dependencies: + is-obj "^1.0.0" + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" -duplexer@^0.1.1: +duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" @@ -2674,6 +2713,18 @@ ethjs-unit@0.1.6: bn.js "4.11.6" number-to-bn "1.7.0" +event-stream@~3.3.0: + version "3.3.4" + resolved "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -2983,6 +3034,10 @@ flow-bin@^0.72.0: version "0.72.0" resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.72.0.tgz#12051180fb2db7ccb728fefe67c77e955e92a44d" +flow-bin@^0.73.0: + version "0.73.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.73.0.tgz#da1b90a02b0ef9c439f068c2fc14968db83be425" + flow-copy-source@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/flow-copy-source/-/flow-copy-source-1.3.0.tgz#591b153f5c01e8fc566c64a97290ea9103b7f1ea" @@ -2993,6 +3048,16 @@ flow-copy-source@^1.2.1: kefir "^3.7.3" yargs "^11.0.0" +flow-copy-source@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flow-copy-source/-/flow-copy-source-2.0.0.tgz#e0984a434fefb5995571d7a28cbff8c3cdda63fe" + dependencies: + chokidar "^2.0.0" + fs-extra "^6.0.1" + glob "^7.0.0" + kefir "^3.7.3" + yargs "^11.0.0" + flow-parser@^0.*: version "0.69.0" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.69.0.tgz#378b5128d6d0b554a8b2f16a4ca3e1ab9649f00e" @@ -3001,6 +3066,13 @@ flow-parser@^0.73.0: version "0.73.0" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.73.0.tgz#525ac0776f743e16b6dca1a3dd6c602260b15773" +flow-remove-types@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/flow-remove-types/-/flow-remove-types-1.2.3.tgz#6131aefc7da43364bb8b479758c9dec7735d1a18" + dependencies: + babylon "^6.15.0" + vlq "^0.2.1" + flush-write-stream@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" @@ -3069,6 +3141,10 @@ from2@^2.1.0, from2@^2.1.1: inherits "^2.0.1" readable-stream "^2.0.0" +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + fs-extra@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" @@ -3085,6 +3161,14 @@ fs-extra@^5.0.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-readdir-recursive@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" @@ -3272,6 +3356,12 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + dependencies: + ini "^1.3.4" + global-modules@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" @@ -3639,10 +3729,18 @@ iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + ignore@^3.3.3: version "3.3.7" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + import-local@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" @@ -3901,6 +3999,17 @@ is-hex-prefixed@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -4639,6 +4748,12 @@ kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + dependencies: + package-json "^4.0.0" + lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" @@ -4936,6 +5051,10 @@ map-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -5317,6 +5436,21 @@ node-pre-gyp@^0.6.39: tar "^2.2.1" tar-pack "^3.4.0" +nodemon@^1.17.5: + version "1.17.5" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.17.5.tgz#e6a665c872fdf09d48bf2a81f3e85f8cfb39322a" + dependencies: + chokidar "^2.0.2" + debug "^3.1.0" + ignore-by-default "^1.0.1" + minimatch "^3.0.4" + pstree.remy "^1.1.0" + semver "^5.5.0" + supports-color "^5.2.0" + touch "^3.1.0" + undefsafe "^2.0.2" + update-notifier "^2.3.0" + nomnom@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" @@ -5331,6 +5465,12 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + dependencies: + abbrev "1" + normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" @@ -5594,7 +5734,7 @@ p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" -package-json@^4.0.1: +package-json@^4.0.0, package-json@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" dependencies: @@ -5732,6 +5872,12 @@ path-type@^3.0.0: dependencies: pify "^3.0.0" +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + dependencies: + through "~2.3" + pbkdf2@^3.0.3: version "3.0.14" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" @@ -5865,10 +6011,22 @@ prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" +ps-tree@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" + dependencies: + event-stream "~3.3.0" + pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +pstree.remy@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.0.tgz#f2af27265bd3e5b32bbfcc10e80bac55ba78688b" + dependencies: + ps-tree "^1.1.0" + public-encrypt@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994" @@ -6446,7 +6604,13 @@ scrypt-js@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4" -"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" + +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" @@ -6741,6 +6905,12 @@ split2@^2.0.0: dependencies: through2 "^2.0.2" +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + dependencies: + through "2" + split@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" @@ -6805,6 +6975,12 @@ stream-browserify@^2.0.1: inherits "~2.0.1" readable-stream "^2.0.2" +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + dependencies: + duplexer "~0.1.1" + stream-each@^1.1.0: version "1.2.2" resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" @@ -6957,6 +7133,12 @@ supports-color@^3.1.2: dependencies: has-flag "^1.0.0" +supports-color@^5.2.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + dependencies: + has-flag "^3.0.0" + supports-color@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" @@ -7044,6 +7226,12 @@ tempfile@^1.1.1: os-tmpdir "^1.0.0" uuid "^2.0.1" +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + dependencies: + execa "^0.7.0" + test-exclude@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa" @@ -7077,7 +7265,7 @@ through2@^2.0.0, through2@^2.0.2: readable-stream "^2.1.5" xtend "~4.0.1" -through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: +through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@~2.3, through@~2.3.1: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -7135,6 +7323,12 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + dependencies: + nopt "~1.0.10" + tough-cookie@>=2.3.3, tough-cookie@^2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.4" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" @@ -7239,6 +7433,12 @@ ultron@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" +undefsafe@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" + dependencies: + debug "^2.2.0" + underscore@1.8.3: version "1.8.3" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" @@ -7268,6 +7468,12 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + dependencies: + crypto-random-string "^1.0.0" + universalify@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" @@ -7295,6 +7501,21 @@ upath@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.4.tgz#ee2321ba0a786c50973db043a50b7bcba822361d" +update-notifier@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + uri-js@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-3.0.2.tgz#f90b858507f81dea4dcfbb3c4c3dbfa2b557faaa" @@ -7438,6 +7659,10 @@ vinyl@^2.0.1: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" +vlq@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" + vm-browserify@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" @@ -7599,6 +7824,12 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2" +widest-line@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.0.tgz#0142a4e8a243f8882c0233aa0e0281aa76152273" + dependencies: + string-width "^2.1.1" + window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" @@ -7687,6 +7918,10 @@ ws@^4.0.0: async-limiter "~1.0.0" safe-buffer "~5.1.0" +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + xhr-request-promise@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz#343c44d1ee7726b8648069682d0f840c83b4261d"