Skip to content
This repository was archived by the owner on Jun 30, 2023. It is now read-only.

Commit 4bc9318

Browse files
author
Alan Shaw
committed
feat: add block API
1 parent 3faa412 commit 4bc9318

31 files changed

+396
-120
lines changed

API.md

+129-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
* [addFromURL](#addfromurl) TODO: add docs
88
* [bitswap.stat](#bitswapstat) TODO: add docs
99
* [bitswap.wantlist](#bitswapwantlist) TODO: add docs
10-
* [block.get](#blockget) TODO: add docs
10+
* [block.get](#blockget)
11+
* [block.put](#blockput)
12+
* [block.stat](#blockstat)
1113
* [cat](#cat)
1214
* [catPullStream](#catpullstream) TODO: add docs
1315
* [ls](#ls) TODO: add docs
@@ -316,6 +318,129 @@ pull(
316318
*/
317319
```
318320

321+
## block.get
322+
323+
Fetch a raw block from the IPFS block store or the network via bitswap if not local.
324+
325+
### `block.get(cid, [options]): Promise<Buffer>`
326+
327+
#### Parameters
328+
329+
* `cid` - CID of the block to fetch
330+
* Type: `String`
331+
* `options` (optional)
332+
* Type: `Object`
333+
* Default: `null`
334+
* `options.signal` (optional) - A signal that can be used to abort the request
335+
* Type: [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)
336+
* Default: `null`
337+
338+
#### Returns
339+
340+
A buffer containing the raw bytes of the block.
341+
342+
* Type: `Promise<Buffer>`
343+
344+
#### Example
345+
346+
```js
347+
const data = await ipfs.block.get('zdpuAtpzCB7ma5zNyCN7eh1Vss1dHWuScf91DbE1ix9ZTbjAk')
348+
console.log(data) // buffer containing block data
349+
```
350+
351+
## block.put
352+
353+
Put a block into the IPFS block store.
354+
355+
### `block.put(data, [options]): Promise<Object>`
356+
357+
#### Parameters
358+
359+
* `data` - Raw data for this block
360+
* Type: `Buffer`/`Blob`/`File`
361+
* `options` (optional)
362+
* Type: `Object`
363+
* Default: `null`
364+
* `options.format` (optional) - Name of the IPLD format this block is encoded with
365+
* Type: `String`
366+
* Default: `dag-pb`
367+
* `options.mhtype` (optional) - Name of the multihash hashing algorithm to use
368+
* Type: `String`
369+
* Default: `sha2-256`
370+
* `options.mhlen` (optional) - Length of the hash in bits
371+
* Type: `Number`
372+
* Default: `256`
373+
* `options.pin` (optional) - Pin this block so it is not garbage collected
374+
* Type: `Boolean`
375+
* Default: `false`
376+
* `options.signal` (optional) - A signal that can be used to abort the request
377+
* Type: [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)
378+
* Default: `null`
379+
380+
#### Returns
381+
382+
CID and size for the block that was added.
383+
384+
* Type: `Promise<Object>`
385+
386+
The `Object` has the following properties:
387+
388+
* `key` - The CID of the block
389+
* Type: `String`
390+
* `size` - Size of the block in bytes
391+
* Type: `Number`
392+
393+
#### Examples
394+
395+
```js
396+
const data = Buffer.from('blorb')
397+
const res = await ipfs.block.put(data)
398+
console.log(res)
399+
/*
400+
{ key: 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ', size: 5 }
401+
*/
402+
```
403+
404+
## block.stat
405+
406+
Get status for a block.
407+
408+
### `block.stat(cid, [options]): Promise<Object>`
409+
410+
#### Parameters
411+
412+
* `cid` - CID of the block
413+
* Type: `String`
414+
* `options` (optional)
415+
* Type: `Object`
416+
* Default: `null`
417+
* `options.signal` (optional) - A signal that can be used to abort the request
418+
* Type: [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)
419+
* Default: `null`
420+
421+
#### Returns
422+
423+
CID and size of the block.
424+
425+
* Type: `Promise<Object>`
426+
427+
The `Object` has the following properties:
428+
429+
* `key` - The CID of the block
430+
* Type: `String`
431+
* `size` - Size of the block in bytes
432+
* Type: `Number`
433+
434+
#### Examples
435+
436+
```js
437+
const res = await ipfs.block.stat('zb2rhj7crUKTQYRGCRATFaQ6YFLTde2YzdqbbhAASkL9uRDXn')
438+
console.log(res)
439+
/*
440+
{ key: 'zb2rhj7crUKTQYRGCRATFaQ6YFLTde2YzdqbbhAASkL9uRDXn', size: 11 }
441+
*/
442+
```
443+
319444
## `cat`
320445

321446
Read files from IPFS.
@@ -335,6 +460,9 @@ Read files from IPFS.
335460
* `options.length` (optional) - Number of bytes to read
336461
* Type: `Number`
337462
* Default: `null` (read to the end of the file)
463+
* `options.signal` (optional) - A signal that can be used to abort the request
464+
* Type: [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)
465+
* Default: `null`
338466

339467
#### Returns
340468

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ This module is in heavy development, not all API methods are available (or docum
145145
* [addFromURL](./API.md#addfromurl) TODO: add docs
146146
* [bitswap.stat](./API.md#bitswapstat) TODO: add docs
147147
* [bitswap.wantlist](./API.md#bitswapwantlist) TODO: add docs
148-
* [block.get](./API.md#blockget) TODO: add docs
148+
* [block.get](./API.md#blockget)
149+
* [block.put](./API.md#blockput)
150+
* [block.stat](./API.md#blockstat)
149151
* [cat](./API.md#cat)
150152
* [catPullStream](./API.md#catpullstream) TODO: add docs
151153
* [ls](./API.md#ls) TODO: add docs

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"dependencies": {
2929
"async-iterator-to-pull-stream": "^1.3.0",
3030
"buffer": "^5.2.1",
31+
"cids": "^0.7.1",
3132
"explain-error": "^1.0.4",
3233
"form-data": "^2.4.0",
3334
"iterable-ndjson": "^1.1.0",
@@ -42,8 +43,10 @@
4243
"dirty-chai": "^2.0.1",
4344
"go-ipfs-dep": "~0.4.21",
4445
"interface-ipfs-core": "~0.105.1",
46+
"ipfs-block": "^0.8.1",
4547
"ipfsd-ctl": "^0.43.0",
4648
"multiaddr-to-uri": "^4.0.1",
49+
"multihashes": "^0.4.14",
4750
"pull-stream": "^3.6.12"
4851
},
4952
"engines": {

src/add-from-url.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
const configure = require('./lib/configure')
44
const { ok, toIterable } = require('./lib/fetch')
55

6-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
7-
const add = require('./add')({ fetch, apiUrl, apiPath, signal, headers })
6+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
7+
const add = require('./add')({ fetch, apiUrl, apiPath, headers })
88

99
return (url, options) => (async function * () {
1010
options = options || {}

src/add/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const { ok, toIterable } = require('../lib/fetch')
77
const { toFormData } = require('./form-data')
88
const toCamel = require('../lib/to-camel')
99

10-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
10+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
1111
return (input, options) => (async function * () {
1212
options = options || {}
1313

src/bitswap/stat.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const configure = require('../lib/configure')
44
const { ok } = require('../lib/fetch')
55
const toCamel = require('../lib/to-camel')
66

7-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
7+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
88
return async (options) => {
99
options = options || {}
1010

src/bitswap/wantlist.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const QueryString = require('querystring')
44
const configure = require('../lib/configure')
55
const { ok } = require('../lib/fetch')
66

7-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
7+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
88
return async (peerId, options) => {
99
if (!options && typeof peerId === 'object') {
1010
options = peerId

src/block/get.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
'use strict'
22

3-
const QueryString = require('querystring')
43
const { Buffer } = require('buffer')
54
const configure = require('../lib/configure')
65
const { ok } = require('../lib/fetch')
76

8-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
7+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
98
return async (cid, options) => {
109
options = options || {}
1110

12-
const qs = { arg: cid }
13-
const url = `${apiUrl}${apiPath}/block/get?${QueryString.stringify(qs)}`
11+
const url = `${apiUrl}${apiPath}/block/get?arg=${encodeURIComponent(cid)}`
1412
const res = await ok(fetch(url, {
1513
signal: options.signal,
1614
headers: options.headers || headers
1715
}))
18-
return Buffer.from(await res.blob())
16+
return Buffer.from(await res.arrayBuffer())
1917
}
2018
})

src/block/put.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use strict'
2+
3+
const QueryString = require('querystring')
4+
const FormData = require('form-data')
5+
const configure = require('../lib/configure')
6+
const { ok } = require('../lib/fetch')
7+
const toCamel = require('../lib/to-camel')
8+
9+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
10+
const put = async (data, options) => {
11+
options = options || {}
12+
13+
const qs = Object.entries({
14+
format: options.format,
15+
mhtype: options.mhtype,
16+
mhlen: options.mhlen,
17+
pin: options.pin
18+
}).reduce((obj, [key, value]) => {
19+
if (value != null) obj[key] = value
20+
return obj
21+
}, {})
22+
23+
const url = `${apiUrl}${apiPath}/block/put?${QueryString.stringify(qs)}`
24+
25+
const body = new FormData()
26+
body.append('file', data)
27+
28+
let res
29+
30+
try {
31+
res = await ok(fetch(url, {
32+
method: 'POST',
33+
signal: options.signal,
34+
headers: options.headers || headers,
35+
body
36+
}))
37+
} catch (err) {
38+
// Retry with "protobuf"/"cbor" format for go-ipfs
39+
// TODO: remove when https://github.com/ipfs/go-cid/issues/75 resolved
40+
if (options.format === 'dag-pb') {
41+
return put(data, { ...options, format: 'protobuf' })
42+
} else if (options.format === 'dag-cbor') {
43+
return put(data, { ...options, format: 'cbor' })
44+
}
45+
46+
throw err
47+
}
48+
49+
return toCamel(await res.json())
50+
}
51+
52+
return put
53+
})

src/block/stat.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict'
2+
3+
const configure = require('../lib/configure')
4+
const { ok } = require('../lib/fetch')
5+
const toCamel = require('../lib/to-camel')
6+
7+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
8+
return async (cid, options) => {
9+
options = options || {}
10+
11+
const url = `${apiUrl}${apiPath}/block/stat?arg=${encodeURIComponent(cid)}`
12+
const res = await ok(fetch(url, {
13+
signal: options.signal,
14+
headers: options.headers || headers
15+
}))
16+
return toCamel(await res.json())
17+
}
18+
})

src/cat.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const { Buffer } = require('buffer')
44
const configure = require('./lib/configure')
55
const { ok, toIterable } = require('./lib/fetch')
66

7-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
7+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
88
return (cid, options) => (async function * () {
99
options = options || {}
1010

src/id.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const configure = require('./lib/configure')
44
const { ok } = require('./lib/fetch')
55
const toCamel = require('./lib/to-camel')
66

7-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
7+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
88
return async options => {
99
options = options || {}
1010
const url = `${apiUrl}${apiPath}/id`

src/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ module.exports = config => {
1919
wantlist: callbackify(require('./bitswap/wantlist')(config))
2020
},
2121
block: {
22-
get: callbackify(require('./block/get')(config))
22+
get: callbackify(require('./block/get')(config)),
23+
put: callbackify(require('./block/put')(config)),
24+
stat: callbackify(require('./block/stat')(config))
2325
},
2426
cat: callbackify(concatify(cat)),
2527
catPullStream: pullify.source(cat),

src/ls.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const configure = require('./lib/configure')
55
const { ok } = require('./lib/fetch')
66
const toCamel = require('./lib/to-camel')
77

8-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
8+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
99
return (path, options) => (async function * () {
1010
options = options || {}
1111

src/ping.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const configure = require('./lib/configure')
66
const { ok, toIterable } = require('./lib/fetch')
77
const toCamel = require('./lib/to-camel')
88

9-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
9+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
1010
return (peerId, options) => (async function * () {
1111
options = options || {}
1212

src/swarm/connect.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const QueryString = require('querystring')
44
const configure = require('../lib/configure')
55
const { ok } = require('../lib/fetch')
66

7-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
7+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
88
return async (addrs, options) => {
99
addrs = Array.isArray(addrs) ? addrs : [addrs]
1010
options = options || {}

src/swarm/peers.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const QueryString = require('querystring')
44
const configure = require('../lib/configure')
55
const { ok } = require('../lib/fetch')
66

7-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
7+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
88
return async options => {
99
options = options || {}
1010

src/version.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const configure = require('./lib/configure')
44
const { ok } = require('./lib/fetch')
55
const toCamel = require('./lib/to-camel')
66

7-
module.exports = configure(({ fetch, apiUrl, apiPath, signal, headers }) => {
7+
module.exports = configure(({ fetch, apiUrl, apiPath, headers }) => {
88
return async options => {
99
options = options || {}
1010
const url = `${apiUrl}${apiPath}/version`

0 commit comments

Comments
 (0)