diff --git a/package.json b/package.json index a7c538f..5cec668 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "pull-handshake": "^1.1.4", "pull-length-prefixed": "^1.2.0", "pull-stream": "^3.5.0", + "semver": "^5.3.0", "varint": "^4.0.1" }, "devDependencies": { diff --git a/src/index.js b/src/index.js index a1fed8e..95db87c 100644 --- a/src/index.js +++ b/src/index.js @@ -2,3 +2,4 @@ exports.Listener = exports.listener = require('./listener') exports.Dialer = exports.dialer = require('./dialer') +exports.matchSemver = require('./listener/match-semver') diff --git a/src/listener/ls-handler.js b/src/listener/ls-handler.js index 3c8b557..f8f3bb2 100644 --- a/src/listener/ls-handler.js +++ b/src/listener/ls-handler.js @@ -5,9 +5,8 @@ const pullLP = require('pull-length-prefixed') const varint = require('varint') function lsHandler (self, conn) { - const protos = Object - .keys(self.handlers) - .filter((key) => key !== 'ls') + const protos = Object.keys(self.handlers) + .filter((key) => key !== 'ls') const nProtos = protos.length // total size of the list of protocols, including varint and newline diff --git a/src/listener/match-exact.js b/src/listener/match-exact.js index 9187b2d..6476672 100644 --- a/src/listener/match-exact.js +++ b/src/listener/match-exact.js @@ -1,11 +1,8 @@ 'use strict' function matchExact (myProtocol, senderProtocol, callback) { - if (myProtocol === senderProtocol) { - callback(null, true) - } else { - callback(null, false) - } + const result = myProtocol === senderProtocol + callback(null, result) } module.exports = matchExact diff --git a/src/listener/match-semver.js b/src/listener/match-semver.js index e69de29..bda8578 100644 --- a/src/listener/match-semver.js +++ b/src/listener/match-semver.js @@ -0,0 +1,23 @@ +'use strict' + +const semver = require('semver') + +function matchSemver (myProtocol, senderProtocol, callback) { + const mps = myProtocol.split('/') + const sps = senderProtocol.split('/') + const myName = mps[1] + const myVersion = mps[2] + + const senderName = sps[1] + const senderVersion = sps[2] + + if (myName !== senderName) { + return callback(null, false) + } + // does my protocol satisfy the sender? + const valid = semver.satisfies(myVersion, '~' + senderVersion) + + callback(null, valid) +} + +module.exports = matchSemver diff --git a/src/listener/select-handler.js b/src/listener/select-handler.js index 1f5f9d1..f31479b 100644 --- a/src/listener/select-handler.js +++ b/src/listener/select-handler.js @@ -48,8 +48,6 @@ function selectHandler (rawConn, handlersMap, log) { } } -module.exports = selectHandler - function matcher (protocol, handlers, callback) { const supportedProtocols = Object.keys(handlers) let supportedProtocol = false @@ -74,3 +72,5 @@ function matcher (protocol, handlers, callback) { } ) } + +module.exports = selectHandler diff --git a/src/util.js b/src/util.js index c814fcb..e0c223d 100644 --- a/src/util.js +++ b/src/util.js @@ -1,3 +1,5 @@ +'use strict' + const pull = require('pull-stream') const pullLP = require('pull-length-prefixed') const debug = require('debug') diff --git a/test/index.spec.js b/test/index.spec.js index a6e383b..d3d8645 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -6,12 +6,12 @@ const expect = require('chai').expect const pull = require('pull-stream') const pullLP = require('pull-length-prefixed') const pullPair = require('pull-pair/duplex') -const multistream = require('../src') +const mss = require('../src') const parallel = require('run-parallel') const series = require('run-series') -describe('multistream dialer', () => { - it('sends the multistream multicodec', (done) => { +describe('mss dialer', () => { + it('sends the mss multicodec', (done) => { const p = pullPair() const dialerConn = p[0] const listenerConn = p[1] @@ -25,13 +25,13 @@ describe('multistream dialer', () => { }) ) - const msd = new multistream.Dialer() + const msd = new mss.Dialer() expect(msd).to.exist msd.handle(dialerConn, () => {}) }) }) -describe('multistream listener', () => { - it('sends the multistream multicodec', (done) => { +describe('mss listener', () => { + it('sends the mss multicodec', (done) => { const p = pullPair() const dialerConn = p[0] const listenerConn = p[1] @@ -45,13 +45,13 @@ describe('multistream listener', () => { }) ) - const msl = new multistream.Listener() + const msl = new mss.Listener() expect(msl).to.exist msl.handle(listenerConn, () => {}) }) }) -describe('multistream handshake', () => { +describe('mss handshake', () => { it('performs the handshake handshake', (done) => { const p = pullPair() const dialerConn = p[0] @@ -59,12 +59,12 @@ describe('multistream handshake', () => { parallel([ (cb) => { - const msl = new multistream.Listener() + const msl = new mss.Listener() expect(msl).to.exist msl.handle(listenerConn, cb) }, (cb) => { - const msd = new multistream.Dialer() + const msd = new mss.Dialer() expect(msd).to.exist msd.handle(dialerConn, cb) } @@ -82,12 +82,12 @@ describe('multistream handshake', () => { (next) => { parallel([ (cb) => { - msl = new multistream.Listener() + msl = new mss.Listener() expect(msl).to.exist msl.handle(listenerConn, cb) }, (cb) => { - msd = new multistream.Dialer() + msd = new mss.Dialer() expect(msd).to.exist msd.handle(dialerConn, cb) } @@ -130,12 +130,12 @@ describe('multistream handshake', () => { (next) => { parallel([ (cb) => { - msl = new multistream.Listener() + msl = new mss.Listener() expect(msl).to.exist msl.handle(listenerConn, cb) }, (cb) => { - msd = new multistream.Dialer() + msd = new mss.Dialer() expect(msd).to.exist msd.handle(dialerConn, cb) } @@ -161,12 +161,12 @@ describe('multistream handshake', () => { (next) => { parallel([ (cb) => { - msl = new multistream.Listener() + msl = new mss.Listener() expect(msl).to.exist msl.handle(listenerConn, cb) }, (cb) => { - msd = new multistream.Dialer() + msd = new mss.Dialer() expect(msd).to.exist msd.handle(dialerConn, cb) } @@ -214,12 +214,12 @@ describe('multistream handshake', () => { (next) => { parallel([ (cb) => { - msl = new multistream.Listener() + msl = new mss.Listener() expect(msl).to.exist msl.handle(listenerConn, cb) }, (cb) => { - msd = new multistream.Dialer() + msd = new mss.Dialer() expect(msd).to.exist msd.handle(dialerConn, cb) } @@ -270,12 +270,12 @@ describe('multistream handshake', () => { (next) => { parallel([ (cb) => { - msl = new multistream.Listener() + msl = new mss.Listener() expect(msl).to.exist msl.handle(listenerConn, cb) }, (cb) => { - msd = new multistream.Dialer() + msd = new mss.Dialer() expect(msd).to.exist msd.handle(dialerConn, cb) } @@ -303,7 +303,7 @@ describe('multistream handshake', () => { (cb) => { series([ (next) => { - msl = new multistream.Listener() + msl = new mss.Listener() expect(msl).to.exist setTimeout(() => { msl.handle(listenerConn, next) @@ -318,7 +318,7 @@ describe('multistream handshake', () => { ], cb) }, (cb) => { - msd = new multistream.Dialer() + msd = new mss.Dialer() msd.handle(dialerConn, (err) => { expect(err).to.not.exist msd.select('/monkey/1.0.0', (err, conn) => { @@ -352,12 +352,12 @@ describe('custom matching function', () => { (next) => { parallel([ (cb) => { - msl = new multistream.Listener() + msl = new mss.Listener() expect(msl).to.exist msl.handle(listenerConn, cb) }, (cb) => { - msd = new multistream.Dialer() + msd = new mss.Dialer() expect(msd).to.exist msd.handle(dialerConn, cb) } @@ -390,6 +390,87 @@ describe('custom matching function', () => { }) describe('semver-match', () => { + it('should match', (done) => { + const p = pullPair() + const dialerConn = p[0] + const listenerConn = p[1] + let msl + let msd + series([ + (next) => { + parallel([ + (cb) => { + msl = new mss.Listener() + expect(msl).to.exist + msl.handle(listenerConn, cb) + }, + (cb) => { + msd = new mss.Dialer() + expect(msd).to.exist + msd.handle(dialerConn, cb) + } + ], next) + }, + (next) => { + msl.addHandler('/monster/1.0.0', (p, conn) => { + pull(conn, conn) + }, mss.matchSemver) + next() + }, + (next) => { + msd.select('/monster/1.0.0', (err, conn) => { + expect(err).to.not.exist + + pull( + pull.values(['cookie']), + conn, + pull.collect((err, data) => { + expect(err).to.not.exist + expect(data).to.be.eql(['cookie']) + next() + }) + ) + }) + } + ], done) + }) + + it('should not match', (done) => { + const p = pullPair() + const dialerConn = p[0] + const listenerConn = p[1] + + let msl + let msd + series([ + (next) => { + parallel([ + (cb) => { + msl = new mss.Listener() + expect(msl).to.exist + msl.handle(listenerConn, cb) + }, + (cb) => { + msd = new mss.Dialer() + expect(msd).to.exist + msd.handle(dialerConn, cb) + } + ], next) + }, + (next) => { + msl.addHandler('/monster/1.1.0', (p, conn) => { + pull(conn, conn) + }, mss.matchSemver) + next() + }, + (next) => { + msd.select('/monster/2.0.0', (err, conn) => { + expect(err).to.exist + next() + }) + } + ], done) + }) }) })