@@ -5,39 +5,90 @@ const multihashing = require('multihashing-async')
55const CID = require ( 'cids' )
66const waterfall = require ( 'async/waterfall' )
77const setImmediate = require ( 'async/setImmediate' )
8+ const isCircular = require ( 'is-circular' )
89
910const resolver = require ( './resolver' )
1011
12+ // https://github.com/ipfs/go-ipfs/issues/3570#issuecomment-273931692
13+ const CID_CBOR_TAG = 42
14+
15+ function tagCID ( cid ) {
16+ return new cbor . Tagged ( CID_CBOR_TAG , cid )
17+ }
18+
19+ const decoder = new cbor . Decoder ( {
20+ tags : {
21+ [ CID_CBOR_TAG ] : ( val ) => ( { '/' : val } )
22+ }
23+ } )
24+
25+ function replaceCIDbyTAG ( dagNode ) {
26+ if ( isCircular ( dagNode ) ) {
27+ throw new Error ( 'The object passed has circular references' )
28+ }
29+
30+ function transform ( obj ) {
31+ if ( ! obj || Buffer . isBuffer ( obj ) || typeof obj === 'string' ) {
32+ return obj
33+ }
34+
35+ if ( Array . isArray ( obj ) ) {
36+ return obj . map ( transform )
37+ }
38+
39+ const keys = Object . keys ( obj )
40+
41+ // only `{'/': 'link'}` are valid
42+ if ( keys . length === 1 && keys [ 0 ] === '/' ) {
43+ // Multiaddr encoding
44+ // if (typeof link === 'string' && isMultiaddr(link)) {
45+ // link = new Multiaddr(link).buffer
46+ // }
47+
48+ return tagCID ( obj [ '/' ] )
49+ } else if ( keys . length > 0 ) {
50+ // Recursive transform
51+ let out = { }
52+ keys . forEach ( ( key ) => {
53+ if ( typeof obj [ key ] === 'object' ) {
54+ out [ key ] = transform ( obj [ key ] )
55+ } else {
56+ out [ key ] = obj [ key ]
57+ }
58+ } )
59+ return out
60+ } else {
61+ return obj
62+ }
63+ }
64+
65+ return transform ( dagNode )
66+ }
67+
1168exports = module . exports
1269
1370exports . serialize = ( dagNode , callback ) => {
1471 let serialized
72+
1573 try {
16- serialized = cbor . encode ( dagNode )
74+ const dagNodeTagged = replaceCIDbyTAG ( dagNode )
75+ serialized = cbor . encode ( dagNodeTagged )
1776 } catch ( err ) {
18- // return is important, otherwise in case of error the execution would continue
19- return setImmediate ( ( ) => {
20- callback ( err )
21- } )
77+ return setImmediate ( ( ) => callback ( err ) )
2278 }
23- setImmediate ( ( ) => {
24- callback ( null , serialized )
25- } )
79+ setImmediate ( ( ) => callback ( null , serialized ) )
2680}
2781
2882exports . deserialize = ( data , callback ) => {
29- let res
83+ let deserialized
84+
3085 try {
31- res = cbor . decodeFirst ( data )
86+ deserialized = decoder . decodeFirst ( data )
3287 } catch ( err ) {
33- return setImmediate ( ( ) => {
34- callback ( err )
35- } )
88+ return setImmediate ( ( ) => callback ( err ) )
3689 }
3790
38- setImmediate ( ( ) => {
39- callback ( null , res )
40- } )
91+ setImmediate ( ( ) => callback ( null , deserialized ) )
4192}
4293
4394exports . cid = ( dagNode , callback ) => {
0 commit comments