diff --git a/CHANGELOG.md b/CHANGELOG.md index 2326ba02..09b79281 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +<a name="7.1.0"></a> +# [7.1.0](https://github.com/multiformats/js-multiaddr/compare/v7.0.0...v7.1.0) (2019-09-10) + + +### Features + +* add decapsulateCode method ([#98](https://github.com/multiformats/js-multiaddr/issues/98)) ([19a3940](https://github.com/multiformats/js-multiaddr/commit/19a3940)) + + + <a name="7.0.0"></a> # [7.0.0](https://github.com/multiformats/js-multiaddr/compare/v6.1.0...v7.0.0) (2019-09-03) diff --git a/package.json b/package.json index 00b509cf..accda8de 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "multiaddr", - "version": "7.0.0", + "version": "7.1.0", "description": "multiaddr implementation (binary + string representation of network addresses)", "leadMaintainer": "Jacob Heun <jacobheun@gmail.com>", "main": "src/index.js", diff --git a/src/index.js b/src/index.js index 638e6b80..395cc576 100644 --- a/src/index.js +++ b/src/index.js @@ -237,6 +237,34 @@ Multiaddr.prototype.decapsulate = function decapsulate (addr) { return Multiaddr(s.slice(0, i)) } +/** + * A more reliable version of `decapsulate` if you are targeting a + * specific code, such as 421 (the `p2p` protocol code). The last index of the code + * will be removed from the `Multiaddr`, and a new instance will be returned. + * If the code is not present, the original `Multiaddr` is returned. + * + * @param {Number} code The code of the protocol to decapsulate from this Multiaddr + * @return {Multiaddr} + * @example + * const addr = Multiaddr('/ip4/0.0.0.0/tcp/8080/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC') + * // <Multiaddr 0400... - /ip4/0.0.0.0/tcp/8080/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC> + * + * addr.decapsulateCode(421).toString() + * // '/ip4/0.0.0.0/tcp/8080' + * + * Multiaddr('/ip4/127.0.0.1/tcp/8080').decapsulateCode(421).toString() + * // '/ip4/127.0.0.1/tcp/8080' + */ +Multiaddr.prototype.decapsulateCode = function decapsulateCode (code) { + const tuples = this.tuples() + for (let i = tuples.length - 1; i >= 0; i--) { + if (tuples[i][0] === code) { + return Multiaddr(codec.tuplesToBuffer(tuples.slice(0, i))) + } + } + return this +} + /** * Extract the peerId if the multiaddr contains one * diff --git a/test/index.spec.js b/test/index.spec.js index ed37bf62..d6e4f0fb 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -598,6 +598,22 @@ describe('helpers', () => { }) }) + describe('.decapsulateCode', () => { + it('removes the last occurrence of the code from the multiaddr', () => { + const relayTCP = multiaddr('/ip4/0.0.0.0/tcp/8080') + const relay = relayTCP.encapsulate('/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6/p2p-circuit') + const target = multiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC') + const original = relay.encapsulate(target) + expect(original.decapsulateCode(421)).to.eql(relay) + expect(relay.decapsulateCode(421)).to.eql(relayTCP) + }) + + it('ignores missing codes', () => { + const tcp = multiaddr('/ip4/0.0.0.0/tcp/8080') + expect(tcp.decapsulateCode(421)).to.eql(tcp) + }) + }) + describe('.equals', () => { it('returns true for equal addresses', () => { const addr1 = multiaddr('/ip4/192.168.0.1')