From 21ddefceceb671fd21aecb123b40d3849d95f162 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 16 Oct 2016 15:11:16 +0100 Subject: [PATCH] feat: resolver.tree and resolver.multicodec --- package.json | 2 +- src/resolver.js | 52 ++++++++++++++++++++++++++- test/resolver.spec.js | 83 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e19d147..58d3010 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "ipld-dag-cbor", "version": "0.6.0", "description": "JavaScript implementation of the IPLD (InterpPlanetary Linked Data)", - "main": "lib/index.js", + "main": "src/index.js", "jsnext:main": "src/index.js", "scripts": { "test": "aegir-test", diff --git a/src/resolver.js b/src/resolver.js index 2653598..9a30a7b 100644 --- a/src/resolver.js +++ b/src/resolver.js @@ -1,14 +1,17 @@ 'use strict' +const util = require('./util') + exports = module.exports exports.multicodec = 'dag-cbor' /* * resolve: receives a path and a block and returns the value on path, - * throw if not possible. `block` is an IPFS Block instance (contains data+key) + * throw if not possible. `block` is an IPFS Block instance (contains data + key) */ exports.resolve = (block, path) => { + } /* @@ -19,6 +22,17 @@ exports.tree = (block, options) => { if (!options) { options = {} } + + const node = util.deserialize(block.data) + const flatObj = flattenObject(node) + const paths = Object.keys(flatObj) + .map((key) => { + return { + path: key, + value: flatObj[key] + } + }) + return paths } // TODO recheck this API @@ -26,3 +40,39 @@ exports.tree = (block, options) => { * patch: modifies or adds value on path, yields a new block with that change */ exports.patch = (block, path, value) => {} + +function flattenObject (obj, delimiter) { + if (!delimiter) { + delimiter = '/' + } + + let toReturn = {} + let flatObject + for (let i in obj) { + if (!obj.hasOwnProperty(i)) { + continue + } + + if (Array.isArray(obj[i])) { + continue + } + + if ((typeof obj[i]) === 'object') { + flatObject = flattenObject(obj[i]) + for (let x in flatObject) { + if (!flatObject.hasOwnProperty(x)) { + continue + } + + if (flatObject[x] && Array === flatObject.constructor) { + continue + } + + toReturn[i + (isNaN(x) ? delimiter + x : '')] = flatObject[x] + } + } else { + toReturn[i] = obj[i] + } + } + return toReturn +} diff --git a/test/resolver.spec.js b/test/resolver.spec.js index e69de29..163e9b5 100644 --- a/test/resolver.spec.js +++ b/test/resolver.spec.js @@ -0,0 +1,83 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect +const dagCBOR = require('../src') +const resolver = dagCBOR.resolver +const Block = require('ipfs-block') + +describe('IPLD format resolver (local)', () => { + let emptyNodeBlock + let nodeBlock + + before(() => { + const emptyNode = {} + const node = { + name: 'I am a node', + someLink: { '/': 'LINK' }, + nest: { + foo: { + bar: 'baz' + } + }, + array: [ + { a: 'b' }, + 2 + ] + + } + + emptyNodeBlock = new Block(dagCBOR.util.serialize(emptyNode)) + nodeBlock = new Block(dagCBOR.util.serialize(node)) + }) + + it('multicodec is dag-cbor', () => { + expect(resolver.multicodec).to.equal('dag-cbor') + }) + + describe('empty node', () => { + describe('resolver.resolve', () => { + it.skip('path', () => { + }) + }) + + it('resolver.tree', () => { + const paths = resolver.tree(emptyNodeBlock) + expect(paths).to.eql([]) + }) + + it.skip('resolver.patch', (done) => {}) + }) + + describe('node', () => { + describe.skip('resolver.resolve', () => { + it('path', () => { + }) + }) + + it('resolver.tree', () => { + const paths = resolver.tree(nodeBlock) + expect(paths).to.eql([{ + path: 'name', + value: 'I am a node' + }, { + // TODO confirm how to represent links in tree + path: 'someLink//', + value: 'LINK' + }, { + path: 'nest/foo/bar', + value: 'baz' + } + // TODO fix array in .tree + /*, { + path: 'array/0/a', + value: 'b' + }, { + path: 'array/1', + value: '2' + } */]) + }) + + it.skip('resolver.patch', () => {}) + }) +})