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

Commit a7ed29d

Browse files
committed
chore: merge
* 'feat/support-file-dom-api' of github.com.:ipfs/js-ipfs: feat: implement ipfs refs and refs local (#2004)
2 parents fe84aab + f7665bd commit a7ed29d

21 files changed

+690
-25
lines changed

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
"@hapi/hapi": "^18.3.1",
8787
"@hapi/joi": "^15.0.1",
8888
"async": "^2.6.1",
89+
"base32.js": "~0.1.0",
8990
"bignumber.js": "^8.0.2",
9091
"binary-querystring": "~0.1.2",
9192
"bl": "^3.0.0",
@@ -177,6 +178,7 @@
177178
"pull-sort": "^1.0.1",
178179
"pull-stream": "^3.6.9",
179180
"pull-stream-to-stream": "^1.3.4",
181+
"pull-traverse": "^1.0.3",
180182
"readable-stream": "^3.1.1",
181183
"receptacle": "^1.3.2",
182184
"stream-to-pull-stream": "^1.7.3",

src/cli/bin.js

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const mfs = require('ipfs-mfs/cli')
1010
const debug = require('debug')('ipfs:cli')
1111
const pkg = require('../../package.json')
1212
const parser = require('./parser')
13+
const commandAlias = require('./command-alias')
1314

1415
async function main (args) {
1516
const oneWeek = 1000 * 60 * 60 * 24 * 7
@@ -22,6 +23,9 @@ async function main (args) {
2223

2324
let getIpfs = null
2425

26+
// Apply command aliasing (eg `refs local` -> `refs-local`)
27+
args = commandAlias(args)
28+
2529
cli
2630
.parse(args)
2731
.then(({ data, argv }) => {

src/cli/command-alias.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict'
2+
3+
const aliases = {
4+
// We need to be able to show help text for both the `refs` command and the
5+
// `refs local` command, but with yargs `refs` cannot be both a command and
6+
// a command directory. So alias `refs local` to `refs-local`
7+
'refs-local': ['refs', 'local']
8+
}
9+
10+
// Replace multi-word command with alias
11+
// eg replace `refs local` with `refs-local`
12+
module.exports = function (args) {
13+
for (const [alias, original] of Object.entries(aliases)) {
14+
if (arrayMatch(args, original)) {
15+
return [alias, ...args.slice(original.length)]
16+
}
17+
}
18+
19+
return args
20+
}
21+
22+
// eg arrayMatch([1, 2, 3], [1, 2]) => true
23+
function arrayMatch (arr, sub) {
24+
if (sub.length > arr.length) {
25+
return false
26+
}
27+
28+
for (let i = 0; i < sub.length; i++) {
29+
if (arr[i] !== sub[i]) {
30+
return false
31+
}
32+
}
33+
34+
return true
35+
}

src/cli/commands/refs-local.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict'
2+
3+
const { print } = require('../utils')
4+
5+
module.exports = {
6+
command: 'refs-local',
7+
8+
describe: 'List all local references.',
9+
10+
handler ({ getIpfs, resolve }) {
11+
resolve((async () => {
12+
const ipfs = await getIpfs()
13+
14+
return new Promise((resolve, reject) => {
15+
const stream = ipfs.refs.localReadableStream()
16+
17+
stream.on('error', reject)
18+
stream.on('end', resolve)
19+
20+
stream.on('data', (ref) => {
21+
if (ref.err) {
22+
print(ref.err, true, true)
23+
} else {
24+
print(ref.ref)
25+
}
26+
})
27+
})
28+
})())
29+
}
30+
}

src/cli/commands/refs.js

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
'use strict'
2+
3+
const { print } = require('../utils')
4+
5+
module.exports = {
6+
command: 'refs <key> [keys..]',
7+
8+
describe: 'List links (references) from an object',
9+
10+
builder: {
11+
recursive: {
12+
alias: 'r',
13+
desc: 'Recursively list links of child nodes.',
14+
type: 'boolean',
15+
default: false
16+
},
17+
format: {
18+
desc: 'Output edges with given format. Available tokens: <src> <dst> <linkname>.',
19+
type: 'string',
20+
default: '<dst>'
21+
},
22+
edges: {
23+
alias: 'e',
24+
desc: 'Output edge format: `<from> -> <to>`',
25+
type: 'boolean',
26+
default: false
27+
},
28+
unique: {
29+
alias: 'u',
30+
desc: 'Omit duplicate refs from output.',
31+
type: 'boolean',
32+
default: false
33+
},
34+
'max-depth': {
35+
desc: 'Only for recursive refs, limits fetch and listing to the given depth.',
36+
type: 'number'
37+
}
38+
},
39+
40+
handler ({ getIpfs, key, keys, recursive, format, edges, unique, maxDepth, resolve }) {
41+
resolve((async () => {
42+
if (maxDepth === 0) {
43+
return
44+
}
45+
46+
const ipfs = await getIpfs()
47+
const k = [key].concat(keys)
48+
49+
return new Promise((resolve, reject) => {
50+
const stream = ipfs.refsReadableStream(k, { recursive, format, edges, unique, maxDepth })
51+
52+
stream.on('error', reject)
53+
stream.on('end', resolve)
54+
55+
stream.on('data', (ref) => {
56+
if (ref.err) {
57+
print(ref.err, true, true)
58+
} else {
59+
print(ref.ref)
60+
}
61+
})
62+
})
63+
})())
64+
}
65+
}

src/cli/utils.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ exports.getRepoPath = () => {
8181
let visible = true
8282
exports.disablePrinting = () => { visible = false }
8383

84-
exports.print = (msg, newline) => {
84+
exports.print = (msg, newline, isError = false) => {
8585
if (newline === undefined) {
8686
newline = true
8787
}
@@ -91,7 +91,8 @@ exports.print = (msg, newline) => {
9191
msg = ''
9292
}
9393
msg = newline ? msg + '\n' : msg
94-
process.stdout.write(msg)
94+
const outStream = isError ? process.stderr : process.stdout
95+
outStream.write(msg)
9596
}
9697
}
9798

+26-17
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
'use strict'
22

3-
module.exports = self => ({
4-
add: require('./add')(self),
5-
addFromFs: require('./add-from-fs')(self),
6-
addFromStream: require('./add-from-stream')(self),
7-
addFromURL: require('./add-from-url')(self),
8-
addPullStream: require('./add-pull-stream')(self),
9-
addReadableStream: require('./add-readable-stream')(self),
10-
cat: require('./cat')(self),
11-
catPullStream: require('./cat-pull-stream')(self),
12-
catReadableStream: require('./cat-readable-stream')(self),
13-
get: require('./get')(self),
14-
getPullStream: require('./get-pull-stream')(self),
15-
getReadableStream: require('./get-readable-stream')(self),
16-
ls: require('./ls')(self),
17-
lsPullStream: require('./ls-pull-stream')(self),
18-
lsReadableStream: require('./ls-readable-stream')(self)
19-
})
3+
module.exports = (self) => {
4+
const filesRegular = {
5+
add: require('./add')(self),
6+
addFromFs: require('./add-from-fs')(self),
7+
addFromStream: require('./add-from-stream')(self),
8+
addFromURL: require('./add-from-url')(self),
9+
addPullStream: require('./add-pull-stream')(self),
10+
addReadableStream: require('./add-readable-stream')(self),
11+
cat: require('./cat')(self),
12+
catPullStream: require('./cat-pull-stream')(self),
13+
catReadableStream: require('./cat-readable-stream')(self),
14+
get: require('./get')(self),
15+
getPullStream: require('./get-pull-stream')(self),
16+
getReadableStream: require('./get-readable-stream')(self),
17+
ls: require('./ls')(self),
18+
lsPullStream: require('./ls-pull-stream')(self),
19+
lsReadableStream: require('./ls-readable-stream')(self),
20+
refs: require('./refs')(self),
21+
refsReadableStream: require('./refs-readable-stream')(self),
22+
refsPullStream: require('./refs-pull-stream')(self)
23+
}
24+
filesRegular.refs.local = require('./refs-local')(self)
25+
filesRegular.refs.localReadableStream = require('./refs-local-readable-stream')(self)
26+
filesRegular.refs.localPullStream = require('./refs-local-pull-stream')(self)
27+
return filesRegular
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict'
2+
3+
const CID = require('cids')
4+
const base32 = require('base32.js')
5+
const pull = require('pull-stream')
6+
const pullDefer = require('pull-defer')
7+
8+
module.exports = function (self) {
9+
return () => {
10+
const deferred = pullDefer.source()
11+
12+
self._repo.blocks.query({ keysOnly: true }, (err, blocks) => {
13+
if (err) {
14+
return deferred.resolve(pull.error(err))
15+
}
16+
17+
const refs = blocks.map(b => dsKeyToRef(b.key))
18+
deferred.resolve(pull.values(refs))
19+
})
20+
21+
return deferred
22+
}
23+
}
24+
25+
function dsKeyToRef (key) {
26+
try {
27+
// Block key is of the form /<base32 encoded string>
28+
const decoder = new base32.Decoder()
29+
const buff = Buffer.from(decoder.write(key.toString().slice(1)).finalize())
30+
return { ref: new CID(buff).toString() }
31+
} catch (err) {
32+
return { err: `Could not convert block with key '${key}' to CID: ${err.message}` }
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict'
2+
3+
const toStream = require('pull-stream-to-stream')
4+
5+
module.exports = function (self) {
6+
return (ipfsPath, options) => {
7+
return toStream.source(self.refs.localPullStream())
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict'
2+
3+
const promisify = require('promisify-es6')
4+
const pull = require('pull-stream')
5+
6+
module.exports = function (self) {
7+
return promisify((callback) => {
8+
pull(
9+
self.refs.localPullStream(),
10+
pull.collect((err, values) => {
11+
if (err) {
12+
return callback(err)
13+
}
14+
callback(null, values)
15+
})
16+
)
17+
})
18+
}

0 commit comments

Comments
 (0)