Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit 1ad6001

Browse files
authored
feat: make ipfs.get output tarballs (#3785)
`ipfs get` on the cli writes files/folders to disk, also tarballs and gzipped tarballs. Also gzipped individual files. In the API it's very similar to `ipfs.ls`. Make it more like the cli so there's a clear reason to use one or the other. Also adds types to `interface-ipfs-core` to better catch broken types in `ipfs-core-types`. BREAKING CHANGE: the output type of `ipfs.get` has changed and the `recursive` option has been removed from `ipfs.ls` since it was not supported everywhere
1 parent 79f661e commit 1ad6001

File tree

217 files changed

+3316
-1556
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

217 files changed

+3316
-1556
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ jobs:
8484
- stage: test
8585
name: lint
8686
script:
87+
- npm run build
8788
- npm run lint -- $RUN_SINCE --concurrency 1
8889

8990
- stage: test

docs/core-api/FILES.md

+15-29
Original file line numberDiff line numberDiff line change
@@ -447,53 +447,39 @@ An optional object which may have the following keys:
447447

448448
| Name | Type | Default | Description |
449449
| ---- | ---- | ------- | ----------- |
450+
| archive | `boolean` | `undefined` | Return the file/directory in a tarball |
451+
| compress | `boolean` | `false` | Gzip the returned stream |
452+
| compressionLevel | `Number` | `undefined` | How much compression to apply (1-9) |
450453
| timeout | `Number` | `undefined` | A timeout in ms |
451454
| signal | [AbortSignal][] | `undefined` | Can be used to cancel any long running requests started as a result of this call |
452455

453456
#### Returns
454457

455458
| Type | Description |
456459
| -------- | -------- |
457-
| `AsyncIterable<Object>` | An async iterable that yields objects representing the files |
460+
| `AsyncIterable<Uint8Array>` | An async iterable that yields bytes |
458461

459-
Each yielded object is of the form:
462+
What is streamed as a response depends on the options passed and what the `ipfsPath` resolves to.
460463

461-
```js
462-
{
463-
type: string, // 'file' or 'dir'
464-
path: string, // a deeply nested path within the directory structure
465-
content?: <AsyncIterable<Uint8Array>>, // only present if `type` is 'file'
466-
mode: Number, // implicit if not provided - 0644 for files, 0755 for directories
467-
mtime?: { secs: Number, nsecs: Number }
468-
}
469-
```
470-
471-
Here, each `path` corresponds to the name of a file, and `content` is an async iterable with the file contents.
464+
1. If `ipfsPath` resolves to a file:
465+
* By default you will get a tarball containing the file
466+
* Pass `compress: true` (and an optional `compressionLevel`) to instead get the gzipped file contents
467+
* Pass `compress: true` (and an optional `compressionLevel`) AND `archive: true` to get a gzipped tarball containing the file
468+
2. If `ipfsPath` resolves to a directory:
469+
* By default you will get a tarball containing the contents of the directory
470+
* Passing `compress: true` will cause an error
471+
* Pass `compress: true` (and an optional `compressionLevel`) AND `archive: true` to get a gzipped tarball containing the contents of the directory
472472

473473
#### Example
474474

475475
```JavaScript
476476
const cid = 'QmQ2r6iMNpky5f1m4cnm3Yqw8VSvjuKpTcK1X7dBR1LkJF'
477477

478-
for await (const file of ipfs.get(cid)) {
479-
console.log(file.type, file.path)
480-
481-
if (!file.content) continue;
482-
483-
const content = []
484-
485-
for await (const chunk of file.content) {
486-
content.push(chunk)
487-
}
488-
489-
console.log(content)
478+
for await (const buf of ipfs.get(cid)) {
479+
// do something with buf
490480
}
491481
```
492482

493-
When invoking this method via the HTTP API client, the response arrives as a stream containing either the entire contents of the file (if the passed [CID][] resolves to a file) or recursive directory tree and all files contained therein (if the passed [CID][] resolves to a directory).
494-
495-
If you are iterating over a directory, in order to proceed to the next entry in the stream, you must consume the `content` field of the current entry if it is present.
496-
497483
A great source of [examples](https://github.com/ipfs/js-ipfs/blob/master/packages/interface-ipfs-core/src/get.js) can be found in the tests for this API.
498484

499485
### `ipfs.ls(ipfsPath)`

examples/browser-ipns-publish/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"devDependencies": {
2929
"delay": "^5.0.0",
3030
"execa": "^5.0.0",
31-
"ipfsd-ctl": "^9.0.0",
31+
"ipfsd-ctl": "^10.0.3",
3232
"go-ipfs": "0.8.0",
3333
"parcel": "2.0.0-beta.2",
3434
"path": "^0.12.7",

examples/http-client-browser-pubsub/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"execa": "^5.0.0",
2323
"go-ipfs": "0.8.0",
2424
"ipfs": "^0.56.1",
25-
"ipfsd-ctl": "^9.0.0",
25+
"ipfsd-ctl": "^10.0.3",
2626
"parcel": "2.0.0-beta.2",
2727
"test-ipfs-example": "^3.0.0"
2828
}

examples/http-client-bundle-webpack/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"copy-webpack-plugin": "^8.1.0",
2626
"execa": "^5.0.0",
2727
"ipfs": "^0.56.1",
28-
"ipfsd-ctl": "^9.0.0",
28+
"ipfsd-ctl": "^10.0.3",
2929
"react-hot-loader": "^4.12.21",
3030
"rimraf": "^3.0.2",
3131
"test-ipfs-example": "^3.0.0",

examples/http-client-name-api/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"devDependencies": {
1919
"execa": "^5.0.0",
2020
"go-ipfs": "0.8.0",
21-
"ipfsd-ctl": "^9.0.0",
21+
"ipfsd-ctl": "^10.0.3",
2222
"parcel": "2.0.0-beta.2",
2323
"rimraf": "^3.0.2",
2424
"test-ipfs-example": "^3.0.0"

examples/ipfs-client-add-files/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"devDependencies": {
1717
"execa": "^5.0.0",
1818
"ipfs": "^0.56.1",
19-
"ipfsd-ctl": "^9.0.0",
19+
"ipfsd-ctl": "^10.0.3",
2020
"parcel": "2.0.0-beta.2",
2121
"rimraf": "^3.0.2",
2222
"test-ipfs-example": "^3.0.0"

packages/interface-ipfs-core/package.json

+10-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313
"ipfs-utils/src/files/glob-source": false
1414
},
1515
"scripts": {
16+
"build": "aegir build",
1617
"lint": "aegir lint",
1718
"test": "echo 'No tests here'",
18-
"dep-check": "aegir dep-check -i abort-controller"
19+
"dep-check": "aegir dep-check -i abort-controller -i ipfs-core-types"
1920
},
2021
"files": [
2122
"src/",
@@ -35,17 +36,21 @@
3536
"test/fixtures/*"
3637
]
3738
},
39+
"types": "dist/src/index.d.ts",
3840
"dependencies": {
3941
"@ipld/car": "^3.1.6",
4042
"@ipld/dag-cbor": "^6.0.5",
4143
"@ipld/dag-pb": "^2.1.3",
44+
"@types/readable-stream": "^2.3.11",
45+
"@types/pako": "^1.0.2",
4246
"abort-controller": "^3.0.0",
4347
"aegir": "^34.0.2",
4448
"delay": "^5.0.0",
4549
"err-code": "^3.0.1",
4650
"interface-blockstore": "^1.0.0",
51+
"ipfs-core-types": "^0.6.0",
4752
"ipfs-unixfs": "^5.0.0",
48-
"ipfs-unixfs-importer": "^8.0.0",
53+
"ipfs-unixfs-importer": "^8.0.2",
4954
"ipfs-utils": "^8.1.4",
5055
"ipns": "^0.13.2",
5156
"is-ipfs": "^6.0.1",
@@ -57,7 +62,9 @@
5762
"it-first": "^1.0.4",
5863
"it-last": "^1.0.4",
5964
"it-map": "^1.0.4",
65+
"it-pipe": "^1.1.0",
6066
"it-pushable": "^1.4.2",
67+
"it-tar": "^4.0.0",
6168
"it-to-buffer": "^2.0.0",
6269
"libp2p-crypto": "^0.19.6",
6370
"libp2p-websockets": "^0.16.1",
@@ -67,6 +74,7 @@
6774
"native-abort-controller": "^1.0.3",
6875
"p-map": "^4.0.0",
6976
"p-retry": "^4.5.0",
77+
"pako": "^1.0.2",
7078
"peer-id": "^0.15.1",
7179
"readable-stream": "^3.4.0",
7280
"uint8arrays": "^2.1.6"

0 commit comments

Comments
 (0)