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

Commit 575ab0b

Browse files
committed
fix: change mfs to use promise-nodeify
1 parent bc95ea4 commit 575ab0b

File tree

2 files changed

+193
-25
lines changed

2 files changed

+193
-25
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@
194194
"execa": "^2.0.4",
195195
"form-data": "^2.5.1",
196196
"hat": "0.0.3",
197-
"interface-ipfs-core": "^0.111.0",
198197
"ipfsd-ctl": "~0.45.0",
198+
"interface-ipfs-core": "^0.111.1",
199199
"libp2p-websocket-star": "~0.10.2",
200200
"ncp": "^2.0.0",
201201
"p-event": "^4.1.0",

src/core/components/files-mfs.js

Lines changed: 192 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ const map = require('pull-stream/throughs/map')
1313
const isIpfs = require('is-ipfs')
1414
const { cidToString } = require('../../utils/cid')
1515

16+
/**
17+
* @typedef { import("readable-stream").Readable } ReadableStream
18+
* @typedef { import("pull-stream") } PullStream
19+
*/
20+
1621
const mapLsFile = (options = {}) => {
1722
const long = options.long || options.l
1823

@@ -26,18 +31,6 @@ const mapLsFile = (options = {}) => {
2631
}
2732
}
2833

29-
const withPreload = fn => (...args) => {
30-
const paths = args.filter(arg => isIpfs.ipfsPath(arg) || isIpfs.cid(arg))
31-
32-
if (paths.length) {
33-
const options = args[args.length - 1]
34-
if (options.preload !== false) {
35-
paths.forEach(path => self._preload(path))
36-
}
37-
}
38-
39-
return fn(...args)
40-
}
4134
module.exports = (/** @type { import("../index") } */ ipfs) => {
4235
const methodsOriginal = mfs({
4336
ipld: ipfs._ipld,
@@ -46,9 +39,22 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
4639
repoOwner: ipfs._options.repoOwner
4740
})
4841

42+
const withPreload = fn => (...args) => {
43+
const paths = args.filter(arg => isIpfs.ipfsPath(arg) || isIpfs.cid(arg))
44+
45+
if (paths.length) {
46+
const options = args[args.length - 1]
47+
if (options.preload !== false) {
48+
paths.forEach(path => ipfs._preload(path))
49+
}
50+
}
51+
52+
return fn(...args)
53+
}
54+
4955
const methods = {
5056
...methodsOriginal,
51-
cp: withPreload(methodsOriginal.cp),
57+
// cp: withPreload(methodsOriginal.cp),
5258
ls: withPreload(methodsOriginal.ls),
5359
mv: withPreload(methodsOriginal.mv),
5460
read: withPreload(methodsOriginal.read),
@@ -67,7 +73,7 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
6773
* @param {String} [opts.hashAlg=sha2-256] - Algorithm to use when creating CIDs for newly created directories. (default: sha2-256) {@link https://github.com/multiformats/js-multihash/blob/master/src/constants.js#L5-L343 The list of all possible values}
6874
* @param {boolean} [opts.flush=true] - Whether or not to immediately flush MFS changes to disk (default: true).
6975
* @param {function(Error): void} [cb] - Callback function.
70-
* @returns {Promise<string> | void} - When callback is provided nothing is returned.
76+
* @returns {Promise<string> | void} When callback is provided nothing is returned.
7177
*/
7278
cp: (from, to, opts, cb) => {
7379
if (typeof opts === 'function') {
@@ -77,6 +83,18 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
7783
return nodeify(methods.cp(from, to, opts), cb)
7884
},
7985

86+
/**
87+
* Make a directory
88+
*
89+
* @param {String} path - The path to the directory to make.
90+
* @param {Object} [opts] - Options for mkdir.
91+
* @param {boolean} [opts.parents=false] - Value to decide whether or not to make the parent directories if they don't exist. (default: false)
92+
* @param {String} [opts.format=dag-pb] - Format of nodes to write any newly created directories as. (default: dag-pb).
93+
* @param {String} [opts.hashAlg] - Algorithm to use when creating CIDs for newly created directories. (default: sha2-256) {@link https://github.com/multiformats/js-multihash/blob/master/src/constants.js#L5-L343 The list of all possible values}
94+
* @param {boolean} [opts.flush=true] - Whether or not to immediately flush MFS changes to disk (default: true).
95+
* @param {function(Error): void} [cb] - Callback function.
96+
* @returns {Promise<undefined> | void} When callback is provided nothing is returned.
97+
*/
8098
mkdir: (path, opts, cb) => {
8199
if (typeof opts === 'function') {
82100
cb = opts
@@ -85,6 +103,30 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
85103
return nodeify(methods.mkdir(path, opts), cb)
86104
},
87105

106+
/**
107+
* @typedef {Object} StatOutput
108+
* @prop {String} hash - Output hash.
109+
* @prop {number} size - File size in bytes.
110+
* @prop {number} cumulativeSize - Integer with the size of the DAGNodes making up the file in Bytes.
111+
* @prop {string} type - Output type either 'directory' or 'file'.
112+
* @prop {number} blocks - If type is directory, this is the number of files in the directory. If it is file it is the number of blocks that make up the file.
113+
* @prop {boolean} withLocality - Indicate if locality information is present.
114+
* @prop {boolean} local - Indicate if the queried dag is fully present locally.
115+
* @prop {number} sizeLocal - Integer indicating the cumulative size of the data present locally.
116+
*/
117+
118+
/**
119+
* Get file or directory status.
120+
*
121+
* @param {String} path - Path to the file or directory to stat.
122+
* @param {Object} [opts] - Options for stat.
123+
* @param {boolean} [opts.hash=false] - Return only the hash. (default: false)
124+
* @param {boolean} [opts.size=false] - Return only the size. (default: false)
125+
* @param {boolean} [opts.withLocal=false] - Compute the amount of the dag that is local, and if possible the total size. (default: false)
126+
* @param {String} [opts.cidBase=base58btc] - Which number base to use to format hashes - e.g. base32, base64 etc. (default: base58btc)
127+
* @param {function(Error, StatOutput): void} [cb] - Callback function.
128+
* @returns {Promise<StatOutput> | void} When callback is provided nothing is returned.
129+
*/
88130
stat: (path, opts, cb) => {
89131
const stat = async (path, opts = {}) => {
90132
const stats = await methods.stat(path, opts)
@@ -103,6 +145,15 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
103145
return nodeify(stat(path, opts), cb)
104146
},
105147

148+
/**
149+
* Remove a file or directory.
150+
*
151+
* @param {String | Array<String>} paths - One or more paths to remove.
152+
* @param {Object} [opts] - Options for remove.
153+
* @param {boolean} [opts.recursive=false] - Whether or not to remove directories recursively. (default: false)
154+
* @param {function(Error): void} [cb] - Callback function.
155+
* @returns {Promise<undefined> | void} When callback is provided nothing is returned.
156+
*/
106157
rm: (paths, opts, cb) => {
107158
if (typeof opts === 'function') {
108159
cb = opts
@@ -111,6 +162,20 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
111162
return nodeify(methods.rm(paths, opts), cb)
112163
},
113164

165+
/**
166+
* @typedef {Object} ReadOptions
167+
* @prop {number} [opts.offset=0] - Integer with the byte offset to begin reading from (default: 0).
168+
* @prop {number} [opts.length] - Integer with the maximum number of bytes to read (default: Read to the end of stream).
169+
*/
170+
171+
/**
172+
* Read a file into a Buffer.
173+
*
174+
* @param {string} path - Path of the file to read and must point to a file (and not a directory).
175+
* @param {ReadOptions} [opts] - Object for read.
176+
* @param {function(Error, Buffer): void} [cb] - Callback function.
177+
* @returns {Promise<Buffer> | void} When callback is provided nothing is returned.
178+
*/
114179
read: (path, opts, cb) => {
115180
const read = async (path, opts = {}) => {
116181
return Buffer.concat(await all(methods.read(path, opts)))
@@ -123,10 +188,40 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
123188
return nodeify(read(path, opts), cb)
124189
},
125190

126-
readPullStream: (path, opts = {}) => toPullStream.source(methods.read(path, opts)),
127-
191+
/**
192+
* Read a file into a ReadableStream.
193+
*
194+
* @param {string} path - Path of the file to read and must point to a file (and not a directory).
195+
* @param {ReadOptions} [opts] - Object for read.
196+
* @returns {ReadableStream} Returns a ReadableStream with the contents of path.
197+
*/
128198
readReadableStream: (path, opts = {}) => toReadableStream(methods.read(path, opts)),
129199

200+
/**
201+
* Read a file into a PullStrean.
202+
*
203+
* @param {string} path - Path of the file to read and must point to a file (and not a directory).
204+
* @param {ReadOptions} [opts] - Object for read.
205+
* @returns {PullStream} Returns a PullStream with the contents of path.
206+
*/
207+
readPullStream: (path, opts = {}) => toPullStream.source(methods.read(path, opts)),
208+
209+
/**
210+
* Write to a file.
211+
*
212+
* @param {string} path - Path of the file to write.
213+
* @param {Buffer | PullStream | ReadableStream | Blob | string} content - Content to write.
214+
* @param {Object} opts - Options for write.
215+
* @param {number} [opts.offset=0] - Integer with the byte offset to begin writing at. (default: 0)
216+
* @param {boolean} [opts.create=false] - Indicate to create the file if it doesn't exist. (default: false)
217+
* @param {boolean} [opts.truncate=false] - Indicate if the file should be truncated after writing all the bytes from content. (default: false)
218+
* @param {boolena} [opts.parents=false] - Value to decide whether or not to make the parent directories if they don't exist. (default: false)
219+
* @param {number} [opts.length] - Maximum number of bytes to read. (default: Read all bytes from content)
220+
* @param {boolean} [opts.rawLeaves=false] - If true, DAG leaves will contain raw file data and not be wrapped in a protobuf. (default: false)
221+
* @param {number} [opts.cidVersion=0] - The CID version to use when storing the data (storage keys are based on the CID, including its version). (default: 0)
222+
* @param {function(Error): void} [cb] - Callback function.
223+
* @returns {Promise<undefined> | void} When callback is provided nothing is returned.
224+
*/
130225
write: (path, content, opts, cb) => {
131226
const write = async (path, content, opts = {}) => {
132227
if (isPullStream.isSource(content)) {
@@ -142,6 +237,29 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
142237
return nodeify(write(path, content, opts), cb)
143238
},
144239

240+
/**
241+
* Move files.
242+
*
243+
* @param {string | Array<string>} from - Path(s) of the source to move.
244+
* @param {string} to - Path of the destination to move to.
245+
* @param {Object} opts - Options for mv.
246+
* @param {boolean} [opts.parents=false] - Value to decide whether or not to make the parent directories if they don't exist. (default: false)
247+
* @param {String} [opts.format=dag-pb] - Format of nodes to write any newly created directories as. (default: dag-pb).
248+
* @param {String} [opts.hashAlg] - Algorithm to use when creating CIDs for newly created directories. (default: sha2-256) {@link https://github.com/multiformats/js-multihash/blob/master/src/constants.js#L5-L343 The list of all possible values}
249+
* @param {boolean} [opts.flush=true] - Value to decide whether or not to immediately flush MFS changes to disk. (default: true)
250+
* @param {function(Error): void} [cb] - Callback function.
251+
* @returns {Promise<undefined> | void} When callback is provided nothing is returned.
252+
* @description
253+
* If from has multiple values then to must be a directory.
254+
*
255+
* If from has a single value and to exists and is a directory, from will be moved into to.
256+
*
257+
* If from has a single value and to exists and is a file, from must be a file and the contents of to will be replaced with the contents of from otherwise an error will be returned.
258+
*
259+
* If from is an IPFS path, and an MFS path exists with the same name, the IPFS path will be chosen.
260+
*
261+
* All values of from will be removed after the operation is complete unless they are an IPFS path.
262+
*/
145263
mv: (from, to, opts, cb) => {
146264
if (typeof opts === 'function') {
147265
cb = opts
@@ -150,8 +268,44 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
150268
return nodeify(methods.mv(from, to, opts), cb)
151269
},
152270

153-
flush: (paths, cb) => nodeify(methods.flush(paths), cb),
271+
/**
272+
* Flush a given path's data to the disk.
273+
*
274+
* @param {string | Array<string>} [paths] - String paths to flush. (default: /)
275+
* @param {function(Error): void} [cb] - Callback function.
276+
* @returns {Promise<undefined> | void} When callback is provided nothing is returned.
277+
*/
278+
flush: (paths, cb) => {
279+
if (typeof paths === 'function') {
280+
cb = paths
281+
paths = undefined
282+
}
283+
return nodeify(methods.flush(paths), cb)
284+
},
285+
286+
/**
287+
* @typedef {Object} ListOutputFile
288+
* @prop {string} name - Which is the file's name.
289+
* @prop {string} type - Which is the object's type (directory or file).
290+
* @prop {number} size - The size of the file in bytes.
291+
* @prop {string} hash - The hash of the file.
292+
*/
293+
294+
/**
295+
* @typedef {Object} ListOptions
296+
* @prop {boolean} [long=false] - Value to decide whether or not to populate type, size and hash. (default: false)
297+
* @prop {string} [cidBase=base58btc] - Which number base to use to format hashes - e.g. base32, base64 etc. (default: base58btc)
298+
* @prop {boolean} [sort=false] - If true entries will be sorted by filename. (default: false)
299+
*/
154300

301+
/**
302+
* List directories in the local mutable namespace.
303+
*
304+
* @param {string} [path="/"] - String to show listing for. (default: /)
305+
* @param {ListOptions} [opts] - Options for list.
306+
* @param {function(Error, Array<ListOutputFile>): void} [cb] - Callback function.
307+
* @returns {Promise<Array<ListOutputFile>> | void} When callback is provided nothing is returned.
308+
*/
155309
ls: (path, opts, cb) => {
156310
const ls = async (path, opts = {}) => {
157311
const files = await all(methods.ls(path, opts))
@@ -172,20 +326,27 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
172326
return nodeify(ls(path, opts), cb)
173327
},
174328

175-
lsReadableStream: (path, options = {}) => {
176-
const stream = toReadableStream.obj(methods.ls(path, options))
329+
/**
330+
* Lists a directory from the local mutable namespace that is addressed by a valid IPFS Path. The list will be yielded as Readable Streams.
331+
*
332+
* @param {string} [path="/"] - String to show listing for. (default: /)
333+
* @param {ListOptions} [opts] - Options for list.
334+
* @returns {ReadableStream} It returns a Readable Stream in Object mode that will yield {@link ListOutputFile}
335+
*/
336+
lsReadableStream: (path, opts = {}) => {
337+
const stream = toReadableStream.obj(methods.ls(path, opts))
177338
const through = new PassThrough({
178339
objectMode: true
179340
})
180341
stream.on('data', (file) => {
181-
through.write(mapLsFile(options)(file))
342+
through.write(mapLsFile(opts)(file))
182343
})
183344
stream.on('error', (err) => {
184345
through.destroy(err)
185346
})
186347
stream.on('end', (file, enc, cb) => {
187348
if (file) {
188-
file = mapLsFile(options)(file)
349+
file = mapLsFile(opts)(file)
189350
}
190351

191352
through.end(file, enc, cb)
@@ -194,10 +355,17 @@ module.exports = (/** @type { import("../index") } */ ipfs) => {
194355
return through
195356
},
196357

197-
lsPullStream: (path, options = {}) => {
358+
/**
359+
* Lists a directory from the local mutable namespace that is addressed by a valid IPFS Path. The list will be yielded as PullStreams.
360+
*
361+
* @param {string} [path="/"] - String to show listing for. (default: /)
362+
* @param {ListOptions} [opts] - Options for list.
363+
* @returns {PullStream} It returns a PullStream that will yield {@link ListOutputFile}
364+
*/
365+
lsPullStream: (path, opts = {}) => {
198366
return pull(
199-
toPullStream.source(methods.ls(path, options)),
200-
map(mapLsFile(options))
367+
toPullStream.source(methods.ls(path, opts)),
368+
map(mapLsFile(opts))
201369
)
202370
}
203371
}

0 commit comments

Comments
 (0)