diff options
22 files changed, 758 insertions, 556 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml index f288a46e6..31954c608 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,16 +17,20 @@ jobs: - run: name: yarn command: yarn --frozen-lockfile install || yarn --frozen-lockfile install - - run: > - if [ -z "$(git diff --name-only development packages/website)" ]; then - yarn build:ci:no_website - else - yarn build:ci - fi + - run: yarn build:ci:no_website - save_cache: key: repo-{{ .Environment.CIRCLE_SHA1 }} paths: - ~/repo + build-website: + docker: + - image: circleci/node:9 + working_directory: ~/repo + steps: + - restore_cache: + keys: + - repo-{{ .Environment.CIRCLE_SHA1 }} + - run: cd packages/website && yarn build test-contracts-ganache: docker: - image: circleci/node:9 @@ -234,6 +238,9 @@ workflows: main: jobs: - build + - build-website: + requires: + - build - test-contracts-ganache: requires: - build diff --git a/package.json b/package.json index 5b2a7b200..8eb736cc4 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "wsrun": "wsrun", "lerna": "lerna", "build": "wsrun build $PKG --fast-exit -r --stages", - "build:ci": "wsrun build:ci $PKG --fast-exit -r --stages", "build:no_website": "wsrun build $PKG --fast-exit -r --stages --exclude @0xproject/website", "build:ci:no_website": "wsrun build:ci $PKG --fast-exit -r --stages --exclude @0xproject/website", "build:monorepo_scripts": "PKG=@0xproject/monorepo-scripts yarn build", @@ -47,6 +46,9 @@ "bundlesize": [ { "path": "packages/0x.js/_bundles/index.min.js" + }, + { + "path": "packages/instant/public/main.bundle.js" } ], "devDependencies": { diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index c89a3e613..268972a4f 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -52,13 +52,12 @@ "@types/node": "*", "@types/sinon": "^2.2.2", "@types/web3-provider-engine": "^14.0.0", - "awesome-typescript-loader": "^3.1.3", + "awesome-typescript-loader": "^5.2.1", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.1", "copyfiles": "^2.0.0", "dirty-chai": "^2.0.1", - "json-loader": "^0.5.4", "make-promises-safe": "^1.1.0", "mocha": "^4.1.0", "npm-run-all": "^4.1.2", @@ -70,8 +69,8 @@ "tslint": "5.11.0", "typedoc": "0.12.0", "typescript": "3.0.1", - "uglifyjs-webpack-plugin": "^1.3.0", - "webpack": "^3.1.0" + "uglifyjs-webpack-plugin": "^2.0.1", + "webpack": "^4.20.2" }, "dependencies": { "@0xproject/assert": "^1.0.12", diff --git a/packages/0x.js/webpack.config.js b/packages/0x.js/webpack.config.js index 1ad0a79ec..397faa76f 100644 --- a/packages/0x.js/webpack.config.js +++ b/packages/0x.js/webpack.config.js @@ -2,8 +2,7 @@ * This is to generate the umd bundle only */ const _ = require('lodash'); -const webpack = require('webpack'); -const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); const path = require('path'); const production = process.env.NODE_ENV === 'production'; @@ -16,6 +15,7 @@ if (production) { module.exports = { entry, + mode: 'production', output: { path: path.resolve(__dirname, '_bundles'), filename: '[name].js', @@ -27,19 +27,18 @@ module.exports = { extensions: ['.ts', '.js', '.json'], }, devtool: 'source-map', - plugins: [ - // TODO: Revert to webpack bundled version with webpack v4. - // The v3 series bundled version does not support ES6 and - // fails to build. - new UglifyJsPlugin({ - sourceMap: true, - uglifyOptions: { - mangle: { - reserved: ['BigNumber'], + optimization: { + minimizer: [ + new TerserPlugin({ + sourceMap: true, + terserOptions: { + mangle: { + reserved: ['BigNumber'], + }, }, - }, - }), - ], + }), + ], + }, module: { rules: [ { @@ -59,10 +58,6 @@ module.exports = { ], exclude: /node_modules/, }, - { - test: /\.json$/, - loader: 'json-loader', - }, ], }, }; diff --git a/packages/asset-buyer/CHANGELOG.json b/packages/asset-buyer/CHANGELOG.json index 8c2c7a8d2..df67059cb 100644 --- a/packages/asset-buyer/CHANGELOG.json +++ b/packages/asset-buyer/CHANGELOG.json @@ -5,6 +5,10 @@ { "note": "Expand AssetBuyer to work with multiple assets at once", "pr": 1086 + }, + { + "note": "Fix minRate and maxRate calculation", + "pr": 1113 } ] }, diff --git a/packages/asset-buyer/src/asset_buyer.ts b/packages/asset-buyer/src/asset_buyer.ts index 0bb757f52..7ec39e012 100644 --- a/packages/asset-buyer/src/asset_buyer.ts +++ b/packages/asset-buyer/src/asset_buyer.ts @@ -123,7 +123,7 @@ export class AssetBuyer { public async getBuyQuoteAsync( assetData: string, assetBuyAmount: BigNumber, - options: Partial<BuyQuoteRequestOpts>, + options: Partial<BuyQuoteRequestOpts> = {}, ): Promise<BuyQuote> { const { feePercentage, shouldForceOrderRefresh, slippagePercentage } = { ...constants.DEFAULT_BUY_QUOTE_REQUEST_OPTS, @@ -164,7 +164,7 @@ export class AssetBuyer { public async getBuyQuoteForERC20TokenAddressAsync( tokenAddress: string, assetBuyAmount: BigNumber, - options: Partial<BuyQuoteRequestOpts>, + options: Partial<BuyQuoteRequestOpts> = {}, ): Promise<BuyQuote> { assert.isETHAddressHex('tokenAddress', tokenAddress); assert.isBigNumber('assetBuyAmount', assetBuyAmount); @@ -179,20 +179,23 @@ export class AssetBuyer { * * @return A promise of the txHash. */ - public async executeBuyQuoteAsync(buyQuote: BuyQuote, options: Partial<BuyQuoteExecutionOpts>): Promise<string> { - const { rate, takerAddress, feeRecipient } = { + public async executeBuyQuoteAsync( + buyQuote: BuyQuote, + options: Partial<BuyQuoteExecutionOpts> = {}, + ): Promise<string> { + const { ethAmount, takerAddress, feeRecipient } = { ...constants.DEFAULT_BUY_QUOTE_EXECUTION_OPTS, ...options, }; assert.isValidBuyQuote('buyQuote', buyQuote); - if (!_.isUndefined(rate)) { - assert.isBigNumber('rate', rate); + if (!_.isUndefined(ethAmount)) { + assert.isBigNumber('ethAmount', ethAmount); } if (!_.isUndefined(takerAddress)) { assert.isETHAddressHex('takerAddress', takerAddress); } assert.isETHAddressHex('feeRecipient', feeRecipient); - const { orders, feeOrders, feePercentage, assetBuyAmount, maxRate } = buyQuote; + const { orders, feeOrders, feePercentage, assetBuyAmount, worstCaseQuoteInfo } = buyQuote; // if no takerAddress is provided, try to get one from the provider let finalTakerAddress; if (!_.isUndefined(takerAddress)) { @@ -207,15 +210,12 @@ export class AssetBuyer { throw new Error(AssetBuyerError.NoAddressAvailable); } } - // if no rate is provided, default to the maxRate from buyQuote - const desiredRate = rate || maxRate; - // calculate how much eth is required to buy assetBuyAmount at the desired rate - const ethAmount = assetBuyAmount.dividedToIntegerBy(desiredRate); + // if no ethAmount is provided, default to the worst ethAmount from buyQuote const txHash = await this._contractWrappers.forwarder.marketBuyOrdersWithEthAsync( orders, assetBuyAmount, finalTakerAddress, - ethAmount, + ethAmount || worstCaseQuoteInfo.totalEthAmount, feeOrders, feePercentage, feeRecipient, diff --git a/packages/asset-buyer/src/types.ts b/packages/asset-buyer/src/types.ts index 8d3dcbfe6..b96795bb6 100644 --- a/packages/asset-buyer/src/types.ts +++ b/packages/asset-buyer/src/types.ts @@ -35,21 +35,32 @@ export interface OrderProvider { /** * assetData: String that represents a specific asset (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md). + * assetBuyAmount: The amount of asset to buy. * orders: An array of objects conforming to SignedOrder. These orders can be used to cover the requested assetBuyAmount plus slippage. * feeOrders: An array of objects conforming to SignedOrder. These orders can be used to cover the fees for the orders param above. - * minRate: Min rate that needs to be paid in order to execute the buy. - * maxRate: Max rate that can be paid in order to execute the buy. - * assetBuyAmount: The amount of asset to buy. * feePercentage: Optional affiliate fee percentage used to calculate the eth amounts above. + * bestCaseQuoteInfo: Info about the best case price for the asset. + * worstCaseQuoteInfo: Info about the worst case price for the asset. */ export interface BuyQuote { assetData: string; + assetBuyAmount: BigNumber; orders: SignedOrder[]; feeOrders: SignedOrder[]; - minRate: BigNumber; - maxRate: BigNumber; - assetBuyAmount: BigNumber; feePercentage?: number; + bestCaseQuoteInfo: BuyQuoteInfo; + worstCaseQuoteInfo: BuyQuoteInfo; +} + +/** + * ethPerAssetPrice: The price of one unit of the desired asset in ETH + * feeEthAmount: The amount of eth required to pay the affiliate fee. + * totalEthAmount: the total amount of eth required to complete the buy. (Filling orders, feeOrders, and paying affiliate fee) + */ +export interface BuyQuoteInfo { + ethPerAssetPrice: BigNumber; + feeEthAmount: BigNumber; + totalEthAmount: BigNumber; } /** @@ -64,12 +75,12 @@ export interface BuyQuoteRequestOpts { } /** - * rate: The desired rate to execute the buy at. Affects the amount of ETH sent with the transaction, defaults to buyQuote.maxRate. + * ethAmount: The desired amount of eth to spend. Defaults to buyQuote.worstCaseQuoteInfo.totalEthAmount. * takerAddress: The address to perform the buy. Defaults to the first available address from the provider. * feeRecipient: The address where affiliate fees are sent. Defaults to null address (0x000...000). */ export interface BuyQuoteExecutionOpts { - rate?: BigNumber; + ethAmount?: BigNumber; takerAddress?: string; feeRecipient: string; } diff --git a/packages/asset-buyer/src/utils/assert.ts b/packages/asset-buyer/src/utils/assert.ts index 04f425237..d43b71fee 100644 --- a/packages/asset-buyer/src/utils/assert.ts +++ b/packages/asset-buyer/src/utils/assert.ts @@ -3,7 +3,7 @@ import { schemas } from '@0xproject/json-schemas'; import { SignedOrder } from '@0xproject/types'; import * as _ from 'lodash'; -import { BuyQuote, OrderProvider, OrderProviderRequest } from '../types'; +import { BuyQuote, BuyQuoteInfo, OrderProvider, OrderProviderRequest } from '../types'; export const assert = { ...sharedAssert, @@ -11,13 +11,18 @@ export const assert = { sharedAssert.isHexString(`${variableName}.assetData`, buyQuote.assetData); sharedAssert.doesConformToSchema(`${variableName}.orders`, buyQuote.orders, schemas.signedOrdersSchema); sharedAssert.doesConformToSchema(`${variableName}.feeOrders`, buyQuote.feeOrders, schemas.signedOrdersSchema); - sharedAssert.isBigNumber(`${variableName}.minRate`, buyQuote.minRate); - sharedAssert.isBigNumber(`${variableName}.maxRate`, buyQuote.maxRate); + assert.isValidBuyQuoteInfo(`${variableName}.bestCaseQuoteInfo`, buyQuote.bestCaseQuoteInfo); + assert.isValidBuyQuoteInfo(`${variableName}.worstCaseQuoteInfo`, buyQuote.worstCaseQuoteInfo); sharedAssert.isBigNumber(`${variableName}.assetBuyAmount`, buyQuote.assetBuyAmount); if (!_.isUndefined(buyQuote.feePercentage)) { sharedAssert.isNumber(`${variableName}.feePercentage`, buyQuote.feePercentage); } }, + isValidBuyQuoteInfo(variableName: string, buyQuoteInfo: BuyQuoteInfo): void { + sharedAssert.isBigNumber(`${variableName}.ethPerAssetPrice`, buyQuoteInfo.ethPerAssetPrice); + sharedAssert.isBigNumber(`${variableName}.feeEthAmount`, buyQuoteInfo.feeEthAmount); + sharedAssert.isBigNumber(`${variableName}.totalEthAmount`, buyQuoteInfo.totalEthAmount); + }, isValidOrderProvider(variableName: string, orderFetcher: OrderProvider): void { sharedAssert.isFunction(`${variableName}.getOrdersAsync`, orderFetcher.getOrdersAsync); }, diff --git a/packages/asset-buyer/src/utils/buy_quote_calculator.ts b/packages/asset-buyer/src/utils/buy_quote_calculator.ts index b706ea143..cb0fd128c 100644 --- a/packages/asset-buyer/src/utils/buy_quote_calculator.ts +++ b/packages/asset-buyer/src/utils/buy_quote_calculator.ts @@ -1,11 +1,9 @@ -import { marketUtils } from '@0xproject/order-utils'; +import { marketUtils, rateUtils } from '@0xproject/order-utils'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import { constants } from '../constants'; -import { AssetBuyerError, BuyQuote, OrdersAndFillableAmounts } from '../types'; - -import { orderUtils } from './order_utils'; +import { AssetBuyerError, BuyQuote, BuyQuoteInfo, OrdersAndFillableAmounts } from '../types'; // Calculates a buy quote for orders that have WETH as the takerAsset export const buyQuoteCalculator = { @@ -21,6 +19,7 @@ export const buyQuoteCalculator = { const feeOrders = feeOrdersAndFillableAmounts.orders; const remainingFillableFeeAmounts = feeOrdersAndFillableAmounts.remainingFillableMakerAssetAmounts; const slippageBufferAmount = assetBuyAmount.mul(slippagePercentage).round(); + // find the orders that cover the desired assetBuyAmount (with slippage) const { resultOrders, remainingFillAmount, @@ -29,9 +28,11 @@ export const buyQuoteCalculator = { remainingFillableMakerAssetAmounts, slippageBufferAmount, }); + // if we do not have enough orders to cover the desired assetBuyAmount, throw if (remainingFillAmount.gt(constants.ZERO_AMOUNT)) { throw new Error(AssetBuyerError.InsufficientAssetLiquidity); } + // given the orders calculated above, find the fee-orders that cover the desired assetBuyAmount (with slippage) // TODO(bmillman): optimization // update this logic to find the minimum amount of feeOrders to cover the worst case as opposed to // finding order that cover all fees, this will help with estimating ETH and minimizing gas usage @@ -40,49 +41,139 @@ export const buyQuoteCalculator = { remainingFeeAmount, feeOrdersRemainingFillableMakerAssetAmounts, } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(resultOrders, feeOrders, { - remainingFillableMakerAssetAmounts, + remainingFillableMakerAssetAmounts: ordersRemainingFillableMakerAssetAmounts, remainingFillableFeeAmounts, }); + // if we do not have enough feeOrders to cover the fees, throw if (remainingFeeAmount.gt(constants.ZERO_AMOUNT)) { throw new Error(AssetBuyerError.InsufficientZrxLiquidity); } + // assetData information for the result const assetData = orders[0].makerAssetData; - - // calculate minRate and maxRate by calculating min and max eth usage and then dividing into - // assetBuyAmount to get assetData / WETH, needs to take into account feePercentage as well - // minEthAmount = (sum(takerAssetAmount[i]) until sum(makerAssetAmount[i]) >= assetBuyAmount ) * (1 + feePercentage) - // maxEthAmount = (sum(takerAssetAmount[i]) until i == orders.length) * (1 + feePercentage) - const allOrders = _.concat(resultOrders, resultFeeOrders); - const allRemainingAmounts = _.concat( - ordersRemainingFillableMakerAssetAmounts, - feeOrdersRemainingFillableMakerAssetAmounts, + // compile the resulting trimmed set of orders for makerAsset and feeOrders that are needed for assetBuyAmount + const trimmedOrdersAndFillableAmounts: OrdersAndFillableAmounts = { + orders: resultOrders, + remainingFillableMakerAssetAmounts: ordersRemainingFillableMakerAssetAmounts, + }; + const trimmedFeeOrdersAndFillableAmounts: OrdersAndFillableAmounts = { + orders: resultFeeOrders, + remainingFillableMakerAssetAmounts: feeOrdersRemainingFillableMakerAssetAmounts, + }; + const bestCaseQuoteInfo = calculateQuoteInfo( + trimmedOrdersAndFillableAmounts, + trimmedFeeOrdersAndFillableAmounts, + assetBuyAmount, + feePercentage, ); - let minEthAmount = constants.ZERO_AMOUNT; - let maxEthAmount = constants.ZERO_AMOUNT; - let cumulativeMakerAmount = constants.ZERO_AMOUNT; - _.forEach(allOrders, (order, index) => { - const remainingFillableMakerAssetAmount = allRemainingAmounts[index]; - const claimableTakerAssetAmount = orderUtils.calculateRemainingTakerAssetAmount( - order, - remainingFillableMakerAssetAmount, - ); - // taker asset is always assumed to be WETH - maxEthAmount = maxEthAmount.plus(claimableTakerAssetAmount); - if (cumulativeMakerAmount.lessThan(assetBuyAmount)) { - minEthAmount = minEthAmount.plus(claimableTakerAssetAmount); - } - cumulativeMakerAmount = cumulativeMakerAmount.plus(remainingFillableMakerAssetAmount); - }); - const feeAdjustedMinRate = minEthAmount.mul(feePercentage + 1).div(assetBuyAmount); - const feeAdjustedMaxRate = minEthAmount.mul(feePercentage + 1).div(assetBuyAmount); + // in order to calculate the maxRate, reverse the ordersAndFillableAmounts such that they are sorted from worst rate to best rate + const worstCaseQuoteInfo = calculateQuoteInfo( + reverseOrdersAndFillableAmounts(trimmedOrdersAndFillableAmounts), + reverseOrdersAndFillableAmounts(trimmedFeeOrdersAndFillableAmounts), + assetBuyAmount, + feePercentage, + ); + return { assetData, orders: resultOrders, feeOrders: resultFeeOrders, - minRate: feeAdjustedMinRate, - maxRate: feeAdjustedMaxRate, + bestCaseQuoteInfo, + worstCaseQuoteInfo, assetBuyAmount, feePercentage, }; }, }; + +function calculateQuoteInfo( + ordersAndFillableAmounts: OrdersAndFillableAmounts, + feeOrdersAndFillableAmounts: OrdersAndFillableAmounts, + assetBuyAmount: BigNumber, + feePercentage: number, +): BuyQuoteInfo { + // find the total eth and zrx needed to buy assetAmount from the resultOrders from left to right + const [ethAmountToBuyAsset, zrxAmountToBuyAsset] = findEthAndZrxAmountNeededToBuyAsset( + ordersAndFillableAmounts, + assetBuyAmount, + ); + // find the total eth needed to buy fees + const ethAmountToBuyFees = findEthAmountNeededToBuyFees(feeOrdersAndFillableAmounts, zrxAmountToBuyAsset); + const ethAmountBeforeAffiliateFee = ethAmountToBuyAsset.plus(ethAmountToBuyFees); + const totalEthAmount = ethAmountBeforeAffiliateFee.mul(feePercentage + 1); + // divide into the assetBuyAmount in order to find rate of makerAsset / WETH + const ethPerAssetPrice = ethAmountBeforeAffiliateFee.div(assetBuyAmount); + return { + totalEthAmount, + feeEthAmount: totalEthAmount.minus(ethAmountBeforeAffiliateFee), + ethPerAssetPrice, + }; +} + +// given an OrdersAndFillableAmounts, reverse the orders and remainingFillableMakerAssetAmounts properties +function reverseOrdersAndFillableAmounts(ordersAndFillableAmounts: OrdersAndFillableAmounts): OrdersAndFillableAmounts { + const ordersCopy = _.clone(ordersAndFillableAmounts.orders); + const remainingFillableMakerAssetAmountsCopy = _.clone(ordersAndFillableAmounts.remainingFillableMakerAssetAmounts); + return { + orders: ordersCopy.reverse(), + remainingFillableMakerAssetAmounts: remainingFillableMakerAssetAmountsCopy.reverse(), + }; +} + +function findEthAmountNeededToBuyFees( + feeOrdersAndFillableAmounts: OrdersAndFillableAmounts, + feeAmount: BigNumber, +): BigNumber { + const { orders, remainingFillableMakerAssetAmounts } = feeOrdersAndFillableAmounts; + const result = _.reduce( + orders, + (acc, order, index) => { + const remainingFillableMakerAssetAmount = remainingFillableMakerAssetAmounts[index]; + const amountToFill = BigNumber.min(acc.remainingFeeAmount, remainingFillableMakerAssetAmount); + const feeAdjustedRate = rateUtils.getFeeAdjustedRateOfFeeOrder(order); + const ethAmountForThisOrder = feeAdjustedRate.mul(amountToFill); + return { + ethAmount: acc.ethAmount.plus(ethAmountForThisOrder), + remainingFeeAmount: BigNumber.max(constants.ZERO_AMOUNT, acc.remainingFeeAmount.minus(amountToFill)), + }; + }, + { + ethAmount: constants.ZERO_AMOUNT, + remainingFeeAmount: feeAmount, + }, + ); + return result.ethAmount; +} + +function findEthAndZrxAmountNeededToBuyAsset( + ordersAndFillableAmounts: OrdersAndFillableAmounts, + assetBuyAmount: BigNumber, +): [BigNumber, BigNumber] { + const { orders, remainingFillableMakerAssetAmounts } = ordersAndFillableAmounts; + const result = _.reduce( + orders, + (acc, order, index) => { + const remainingFillableMakerAssetAmount = remainingFillableMakerAssetAmounts[index]; + const amountToFill = BigNumber.min(acc.remainingAssetBuyAmount, remainingFillableMakerAssetAmount); + // find the amount of eth required to fill amountToFill (amountToFill / makerAssetAmount) * takerAssetAmount + const ethAmountForThisOrder = amountToFill + .mul(order.takerAssetAmount) + .dividedToIntegerBy(order.makerAssetAmount); + // find the amount of zrx required to fill fees for amountToFill (amountToFill / makerAssetAmount) * takerFee + const zrxAmountForThisOrder = amountToFill.mul(order.takerFee).dividedToIntegerBy(order.makerAssetAmount); + return { + ethAmount: acc.ethAmount.plus(ethAmountForThisOrder), + zrxAmount: acc.zrxAmount.plus(zrxAmountForThisOrder), + remainingAssetBuyAmount: BigNumber.max( + constants.ZERO_AMOUNT, + acc.remainingAssetBuyAmount.minus(amountToFill), + ), + }; + }, + { + ethAmount: constants.ZERO_AMOUNT, + zrxAmount: constants.ZERO_AMOUNT, + remainingAssetBuyAmount: assetBuyAmount, + }, + ); + return [result.ethAmount, result.zrxAmount]; +} diff --git a/packages/asset-buyer/test/buy_quote_calculator_test.ts b/packages/asset-buyer/test/buy_quote_calculator_test.ts new file mode 100644 index 000000000..b987b45a8 --- /dev/null +++ b/packages/asset-buyer/test/buy_quote_calculator_test.ts @@ -0,0 +1,160 @@ +import { orderFactory } from '@0xproject/order-utils/lib/src/order_factory'; +import { BigNumber } from '@0xproject/utils'; +import * as chai from 'chai'; +import * as _ from 'lodash'; +import 'mocha'; + +import { AssetBuyerError, OrdersAndFillableAmounts } from '../src/types'; +import { buyQuoteCalculator } from '../src/utils/buy_quote_calculator'; + +import { chaiSetup } from './utils/chai_setup'; + +chaiSetup.configure(); +const expect = chai.expect; + +// tslint:disable:custom-no-magic-numbers +describe('buyQuoteCalculator', () => { + describe('#calculate', () => { + let ordersAndFillableAmounts: OrdersAndFillableAmounts; + let smallFeeOrderAndFillableAmount: OrdersAndFillableAmounts; + let allFeeOrdersAndFillableAmounts: OrdersAndFillableAmounts; + beforeEach(() => { + // generate two orders for our desired maker asset + // the first order has a rate of 4 makerAsset / WETH with a takerFee of 200 ZRX and has only 200 / 400 makerAsset units left to fill (half fillable) + // the second order has a rate of 2 makerAsset / WETH with a takerFee of 100 ZRX and has 200 / 200 makerAsset units left to fill (completely fillable) + // generate one order for fees + // the fee order has a rate of 1 ZRX / WETH with no taker fee and has 100 ZRX left to fill (completely fillable) + const firstOrder = orderFactory.createSignedOrderFromPartial({ + makerAssetAmount: new BigNumber(400), + takerAssetAmount: new BigNumber(100), + takerFee: new BigNumber(200), + }); + const firstRemainingFillAmount = new BigNumber(200); + const secondOrder = orderFactory.createSignedOrderFromPartial({ + makerAssetAmount: new BigNumber(200), + takerAssetAmount: new BigNumber(100), + takerFee: new BigNumber(100), + }); + const secondRemainingFillAmount = secondOrder.makerAssetAmount; + ordersAndFillableAmounts = { + orders: [firstOrder, secondOrder], + remainingFillableMakerAssetAmounts: [firstRemainingFillAmount, secondRemainingFillAmount], + }; + const smallFeeOrder = orderFactory.createSignedOrderFromPartial({ + makerAssetAmount: new BigNumber(100), + takerAssetAmount: new BigNumber(100), + }); + smallFeeOrderAndFillableAmount = { + orders: [smallFeeOrder], + remainingFillableMakerAssetAmounts: [smallFeeOrder.makerAssetAmount], + }; + const largeFeeOrder = orderFactory.createSignedOrderFromPartial({ + makerAssetAmount: new BigNumber(110), + takerAssetAmount: new BigNumber(200), + takerFee: new BigNumber(10), + }); + allFeeOrdersAndFillableAmounts = { + orders: [smallFeeOrder, largeFeeOrder], + remainingFillableMakerAssetAmounts: [ + smallFeeOrder.makerAssetAmount, + largeFeeOrder.makerAssetAmount.minus(largeFeeOrder.takerFee), + ], + }; + }); + it('should throw if not enough maker asset liquidity', () => { + // we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units + expect(() => + buyQuoteCalculator.calculate( + ordersAndFillableAmounts, + smallFeeOrderAndFillableAmount, + new BigNumber(500), + 0, + 0, + ), + ).to.throw(AssetBuyerError.InsufficientAssetLiquidity); + }); + it('should throw if not enough ZRX liquidity', () => { + // we request 300 makerAsset units but the ZRX order is only enough to fill the first order, which only has 200 makerAssetUnits available + expect(() => + buyQuoteCalculator.calculate( + ordersAndFillableAmounts, + smallFeeOrderAndFillableAmount, + new BigNumber(300), + 0, + 0, + ), + ).to.throw(AssetBuyerError.InsufficientZrxLiquidity); + }); + it('calculates a correct buyQuote with no slippage', () => { + // we request 200 makerAsset units which can be filled using the first order + // the first order requires a fee of 100 ZRX from the taker which can be filled by the feeOrder + const assetBuyAmount = new BigNumber(200); + const feePercentage = 0.02; + const slippagePercentage = 0; + const buyQuote = buyQuoteCalculator.calculate( + ordersAndFillableAmounts, + smallFeeOrderAndFillableAmount, + assetBuyAmount, + feePercentage, + slippagePercentage, + ); + // test if orders are correct + expect(buyQuote.orders).to.deep.equal([ordersAndFillableAmounts.orders[0]]); + expect(buyQuote.feeOrders).to.deep.equal([smallFeeOrderAndFillableAmount.orders[0]]); + // test if rates are correct + // 50 eth to fill the first order + 100 eth for fees + const expectedFillEthAmount = new BigNumber(150); + const expectedTotalEthAmount = expectedFillEthAmount.mul(feePercentage + 1); + const expectedFeeEthAmount = expectedTotalEthAmount.minus(expectedFillEthAmount); + const expectedEthPerAssetPrice = expectedFillEthAmount.div(assetBuyAmount); + expect(buyQuote.bestCaseQuoteInfo.feeEthAmount).to.bignumber.equal(expectedFeeEthAmount); + expect(buyQuote.bestCaseQuoteInfo.totalEthAmount).to.bignumber.equal(expectedTotalEthAmount); + expect(buyQuote.bestCaseQuoteInfo.ethPerAssetPrice).to.bignumber.equal(expectedEthPerAssetPrice); + // because we have no slippage protection, minRate is equal to maxRate + expect(buyQuote.worstCaseQuoteInfo.feeEthAmount).to.bignumber.equal(expectedFeeEthAmount); + expect(buyQuote.worstCaseQuoteInfo.totalEthAmount).to.bignumber.equal(expectedTotalEthAmount); + expect(buyQuote.worstCaseQuoteInfo.ethPerAssetPrice).to.bignumber.equal(expectedEthPerAssetPrice); + // test if feePercentage gets passed through + expect(buyQuote.feePercentage).to.equal(feePercentage); + }); + it('calculates a correct buyQuote with with slippage', () => { + // we request 200 makerAsset units which can be filled using the first order + // however with 50% slippage we are protecting the buy with 100 extra makerAssetUnits + // so we need enough orders to fill 300 makerAssetUnits + // 300 makerAssetUnits can only be filled using both orders + // the first order requires a fee of 100 ZRX from the taker which can be filled by the feeOrder + const assetBuyAmount = new BigNumber(200); + const feePercentage = 0.02; + const slippagePercentage = 0.5; + const buyQuote = buyQuoteCalculator.calculate( + ordersAndFillableAmounts, + allFeeOrdersAndFillableAmounts, + assetBuyAmount, + feePercentage, + slippagePercentage, + ); + // test if orders are correct + expect(buyQuote.orders).to.deep.equal(ordersAndFillableAmounts.orders); + expect(buyQuote.feeOrders).to.deep.equal(allFeeOrdersAndFillableAmounts.orders); + // test if rates are correct + // 50 eth to fill the first order + 100 eth for fees + const expectedFillEthAmount = new BigNumber(150); + const expectedTotalEthAmount = expectedFillEthAmount.mul(feePercentage + 1); + const expectedFeeEthAmount = expectedTotalEthAmount.minus(expectedFillEthAmount); + const expectedEthPerAssetPrice = expectedFillEthAmount.div(assetBuyAmount); + expect(buyQuote.bestCaseQuoteInfo.feeEthAmount).to.bignumber.equal(expectedFeeEthAmount); + expect(buyQuote.bestCaseQuoteInfo.totalEthAmount).to.bignumber.equal(expectedTotalEthAmount); + expect(buyQuote.bestCaseQuoteInfo.ethPerAssetPrice).to.bignumber.equal(expectedEthPerAssetPrice); + // 100 eth to fill the first order + 200 eth for fees + const expectedWorstFillEthAmount = new BigNumber(300); + const expectedWorstTotalEthAmount = expectedWorstFillEthAmount.mul(feePercentage + 1); + const expectedWorstFeeEthAmount = expectedWorstTotalEthAmount.minus(expectedWorstFillEthAmount); + const expectedWorstEthPerAssetPrice = expectedWorstFillEthAmount.div(assetBuyAmount); + expect(buyQuote.worstCaseQuoteInfo.feeEthAmount).to.bignumber.equal(expectedWorstFeeEthAmount); + expect(buyQuote.worstCaseQuoteInfo.totalEthAmount).to.bignumber.equal(expectedWorstTotalEthAmount); + expect(buyQuote.worstCaseQuoteInfo.ethPerAssetPrice).to.bignumber.equal(expectedWorstEthPerAssetPrice); + // test if feePercentage gets passed through + expect(buyQuote.feePercentage).to.equal(feePercentage); + }); + }); +}); diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 22dd6521c..c345d0a6a 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -53,7 +53,6 @@ "@types/sinon": "^2.2.2", "@types/uuid": "^3.4.2", "@types/web3-provider-engine": "^14.0.0", - "awesome-typescript-loader": "^3.1.3", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.1", diff --git a/packages/order-utils/src/order_factory.ts b/packages/order-utils/src/order_factory.ts index 46a69ae4d..b1292903a 100644 --- a/packages/order-utils/src/order_factory.ts +++ b/packages/order-utils/src/order_factory.ts @@ -8,8 +8,21 @@ import { orderHashUtils } from './order_hash'; import { generatePseudoRandomSalt } from './salt'; import { signatureUtils } from './signature_utils'; import { CreateOrderOpts } from './types'; - export const orderFactory = { + createOrderFromPartial(partialOrder: Partial<Order>): Order { + const defaultOrder = generateEmptyOrder(); + return { + ...defaultOrder, + ...partialOrder, + }; + }, + createSignedOrderFromPartial(partialSignedOrder: Partial<SignedOrder>): SignedOrder { + const defaultOrder = generateEmptySignedOrder(); + return { + ...defaultOrder, + ...partialSignedOrder, + }; + }, createOrder( makerAddress: string, makerAssetAmount: BigNumber, @@ -69,6 +82,30 @@ export const orderFactory = { }, }; +function generateEmptySignedOrder(): SignedOrder { + return { + ...generateEmptyOrder(), + signature: constants.NULL_BYTES, + }; +} +function generateEmptyOrder(): Order { + return { + senderAddress: constants.NULL_ADDRESS, + makerAddress: constants.NULL_ADDRESS, + takerAddress: constants.NULL_ADDRESS, + makerFee: constants.ZERO_AMOUNT, + takerFee: constants.ZERO_AMOUNT, + makerAssetAmount: constants.ZERO_AMOUNT, + takerAssetAmount: constants.ZERO_AMOUNT, + makerAssetData: constants.NULL_BYTES, + takerAssetData: constants.NULL_BYTES, + salt: generatePseudoRandomSalt(), + exchangeAddress: constants.NULL_ADDRESS, + feeRecipientAddress: constants.NULL_ADDRESS, + expirationTimeSeconds: constants.INFINITE_TIMESTAMP_SEC, + }; +} + function generateDefaultCreateOrderOpts(): { takerAddress: string; senderAddress: string; diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json index 9f57dd6fd..de5f7ba09 100644 --- a/packages/order-watcher/package.json +++ b/packages/order-watcher/package.json @@ -52,13 +52,11 @@ "@types/mocha": "^2.2.42", "@types/node": "*", "@types/sinon": "^2.2.2", - "awesome-typescript-loader": "^3.1.3", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.1", "copyfiles": "^2.0.0", "dirty-chai": "^2.0.1", - "json-loader": "^0.5.4", "make-promises-safe": "^1.1.0", "mocha": "^4.1.0", "npm-run-all": "^4.1.2", diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts index a29367485..7eefc1474 100644 --- a/packages/sol-compiler/src/compiler.ts +++ b/packages/sol-compiler/src/compiler.ts @@ -296,13 +296,16 @@ export class Compiler { compilerOutput: solc.StandardOutput, ): Promise<void> { const compiledContract = compilerOutput.contracts[contractPath][contractName]; - const sourceCodes = _.mapValues( - compilerOutput.sources, - (_1, sourceFilePath) => this._resolver.resolve(sourceFilePath).source, - ); + + // need to gather sourceCodes for this artifact, but compilerOutput.sources (the list of contract modules) + // contains listings for for every contract compiled during the compiler invocation that compiled the contract + // to be persisted, which could include many that are irrelevant to the contract at hand. So, gather up only + // the relevant sources: + const { sourceCodes, sources } = this._getSourcesWithDependencies(contractPath, compilerOutput.sources); + const contractVersion: ContractVersionData = { compilerOutput: compiledContract, - sources: compilerOutput.sources, + sources, sourceCodes, sourceTreeHashHex, compiler: { @@ -333,6 +336,80 @@ export class Compiler { await fsWrapper.writeFileAsync(currentArtifactPath, artifactString); logUtils.warn(`${contractName} artifact saved!`); } + /** + * For the given @param contractPath, populates JSON objects to be used in the ContractVersionData interface's + * properties `sources` (source code file names mapped to ID numbers) and `sourceCodes` (source code content of + * contracts) for that contract. The source code pointed to by contractPath is read and parsed directly (via + * `this._resolver.resolve().source`), as are its imports, recursively. The ID numbers for @return `sources` are + * taken from the corresponding ID's in @param fullSources, and the content for @return sourceCodes is read from + * disk (via the aforementioned `resolver.source`). + */ + private _getSourcesWithDependencies( + contractPath: string, + fullSources: { [sourceName: string]: { id: number } }, + ): { sourceCodes: { [sourceName: string]: string }; sources: { [sourceName: string]: { id: number } } } { + const sources = { [contractPath]: { id: fullSources[contractPath].id } }; + const sourceCodes = { [contractPath]: this._resolver.resolve(contractPath).source }; + this._recursivelyGatherDependencySources( + contractPath, + sourceCodes[contractPath], + fullSources, + sources, + sourceCodes, + ); + return { sourceCodes, sources }; + } + private _recursivelyGatherDependencySources( + contractPath: string, + contractSource: string, + fullSources: { [sourceName: string]: { id: number } }, + sourcesToAppendTo: { [sourceName: string]: { id: number } }, + sourceCodesToAppendTo: { [sourceName: string]: string }, + ): void { + const importStatementMatches = contractSource.match(/\nimport[^;]*;/g); + if (importStatementMatches === null) { + return; + } + for (const importStatementMatch of importStatementMatches) { + const importPathMatches = importStatementMatch.match(/\"([^\"]*)\"/); + if (importPathMatches === null || importPathMatches.length === 0) { + continue; + } + + let importPath = importPathMatches[1]; + // HACK(ablrow): We have, e.g.: + // + // importPath = "../../utils/LibBytes/LibBytes.sol" + // contractPath = "2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol" + // + // Resolver doesn't understand "../" so we want to pass + // "2.0.0/utils/LibBytes/LibBytes.sol" to resolver. + // + // This hack involves using path.resolve. But path.resolve returns + // absolute directories by default. We trick it into thinking that + // contractPath is a root directory by prepending a '/' and then + // removing the '/' the end. + // + // path.resolve("/a/b/c", ""../../d/e") === "/a/d/e" + // + const lastPathSeparatorPos = contractPath.lastIndexOf('/'); + const contractFolder = lastPathSeparatorPos === -1 ? '' : contractPath.slice(0, lastPathSeparatorPos + 1); + importPath = path.resolve('/' + contractFolder, importPath).replace('/', ''); + + if (_.isUndefined(sourcesToAppendTo[importPath])) { + sourcesToAppendTo[importPath] = { id: fullSources[importPath].id }; + sourceCodesToAppendTo[importPath] = this._resolver.resolve(importPath).source; + + this._recursivelyGatherDependencySources( + importPath, + this._resolver.resolve(importPath).source, + fullSources, + sourcesToAppendTo, + sourceCodesToAppendTo, + ); + } + } + } private _compile(solcInstance: solc.SolcInstance, standardInput: solc.StandardInput): solc.StandardOutput { const compiled: solc.StandardOutput = JSON.parse( solcInstance.compileStandardWrapper(JSON.stringify(standardInput), importPath => { diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index f9063228f..491f079d2 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -76,7 +76,7 @@ "tslint": "5.11.0", "typedoc": "0.12.0", "typescript": "3.0.1", - "webpack": "^3.1.0" + "webpack": "^4.20.2" }, "optionalDependencies": { "@ledgerhq/hw-transport-node-hid": "^4.3.0" diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index 33f557538..8213f896f 100644 --- a/packages/testnet-faucets/package.json +++ b/packages/testnet-faucets/package.json @@ -36,15 +36,15 @@ "@types/body-parser": "^1.16.1", "@types/express": "^4.0.35", "@types/lodash": "4.14.104", - "awesome-typescript-loader": "^3.1.3", + "awesome-typescript-loader": "^5.2.1", "gulp": "^3.9.1", "make-promises-safe": "^1.1.0", "nodemon": "^1.11.0", "shx": "^0.2.2", - "source-map-loader": "^0.1.6", + "source-map-loader": "^0.2.4", "tslint": "5.11.0", "typescript": "3.0.1", - "webpack": "^3.1.0", + "webpack": "^4.20.2", "webpack-node-externals": "^1.6.0" } } diff --git a/packages/website/README.md b/packages/website/README.md index 7115a3b5c..2edc17cd9 100644 --- a/packages/website/README.md +++ b/packages/website/README.md @@ -14,7 +14,7 @@ Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting ## Local Dev Setup -Requires Node version 6.9.5 or higher. +Requires Node version 6.9.5 or higher Add the following to your `/etc/hosts` file: diff --git a/packages/website/package.json b/packages/website/package.json index 8c115d8a0..3cf243645 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -7,11 +7,11 @@ "private": true, "description": "Website and 0x portal dapp", "scripts": { - "build": "NODE_ENV=production node --max_old_space_size=8192 ../../node_modules/.bin/webpack", - "build:ci": "yarn build", + "build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production", + "build:dev": "../../node_modules/.bin/webpack --mode development", "clean": "shx rm -f public/bundle*", "lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'", - "watch_without_deps": "webpack-dev-server --content-base public --https", + "dev": "webpack-dev-server --mode development --content-base public --https", "deploy_dogfood": "npm run build; aws s3 sync ./public/. s3://dogfood.0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers", "deploy_staging": "npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers", "deploy_live": "DEPLOY_ROLLBAR_SOURCEMAPS=true npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --exclude *.map.js" @@ -87,26 +87,23 @@ "@types/react-tap-event-plugin": "0.0.30", "@types/redux": "^3.6.0", "@types/web3-provider-engine": "^14.0.0", - "awesome-typescript-loader": "^3.1.3", - "copy-webpack-plugin": "^4.0.1", + "awesome-typescript-loader": "^5.2.1", "copyfiles": "^2.0.0", "css-loader": "0.23.x", - "exports-loader": "0.6.x", - "imports-loader": "0.6.x", - "json-loader": "^0.5.4", - "less-loader": "^2.2.3", + "less-loader": "^4.1.0", "make-promises-safe": "^1.1.0", "raw-loader": "^0.5.1", - "rollbar-sourcemap-webpack-plugin": "^2.3.0", + "rollbar-sourcemap-webpack-plugin": "^2.4.0", "shx": "^0.2.2", - "source-map-loader": "^0.1.6", - "style-loader": "0.13.x", + "source-map-loader": "^0.2.4", + "style-loader": "0.23.x", + "terser-webpack-plugin": "^1.1.0", "tslint": "5.11.0", "tslint-config-0xproject": "^0.0.2", "typescript": "3.0.1", - "uglifyjs-webpack-plugin": "^1.2.5", - "webpack": "^3.1.0", - "webpack-dev-middleware": "^1.10.0", - "webpack-dev-server": "^2.5.0" + "uglifyjs-webpack-plugin": "^2.0.1", + "webpack": "^4.20.2", + "webpack-cli": "3.1.2", + "webpack-dev-server": "^3.1.9" } } diff --git a/packages/website/ts/index.tsx b/packages/website/ts/index.tsx index 9e59b00ac..d4a79cc4f 100644 --- a/packages/website/ts/index.tsx +++ b/packages/website/ts/index.tsx @@ -26,47 +26,47 @@ import 'less/all.less'; // We pass modulePromise returning lambda instead of module promise, // cause we only want to import the module when the user navigates to the page. -// At the same time webpack statically parses for System.import() to determine bundle chunk split points -// so each lazy import needs it's own `System.import()` declaration. +// At the same time webpack statically parses for import() to determine bundle chunk split points +// so each lazy import needs it's own `import()` declaration. const LazyPortal = createLazyComponent('Portal', async () => - System.import<any>(/* webpackChunkName: "portal" */ 'ts/containers/portal'), + import(/* webpackChunkName: "portal" */ 'ts/containers/portal'), ); const LazyZeroExJSDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "zeroExDocs" */ 'ts/containers/zero_ex_js_documentation'), + import(/* webpackChunkName: "zeroExDocs" */ 'ts/containers/zero_ex_js_documentation'), ); const LazyContractWrappersDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "contractWrapperDocs" */ 'ts/containers/contract_wrappers_documentation'), + import(/* webpackChunkName: "contractWrapperDocs" */ 'ts/containers/contract_wrappers_documentation'), ); const LazyOrderWatcherDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "orderWatcherDocs" */ 'ts/containers/order_watcher_documentation'), + import(/* webpackChunkName: "orderWatcherDocs" */ 'ts/containers/order_watcher_documentation'), ); const LazySmartContractsDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "smartContractDocs" */ 'ts/containers/smart_contracts_documentation'), + import(/* webpackChunkName: "smartContractDocs" */ 'ts/containers/smart_contracts_documentation'), ); const LazyConnectDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "connectDocs" */ 'ts/containers/connect_documentation'), + import(/* webpackChunkName: "connectDocs" */ 'ts/containers/connect_documentation'), ); const LazyWeb3WrapperDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "web3WrapperDocs" */ 'ts/containers/web3_wrapper_documentation'), + import(/* webpackChunkName: "web3WrapperDocs" */ 'ts/containers/web3_wrapper_documentation'), ); const LazySolCompilerDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "solCompilerDocs" */ 'ts/containers/sol_compiler_documentation'), + import(/* webpackChunkName: "solCompilerDocs" */ 'ts/containers/sol_compiler_documentation'), ); const LazyJSONSchemasDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "jsonSchemasDocs" */ 'ts/containers/json_schemas_documentation'), + import(/* webpackChunkName: "jsonSchemasDocs" */ 'ts/containers/json_schemas_documentation'), ); const LazySolCovDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "solCovDocs" */ 'ts/containers/sol_cov_documentation'), + import(/* webpackChunkName: "solCovDocs" */ 'ts/containers/sol_cov_documentation'), ); const LazySubprovidersDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "subproviderDocs" */ 'ts/containers/subproviders_documentation'), + import(/* webpackChunkName: "subproviderDocs" */ 'ts/containers/subproviders_documentation'), ); const LazyOrderUtilsDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "orderUtilsDocs" */ 'ts/containers/order_utils_documentation'), + import(/* webpackChunkName: "orderUtilsDocs" */ 'ts/containers/order_utils_documentation'), ); const LazyEthereumTypesDocumentation = createLazyComponent('Documentation', async () => - System.import<any>(/* webpackChunkName: "ethereumTypesDocs" */ 'ts/containers/ethereum_types_documentation'), + import(/* webpackChunkName: "ethereumTypesDocs" */ 'ts/containers/ethereum_types_documentation'), ); const DOCUMENT_TITLE = '0x: The Protocol for Trading Tokens'; diff --git a/packages/website/ts/lazy_component.tsx b/packages/website/ts/lazy_component.tsx index dce06ed8d..9d3b9944a 100644 --- a/packages/website/ts/lazy_component.tsx +++ b/packages/website/ts/lazy_component.tsx @@ -49,7 +49,7 @@ export class LazyComponent extends React.Component<LazyComponentProps, LazyCompo * @param componentName name of exported component * @param lazyImport lambda returning module promise * we pass a lambda because we only want to require a module if it's used - * @example `const LazyPortal = createLazyComponent('Portal', () => System.import<any>('ts/containers/portal'));`` + * @example `const LazyPortal = createLazyComponent('Portal', () => import<any>('ts/containers/portal'));`` */ export const createLazyComponent = (componentName: string, lazyImport: () => Promise<any>) => { return (props: any) => { diff --git a/packages/website/webpack.config.js b/packages/website/webpack.config.js index 8653196a6..ec265be93 100644 --- a/packages/website/webpack.config.js +++ b/packages/website/webpack.config.js @@ -1,6 +1,6 @@ const path = require('path'); const webpack = require('webpack'); -const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); const RollbarSourceMapPlugin = require('rollbar-sourcemap-webpack-plugin'); const childProcess = require('child_process'); @@ -9,44 +9,7 @@ const GIT_SHA = childProcess .toString() .trim(); -const generatePlugins = () => { - let plugins = []; - if (process.env.NODE_ENV === 'production') { - plugins = plugins.concat([ - // Since we do not use moment's locale feature, we exclude them from the bundle. - // This reduces the bundle size by 0.4MB. - new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), - new webpack.DefinePlugin({ - 'process.env': { - NODE_ENV: JSON.stringify(process.env.NODE_ENV), - GIT_SHA: JSON.stringify(GIT_SHA), - }, - }), - // TODO: Revert to webpack bundled version with webpack v4. - // The v3 series bundled version does not support ES6 and - // fails to build. - new UglifyJsPlugin({ - sourceMap: true, - uglifyOptions: { - mangle: { - reserved: ['BigNumber'], - }, - }, - }), - ]); - if (process.env.DEPLOY_ROLLBAR_SOURCEMAPS === 'true') { - plugins = plugins.concat([ - new RollbarSourceMapPlugin({ - accessToken: '32c39bfa4bb6440faedc1612a9c13d28', - version: GIT_SHA, - publicPath: 'https://0xproject.com/', - }), - ]); - } - } - return plugins; -}; -module.exports = { +const config = { entry: ['./ts/index.tsx'], output: { path: path.join(__dirname, '/public'), @@ -92,10 +55,18 @@ module.exports = { test: /\.css$/, loaders: ['style-loader', 'css-loader'], }, - { - test: /\.json$/, - loader: 'json-loader', - }, + ], + }, + optimization: { + minimizer: [ + new TerserPlugin({ + sourceMap: true, + terserOptions: { + mangle: { + reserved: ['BigNumber'], + }, + }, + }), ], }, devServer: { @@ -115,5 +86,39 @@ module.exports = { }, disableHostCheck: true, }, - plugins: generatePlugins(), +}; + +module.exports = (_env, argv) => { + let plugins = []; + if (argv.mode === 'development') { + config.mode = 'development'; + } else { + config.mode = 'production'; + plugins = plugins.concat([ + // Since we do not use moment's locale feature, we exclude them from the bundle. + // This reduces the bundle size by 0.4MB. + new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify(process.env.NODE_ENV), + GIT_SHA: JSON.stringify(GIT_SHA), + }, + }), + ]); + if (process.env.DEPLOY_ROLLBAR_SOURCEMAPS === 'true') { + plugins = plugins.concat([ + new RollbarSourceMapPlugin({ + accessToken: '32c39bfa4bb6440faedc1612a9c13d28', + version: GIT_SHA, + publicPath: 'https://0xproject.com/', + }), + ]); + } + } + console.log('i 「atl」: Mode: ', config.mode); + + config.plugins = plugins; + console.log('i 「atl」: Plugin Count: ', config.plugins.length); + + return config; }; @@ -1559,12 +1559,6 @@ accounting@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/accounting/-/accounting-0.4.1.tgz#87dd4103eff7f4460f1e186f5c677ed6cf566883" -acorn-dynamic-import@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" - dependencies: - acorn "^4.0.3" - acorn-dynamic-import@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" @@ -1592,10 +1586,6 @@ acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^4.0.3: - version "4.0.13" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" - acorn@^5.0.0: version "5.5.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" @@ -1616,9 +1606,9 @@ aes-js@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" -aes-js@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.1.tgz#89fd1f94ae51b4c72d62466adc1a7323ff52f072" +aes-js@^0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-0.2.4.tgz#94b881ab717286d015fa219e08fb66709dda5a3d" ajv-errors@^1.0.0: version "1.0.0" @@ -1848,13 +1838,6 @@ array-ify@^1.0.0: version "1.0.0" resolved "http://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" -array-includes@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.7.0" - array-map@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" @@ -2020,18 +2003,6 @@ autoprefixer@^6.3.1: postcss "^5.2.16" postcss-value-parser "^3.2.3" -awesome-typescript-loader@^3.1.3: - version "3.5.0" - resolved "https://registry.yarnpkg.com/awesome-typescript-loader/-/awesome-typescript-loader-3.5.0.tgz#4d4d10cba7a04ed433dfa0334250846fb11a1a5a" - dependencies: - chalk "^2.3.1" - enhanced-resolve "3.3.0" - loader-utils "^1.1.0" - lodash "^4.17.4" - micromatch "^3.0.3" - mkdirp "^0.5.1" - source-map-support "^0.5.3" - awesome-typescript-loader@^5.2.1: version "5.2.1" resolved "https://registry.npmjs.org/awesome-typescript-loader/-/awesome-typescript-loader-5.2.1.tgz#a41daf7847515f4925cdbaa3075d61f289e913fc" @@ -2791,6 +2762,10 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +base-x@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-1.1.0.tgz#42d3d717474f9ea02207f6d1aa1f426913eeb7ac" + base-x@^3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.4.tgz#94c1788736da065edb1d68808869e357c977fa77" @@ -3229,7 +3204,7 @@ bs-logger@0.x: dependencies: fast-json-stable-stringify "^2.0.0" -bs58@=4.0.1, bs58@^4.0.0: +bs58@=4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" dependencies: @@ -3239,13 +3214,18 @@ bs58@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d" -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" +bs58@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-3.1.0.tgz#d4c26388bf4804cac714141b1945aa47e5eb248e" + dependencies: + base-x "^1.1.0" + +bs58check@^1.0.8: + version "1.3.4" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-1.3.4.tgz#c52540073749117714fa042c3047eb8f9151cbf8" dependencies: - bs58 "^4.0.0" + bs58 "^3.1.0" create-hash "^1.1.0" - safe-buffer "^5.1.2" bser@^2.0.0: version "2.0.0" @@ -3382,6 +3362,25 @@ cacache@^10.0.4: unique-filename "^1.1.0" y18n "^4.0.0" +cacache@^11.0.2, cacache@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.2.0.tgz#617bdc0b02844af56310e411c0878941d5739965" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + figgy-pudding "^3.1.0" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.3" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.0" + unique-filename "^1.1.0" + y18n "^4.0.0" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -4018,7 +4017,7 @@ commander@^2.11.0: version "2.18.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" -commander@^2.7.1: +commander@^2.7.1, commander@~2.17.1: version "2.17.1" resolved "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" @@ -4252,19 +4251,6 @@ copy-to-clipboard@^3: dependencies: toggle-selection "^1.0.3" -copy-webpack-plugin@^4.0.1: - version "4.5.2" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.5.2.tgz#d53444a8fea2912d806e78937390ddd7e632ee5c" - dependencies: - cacache "^10.0.4" - find-cache-dir "^1.0.0" - globby "^7.1.1" - is-glob "^4.0.0" - loader-utils "^1.1.0" - minimatch "^3.0.4" - p-limit "^1.0.0" - serialize-javascript "^1.4.0" - copyfiles@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-1.2.0.tgz#a8da3ac41aa2220ae29bd3c58b6984294f2c593c" @@ -5278,24 +5264,6 @@ end-of-stream@~0.1.5: dependencies: once "~1.3.0" -enhanced-resolve@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.3.0.tgz#950964ecc7f0332a42321b673b38dc8ff15535b3" - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - object-assign "^4.0.1" - tapable "^0.2.5" - -enhanced-resolve@^3.4.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - object-assign "^4.0.1" - tapable "^0.2.7" - enhanced-resolve@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a" @@ -5393,7 +5361,7 @@ es-abstract@^1.10.0, es-abstract@^1.5.1, es-abstract@^1.6.1: is-callable "^1.1.3" is-regex "^1.0.4" -es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.7.0: +es-abstract@^1.4.3, es-abstract@^1.5.0: version "1.11.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.11.0.tgz#cce87d518f0496893b1a30cd8461835535480681" dependencies: @@ -5411,7 +5379,7 @@ es-to-primitive@^1.1.1: is-date-object "^1.0.1" is-symbol "^1.0.1" -es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: +es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: version "0.10.42" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.42.tgz#8c07dd33af04d5dcd1310b5cef13bea63a89ba8d" dependencies: @@ -5419,7 +5387,7 @@ es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: es6-symbol "~3.1.1" next-tick "1" -es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: +es6-iterator@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" dependencies: @@ -5427,17 +5395,6 @@ es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-map@^0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-set "~0.1.5" - es6-symbol "~3.1.1" - event-emitter "~0.3.5" - es6-object-assign@^1.0.3: version "1.1.0" resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" @@ -5452,32 +5409,13 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -es6-set@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-symbol "3.1.1" - event-emitter "~0.3.5" - -es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: +es6-symbol@^3.1.1, es6-symbol@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" dependencies: d "1" es5-ext "~0.10.14" -es6-weak-map@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" - dependencies: - d "1" - es5-ext "^0.10.14" - es6-iterator "^2.0.1" - es6-symbol "^3.1.1" - escape-html@1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -5508,15 +5446,6 @@ escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" -escope@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" - dependencies: - es6-map "^0.1.3" - es6-weak-map "^2.0.1" - esrecurse "^4.1.0" - estraverse "^4.1.1" - eslint-scope@^3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" @@ -5852,7 +5781,7 @@ ethereumjs-util@5.1.5, ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumj safe-buffer "^5.1.1" secp256k1 "^3.0.1" -ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0: +ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumjs-util@^4.4.0: version "4.5.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz#3e9428b317eebda3d7260d854fddda954b1f1bc6" dependencies: @@ -5906,18 +5835,17 @@ ethereumjs-vm@^2.0.2, ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4: rustbn.js "~0.1.1" safe-buffer "^5.1.1" -ethereumjs-wallet@~0.6.0: - version "0.6.2" - resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz#67244b6af3e8113b53d709124b25477b64aeccda" +ethereumjs-wallet@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz#82763b1697ee7a796be7155da9dfb49b2f98cfdb" dependencies: - aes-js "^3.1.1" - bs58check "^2.1.2" - ethereumjs-util "^5.2.0" - hdkey "^1.0.0" - safe-buffer "^5.1.2" + aes-js "^0.2.3" + bs58check "^1.0.8" + ethereumjs-util "^4.4.0" + hdkey "^0.7.0" scrypt.js "^0.2.0" - utf8 "^3.0.0" - uuid "^3.3.2" + utf8 "^2.1.1" + uuid "^2.0.1" ethers@3.0.22: version "3.0.22" @@ -5979,13 +5907,6 @@ ethjs-util@^0.1.3: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" -event-emitter@~0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - dependencies: - d "1" - es5-ext "~0.10.14" - event-stream@~3.3.0: version "3.3.4" resolved "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" @@ -6134,13 +6055,6 @@ expect@^23.6.0: jest-message-util "^23.4.0" jest-regex-util "^23.3.0" -exports-loader@0.6.x: - version "0.6.4" - resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-0.6.4.tgz#d70fc6121975b35fc12830cf52754be2740fc886" - dependencies: - loader-utils "^1.0.2" - source-map "0.5.x" - express@^4.14.0, express@^4.15.2, express@^4.16.2: version "4.16.3" resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" @@ -6326,6 +6240,10 @@ fetch-ponyfill@^4.0.0: dependencies: node-fetch "~1.7.1" +figgy-pudding@^3.1.0, figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + figures@^1.3.5, figures@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" @@ -6420,6 +6338,14 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-cache-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^3.0.0" + find-index@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" @@ -6745,7 +6671,7 @@ ganache-core@0xProject/ganache-core#monorepo-dep: ethereumjs-tx "0xProject/ethereumjs-tx#fake-tx-include-signature-by-default" ethereumjs-util "^5.2.0" ethereumjs-vm "2.3.5" - ethereumjs-wallet "~0.6.0" + ethereumjs-wallet "0.6.0" fake-merkle-patricia-tree "~1.0.1" heap "~0.2.6" js-scrypt "^0.2.0" @@ -7090,17 +7016,6 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globby@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" - dependencies: - array-union "^1.0.1" - dir-glob "^2.0.0" - glob "^7.1.2" - ignore "^3.3.5" - pify "^3.0.0" - slash "^1.0.0" - globby@^8.0.0, globby@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" @@ -7454,21 +7369,13 @@ hawk@~6.0.2: hoek "4.x.x" sntp "2.x.x" -hdkey@^0.7.1: +hdkey@^0.7.0, hdkey@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-0.7.1.tgz#caee4be81aa77921e909b8d228dd0f29acaee632" dependencies: coinstring "^2.0.0" secp256k1 "^3.0.1" -hdkey@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" - dependencies: - coinstring "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" - he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" @@ -7615,15 +7522,6 @@ http-parser-js@>=0.4.0: version "0.4.11" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.11.tgz#5b720849c650903c27e521633d94696ee95f3529" -http-proxy-middleware@~0.17.4: - version "0.17.4" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" - dependencies: - http-proxy "^1.16.2" - is-glob "^3.1.0" - lodash "^4.17.2" - micromatch "^2.3.11" - http-proxy-middleware@~0.18.0: version "0.18.0" resolved "http://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz#0987e6bb5a5606e5a69168d8f967a87f15dd8aab" @@ -7792,13 +7690,6 @@ import-local@^2.0.0: pkg-dir "^3.0.0" resolve-cwd "^2.0.0" -imports-loader@0.6.x: - version "0.6.5" - resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-0.6.5.tgz#ae74653031d59e37b3c2fb2544ac61aeae3530a6" - dependencies: - loader-utils "0.2.x" - source-map "0.1.x" - imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -7931,12 +7822,6 @@ intel@1.2.0: symbol "~0.3.1" utcstring "~0.1.0" -internal-ip@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" - dependencies: - meow "^3.3.0" - internal-ip@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/internal-ip/-/internal-ip-3.0.1.tgz#df5c99876e1d2eb2ea2d74f520e3f669a00ece27" @@ -9021,10 +8906,6 @@ json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" -json-loader@^0.5.4: - version "0.5.7" - resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" - json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -9330,11 +9211,13 @@ left-pad@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" -less-loader@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-2.2.3.tgz#b6d8f8139c8493df09d992a93a00734b08f84528" +less-loader@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.1.0.tgz#2c1352c5b09a4f84101490274fd51674de41363e" dependencies: - loader-utils "^0.2.5" + clone "^2.1.1" + loader-utils "^1.1.0" + pify "^3.0.0" less@^2.7.2: version "2.7.3" @@ -9565,22 +9448,22 @@ loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" -loader-utils@0.2.x, loader-utils@^0.2.5, loader-utils@~0.2.2: - version "0.2.17" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" +loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" dependencies: big.js "^3.1.3" emojis-list "^2.0.0" json5 "^0.5.0" - object-assign "^4.0.1" -loader-utils@^1.0.2, loader-utils@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" +loader-utils@~0.2.2: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" dependencies: big.js "^3.1.3" emojis-list "^2.0.0" json5 "^0.5.0" + object-assign "^4.0.1" localstorage-down@^0.6.7: version "0.6.7" @@ -9947,6 +9830,13 @@ lru-cache@^4.0.1, lru-cache@^4.1.1: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + lru-cache@~2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" @@ -10244,7 +10134,7 @@ micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.0.3, micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9: +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" dependencies: @@ -10309,7 +10199,7 @@ mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" -mime@^1.2.11, mime@^1.3.4, mime@^1.5.0: +mime@^1.2.11, mime@^1.3.4: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -10409,6 +10299,21 @@ mississippi@^2.0.0: stream-each "^1.1.0" through2 "^2.0.0" +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" @@ -11411,7 +11316,7 @@ p-lazy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-lazy/-/p-lazy-1.0.0.tgz#ec53c802f2ee3ac28f166cc82d0b2b02de27a835" -p-limit@^1.0.0, p-limit@^1.1.0: +p-limit@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" dependencies: @@ -12464,6 +12369,13 @@ pump@^2.0.0, pump@^2.0.1: end-of-stream "^1.1.0" once "^1.3.1" +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + pumpify@^1.3.3: version "1.4.0" resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb" @@ -13557,9 +13469,9 @@ rlp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.0.0.tgz#9db384ff4b89a8f61563d92395d8625b18f3afb0" -rollbar-sourcemap-webpack-plugin@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/rollbar-sourcemap-webpack-plugin/-/rollbar-sourcemap-webpack-plugin-2.3.0.tgz#47176fd6441d1ce17b4d3c7e9c9cf7f2076b0485" +rollbar-sourcemap-webpack-plugin@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/rollbar-sourcemap-webpack-plugin/-/rollbar-sourcemap-webpack-plugin-2.4.0.tgz#0d864fe4d7a141a09fafd417415b704f95faddad" dependencies: async "^2.6.0" babel-runtime "^6.26.0" @@ -14149,17 +14061,6 @@ sntp@2.x.x: dependencies: hoek "4.x.x" -sockjs-client@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12" - dependencies: - debug "^2.6.6" - eventsource "0.1.6" - faye-websocket "~0.11.0" - inherits "^2.0.1" - json3 "^3.3.2" - url-parse "^1.1.8" - sockjs-client@1.1.5: version "1.1.5" resolved "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.5.tgz#1bb7c0f7222c40f42adf14f4442cbd1269771a83" @@ -14243,13 +14144,12 @@ source-list-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" -source-map-loader@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.1.6.tgz#c09903da6d73b9e53b7ed8ee5245597051e98e91" +source-map-loader@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.2.4.tgz#c18b0dc6e23bf66f6792437557c569a11e072271" dependencies: - async "^0.9.0" - loader-utils "~0.2.2" - source-map "~0.1.33" + async "^2.5.0" + loader-utils "^1.1.0" source-map-resolve@^0.5.0: version "0.5.1" @@ -14280,26 +14180,27 @@ source-map-support@^0.5.0, source-map-support@^0.5.3: dependencies: source-map "^0.6.0" +source-map-support@~0.5.6: + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" -source-map@0.1.x, source-map@~0.1.33: - version "0.1.43" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" - dependencies: - amdefine ">=0.0.4" - -source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - source-map@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" dependencies: amdefine ">=0.0.4" +source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -14429,6 +14330,12 @@ ssri@^5.2.4: dependencies: safe-buffer "^5.1.1" +ssri@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + dependencies: + figgy-pudding "^3.5.1" + stack-trace@0.0.9: version "0.0.9" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695" @@ -14689,11 +14596,12 @@ strong-log-transformer@^1.0.6: moment "^2.6.0" through "^2.3.4" -style-loader@0.13.x: - version "0.13.2" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.13.2.tgz#74533384cf698c7104c7951150b49717adc2f3bb" +style-loader@0.23.x: + version "0.23.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.0.tgz#8377fefab68416a2e05f1cabd8c3a3acfcce74f1" dependencies: - loader-utils "^1.0.2" + loader-utils "^1.1.0" + schema-utils "^0.4.5" styled-components@^3.3.0: version "3.3.0" @@ -14768,7 +14676,7 @@ supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3: dependencies: has-flag "^1.0.0" -supports-color@^4.0.0, supports-color@^4.2.1: +supports-color@^4.0.0: version "4.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" dependencies: @@ -14883,10 +14791,6 @@ table@4.0.2: slice-ansi "1.0.0" string-width "^2.1.1" -tapable@^0.2.5, tapable@^0.2.7: - version "0.2.8" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" - tapable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" @@ -15013,6 +14917,27 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" +terser-webpack-plugin@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.1.0.tgz#cf7c25a1eee25bf121f4a587bb9e004e3f80e528" + dependencies: + cacache "^11.0.2" + find-cache-dir "^2.0.0" + schema-utils "^1.0.0" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + terser "^3.8.1" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +terser@^3.8.1: + version "3.9.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.9.2.tgz#d139d8292eb3a23091304c934fb539d9f456fb19" + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + source-map-support "~0.5.6" + test-exclude@^4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa" @@ -15124,10 +15049,6 @@ time-stamp@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" -time-stamp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357" - timed-out@^4.0.0, timed-out@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -15536,7 +15457,7 @@ uglify-es@^3.3.4: commander "~2.13.0" source-map "~0.6.1" -uglify-js@^2.6, uglify-js@^2.8.29: +uglify-js@^2.6: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" dependencies: @@ -15545,19 +15466,18 @@ uglify-js@^2.6, uglify-js@^2.8.29: optionalDependencies: uglify-to-browserify "~1.0.0" +uglify-js@^3.0.0: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" -uglifyjs-webpack-plugin@^0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" - dependencies: - source-map "^0.5.6" - uglify-js "^2.8.29" - webpack-sources "^1.0.1" - -uglifyjs-webpack-plugin@^1.2.4, uglifyjs-webpack-plugin@^1.3.0: +uglifyjs-webpack-plugin@^1.2.4: version "1.3.0" resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz#75f548160858163a08643e086d5fefe18a5d67de" dependencies: @@ -15570,16 +15490,16 @@ uglifyjs-webpack-plugin@^1.2.4, uglifyjs-webpack-plugin@^1.3.0: webpack-sources "^1.1.0" worker-farm "^1.5.2" -uglifyjs-webpack-plugin@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.5.tgz#2ef8387c8f1a903ec5e44fa36f9f3cbdcea67641" +uglifyjs-webpack-plugin@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-2.0.1.tgz#f346af53ed496ce72fef462517d417f62bec3010" dependencies: - cacache "^10.0.4" - find-cache-dir "^1.0.0" - schema-utils "^0.4.5" + cacache "^11.2.0" + find-cache-dir "^2.0.0" + schema-utils "^1.0.0" serialize-javascript "^1.4.0" source-map "^0.6.1" - uglify-es "^3.3.4" + uglify-js "^3.0.0" webpack-sources "^1.1.0" worker-farm "^1.5.2" @@ -15855,10 +15775,6 @@ utf8@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" -utf8@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -16135,14 +16051,6 @@ watch@~0.18.0: exec-sh "^0.2.0" minimist "^1.2.0" -watchpack@^1.4.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.5.0.tgz#231e783af830a22f8966f65c4c4bacc814072eed" - dependencies: - chokidar "^2.0.2" - graceful-fs "^4.1.2" - neo-async "^2.5.0" - watchpack@^1.5.0: version "1.6.0" resolved "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" @@ -16490,6 +16398,21 @@ webpack-addons@^1.1.5: dependencies: jscodeshift "^0.4.0" +webpack-cli@3.1.2, webpack-cli@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.1.2.tgz#17d7e01b77f89f884a2bbf9db545f0f6a648e746" + dependencies: + chalk "^2.4.1" + cross-spawn "^6.0.5" + enhanced-resolve "^4.1.0" + global-modules-path "^2.3.0" + import-local "^2.0.0" + interpret "^1.1.0" + loader-utils "^1.1.0" + supports-color "^5.5.0" + v8-compile-cache "^2.0.2" + yargs "^12.0.2" + webpack-cli@^2.0.9: version "2.1.3" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-2.1.3.tgz#65d166851abaa56067ef3f716b02a97ba6bbe84d" @@ -16521,31 +16444,6 @@ webpack-cli@^2.0.9: yeoman-environment "^2.0.0" yeoman-generator "^2.0.4" -webpack-cli@^3.1.1: - version "3.1.2" - resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.1.2.tgz#17d7e01b77f89f884a2bbf9db545f0f6a648e746" - dependencies: - chalk "^2.4.1" - cross-spawn "^6.0.5" - enhanced-resolve "^4.1.0" - global-modules-path "^2.3.0" - import-local "^2.0.0" - interpret "^1.1.0" - loader-utils "^1.1.0" - supports-color "^5.5.0" - v8-compile-cache "^2.0.2" - yargs "^12.0.2" - -webpack-dev-middleware@1.12.2, webpack-dev-middleware@^1.10.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e" - dependencies: - memory-fs "~0.4.1" - mime "^1.5.0" - path-is-absolute "^1.0.0" - range-parser "^1.0.3" - time-stamp "^2.0.0" - webpack-dev-middleware@3.4.0: version "3.4.0" resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz#1132fecc9026fd90f0ecedac5cbff75d1fb45890" @@ -16555,38 +16453,6 @@ webpack-dev-middleware@3.4.0: range-parser "^1.0.3" webpack-log "^2.0.0" -webpack-dev-server@^2.5.0: - version "2.11.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.11.2.tgz#1f4f4c78bf1895378f376815910812daf79a216f" - dependencies: - ansi-html "0.0.7" - array-includes "^3.0.3" - bonjour "^3.5.0" - chokidar "^2.0.0" - compression "^1.5.2" - connect-history-api-fallback "^1.3.0" - debug "^3.1.0" - del "^3.0.0" - express "^4.16.2" - html-entities "^1.2.0" - http-proxy-middleware "~0.17.4" - import-local "^1.0.0" - internal-ip "1.2.0" - ip "^1.1.5" - killable "^1.0.0" - loglevel "^1.4.1" - opn "^5.1.0" - portfinder "^1.0.9" - selfsigned "^1.9.1" - serve-index "^1.7.2" - sockjs "0.3.19" - sockjs-client "1.1.4" - spdy "^3.4.1" - strip-ansi "^3.0.0" - supports-color "^5.1.0" - webpack-dev-middleware "1.12.2" - yargs "6.6.0" - webpack-dev-server@^3.1.9: version "3.1.9" resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.9.tgz#8b32167624d2faff40dcedc2cbce17ed1f34d3e0" @@ -16640,7 +16506,7 @@ webpack-node-externals@^1.6.0: version "1.7.2" resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" -webpack-sources@^1.0.1, webpack-sources@^1.1.0: +webpack-sources@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" dependencies: @@ -16654,33 +16520,6 @@ webpack-sources@^1.3.0: source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^3.1.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.11.0.tgz#77da451b1d7b4b117adaf41a1a93b5742f24d894" - dependencies: - acorn "^5.0.0" - acorn-dynamic-import "^2.0.0" - ajv "^6.1.0" - ajv-keywords "^3.1.0" - async "^2.1.2" - enhanced-resolve "^3.4.0" - escope "^3.6.0" - interpret "^1.0.0" - json-loader "^0.5.4" - json5 "^0.5.1" - loader-runner "^2.3.0" - loader-utils "^1.1.0" - memory-fs "~0.4.1" - mkdirp "~0.5.0" - node-libs-browser "^2.0.0" - source-map "^0.5.3" - supports-color "^4.2.1" - tapable "^0.2.7" - uglifyjs-webpack-plugin "^0.4.6" - watchpack "^1.4.0" - webpack-sources "^1.0.1" - yargs "^8.0.2" - webpack@^4.20.2: version "4.20.2" resolved "https://registry.npmjs.org/webpack/-/webpack-4.20.2.tgz#89f6486b6bb276a91b0823453d377501fc625b5a" @@ -17061,12 +16900,6 @@ yargs-parser@^2.4.1: camelcase "^3.0.0" lodash.assign "^4.0.6" -yargs-parser@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" - dependencies: - camelcase "^3.0.0" - yargs-parser@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" @@ -17125,24 +16958,6 @@ yargs@12.0.2, yargs@^12.0.2: y18n "^3.2.1 || ^4.0.0" yargs-parser "^10.1.0" -yargs@6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" - dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^4.2.0" - yargs@^10.0.3: version "10.1.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5" |