Skip to content
This repository was archived by the owner on Aug 11, 2021. It is now read-only.

Commit cde65dd

Browse files
authored
chore: add types (#139)
Updates deps, adds types and fixes all compiler warnings
1 parent 361f66e commit cde65dd

File tree

7 files changed

+99
-30
lines changed

7 files changed

+99
-30
lines changed

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
"description": "JavaScript implementation of the IPLD (InterpPlanetary Linked Data)",
55
"leadMaintainer": "Volker Mische <[email protected]>",
66
"main": "src/index.js",
7+
"types": "./dist/src/index.d.ts",
78
"scripts": {
9+
"prepare": "aegir build",
810
"test": "aegir test",
911
"test:browser": "aegir test --target browser",
1012
"test:node": "aegir test --target node",
@@ -37,12 +39,14 @@
3739
"dependencies": {
3840
"borc": "^2.1.2",
3941
"cids": "^1.0.0",
42+
"interface-ipld-format": "^1.0.0",
4043
"is-circular": "^1.0.2",
4144
"multicodec": "^3.0.1",
4245
"multihashing-async": "^2.0.0",
4346
"uint8arrays": "^2.1.3"
4447
},
4548
"devDependencies": {
49+
"@types/detect-node": "^2.0.0",
4650
"aegir": "^31.0.1",
4751
"detect-node": "^2.0.4",
4852
"garbage": "0.0.0",

src/index.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
'use strict'
22

3-
exports.util = require('./util.js')
4-
exports.resolver = require('./resolver.js')
5-
exports.codec = exports.util.codec
6-
exports.defaultHashAlg = exports.util.defaultHashAlg
3+
const util = require('./util.js')
4+
const resolver = require('./resolver.js')
5+
6+
/**
7+
* @typedef {import('interface-ipld-format').Format<object>} ObjectFormat
8+
*/
9+
10+
/**
11+
* @type {ObjectFormat}
12+
*/
13+
module.exports = {
14+
util,
15+
resolver,
16+
codec: util.codec,
17+
defaultHashAlg: util.defaultHashAlg
18+
}

src/resolver.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ const util = require('./util')
1212
* @param {Uint8Array} binaryBlob - Binary representation of a CBOR block
1313
* @param {string} [path='/'] - Path that should be resolved
1414
*/
15-
exports.resolve = (binaryBlob, path) => {
15+
exports.resolve = (binaryBlob, path = '') => {
1616
let node = util.deserialize(binaryBlob)
1717

1818
const parts = path.split('/').filter(Boolean)
1919
while (parts.length) {
2020
const key = parts.shift()
21-
if (node[key] === undefined) {
21+
if (!key || !(key in node)) {
2222
throw new Error(`Object has no property '${key}'`)
2323
}
2424

@@ -37,17 +37,25 @@ exports.resolve = (binaryBlob, path) => {
3737
}
3838
}
3939

40+
/**
41+
* @param {any} node
42+
* @param {string} [path]
43+
* @returns {Generator<string, void, undefined>}
44+
*/
4045
const traverse = function * (node, path) {
4146
// Traverse only objects and arrays
42-
if (node instanceof Uint8Array || CID.isCID(node) || typeof node === 'string' ||
43-
node === null) {
47+
if (node instanceof Uint8Array || CID.isCID(node) || typeof node === 'string' || node === null) {
4448
return
4549
}
50+
4651
for (const item of Object.keys(node)) {
4752
const nextpath = path === undefined ? item : path + '/' + item
4853
yield nextpath
4954
yield * traverse(node[item], nextpath)
5055
}
56+
57+
// to stop eslint and tsc fighting
58+
return undefined
5159
}
5260

5361
/**

src/util.js

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,47 @@
11
'use strict'
22

3+
// @ts-ignore TODO: switch to cborg
34
const cbor = require('borc')
45
const multicodec = require('multicodec')
56
const multihashing = require('multihashing-async')
7+
const { multihash } = multihashing
68
const CID = require('cids')
9+
// @ts-ignore
710
const isCircular = require('is-circular')
811
const uint8ArrayConcat = require('uint8arrays/concat')
912
const uint8ArrayFromString = require('uint8arrays/from-string')
1013

14+
/**
15+
* @typedef {import('cids').CIDVersion} CIDVersion
16+
* @typedef {import('multihashing-async').multihash.HashCode} HashCode
17+
*/
18+
1119
// https://github.com/ipfs/go-ipfs/issues/3570#issuecomment-273931692
1220
const CID_CBOR_TAG = 42
1321

22+
/**
23+
* @param {CID | string} cid
24+
*/
1425
function tagCID (cid) {
26+
let buf
27+
1528
if (typeof cid === 'string') {
16-
cid = new CID(cid).bytes
29+
buf = new CID(cid).bytes
1730
} else if (CID.isCID(cid)) {
18-
cid = cid.bytes
31+
buf = cid.bytes
32+
} else {
33+
throw new Error('Could not tag CID - was not string or CID')
1934
}
2035

2136
return new cbor.Tagged(CID_CBOR_TAG, uint8ArrayConcat([
2237
uint8ArrayFromString('00', 'base16'), // thanks jdag
23-
cid
24-
], 1 + cid.length))
38+
buf
39+
], 1 + buf.length))
2540
}
2641

42+
/**
43+
* @param {any} dagNode
44+
*/
2745
function replaceCIDbyTAG (dagNode) {
2846
let circular
2947
try {
@@ -35,6 +53,10 @@ function replaceCIDbyTAG (dagNode) {
3553
throw new Error('The object passed has circular references')
3654
}
3755

56+
/**
57+
* @param {any} obj
58+
* @returns {any}
59+
*/
3860
function transform (obj) {
3961
if (!obj || obj instanceof Uint8Array || typeof obj === 'string') {
4062
return obj
@@ -52,6 +74,7 @@ function replaceCIDbyTAG (dagNode) {
5274

5375
if (keys.length > 0) {
5476
// Recursive transform
77+
/** @type {Record<string, any>} */
5578
const out = {}
5679
keys.forEach((key) => {
5780
if (typeof obj[key] === 'object') {
@@ -70,9 +93,12 @@ function replaceCIDbyTAG (dagNode) {
7093
}
7194

7295
const codec = multicodec.DAG_CBOR
73-
const defaultHashAlg = multicodec.SHA2_256
96+
const defaultHashAlg = multihash.names['sha2-256']
7497

7598
const defaultTags = {
99+
/**
100+
* @param {Uint8Array} val
101+
*/
76102
[CID_CBOR_TAG]: (val) => {
77103
// remove that 0
78104
val = val.slice(1)
@@ -83,7 +109,8 @@ const defaultSize = 64 * 1024 // current decoder heap size, 64 Kb
83109
let currentSize = defaultSize
84110
const defaultMaxSize = 64 * 1024 * 1024 // max heap size when auto-growing, 64 Mb
85111
let maxSize = defaultMaxSize
86-
let decoder = null
112+
/** @type {cbor.Decoder} */
113+
let decoder
87114

88115
/**
89116
* Configure the underlying CBOR decoder.
@@ -141,7 +168,7 @@ function serialize (node) {
141168
* Deserialize CBOR block into the internal representation.
142169
*
143170
* @param {Uint8Array} data - Binary representation of a CBOR block
144-
* @returns {Object} - An object that conforms to the IPLD Data Model
171+
* @returns {any} - An object that conforms to the IPLD Data Model
145172
*/
146173
function deserialize (data) {
147174
if (data.length > currentSize && data.length <= maxSize) {
@@ -165,19 +192,21 @@ function deserialize (data) {
165192
/**
166193
* Calculate the CID of the binary blob.
167194
*
168-
* @param {Object} binaryBlob - Encoded IPLD Node
195+
* @param {Uint8Array} binaryBlob - Encoded IPLD Node
169196
* @param {Object} [userOptions] - Options to create the CID
170-
* @param {number} [userOptions.cidVersion=1] - CID version number
171-
* @param {string} [userOptions.hashAlg] - Defaults to the defaultHashAlg of the format
172-
* @returns {Promise.<CID>}
197+
* @param {CIDVersion} [userOptions.cidVersion=1] - CID version number
198+
* @param {HashCode} [userOptions.hashAlg=multihash.names['sha2-256']] - Defaults to the defaultHashAlg of the format
173199
*/
174-
async function cid (binaryBlob, userOptions) {
175-
const defaultOptions = { cidVersion: 1, hashAlg: defaultHashAlg }
176-
const options = Object.assign(defaultOptions, userOptions)
200+
async function cid (binaryBlob, userOptions = {}) {
201+
const options = {
202+
cidVersion: userOptions.cidVersion == null ? 1 : userOptions.cidVersion,
203+
hashAlg: userOptions.hashAlg == null ? module.exports.defaultHashAlg : userOptions.hashAlg
204+
}
177205

178-
const multihash = await multihashing(binaryBlob, options.hashAlg)
179-
const codecName = multicodec.getNameFromCode(codec)
180-
const cid = new CID(options.cidVersion, codecName, multihash)
206+
const hashName = multihash.codes[options.hashAlg]
207+
const hash = await multihashing(binaryBlob, hashName)
208+
const codecName = multicodec.getNameFromCode(module.exports.codec)
209+
const cid = new CID(options.cidVersion, codecName, hash)
181210

182211
return cid
183212
}

test/resolver.spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ describe('IPLD format resolver (local)', () => {
7474
})
7575

7676
it('should resolve falsy values for path within scope', () => {
77+
/** @type {{ [key: string]: any }} */
7778
const falsyNode = {
7879
nu11: null,
7980
f4lse: false,

test/util.spec.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22
'use strict'
33

44
const { expect } = require('aegir/utils/chai')
5+
// @ts-ignore
56
const garbage = require('garbage')
67
const dagCBOR = require('../src')
78
const multihash = require('multihashes')
89
const CID = require('cids')
910
const uint8ArrayFromString = require('uint8arrays/from-string')
11+
const uint8ArrayToString = require('uint8arrays/to-string')
1012
const uint8ArrayConcat = require('uint8arrays/concat')
13+
const {
14+
configureDecoder
15+
} = require('../src/util')
1116

1217
describe('util', () => {
1318
const obj = {
@@ -30,7 +35,7 @@ describe('util', () => {
3035
// Check for the tag 42
3136
// d8 = tag, 2a = 42
3237
expect(
33-
serializedObj.toString('hex').match(/d82a/g)
38+
uint8ArrayToString(serializedObj, 'base16').match(/d82a/g)
3439
).to.have.length(4)
3540

3641
const deserializedObj = dagCBOR.util.deserialize(serializedObj)
@@ -48,22 +53,22 @@ describe('util', () => {
4853
const deserialized = dagCBOR.util.deserialize(serialized)
4954
expect(largeObj).to.eql(deserialized)
5055
// reset decoder to default
51-
dagCBOR.util.configureDecoder()
56+
configureDecoder()
5257
})
5358

5459
it('.deserialize fail on large objects beyond maxSize', () => {
5560
// larger than the default borc heap size, should bust the heap if we turn off auto-grow
5661
const dataSize = (128 * 1024) + 1
5762
const largeObj = { someKey: [].slice.call(new Uint8Array(dataSize)) }
5863

59-
dagCBOR.util.configureDecoder({ size: 64 * 1024, maxSize: 128 * 1024 }) // 64 Kb start, 128 Kb max
64+
configureDecoder({ size: 64 * 1024, maxSize: 128 * 1024 }) // 64 Kb start, 128 Kb max
6065
const serialized = dagCBOR.util.serialize(largeObj)
6166
expect(serialized).to.be.a('Uint8Array')
6267

6368
expect(() => dagCBOR.util.deserialize(serialized)).to.throw(
6469
'Data is too large to deserialize with current decoder')
6570
// reset decoder to default
66-
dagCBOR.util.configureDecoder()
71+
configureDecoder()
6772
})
6873

6974
it('.serialize and .deserialize object with slash as property', () => {
@@ -90,7 +95,7 @@ describe('util', () => {
9095
})
9196

9297
it('.cid with hashAlg', async () => {
93-
const cid = await dagCBOR.util.cid(serializedObj, { hashAlg: 'sha2-512' })
98+
const cid = await dagCBOR.util.cid(serializedObj, { hashAlg: multihash.names['sha2-512'] })
9499
expect(cid.version).to.equal(1)
95100
expect(cid.codec).to.equal('dag-cbor')
96101
expect(cid.multihash).to.exist()

tsconfig.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "./node_modules/aegir/src/config/tsconfig.aegir.json",
3+
"compilerOptions": {
4+
"outDir": "dist"
5+
},
6+
"include": [
7+
"src",
8+
"test"
9+
]
10+
}

0 commit comments

Comments
 (0)