diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..67a69db --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: node_js + +node_js: + - "8" \ No newline at end of file diff --git a/ecosystem.config.js b/ecosystem.config.js index fdc5e5f..6114e89 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -18,26 +18,42 @@ module.exports = { * http://pm2.keymetrics.io/docs/usage/application-declaration/ */ apps: [ + // Low-level services necessary for Chlu ecosystem { - name: 'chlu-marketplace', - script: projectPath('chlu-marketplace-js/src/bin/index.js'), + name: 'rendezvous', + script: projectPath('libp2p-websocket-star-rendezvous/src/bin.js'), watch: false, - args: 'serve -c marketplace-config.json', + args: '--port=4003', max_memory_restart: '250M' }, { - name: 'chlu-service-node', - script: projectPath('chlu-ipfs-support/bin/chlu-service-node.js'), + name: 'chlu-collector', + script: projectPath('chlu-collector/src/bin.js'), watch: false, - // This is running on the master branch and does not require additional CLI params args: `start --network ${network} ` + (blockcypherToken ? ` --btc ${blockcypherToken}` : ''), max_memory_restart: '250M' }, + // Mid-level services (API Gateways) { - name: 'rendezvous', - script: projectPath('libp2p-websocket-star-rendezvous/src/bin.js'), + name: 'chlu-api-query', + script: projectPath('chlu-api-query/src/bin.js'), watch: false, - args: '--port=4003', + args: `start --network ${network} ` + (blockcypherToken ? ` --btc ${blockcypherToken}` : ''), + max_memory_restart: '250M' + }, + { + name: 'chlu-api-publish', + script: projectPath('chlu-api-publish/src/bin.js'), + watch: false, + args: `start --network ${network} ` + (blockcypherToken ? ` --btc ${blockcypherToken}` : ''), + max_memory_restart: '250M' + }, + // High-level services built on Chlu libraries + { + name: 'chlu-marketplace', + script: projectPath('chlu-marketplace-js/src/bin/index.js'), + watch: false, + args: 'serve -c marketplace-config.json', max_memory_restart: '250M' }, { diff --git a/package.json b/package.json index 0f5b363..52ee4a2 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,63 @@ "version": "1.0.0", "license": "MIT", "private": true, + "scripts": { + "test": "mocha --opts tests/mocha.opts", + "start": "bash ./start.sh" + }, "dependencies": { - "chlu-did-service": "ChluNetwork/chlu-did-service#upgrade-chlu", - "chlu-ipfs-support": "ChluNetwork/chlu-ipfs-support#protobuf-upgrade", + "chlu-api-publish": "ChluNetwork/chlu-api-publish#implementation", + "chlu-api-query": "ChluNetwork/chlu-api-query#implementation", + "chlu-collector": "ChluNetwork/chlu-collector#implementation", + "chlu-did-service": "ChluNetwork/chlu-did-service#upgrade-chlu2", "chlu-marketplace-js": "ChluNetwork/chlu-marketplace-js#upgrade-chlu", "libp2p-websocket-star-rendezvous": "^0.2.3", "node-env-file": "^0.1.8" + }, + "devDependencies": { + "chai": "^4.1.2", + "chlu-api-client": "ChluNetwork/chlu-api-client-js#implementation", + "eslint": "^4.12.0", + "lodash": "^4.17.10", + "mocha": "^5.2.0", + "rimraf": "^2.6.2", + "sinon": "^6.1.4" + }, + "eslintConfig": { + "root": true, + "extends": [ + "eslint:recommended" + ], + "parserOptions": { + "ecmaVersion": 8 + }, + "env": { + "es6": true, + "browser": true, + "node": true, + "jest": true + }, + "rules": { + "indent": [ + "error", + 4 + ], + "quotes": [ + "error", + "single", + { + "avoidEscape": true + } + ], + "no-console": 0, + "no-debugger": 1, + "no-var": 1, + "no-trailing-spaces": 0, + "eol-last": 0, + "no-underscore-dangle": 0, + "no-alert": 0, + "no-lone-blocks": 0 + }, + "globals": {} } } diff --git a/tests/api.test.js b/tests/api.test.js new file mode 100644 index 0000000..9065b0f --- /dev/null +++ b/tests/api.test.js @@ -0,0 +1,307 @@ +const ChluIPFS = require('chlu-ipfs-support') +const ChluAPIClient = require('chlu-api-client') +const ChluAPIQuery = require('chlu-api-query') +const ChluAPIPublish = require('chlu-api-publish') +const ChluCollector = require('chlu-collector') +const startMarketplace = require('chlu-marketplace-js/src/bin/serve.js') +const logger = require('chlu-ipfs-support/tests/utils/logger'); +const { createIPFS } = require('chlu-ipfs-support/tests/utils/ipfs'); +const { getFakeReviewRecord } = require('chlu-ipfs-support/tests/utils/protobuf'); +const btcUtils = require('chlu-ipfs-support/tests/utils/bitcoin'); +const path = require('path') +const os = require('os') +const rimraf = require('rimraf') +const expect = require('chai').expect +const { get } = require('lodash') +const sinon = require('sinon') + +require('./index.js') + +function getTestDir(name, date) { + return path.join(os.tmpdir(), `chlu-integration-test-${date}`, name) +} + +const marketplacePort = 3101 + +describe('Integration: API Client + ChluIPFS with Query+Publish API Servers and Collector', () => { + + let api, customer, vendor, publishServer, queryServer, collector, makeDID, mkt + + const verbose = false // set this to true to get all components to log debug strings + + before(async () => { + const date = Date.now() + // Use custom port so it does not conflict + const queryPort = 3105 + const publishPort = 3106 + queryServer = new ChluAPIQuery({ + port: queryPort, + logger: logger('Query', verbose), + chluIpfsConfig: { + directory: getTestDir('query-server', date), + logger: logger('Query', verbose) + } + }) + queryServer.chluIpfs.ipfs = await createIPFS({ + repo: getTestDir('query-server/ipfs', date) + }) + publishServer = new ChluAPIPublish({ + port: publishPort, + logger: logger('Publish', verbose), + chluIpfsConfig: { + directory: getTestDir('publish-server', date), + logger: logger('Query', verbose) + } + }) + publishServer.chluIpfs.ipfs = await createIPFS({ + repo: getTestDir('publish-server/ipfs', date) + }) + api = new ChluAPIClient({ + publishApiUrl: `http://localhost:${publishPort}`, + queryApiUrl: `http://localhost:${queryPort}`, + directory: getTestDir('api-client', date), + logger: logger('Client', verbose), + }) + customer = new ChluIPFS({ + directory: getTestDir('customer', date), + logger: logger('Customer', verbose) + }) + customer.ipfs = await createIPFS({ + repo: getTestDir('customer/ipfs', date) + }) + vendor = new ChluIPFS({ + directory: getTestDir('vendor', date), + logger: logger('Vendor', verbose) + }) + vendor.ipfs = await createIPFS({ + repo: getTestDir('vendor/ipfs', date) + }) + collector = new ChluIPFS({ + directory: getTestDir('collector', date), + logger: logger('Collector', verbose) + }) + collector.ipfs = await createIPFS({ + repo: getTestDir('collector/ipfs', date) + }) + collector.collector = new ChluCollector(collector) + + const marketplace = await startMarketplace(marketplacePort, { + marketplaceLocation: `http://localhost:${marketplacePort}`, + logger: logger('Chlu Marketplace', verbose), + chluIpfs: { + network: 'experimental', + directory: getTestDir('marketplace', date) + }, + db: { + password: 'test', + storage: path.join(getTestDir('marketplace/db'), 'db.sqlite') + }, + ipfs: await createIPFS({ + repo: getTestDir('marketplace/ipfs', date) + }) + }) + mkt = marketplace.mkt + + // Spies and mocks + sinon.spy(collector, 'pin') // Spy pinning activity of Collector + + // Set up mocks to make validator work + publishServer.chluIpfs.bitcoin.Blockcypher = btcUtils.BlockcypherMock; + queryServer.chluIpfs.bitcoin.Blockcypher = btcUtils.BlockcypherMock; + collector.bitcoin.Blockcypher = btcUtils.BlockcypherMock; + customer.bitcoin.Blockcypher = btcUtils.BlockcypherMock; + + // Start modules + await collector.collector.start() + await collector.start() + await queryServer.start() + await publishServer.start() + await api.start() + await customer.start() + await customer.importDID(await api.exportDID(), false) + await vendor.start() + + await vendor.vendor.registerToMarketplace(`http://localhost:${marketplacePort}`) + const v = await vendor.exportDID() + const m = await mkt.chluIpfs.exportDID() + + // Do some DID prework to make sure nodes have everything they need + + // wait until API Client DID is replicated + await queryServer.chluIpfs.getDID(api.didIpfsHelper.didId, true) + await customer.getDID(api.didIpfsHelper.didId, true) + await publishServer.chluIpfs.getDID(api.didIpfsHelper.didId, true) + // wait for Publish and Query to have DIDs for vendor and marketplace + await queryServer.chluIpfs.getDID(v.publicDidDocument.id, true) + await queryServer.chluIpfs.getDID(m.publicDidDocument.id, true) + await customer.getDID(v.publicDidDocument.id, true) + await customer.getDID(m.publicDidDocument.id, true) + await publishServer.chluIpfs.getDID(v.publicDidDocument.id, true) + await publishServer.chluIpfs.getDID(m.publicDidDocument.id, true) + // IMPORTANT note for the future: do not parallelize these operations, + // it introduces some kind of OrbitDB bug where the tests fail intermittently + }) + + after(async () => { + try { + await collector.collector.stop() + await api.stop() + await customer.stop() + await publishServer.stop() + await queryServer.stop() + await mkt.stop() + await collector.stop() + } catch(error){ + console.log(error) + } + cleanup() + }) + + function cleanup() { + rimraf.sync(publishServer.chluIpfs.directory); + rimraf.sync(collector.directory); + rimraf.sync(queryServer.chluIpfs.directory); + rimraf.sync(api.directory); + } + + function setupBtcMock(multihash, rr) { + // delete cached info, since we are about to change it + collector.cache.cache.del(btcUtils.exampleTransaction.hash); + customer.cache.cache.del(btcUtils.exampleTransaction.hash); + publishServer.chluIpfs.cache.cache.del(btcUtils.exampleTransaction.hash); + queryServer.chluIpfs.cache.cache.del(btcUtils.exampleTransaction.hash); + // tell mock btc module to return a TX that matches the RR + collector.bitcoin.api.returnMatchingTXForRR(Object.assign({}, rr, { multihash })); + customer.bitcoin.api.returnMatchingTXForRR(Object.assign({}, rr, { multihash })); + publishServer.chluIpfs.bitcoin.api.returnMatchingTXForRR(Object.assign({}, rr, { multihash })); + queryServer.chluIpfs.bitcoin.api.returnMatchingTXForRR(Object.assign({}, rr, { multihash })); + } + + async function preparePoPR(poprData) { + const vendorId = vendor.didIpfsHelper.didId + const { popr } = await mkt.createPoPR(vendorId, poprData) + expect(popr.marketplace_url).to.equal(`http://localhost:${marketplacePort}`) + return popr + } + + describe('API Client + Customer ChluIPFS with API Servers', () => { + + it('client DID generated when starting is published', async () => { + expect(customer.didIpfsHelper.didId).to.equal(api.didIpfsHelper.didId) + const didId = get(await api.exportDID(), 'publicDidDocument.id') + // check that the publish server has it + expect(get(await publishServer.chluIpfs.getDID(didId), 'id')).to.equal(didId) + // check that the collector picks it up + expect(get(await collector.getDID(didId, true), 'id')).to.equal(didId) + // check that the query server picks it up too + expect(get(await queryServer.chluIpfs.getDID(didId, true), 'id')).to.equal(didId) + }) + + it('ChluIPFS stores a verified review record, then API Client reads it', async () => { + const reviewRecord = await getFakeReviewRecord() + reviewRecord.popr = await preparePoPR(reviewRecord.popr); + // Store the RR + const multihash = await customer.storeReviewRecord(reviewRecord, { + publish: false + }) + // set up btc mock to return the right content + setupBtcMock(multihash, reviewRecord); + const multihash2 = await customer.storeReviewRecord(reviewRecord, { + publish: true, + bitcoinTransactionHash: 'fake', + expectedMultihash: multihash + }) + expect(multihash).to.equal(multihash2) + // Check that it's present in the list for all three + expect(await publishServer.chluIpfs.getReviewList()).to.contain(multihash) + expect(await queryServer.chluIpfs.getReviewList()).to.contain(multihash) + expect(await collector.getReviewList()).to.contain(multihash) + // Check that the collector pinned it + expect(collector.pin.calledWith(multihash)).to.be.true + // Read it + const readRecord = await api.readReviewRecord(multihash) + expect(readRecord.requestedMultihash).to.equal(multihash) + // Check that it was signed by the customer + expect(readRecord.customer_signature.creator).to.equal(api.didIpfsHelper.didId) + expect(readRecord.issuer_signature.creator).to.equal(api.didIpfsHelper.didId) + }) + + it('API Client publishes a DID, then reads it', async () => { + const did = await api.didIpfsHelper.chluDID.generateDID() + collector.didIpfsHelper.publish(did) + const result = await api.getDID(did.publicDidDocument.id, true) + expect(result).to.deep.equal(did.publicDidDocument) + }) + + it('ChluIPFS publishes a review, then API Client reads review records by author', async () => { + const reviewRecord = await getFakeReviewRecord() + reviewRecord.popr = await preparePoPR(reviewRecord.popr); + // Store the RR + const multihash = await customer.storeReviewRecord(reviewRecord, { + publish: false + }) + // set up btc mock to return the right content + setupBtcMock(multihash, reviewRecord); + // Publish it using the Publish Server + await customer.storeReviewRecord(reviewRecord, { + publish: true, + bitcoinTransactionHash: 'fake', + expectedMultihash: multihash + }) + // Read it from Query Server + const rr = await queryServer.chluIpfs.readReviewRecord(multihash) + // Make sure customer signature is correct + expect(rr.customer_signature.creator).to.equal(api.didIpfsHelper.didId) + // Check reviews by author + let reviewsByAuthor + do { + // It might not be correct right away, need to wait for orbit-db to replicate + reviewsByAuthor = await api.getReviewsWrittenByDID(api.didIpfsHelper.didId) + if (reviewsByAuthor.length < 1) await waitMs(1000) + } while(reviewsByAuthor.length < 1) + expect(reviewsByAuthor).to.contain(multihash) + }) + + it('ChluIPFS publishes a review, then API Client reads review records by subject', async () => { + const reviewRecord = await getFakeReviewRecord() + reviewRecord.popr = await preparePoPR(reviewRecord.popr); + // Store the RR + const multihash = await customer.storeReviewRecord(reviewRecord, { + publish: false + }) + // set up btc mock to return the right content + setupBtcMock(multihash, reviewRecord); + // Publish it using the Publish Server + await customer.storeReviewRecord(reviewRecord, { + publish: true, + bitcoinTransactionHash: 'fake', + expectedMultihash: multihash + }) + // Read it from Query Server + const rr = await queryServer.chluIpfs.readReviewRecord(multihash) + // Make sure Subject DID is correct + expect(rr.popr.vendor_did).to.equal(vendor.didIpfsHelper.didId) + // Check reviews by author + let reviewsBySubject + do { + // It might not be correct right away, need to wait for orbit-db to replicate + reviewsBySubject = await api.getReviewsAboutDID(vendor.didIpfsHelper.didId) + if (reviewsBySubject.length < 1) await waitMs(1000) + } while(reviewsBySubject.length < 1) + expect(reviewsBySubject).to.contain(multihash) + + }) + }) + + describe('API Client and Marketplace', () => { + it('API Client registers as Vendor', async () => { + const vendorData = await mkt.getVendor(vendor.didIpfsHelper.didId) + expect(vendorData.vDidId).to.equal(vendor.didIpfsHelper.didId) + expect(vendorData.vSignature).to.be.a('string') + }) + }) +}) + +async function waitMs(x) { + return new Promise(resolve => setTimeout(resolve, x)) +} \ No newline at end of file diff --git a/tests/collector-reviews.test.js b/tests/collector-reviews.test.js new file mode 100644 index 0000000..b7dd409 --- /dev/null +++ b/tests/collector-reviews.test.js @@ -0,0 +1,313 @@ +const expect = require('chai').expect; + +const ChluIPFS = require('chlu-ipfs-support'); +const ChluCollector = require('chlu-collector') +// Test utilities +const { getFakeReviewRecord, makeUnverified } = require('chlu-ipfs-support/tests/utils/protobuf'); +const utils = require('chlu-ipfs-support/tests/utils/ipfs'); +const env = require('chlu-ipfs-support/src/utils/env'); +const logger = require('chlu-ipfs-support/tests/utils/logger'); +const cryptoTestUtils = require('chlu-ipfs-support/tests/utils/crypto'); +const fakeHttpModule = require('chlu-ipfs-support/tests/utils/http'); +const btcUtils = require('chlu-ipfs-support/tests/utils/bitcoin'); +// Libs +const { cloneDeep } = require('lodash'); +const rimraf = require('rimraf'); +const sinon = require('sinon'); + +require('./index.js') + +function withoutHashAndSig(obj) { + return Object.assign({}, obj, { + sig: null, + hash: '' + }); +} + +function strip(obj) { + delete obj.gotLatestVersion; + delete obj.multihash; + delete obj.requestedMultihhash; + delete obj.editable; + delete obj.watching; +} + +describe('Integration: Chlu Collector and Review Records', function() { + let testDir, ipfsDir, customerNode, customerIpfs, serviceNode, serviceIpfs; + let v, vm, m, preparePoPR; + + const verbose = false // set this to true to get all components to log debug strings + + before(async () => { + ipfsDir = env.isNode() ? '/tmp/chlu-test-ipfs-' + Date.now() + Math.random() + '/' : Date.now() + Math.random(); + serviceIpfs = await utils.createIPFS({ repo: ipfsDir + '/' + 'service' }); + customerIpfs = await utils.createIPFS({ repo: ipfsDir + '/' + 'customer' }); + + // Connect the peers manually to speed up test times + // await utils.connect(serviceNode.ipfs, customerNode.ipfs); + + testDir = env.isNode() ? '/tmp/chlu-test-' + Date.now() + Math.random() + '/' : Date.now() + Math.random(); + + const serviceNodeDir = testDir + 'chlu-service-node'; + const customerDir = testDir + 'chlu-customer'; + + serviceNode = new ChluIPFS({ + logger: logger('Collector', verbose), + directory: serviceNodeDir, + enablePersistence: false, + bootstrap: false + }); + serviceNode.collector = new ChluCollector(serviceNode) + customerNode = new ChluIPFS({ + logger: logger('Customer', verbose), + directory: customerDir, + enablePersistence: false, + bootstrap: false + }); + // Make sure they don't connect to production + expect(customerNode.network).to.equal(ChluIPFS.networks.experimental); + expect(serviceNode.network).to.equal(ChluIPFS.networks.experimental); + + serviceNode.ipfs = serviceIpfs; + customerNode.ipfs = customerIpfs; + + // Spies + sinon.spy(serviceNode, 'pin'); + + // Stubs + const crypto = cryptoTestUtils(serviceNode); + const makeKeyPair = crypto.makeKeyPair; + const makeDID = crypto.makeDID + preparePoPR = crypto.preparePoPR; + vm = await makeKeyPair(); + v = await makeDID(); + m = await makeDID(); + const http = fakeHttpModule(() => ({ didId: m.publicDidDocument.id })); + serviceNode.http = http; + customerNode.http = http; + serviceNode.ipfsUtils.stop = sinon.stub().resolves(); + customerNode.ipfsUtils.stop = sinon.stub().resolves(); + serviceNode.bitcoin.Blockcypher = btcUtils.BlockcypherMock; + customerNode.bitcoin.Blockcypher = btcUtils.BlockcypherMock; + + // Start nodes + await Promise.all([serviceNode.start(), customerNode.start()]); + await serviceNode.collector.start() + + // Do some DID prework to make sure nodes have everything they need + + // Publish Vendor and Marketplace DIDs from service node + await serviceNode.didIpfsHelper.publish(v, false) + await serviceNode.didIpfsHelper.publish(m, false) + // wait until Customer DID is replicated into Service Node's OrbitDB + await serviceNode.getDID(customerNode.didIpfsHelper.didId, true) + // wait for customer node to have DIDs for vendor and marketplace + await customerNode.getDID(v.publicDidDocument.id, true) + await customerNode.getDID(m.publicDidDocument.id, true) + // IMPORTANT note for the future: do not parallelize these operations, + // it introduces some kind of OrbitDB bug where the tests fail intermittently + }); + + after(async () => { + await serviceNode.collector.stop() + await Promise.all([serviceNode.stop(), customerNode.stop()]); + rimraf.sync(testDir); + }); + + function setupBtcMock(multihash, rr) { + // delete cached info, since we are about to change it + serviceNode.cache.cache.del(btcUtils.exampleTransaction.hash); + customerNode.cache.cache.del(btcUtils.exampleTransaction.hash); + // tell mock btc module to return a TX that matches the RR + serviceNode.bitcoin.api.returnMatchingTXForRR(Object.assign({}, rr, { multihash })); + customerNode.bitcoin.api.returnMatchingTXForRR(Object.assign({}, rr, { multihash })); + } + + it('collector handles Unverified Reviews', async () => { + // Create fake review record + let reviewRecord = makeUnverified(await getFakeReviewRecord()) + // import reviews and await for completion + const reviews = [reviewRecord] + const [hash] = await customerNode.reviewRecords.importUnverifiedReviews(reviews) + const customerRecord = await customerNode.readReviewRecord(hash); + expect(customerRecord.editable).to.be.false; + // check hash validity + expect(hash).to.be.a('string').that.is.not.empty; + // the service node should already have pinned the hash + expect(serviceNode.pin.calledWith(hash)).to.be.true; + // check that reading works + const readRecord = await serviceNode.readReviewRecord(hash); + expect(readRecord.editable).to.be.false; + expect(strip(readRecord)).to.deep.equal(strip(customerRecord)); + // check orbit-db did indexing + expect(await serviceNode.orbitDb.getReviewsAboutDID(readRecord.subject.did)) + .to.contain(hash) + }) + + it('collector handles Verified Reviews', async () => { + // Create fake review record + let reviewRecord = await getFakeReviewRecord(); + reviewRecord.popr = await preparePoPR(reviewRecord.popr, vm, v, m); + // store review record and await for completion + const hash = await customerNode.storeReviewRecord(reviewRecord, { + publish: false + }); + // set up btc mock to return the right content + setupBtcMock(hash, reviewRecord); + // publish + await customerNode.storeReviewRecord(reviewRecord, { + bitcoinTransactionHash: btcUtils.exampleTransaction.hash + }); + const customerRecord = await customerNode.readReviewRecord(hash); + expect(customerRecord.editable).to.be.true; + // check hash validity + expect(hash).to.be.a('string').that.is.not.empty; + // the service node should already have pinned the hash + expect(serviceNode.pin.calledWith(hash)).to.be.true; + // check that reading works + const readRecord = await serviceNode.readReviewRecord(hash); + expect(readRecord.editable).to.be.false; + expect(strip(readRecord)).to.deep.equal(strip(customerRecord)); + // check orbit-db by did indexing + expect(await serviceNode.getReviewsWrittenByDID(readRecord.customer_signature.creator)) + .to.contain(hash) + expect(await serviceNode.getReviewsAboutDID(readRecord.popr.vendor_did)) + .to.contain(hash) + }); + + describe('Verified Review Updates', () => { + + it('collector handles updates', async () => { + // Create fake review record + let reviewRecord = await getFakeReviewRecord(); + reviewRecord.popr = await preparePoPR(reviewRecord.popr, vm, v, m); + // Now create a fake update + let reviewUpdate = await getFakeReviewRecord(); + reviewUpdate.popr = cloneDeep(reviewRecord.popr); + reviewUpdate.review_text = 'Actually it broke after just a week!'; + reviewUpdate.rating = 1; + // Store the original review + const multihash = await customerNode.storeReviewRecord(reviewRecord, { + publish: false + }); + setupBtcMock(multihash, reviewRecord); + await customerNode.storeReviewRecord(reviewRecord, { + bitcoinTransactionHash: btcUtils.exampleTransaction.hash + }); + // Check that the review list is updated + expect((await customerNode.getReviewList())).to.contain(multihash); + // Store the update + reviewUpdate.previous_version_multihash = multihash + const updatedMultihash = await customerNode.storeReviewRecord(reviewUpdate); + const rr = await serviceNode.readReviewRecord(multihash, { getLatestVersion: true }); + const rrUpdate = await serviceNode.readReviewRecord(updatedMultihash); + expect(strip(rr)).to.deep.equal(strip(rrUpdate)); + }); + + it('collector handles updates happening after a read', async () => { + await new Promise(async (resolve, reject) => { + // Create fake review record + let reviewRecord = await getFakeReviewRecord(); + reviewRecord.popr = await preparePoPR(reviewRecord.popr, vm, v, m); + // Store the original review + const multihash = await customerNode.storeReviewRecord(reviewRecord, { + publish: false + }); + setupBtcMock(multihash, reviewRecord); + await customerNode.storeReviewRecord(reviewRecord, { + bitcoinTransactionHash: btcUtils.exampleTransaction.hash + }); + // Now try to fetch it from the service node while checking for updates + const notifyUpdate = async (originalHash, newHash, rr) => { + try { + expect(newHash).to.not.equal(multihash); + expect(originalHash).to.equal(multihash); + expect(withoutHashAndSig(rr)).to.not.deep.equal(reviewRecord); + resolve(); + } catch (err) { + reject(err); + } + }; + serviceNode.events.once('reviewrecord/updated', notifyUpdate); + await serviceNode.readReviewRecord(multihash, { checkForUpdates: true }); + // Now create a fake update + let reviewUpdate = await getFakeReviewRecord(); + reviewUpdate.previous_version_multihash = multihash + reviewUpdate.popr = cloneDeep(reviewRecord.popr); + reviewUpdate.review_text = 'Actually it broke after just a week!'; + reviewUpdate.rating = 1; + // Store the update + await customerNode.storeReviewRecord(reviewUpdate); + }); + }); + + it('collector handles updates written by the current node', async () => { + // Create fake review record + let reviewRecord = await getFakeReviewRecord(); + reviewRecord.popr = await preparePoPR(reviewRecord.popr, vm, v, m); + // Now create a fake update + let reviewUpdate = await getFakeReviewRecord(); + reviewUpdate.popr = cloneDeep(reviewRecord.popr); + reviewUpdate.review_text = 'Actually it broke after just a week!'; + reviewUpdate.rating = 1; + // Store the original review + const multihash = await customerNode.storeReviewRecord(reviewRecord, { + publish: false + }); + setupBtcMock(multihash, reviewRecord); + await customerNode.storeReviewRecord(reviewRecord, { + bitcoinTransactionHash: btcUtils.exampleTransaction.hash + }); + // Store the update + reviewUpdate.previous_version_multihash = multihash + const updatedMultihash = await customerNode.storeReviewRecord(reviewUpdate); + const rr = await customerNode.readReviewRecord(multihash, { getLatestVersion: true }); + const rrUpdate = await customerNode.readReviewRecord(updatedMultihash); + expect(strip(rrUpdate)).to.deep.equal(strip(rr)); + }); + + it('collector handles updates after the read, written by the current node', async () => { + await new Promise(async (resolve, reject) => { + // Create fake review record + let reviewRecord = await getFakeReviewRecord(); + reviewRecord.popr = await preparePoPR(reviewRecord.popr, vm, v, m); + // Store the original review + const multihash = await customerNode.storeReviewRecord(reviewRecord, { + publish: false + }); + setupBtcMock(multihash, reviewRecord); + await customerNode.storeReviewRecord(reviewRecord, { + bitcoinTransactionHash: btcUtils.exampleTransaction.hash + }); + // Now try to fetch it from the customer node while checking for updates + const notifyUpdate = async (originalHash, newHash, rr) => { + try { + expect(newHash).to.not.equal(multihash); + expect(originalHash).to.equal(multihash); + expect(rr.previous_version_multihash).to.equal(originalHash); + const customerUpdate = await customerNode.readReviewRecord(newHash); + expect(strip(rr)).to.deep.equal(strip(customerUpdate)); + resolve(); + } catch (err) { + reject(err); + } + }; + customerNode.events.once('reviewrecord/updated', notifyUpdate); + await customerNode.readReviewRecord(multihash, { checkForUpdates: true }); + // Now create a fake update + let reviewUpdate = await getFakeReviewRecord(); + reviewUpdate.previous_version_multihash = multihash + reviewUpdate.popr = cloneDeep(reviewRecord.popr); + reviewUpdate.review_text = 'Actually it broke after just a week!'; + reviewUpdate.rating = 1; + // Store the update + await customerNode.storeReviewRecord(reviewUpdate); + }); + }); + }) + + describe('Integration: Collector and DIDs', () => { + it('collector handles DID publishing') + it('collector handles DID updates') + }) +}); diff --git a/tests/index.js b/tests/index.js new file mode 100644 index 0000000..845bde3 --- /dev/null +++ b/tests/index.js @@ -0,0 +1,13 @@ +const ChluIPFS = require('chlu-ipfs-support'); +const { startRendezvousServer } = require('chlu-collector/src/rendezvous') + +let server + +before(async () => { + process.env.DISABLE_LOGS = '1' + server = await startRendezvousServer(ChluIPFS.rendezvousPorts.test); +}) + +after(async () => { + await server.stop() +}) \ No newline at end of file diff --git a/tests/mocha.opts b/tests/mocha.opts new file mode 100644 index 0000000..3471cc0 --- /dev/null +++ b/tests/mocha.opts @@ -0,0 +1 @@ +tests/**/*.test.js --timeout 30000 --exit \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index d932f4a..558a4ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6,13 +6,23 @@ version "0.7.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" +"@sinonjs/formatio@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2" + dependencies: + samsam "1.3.0" + +"@sinonjs/samsam@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-2.0.0.tgz#9163742ac35c12d3602dece74317643b35db6a80" + "@types/geojson@^1.0.0": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-1.0.6.tgz#3e02972728c69248c2af08d60a48cbb8680fffdf" "@types/node@*": - version "10.5.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.2.tgz#f19f05314d5421fe37e74153254201a7bf00a707" + version "10.5.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.5.tgz#8e84d24e896cd77b0d4f73df274027e3149ec2ba" abab@^1.0.3: version "1.0.4" @@ -78,14 +88,32 @@ acorn-globals@^3.1.0: dependencies: acorn "^4.0.4" +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + acorn@^4.0.4: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" +acorn@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" + after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" @@ -93,7 +121,7 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.1.0: +ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: @@ -205,6 +233,16 @@ array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" @@ -217,7 +255,7 @@ arraybuffer.slice@~0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" -arrify@^1.0.1: +arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -313,7 +351,7 @@ b64@3.x.x: version "3.0.3" resolved "https://registry.yarnpkg.com/b64/-/b64-3.0.3.tgz#36afeee0d9345f046387ce6de8a6702afe5bb56e" -babel-code-frame@^6.26.0: +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -650,6 +688,21 @@ body-parser@1.18.2: raw-body "2.3.2" type-is "~1.6.15" +body-parser@^1.18.3: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + boom@2.x.x: version "2.10.1" resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" @@ -729,6 +782,10 @@ browser-resolve@^1.11.2: dependencies: resolve "1.1.7" +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + browserify-aes@^1.0.6, browserify-aes@^1.1.1, browserify-aes@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -751,11 +808,12 @@ bs58@=2.0.0: resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.0.tgz#72b713bed223a0ac518bbda0e3ce3f4817f39eb5" bs58check@<3.0.0, bs58check@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.1.tgz#8a5d0e587af97b784bf9cbf1b29f454d82bc0222" + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" dependencies: bs58 "^4.0.0" create-hash "^1.1.0" + safe-buffer "^5.1.2" bser@^2.0.0: version "2.0.0" @@ -787,8 +845,8 @@ buffer-fill@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" buffer-from@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04" + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" buffer-indexof@~0.0.0: version "0.0.2" @@ -845,10 +903,20 @@ call@^4.0.2: boom "5.x.x" hoek "4.x.x" +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + callsite@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" @@ -917,7 +985,7 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" dependencies: @@ -925,15 +993,58 @@ chalk@^2.0.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + check-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" -chlu-did-service@ChluNetwork/chlu-did-service#upgrade-chlu: +chlu-api-client@ChluNetwork/chlu-api-client-js#implementation: + version "0.1.0" + resolved "https://codeload.github.com/ChluNetwork/chlu-api-client-js/tar.gz/37b3dd9e18a1ec93c590b843b0495125dddd593c" + dependencies: + axios "^0.18.0" + chlu-ipfs-support ChluNetwork/chlu-ipfs-support#misc-features + lodash "^4.17.10" + +chlu-api-publish@ChluNetwork/chlu-api-publish#implementation: + version "0.1.0" + resolved "https://codeload.github.com/ChluNetwork/chlu-api-publish/tar.gz/ecaadbec3128ca0cfcb390caa78ba299a0bbcc65" + dependencies: + body-parser "^1.18.3" + chlu-ipfs-support ChluNetwork/chlu-ipfs-support#misc-features + commander "^2.16.0" + cors "^2.8.4" + express "^4.16.3" + lodash "^4.17.10" + +chlu-api-query@ChluNetwork/chlu-api-query#implementation: + version "0.1.0" + resolved "https://codeload.github.com/ChluNetwork/chlu-api-query/tar.gz/3d100ca4e285246ff3e3b30259033d75fc6d043e" + dependencies: + body-parser "^1.18.3" + chlu-ipfs-support ChluNetwork/chlu-ipfs-support#misc-features + commander "^2.16.0" + cors "^2.8.4" + express "^4.16.3" + lodash "^4.17.10" + +chlu-collector@ChluNetwork/chlu-collector#implementation: + version "0.1.0" + resolved "https://codeload.github.com/ChluNetwork/chlu-collector/tar.gz/5f5aa5dfcfaca184acf32f0008aada637d0ad3fd" + dependencies: + chlu-ipfs-support ChluNetwork/chlu-ipfs-support#misc-features + commander "^2.15.1" + libp2p-websocket-star-rendezvous "^0.2.3" + lodash "^4.17.5" + +chlu-did-service@ChluNetwork/chlu-did-service#upgrade-chlu2: version "1.0.0" - resolved "https://codeload.github.com/ChluNetwork/chlu-did-service/tar.gz/6bb262bc69fa94c9658c8d46a476c5caf7ea7156" + resolved "https://codeload.github.com/ChluNetwork/chlu-did-service/tar.gz/2266574e58cd6e75a2e1ae3bcfd7dd86b0d3a24d" dependencies: - chlu-ipfs-support ChluNetwork/chlu-ipfs-support#protobuf-upgrade + chlu-ipfs-support ChluNetwork/chlu-ipfs-support#misc-features commander "^2.15.1" express "^4.16.3" @@ -946,9 +1057,9 @@ chlu-did@ChluNetwork/chlu-did: elliptic "^6.4.0" js-sha3 "^0.7.0" -chlu-ipfs-support@ChluNetwork/chlu-ipfs-support#protobuf-upgrade: +chlu-ipfs-support@ChluNetwork/chlu-ipfs-support#misc-features: version "0.2.0" - resolved "https://codeload.github.com/ChluNetwork/chlu-ipfs-support/tar.gz/d17eb5982bb272ef96aa324ae2f477607655e128" + resolved "https://codeload.github.com/ChluNetwork/chlu-ipfs-support/tar.gz/60fb9eae97b95a7bf4afe3cc06b700283e8040dd" dependencies: axios "^0.18.0" blockcypher ChluNetwork/node-client @@ -963,16 +1074,15 @@ chlu-ipfs-support@ChluNetwork/chlu-ipfs-support#protobuf-upgrade: libp2p-websocket-star-rendezvous "^0.2.3" lodash "^4.17.5" lru-cache "^4.1.2" - moment "^2.22.2" orbit-db "~0.19.8" protons "~1.0.1" chlu-marketplace-js@ChluNetwork/chlu-marketplace-js#upgrade-chlu: version "0.1.0" - resolved "https://codeload.github.com/ChluNetwork/chlu-marketplace-js/tar.gz/300eeeb16c0c692a7d8987752439012c12b7368f" + resolved "https://codeload.github.com/ChluNetwork/chlu-marketplace-js/tar.gz/1aa80d349de483ea2eba36cf101ed2b3aa9843f3" dependencies: axios "^0.18.0" - chlu-ipfs-support ChluNetwork/chlu-ipfs-support#protobuf-upgrade + chlu-ipfs-support ChluNetwork/chlu-ipfs-support#misc-features commander "^2.15.0" cors "^2.8.4" express "^4.16.2" @@ -1020,6 +1130,10 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + class-is@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" @@ -1037,6 +1151,16 @@ 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@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + cliui@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" @@ -1103,7 +1227,11 @@ combined-stream@1.0.6, combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -commander@^2.11.0, commander@^2.15.0, commander@^2.15.1: +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + +commander@^2.11.0, commander@^2.15.0, commander@^2.15.1, commander@^2.16.0: version "2.16.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.16.0.tgz#f16390593996ceb4f3eeb020b31d78528f7f8a50" @@ -1127,7 +1255,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.6.2: +concat-stream@^1.6.0, concat-stream@^1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" dependencies: @@ -1235,7 +1363,7 @@ create-hmac@^1.1.3, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-spawn@^5.0.1: +cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: @@ -1323,7 +1451,7 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.1, debug@^2.6. dependencies: ms "2.0.0" -debug@^3.0.1, debug@^3.1.0, debug@~3.1.0: +debug@3.1.0, debug@^3.0.1, debug@^3.1.0, debug@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: @@ -1400,6 +1528,18 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1445,7 +1585,7 @@ dicer@^0.2.5: readable-stream "1.1.x" streamsearch "0.1.2" -diff@^3.2.0: +diff@3.5.0, diff@^3.2.0, diff@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -1460,6 +1600,12 @@ dns-packet@^1.3.1: ip "^1.1.0" safe-buffer "^5.0.1" +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + dependencies: + esutils "^2.0.2" + dot-prop@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" @@ -1496,10 +1642,11 @@ duplexify@^3.4.2: stream-shift "^1.0.0" ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" dependencies: jsbn "~0.1.0" + safer-buffer "^2.1.0" ecurve@^1.0.0: version "1.0.6" @@ -1612,7 +1759,7 @@ escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -1627,6 +1774,67 @@ escodegen@^1.6.1: optionalDependencies: source-map "~0.6.1" +eslint-scope@^3.7.1: + version "3.7.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + +eslint@^4.12.0: + version "4.19.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" + dependencies: + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.4" + esquery "^1.0.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^1.0.1" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "4.0.2" + text-table "~0.2.0" + +espree@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + esprima@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -1635,7 +1843,19 @@ esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" -estraverse@^4.2.0: +esquery@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -1674,8 +1894,8 @@ ethereumjs-block@^1.7.1: merkle-patricia-tree "^2.1.2" ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3: - version "1.3.6" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.6.tgz#d581c1703b7b250b2e54892031626534d53e0a79" + version "1.3.7" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" dependencies: ethereum-common "^0.0.18" ethereumjs-util "^5.0.0" @@ -1812,8 +2032,16 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: is-extendable "^1.0.1" extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + +external-editor@^2.0.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" extglob@^0.3.1: version "0.3.2" @@ -1864,6 +2092,19 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + file-type@^7.6.0: version "7.7.1" resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.7.1.tgz#91c2f5edb8ce70688b9b68a90d931bbb6cb21f65" @@ -1935,13 +2176,22 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +flat-cache@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + flatmap@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/flatmap/-/flatmap-0.0.3.tgz#1f18a4d938152d495965f9c958d923ab2dd669b4" follow-redirects@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.1.tgz#67a8f14f5a1f67f962c2c46469c79eaec0a90291" + version "1.5.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.2.tgz#5a9d80e0165957e5ef0c1210678fc5c4acb9fb03" dependencies: debug "^3.1.0" @@ -2115,8 +2365,8 @@ getpass@^0.1.1: assert-plus "^1.0.0" git-validate@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/git-validate/-/git-validate-2.2.2.tgz#9cc8ff001177957a11726ab508d415bb80b18bcf" + version "2.2.4" + resolved "https://registry.yarnpkg.com/git-validate/-/git-validate-2.2.4.tgz#0adc02a2887f09ffe077db38932ba8a3de508cbe" github-from-package@0.0.0: version "0.0.0" @@ -2135,7 +2385,7 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: +glob@7.1.2, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -2152,10 +2402,25 @@ global-dirs@^0.1.0: dependencies: ini "^1.3.4" +globals@^11.0.1: + version "11.7.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673" + globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" @@ -2176,6 +2441,10 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -2321,6 +2590,10 @@ hawk@3.1.3, hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + heap@^0.2.6: version "0.2.6" resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac" @@ -2379,7 +2652,7 @@ http-errors@1.6.2: setprototypeof "1.0.3" statuses ">= 1.3.1 < 2" -http-errors@~1.6.2: +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" dependencies: @@ -2414,7 +2687,7 @@ iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" -iconv-lite@^0.4.4: +iconv-lite@0.4.23, iconv-lite@^0.4.17, iconv-lite@^0.4.4: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" dependencies: @@ -2440,6 +2713,10 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" +ignore@^3.3.3: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + immediate@^3.2.3, immediate@~3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" @@ -2490,6 +2767,25 @@ ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" +inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + interface-connection@^0.3.2, interface-connection@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/interface-connection/-/interface-connection-0.3.2.tgz#e4949883f6ea79fb7edd01ee3f4fca47a29fd2c4" @@ -2532,9 +2828,9 @@ ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" -ipaddr.js@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" +ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" ipfs-api@^18.1.2: version "18.2.1" @@ -2869,8 +3165,8 @@ ipld-dag-pb@~0.13.0, ipld-dag-pb@~0.13.1: stable "^0.1.6" ipld-dag-pb@~0.14.4: - version "0.14.5" - resolved "https://registry.yarnpkg.com/ipld-dag-pb/-/ipld-dag-pb-0.14.5.tgz#bec6417401b32a80818190636a08edc0048dccec" + version "0.14.6" + resolved "https://registry.yarnpkg.com/ipld-dag-pb/-/ipld-dag-pb-0.14.6.tgz#1b0357c7db8c1a75f8eef6e89505ddc614a7faaa" dependencies: async "^2.6.1" bs58 "^4.0.1" @@ -3121,6 +3417,16 @@ is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + dependencies: + is-path-inside "^1.0.0" + is-path-inside@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" @@ -3141,6 +3447,10 @@ is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + is-promise@~1, is-promise@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-1.0.1.tgz#31573761c057e33c2e91aab9e96da08cefbe76e5" @@ -3153,6 +3463,10 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -3543,8 +3857,8 @@ joi@^11.1.0: topo "2.x.x" joi@^13.1.2: - version "13.4.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-13.4.0.tgz#afc359ee3d8bc5f9b9ba6cdc31b46d44af14cecc" + version "13.5.2" + resolved "https://registry.yarnpkg.com/joi/-/joi-13.5.2.tgz#32207c85fa76d889f1e971c7eaaf69b232259a91" dependencies: hoek "5.x.x" isemail "3.x.x" @@ -3562,7 +3876,7 @@ js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.7.0: +js-yaml@^3.7.0, js-yaml@^3.9.1: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" dependencies: @@ -3617,6 +3931,10 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" @@ -3650,6 +3968,10 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +just-extend@^1.1.27: + version "1.1.27" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.27.tgz#ec6e79410ff914e472652abfa0e603c03d60e905" + k-bucket@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/k-bucket/-/k-bucket-3.3.1.tgz#de219f00b310ca17fdd7e2790a077d78b70d92c8" @@ -3755,7 +4077,7 @@ level-js@^2.2.4: typedarray-to-buffer "~1.0.0" xtend "~2.1.2" -"level-js@github:timkuijsten/level.js#idbunwrapper": +level-js@timkuijsten/level.js#idbunwrapper: version "2.2.3" resolved "https://codeload.github.com/timkuijsten/level.js/tar.gz/18e03adab34c49523be7d3d58fafb0c632f61303" dependencies: @@ -3817,7 +4139,7 @@ leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" -levn@~0.3.0: +levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" dependencies: @@ -4295,13 +4617,17 @@ lodash@=3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.17.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5: +lodash@^4.17.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" logplease@^1.2.14, logplease@~1.2.14: - version "1.2.14" - resolved "https://registry.yarnpkg.com/logplease/-/logplease-1.2.14.tgz#e509dd4c455c1aed7dd105a17694daa5b9ac579f" + version "1.2.15" + resolved "https://registry.yarnpkg.com/logplease/-/logplease-1.2.15.tgz#3da442e93751a5992cc19010a826b08d0293c48a" + +lolex@^2.3.2, lolex@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.1.tgz#e40a8c4d1f14b536aa03e42a537c7adbaf0c20be" longest@^1.0.1: version "1.0.1" @@ -4512,7 +4838,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" -minimatch@^3.0.0, minimatch@^3.0.3, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -4550,12 +4876,28 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" +mocha@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + moment-timezone@^0.5.14: version "0.5.21" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.21.tgz#3cba247d84492174dbf71de2a9848fa13207b845" @@ -4669,7 +5011,7 @@ multihashing-async@~0.5.1: murmurhash3js "^3.0.1" nodeify "^1.0.1" -"multiplex@github:dignifiedquire/multiplex": +multiplex@dignifiedquire/multiplex: version "6.7.0" resolved "https://codeload.github.com/dignifiedquire/multiplex/tar.gz/b5d5edd30454e2c978ee8c52df86f5f4840d2eab" dependencies: @@ -4698,6 +5040,10 @@ murmurhash3js@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/murmurhash3js/-/murmurhash3js-3.0.1.tgz#3e983e5b47c2a06f43a713174e7e435ca044b998" +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + nan@^2.10.0, nan@^2.2.1, nan@^2.9.2, nan@~2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" @@ -4754,9 +5100,19 @@ nigel@2.x.x: hoek "4.x.x" vise "2.x.x" +nise@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.4.2.tgz#a9a3800e3994994af9e452333d549d60f72b8e8c" + dependencies: + "@sinonjs/formatio" "^2.0.0" + just-extend "^1.1.27" + lolex "^2.3.2" + path-to-regexp "^1.7.0" + text-encoding "^0.6.4" + nock@^9.0.18: - version "9.4.2" - resolved "https://registry.yarnpkg.com/nock/-/nock-9.4.2.tgz#bab58a44b5781bdb74d7808673a2dbeefafb898d" + version "9.4.4" + resolved "https://registry.yarnpkg.com/nock/-/nock-9.4.4.tgz#d58a6d54ca26735d792aa776801cd0623789bdb6" dependencies: chai "^4.1.2" debug "^3.1.0" @@ -4870,8 +5226,8 @@ npm-bundled@^1.0.1: resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" npm-packlist@^1.1.6: - version "1.1.10" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" + version "1.1.11" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -4907,7 +5263,7 @@ object-assign@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa" -object-assign@^4, object-assign@^4.1.0: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -4962,6 +5318,12 @@ once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: dependencies: wrappy "1" +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -4979,7 +5341,7 @@ optional@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/optional/-/optional-0.1.4.tgz#cdb1a9bedc737d2025f690ceeb50e049444fd5b3" -optionator@^0.8.1: +optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" dependencies: @@ -4994,7 +5356,7 @@ options@>=0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" -orbit-db-cache@~0.2.2: +orbit-db-cache@~0.2.4: version "0.2.4" resolved "https://registry.yarnpkg.com/orbit-db-cache/-/orbit-db-cache-0.2.4.tgz#0c4defe2b581dce4dd3f1cd7d4e06087fae52e19" dependencies: @@ -5010,7 +5372,7 @@ orbit-db-counterstore@~1.4.0: crdts "~0.1.2" orbit-db-store "~2.5.0" -orbit-db-docstore@~1.4.1: +orbit-db-docstore@~1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/orbit-db-docstore/-/orbit-db-docstore-1.4.3.tgz#0e802ad0d23a70f65ccb7f612be00424722253c3" dependencies: @@ -5043,7 +5405,7 @@ orbit-db-kvstore@~1.4.0: dependencies: orbit-db-store "~2.5.0" -orbit-db-pubsub@~0.5.3: +orbit-db-pubsub@~0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/orbit-db-pubsub/-/orbit-db-pubsub-0.5.5.tgz#7d6d153b700e4b4396266a0ec354212717f28ee6" dependencies: @@ -5051,9 +5413,9 @@ orbit-db-pubsub@~0.5.3: logplease "~1.2.14" p-series "^1.1.0" -orbit-db-store@~2.5.0: - version "2.5.2" - resolved "https://registry.yarnpkg.com/orbit-db-store/-/orbit-db-store-2.5.2.tgz#c798426f2bc80b0e8433e171afb84c75d227c6fb" +orbit-db-store@~2.5.0, orbit-db-store@~2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/orbit-db-store/-/orbit-db-store-2.5.3.tgz#e13ad350a57faf153ae6621cdddecb5a6b3e528b" dependencies: ipfs-log "~4.1.0" logplease "^1.2.14" @@ -5061,21 +5423,21 @@ orbit-db-store@~2.5.0: readable-stream "~2.3.5" orbit-db@~0.19.8: - version "0.19.8" - resolved "https://registry.yarnpkg.com/orbit-db/-/orbit-db-0.19.8.tgz#5d07c96c579d85ca96bacd7f3fdd02a576e0e8cc" + version "0.19.9" + resolved "https://registry.yarnpkg.com/orbit-db/-/orbit-db-0.19.9.tgz#839871d77d426244b2fc6a1ceb46a7585f061b1c" dependencies: ipfs-pubsub-1on1 "~0.0.4" logplease "^1.2.14" multihashes "^0.4.12" - orbit-db-cache "~0.2.2" + orbit-db-cache "~0.2.4" orbit-db-counterstore "~1.4.0" - orbit-db-docstore "~1.4.1" + orbit-db-docstore "~1.4.3" orbit-db-eventstore "~1.4.0" orbit-db-feedstore "~1.4.0" orbit-db-keystore "~0.1.0" orbit-db-kvstore "~1.4.0" - orbit-db-pubsub "~0.5.3" - orbit-db-store "~2.5.0" + orbit-db-pubsub "~0.5.5" + orbit-db-store "~2.5.3" os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" @@ -5089,7 +5451,7 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -5226,7 +5588,7 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" @@ -5242,6 +5604,12 @@ path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + dependencies: + isarray "0.0.1" + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -5352,6 +5720,10 @@ pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + podium@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/podium/-/podium-1.3.0.tgz#3c490f54d16f10f5260cbe98641f1cb733a8851c" @@ -5481,11 +5853,11 @@ protons@^1.0.0, protons@^1.0.1, protons@~1.0.1: varint "^5.0.0" proxy-addr@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" dependencies: forwarded "~0.1.2" - ipaddr.js "1.6.0" + ipaddr.js "1.8.0" prr@~1.0.1: version "1.0.1" @@ -5685,7 +6057,7 @@ qs@6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" -qs@^6.5.1, qs@^6.5.2, qs@~6.5.1: +qs@6.5.2, qs@^6.5.1, qs@^6.5.2, qs@~6.5.1: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -5720,6 +6092,15 @@ raw-body@2.3.2: iconv-lite "0.4.19" unpipe "1.0.0" +raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + rc@^1.0.1, rc@^1.1.6, rc@^1.1.7, rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -5833,6 +6214,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + registry-auth-token@^3.0.1: version "3.3.2" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" @@ -5928,6 +6313,17 @@ require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -5936,6 +6332,13 @@ resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -5953,7 +6356,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1, rimraf@^2.6.2: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1, rimraf@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: @@ -5993,6 +6396,22 @@ rsvp@^3.3.3: version "3.6.2" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + safe-buffer@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -6007,10 +6426,14 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2: +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" +samsam@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" + sane@^2.0.0: version "2.5.2" resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" @@ -6214,10 +6637,29 @@ simple-peer@^8.5.0: randombytes "^2.0.3" readable-stream "^2.3.4" +sinon@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-6.1.4.tgz#b67f7a7b7fe2496042b54a5c2f425e2d699927a2" + dependencies: + "@sinonjs/formatio" "^2.0.0" + "@sinonjs/samsam" "^2.0.0" + diff "^3.5.0" + lodash.get "^4.4.2" + lolex "^2.7.1" + nise "^1.4.2" + supports-color "^5.4.0" + type-detect "^4.0.8" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + dependencies: + is-fullwidth-code-point "^2.0.0" + slide@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -6492,7 +6934,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: @@ -6580,6 +7022,12 @@ superagent@^3.8.2: qs "^6.5.1" readable-stream "^2.3.5" +supports-color@5.4.0, supports-color@^5.3.0, supports-color@^5.4.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@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -6590,16 +7038,21 @@ supports-color@^3.1.2: dependencies: has-flag "^1.0.0" -supports-color@^5.3.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" - symbol-tree@^3.2.1: version "3.2.2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" +table@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + dependencies: + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" + tar-fs@^1.13.0: version "1.16.3" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" @@ -6643,8 +7096,8 @@ tar@^2.2.1: inherits "2" tar@^4: - version "4.4.4" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.4.tgz#ec8409fae9f665a4355cc3b4087d0820232bb8cd" + version "4.4.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" dependencies: chownr "^1.0.1" fs-minipass "^1.2.5" @@ -6696,6 +7149,14 @@ test-exclude@^4.2.1: read-pkg-up "^1.0.1" require-main-filename "^1.0.1" +text-encoding@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + throat@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" @@ -6707,7 +7168,7 @@ through2@^2.0.2, through2@^2.0.3: readable-stream "^2.1.5" xtend "~4.0.1" -through@2: +through@2, through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -6729,6 +7190,12 @@ timed-tape@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/timed-tape/-/timed-tape-0.1.1.tgz#9b6e569f17e66c79f1eed2d25ff7962fc7418e49" +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -6838,7 +7305,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-detect@^4.0.0: +type-detect@^4.0.0, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -7162,6 +7629,12 @@ write-file-atomic@^2.0.0, write-file-atomic@^2.1.0, write-file-atomic@^2.3.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + ws@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51"