diff --git a/.travis.yml b/.travis.yml index e1d6320..5c9015c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ language: node_js node_js: - 4 - 5 + - stable # Make sure we have new NPM. before_install: @@ -13,12 +14,12 @@ script: - npm test - npm run coverage -addons: - firefox: 'latest' - before_script: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start after_success: - npm run coverage-publish + +addons: + firefox: 'latest' diff --git a/package.json b/package.json index 3491dee..12ca60d 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,12 @@ "jsnext:main": "src/index.js", "scripts": { "test": "aegir-test", - "test:browser": "aegir-test browser", - "test:node": "aegir-test node", + "test:browser": "aegir-test --env browser", + "test:node": "aegir-test --env node", "lint": "aegir-lint", "release": "aegir-release", - "release-minor": "aegir-release minor", - "release-major": "aegir-release major", + "release-minor": "aegir-release --type minor", + "release-major": "aegir-release --type major", "build": "aegir-build", "coverage": "aegir-coverage", "coverage-publish": "aegir-coverage publish" @@ -39,18 +39,18 @@ "dependencies": { "babel-runtime": "^6.6.1", "bs58": "^3.0.0", - "cbor": "^1.0.3", + "cbor": "^1.0.4", "lodash.clonedeep": "^4.3.2", "lodash.defaults": "^4.0.1", - "lodash.includes": "^4.1.2", - "multiaddr": "^1.4.1", - "multihashes": "^0.2.1", + "lodash.includes": "^4.1.3", + "multiaddr": "^2.0.0", + "multihashes": "^0.2.2", "multihashing": "^0.2.1", "nofilter": "0.0.2" }, "devDependencies": { - "aegir": "^3.0.0", + "aegir": "^3.0.4", "chai": "^3.5.0", - "pre-commit": "^1.1.2" + "pre-commit": "^1.1.3" } } diff --git a/src/cbor.js b/src/cbor.js index d4bc687..c668e40 100644 --- a/src/cbor.js +++ b/src/cbor.js @@ -11,6 +11,7 @@ const cloneDeep = require('lodash.clonedeep') exports = module.exports exports.LINK_TAG = 258 +const LINK_SYMBOL = exports.LINK_SYMBOL = '/' exports.marshal = (original) => { const input = cloneDeep(original) @@ -25,8 +26,8 @@ exports.marshal = (original) => { } }) - if (includes(keys, '@link')) { - let link = obj['@link'] + if (includes(keys, LINK_SYMBOL)) { + let link = obj[LINK_SYMBOL] // Multiaddr encoding if (typeof link === 'string' && isMultiaddr(link)) { @@ -34,14 +35,11 @@ exports.marshal = (original) => { } // Remove the @link - delete obj['@link'] + delete obj[LINK_SYMBOL] // Non empty if (keys.length > 1) { - return new cbor.Tagged(exports.LINK_TAG, [ - link, - obj - ]) + throw new Error('Links must not have siblings') } return new cbor.Tagged(exports.LINK_TAG, link) @@ -69,14 +67,20 @@ exports.unmarshal = (input, opts) => { function transform (obj) { Object.keys(obj).forEach((key) => { const val = obj[key] + // This is safe as we reference the same cbor instance + // as we used to decode with if (val instanceof cbor.Tagged) { if (typeof val.value === 'string') { obj[key] = { - '@link': val.value + [LINK_SYMBOL]: val.value + } + } else if (Buffer.isBuffer(val.value)) { + obj[key] = { + [LINK_SYMBOL]: (new Multiaddr(val.value)).toString() } } else { obj[key] = defaults({ - '@link': val.value[0] + [LINK_SYMBOL]: val.value[0] }, transform(val.value[1])) } } else if (typeof val === 'object') { diff --git a/src/index.js b/src/index.js index 48765ec..a917452 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ const multihash = require('./multihash') exports = module.exports exports.LINK_TAG = cbor.LINK_TAG +exports.LINK_SYMBOL = cbor.LINK_SYMBOL exports.marshal = cbor.marshal exports.unmarshal = cbor.unmarshal exports.multihash = multihash diff --git a/test/cbor.spec.js b/test/cbor.spec.js index 08b6d65..e1da526 100644 --- a/test/cbor.spec.js +++ b/test/cbor.spec.js @@ -8,7 +8,7 @@ const Multiaddr = require('multiaddr') const ipld = require('../src') describe('IPLD -> CBOR', () => { - it('no @link', () => { + it('no /', () => { const src = { data: 'hello world', size: 11 @@ -26,20 +26,18 @@ describe('IPLD -> CBOR', () => { ) }) - it('@link, is a string', () => { + it('/, is a string', () => { const src = { data: 'hello world', size: 11, - '@link': 'hello-world' + l1: {'/': 'hello-world'} } - const expected = new cbor.Tagged(ipld.LINK_TAG, [ - 'hello-world', - { - data: 'hello world', - size: 11 - } - ]) + const expected = { + data: 'hello world', + size: 11, + l1: new cbor.Tagged(ipld.LINK_TAG, 'hello-world') + } expect( ipld.marshal(src) @@ -48,21 +46,22 @@ describe('IPLD -> CBOR', () => { ) }) - it('@link, is a valid multiaddress', () => { - const addr = new Multiaddr('/ip4/127.0.0.1/udp/1234') + it('/, is a valid multiaddress', () => { + const addr1 = new Multiaddr('/ip4/127.0.0.1/udp/1234') + const addr2 = new Multiaddr('/ipfs/Qmafmh1Cw3H1bwdYpaaj5AbCW4LkYyUWaM7Nykpn5NZoYL') const src = { data: 'hello world', size: 11, - '@link': addr.toString() + l1: {'/': addr1.toString()}, + l2: {'/': addr2.toString()} } - const expected = new cbor.Tagged(ipld.LINK_TAG, [ - addr.buffer, - { - data: 'hello world', - size: 11 - } - ]) + const expected = { + data: 'hello world', + size: 11, + l1: new cbor.Tagged(ipld.LINK_TAG, addr1.buffer), + l2: new cbor.Tagged(ipld.LINK_TAG, addr2.buffer) + } expect( ipld.marshal(src) @@ -71,52 +70,41 @@ describe('IPLD -> CBOR', () => { ) }) - it('@link, with properties', () => { + it('/, with properties', () => { const src = { data: 'hello world', size: 11, secret: { - '@link': 'hello-world', - secret: 3 + '/': 'hello-world', + i: 'should not be here' } } - const expected = { - data: 'hello world', - size: 11, - secret: new cbor.Tagged(ipld.LINK_TAG, [ - 'hello-world', - { - secret: 3 - } - ]) - } - expect( - ipld.marshal(src) - ).to.be.eql( - cbor.encode(expected) + () => ipld.marshal(src) + ).to.throw( + 'Links must not have siblings' ) }) - it('nested @link', () => { + it('nested /', () => { const src = { data: 'hello world', size: 11, - '@link': 'hello-world', + l1: {'/': 'hello-world'}, secret: { - '@link': 'secret-link' + l1: {'/': 'secret-link'} } } - const expected = new cbor.Tagged(ipld.LINK_TAG, [ - 'hello-world', - { - data: 'hello world', - size: 11, - secret: new cbor.Tagged(ipld.LINK_TAG, 'secret-link') + const expected = { + data: 'hello world', + size: 11, + l1: new cbor.Tagged(ipld.LINK_TAG, 'hello-world'), + secret: { + l1: new cbor.Tagged(ipld.LINK_TAG, 'secret-link') } - ]) + } expect( ipld.marshal(src) @@ -127,13 +115,13 @@ describe('IPLD -> CBOR', () => { it('does not modify the input', () => { let src = { - '@link': 'hello' + l1: {'/': 'hello'} } ipld.marshal(src) expect(src).to.be.eql({ - '@link': 'hello' + l1: {'/': 'hello'} }) }) }) @@ -168,71 +156,7 @@ describe('CBOR -> IPLD', () => { data: 'hello world', size: 11, nested: { - '@link': 'hello-world' - } - } - - expect( - ipld.unmarshal(src) - ).to.be.eql( - target - ) - }) - - it('one link, with properties', () => { - const src = cbor.encode({ - data: 'hello world', - size: 11, - nested: new cbor.Tagged(ipld.LINK_TAG, [ - 'hello-world', - {cool: 'property'} - ]) - }) - - const target = { - data: 'hello world', - size: 11, - nested: { - '@link': 'hello-world', - cool: 'property' - } - } - - expect( - ipld.unmarshal(src) - ).to.be.eql( - target - ) - }) - - it('nested links, with properties', () => { - const src = cbor.encode({ - data: 'hello world', - size: 11, - secret: { - links: [ - new cbor.Tagged(ipld.LINK_TAG, 'secret-link') - ] - }, - nested: new cbor.Tagged(ipld.LINK_TAG, [ - 'hello-world', - { - cool: 'property', - ref: new cbor.Tagged(ipld.LINK_TAG, 'world') - } - ]) - }) - - const target = { - data: 'hello world', - size: 11, - secret: { - links: [{'@link': 'secret-link'}] - }, - nested: { - '@link': 'hello-world', - cool: 'property', - ref: {'@link': 'world'} + '/': 'hello-world' } }