From 6fccc0b0b19c9f8316a0d13032784b65a6212ce2 Mon Sep 17 00:00:00 2001 From: Xmader Date: Thu, 20 Aug 2020 18:00:08 -0400 Subject: [PATCH 01/20] docs: TypeScript support --- docs/core-api/FILES.md | 8 ++-- packages/ipfs/package.json | 3 +- .../ipfs/src/core/components/add-all/index.js | 45 ++++++++++++++++++- packages/ipfs/src/core/components/add.js | 17 ++++++- packages/ipfs/src/core/utils.js | 10 ++++- 5 files changed, 74 insertions(+), 9 deletions(-) diff --git a/docs/core-api/FILES.md b/docs/core-api/FILES.md index 21827f1a7b..1f14ee0f2d 100644 --- a/docs/core-api/FILES.md +++ b/docs/core-api/FILES.md @@ -162,7 +162,7 @@ An optional object which may have the following keys: | Name | Type | Default | Description | | ---- | ---- | ------- | ----------- | -| chunker | `String` | `'size-262144` | chunking algorithm used to build ipfs DAGs | +| chunker | `String` | `'size-262144'` | chunking algorithm used to build ipfs DAGs | | cidVersion | `Number` | `0` | the CID version to use when storing the data | | hashAlg | `String` | `'sha2-256'` | multihash hashing algorithm to use | | onlyHash | `boolean` | `false` | If true, will not add blocks to the blockstore | @@ -178,7 +178,7 @@ An optional object which may have the following keys: | Type | Description | | -------- | -------- | -| `UnixFSEntry` | A object describing the added data | +| `Promise` | A object describing the added data | Each yielded object is of the form: @@ -226,7 +226,7 @@ Now [ipfs.io/ipfs/Qm..pg/myfile.txt](https://ipfs.io/ipfs/QmWXdjNC362aPDtwHPUE9o | Name | Type | Description | | ---- | ---- | ----------- | -| source | [FileStream](#filestream) | Data to import (see below) | +| source | [FileStream](#filestream) | Data to import (see below) | ##### FileStream @@ -242,7 +242,7 @@ An optional object which may have the following keys: | Name | Type | Default | Description | | ---- | ---- | ------- | ----------- | -| chunker | `String` | `'size-262144` | chunking algorithm used to build ipfs DAGs | +| chunker | `String` | `'size-262144'` | chunking algorithm used to build ipfs DAGs | | cidVersion | `Number` | `0` | the CID version to use when storing the data | | enableShardingExperiment | `boolean` | `false` | allows to create directories with an unlimited number of entries currently size of unixfs directories is limited by the maximum block size. Note that this is an experimental feature | | hashAlg | `String` | `'sha2-256'` | multihash hashing algorithm to use | diff --git a/packages/ipfs/package.json b/packages/ipfs/package.json index 359d011ddb..21c4787a2a 100644 --- a/packages/ipfs/package.json +++ b/packages/ipfs/package.json @@ -346,6 +346,7 @@ "tcme ", "victorbjelkholm ", "Łukasz Magiera ", - "Максим Ильин " + "Максим Ильин ", + "Xmader " ] } diff --git a/packages/ipfs/src/core/components/add-all/index.js b/packages/ipfs/src/core/components/add-all/index.js index f72c337439..daa962b595 100644 --- a/packages/ipfs/src/core/components/add-all/index.js +++ b/packages/ipfs/src/core/components/add-all/index.js @@ -6,10 +6,53 @@ const { parseChunkerString } = require('./utils') const pipe = require('it-pipe') const { withTimeoutOption } = require('../../utils') +/** + * @typedef {Uint8Array | Blob | String | Iterable | AsyncIterable | ReadableStream} FileContent + * + * @typedef {object} FileObject + * @property {string} [path] - The path you want to the file to be accessible at from the root CID _after_ it has been added + * @property {FileContent} [content] - The contents of the file + * @property {number | string} [mode] - File mode to store the entry with (see https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation) + * @property {UnixTime} [mtime] - The modification time of the entry + * + * @typedef {FileContent | FileObject} Source + * @typedef {Iterable | AsyncIterable | ReadableStream} FileStream + * + * @typedef {Date | UnixTimeObj | number[]} UnixTime + * + * @typedef {object} UnixTimeObj + * @property {number} secs - the number of seconds since (positive) or before (negative) the Unix Epoch began + * @property {number} [nsecs] - the number of nanoseconds since the last full second. + * + * @typedef {object} UnixFSEntry + * @property {string} path + * @property {import('cids')} cid + * @property {number} mode + * @property {UnixTimeObj} mtime + * @property {number} size + */ + +/** + * @typedef {object} Options + * @property {string} [chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) + * @property {Number} [cidVersion] - the CID version to use when storing the data (default: `0`) + * @property {boolean} [enableShardingExperiment] - allows to create directories with an unlimited number of entries currently size of unixfs directories is limited by the maximum block size. Note that this is an experimental feature (default: `false`) + * @property {String} [hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) + * @property {boolean} [onlyHash] - If true, will not add blocks to the blockstore (default: `false`) + * @property {boolean} [pin] - pin this object when adding (default: `true`) + * @property {function} [progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) + * @property {boolean} [rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) + * @property {Number} [shardSplitThreshold] - Directories with more than this number of files will be created as HAMT-sharded directories (default: `1000`) + * @property {boolean} [trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) + * @property {boolean} [wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) + * @property {Number} [timeout] - A timeout in ms (default: `undefined`) + * @property {AbortSignal} [signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) + */ + module.exports = ({ block, gcLock, preload, pin, options: constructorOptions }) => { const isShardingEnabled = constructorOptions.EXPERIMENTAL && constructorOptions.EXPERIMENTAL.sharding - return withTimeoutOption(async function * addAll (source, options) { + return withTimeoutOption(/** @returns {AsyncIterable} */ async function * addAll (/**@type {FileStream}*/ source, /**@type {Options}*/ options) { options = options || {} const opts = { diff --git a/packages/ipfs/src/core/components/add.js b/packages/ipfs/src/core/components/add.js index 89a240df63..15e724c9b5 100644 --- a/packages/ipfs/src/core/components/add.js +++ b/packages/ipfs/src/core/components/add.js @@ -2,8 +2,23 @@ const last = require('it-last') +/** + * @typedef {object} Options + * @property {String} [chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) + * @property {Number} [cidVersion] - the CID version to use when storing the data (default: `0`) + * @property {String} [hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) + * @property {boolean} [onlyHash] - If true, will not add blocks to the blockstore (default: `false`) + * @property {boolean} [pin] - pin this object when adding (default: `true`) + * @property {function} [progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) + * @property {boolean} [rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) + * @property {boolean} [trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) + * @property {boolean} [wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) + * @property {Number} [timeout] - A timeout in ms (default: `undefined`) + * @property {AbortSignal} [signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) + */ + module.exports = ({ addAll }) => { - return async function add (source, options) { // eslint-disable-line require-await + return /**@returns {Promise}*/ async function add (/**@type {import('./add-all').Source}*/ source, /**@type {Options}*/ options) { // eslint-disable-line require-await return last(addAll(source, options)) } } diff --git a/packages/ipfs/src/core/utils.js b/packages/ipfs/src/core/utils.js index d3e0661dfd..d83e677f26 100644 --- a/packages/ipfs/src/core/utils.js +++ b/packages/ipfs/src/core/utils.js @@ -142,8 +142,14 @@ const mapFile = (file, options) => { return output } -function withTimeoutOption (fn, optionsArgIndex) { - return (...args) => { +/** + * @template {any[]} ARGS + * @template R - The return type of `fn` + * @param {(...args: ARGS) => R} fn + * @param {number} [optionsArgIndex] + */ +function withTimeoutOption(fn, optionsArgIndex) { + return /**@returns {R}*/ (/**@type {ARGS}*/...args) => { const options = args[optionsArgIndex == null ? args.length - 1 : optionsArgIndex] if (!options || !options.timeout) return fn(...args) From ac3ee3fa0a2c94e5ca52620e0ff22962d0331a58 Mon Sep 17 00:00:00 2001 From: Xmader Date: Thu, 20 Aug 2020 19:16:26 -0400 Subject: [PATCH 02/20] docs: add JSDoc --- .../ipfs/src/core/components/add-all/index.js | 52 +++++++++++-------- packages/ipfs/src/core/components/add.js | 38 ++++++++------ 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/packages/ipfs/src/core/components/add-all/index.js b/packages/ipfs/src/core/components/add-all/index.js index daa962b595..eb6e98b08c 100644 --- a/packages/ipfs/src/core/components/add-all/index.js +++ b/packages/ipfs/src/core/components/add-all/index.js @@ -9,7 +9,10 @@ const { withTimeoutOption } = require('../../utils') /** * @typedef {Uint8Array | Blob | String | Iterable | AsyncIterable | ReadableStream} FileContent * - * @typedef {object} FileObject + * @typedef {object} FileObject + * - If no path is specified, then the item will be added to the root level and will be given a name according to it's CID. + * - If no content is passed, then the item is treated as an empty directory. + * - One of path or content must be passed. * @property {string} [path] - The path you want to the file to be accessible at from the root CID _after_ it has been added * @property {FileContent} [content] - The contents of the file * @property {number | string} [mode] - File mode to store the entry with (see https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation) @@ -18,7 +21,7 @@ const { withTimeoutOption } = require('../../utils') * @typedef {FileContent | FileObject} Source * @typedef {Iterable | AsyncIterable | ReadableStream} FileStream * - * @typedef {Date | UnixTimeObj | number[]} UnixTime + * @typedef {Date | UnixTimeObj | [number, number]} UnixTime - As an array of numbers, it must have two elements, as per the output of [`process.hrtime()`](https://nodejs.org/dist/latest/docs/api/process.html#process_process_hrtime_time). * * @typedef {object} UnixTimeObj * @property {number} secs - the number of seconds since (positive) or before (negative) the Unix Epoch began @@ -32,27 +35,32 @@ const { withTimeoutOption } = require('../../utils') * @property {number} size */ -/** - * @typedef {object} Options - * @property {string} [chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) - * @property {Number} [cidVersion] - the CID version to use when storing the data (default: `0`) - * @property {boolean} [enableShardingExperiment] - allows to create directories with an unlimited number of entries currently size of unixfs directories is limited by the maximum block size. Note that this is an experimental feature (default: `false`) - * @property {String} [hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) - * @property {boolean} [onlyHash] - If true, will not add blocks to the blockstore (default: `false`) - * @property {boolean} [pin] - pin this object when adding (default: `true`) - * @property {function} [progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) - * @property {boolean} [rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) - * @property {Number} [shardSplitThreshold] - Directories with more than this number of files will be created as HAMT-sharded directories (default: `1000`) - * @property {boolean} [trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) - * @property {boolean} [wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) - * @property {Number} [timeout] - A timeout in ms (default: `undefined`) - * @property {AbortSignal} [signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - */ - module.exports = ({ block, gcLock, preload, pin, options: constructorOptions }) => { const isShardingEnabled = constructorOptions.EXPERIMENTAL && constructorOptions.EXPERIMENTAL.sharding - return withTimeoutOption(/** @returns {AsyncIterable} */ async function * addAll (/**@type {FileStream}*/ source, /**@type {Options}*/ options) { + /** + * Import multiple files and data into IPFS. + * + * @param {FileStream} source + * + * @param {object} [options] + * @param {string} [options.chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) + * @param {Number} [options.cidVersion] - the CID version to use when storing the data (default: `0`) + * @param {boolean} [options.enableShardingExperiment] - allows to create directories with an unlimited number of entries currently size of unixfs directories is limited by the maximum block size. Note that this is an experimental feature (default: `false`) + * @param {String} [options.hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) + * @param {boolean} [options.onlyHash] - If true, will not add blocks to the blockstore (default: `false`) + * @param {boolean} [options.pin] - pin this object when adding (default: `true`) + * @param {function} [options.progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) + * @param {boolean} [options.rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) + * @param {Number} [options.shardSplitThreshold] - Directories with more than this number of files will be created as HAMT-sharded directories (default: `1000`) + * @param {boolean} [options.trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) + * @param {boolean} [options.wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) + * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) + * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) + + * @returns {AsyncIterable} + */ + async function * addAll (source, options) { options = options || {} const opts = { @@ -101,7 +109,9 @@ module.exports = ({ block, gcLock, preload, pin, options: constructorOptions }) } finally { releaseLock() } - }) + } + + return withTimeoutOption(addAll) } function transformFile (opts) { diff --git a/packages/ipfs/src/core/components/add.js b/packages/ipfs/src/core/components/add.js index 15e724c9b5..125b31f1f2 100644 --- a/packages/ipfs/src/core/components/add.js +++ b/packages/ipfs/src/core/components/add.js @@ -2,23 +2,29 @@ const last = require('it-last') -/** - * @typedef {object} Options - * @property {String} [chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) - * @property {Number} [cidVersion] - the CID version to use when storing the data (default: `0`) - * @property {String} [hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) - * @property {boolean} [onlyHash] - If true, will not add blocks to the blockstore (default: `false`) - * @property {boolean} [pin] - pin this object when adding (default: `true`) - * @property {function} [progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) - * @property {boolean} [rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) - * @property {boolean} [trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) - * @property {boolean} [wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) - * @property {Number} [timeout] - A timeout in ms (default: `undefined`) - * @property {AbortSignal} [signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - */ - module.exports = ({ addAll }) => { - return /**@returns {Promise}*/ async function add (/**@type {import('./add-all').Source}*/ source, /**@type {Options}*/ options) { // eslint-disable-line require-await + /** + * Import a file or data into IPFS. + * + * @param {import('./add-all').Source} source - Data to import + * + * @param {object} [options] + * @param {String} [options.chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) + * @param {Number} [options.cidVersion] - the CID version to use when storing the data (default: `0`) + * @param {String} [options.hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) + * @param {boolean} [options.onlyHash] - If true, will not add blocks to the blockstore (default: `false`) + * @param {boolean} [options.pin] - pin this object when adding (default: `true`) + * @param {function} [options.progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) + * @param {boolean} [options.rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) + * @param {boolean} [options.trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) + * @param {boolean} [options.wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) + * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) + * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) + * + * @returns {Promise} + */ + async function add (source, options) { // eslint-disable-line require-await return last(addAll(source, options)) } + return add } From 085a5cdfae0cefd21bca1a186d58096ce577e89d Mon Sep 17 00:00:00 2001 From: Xmader Date: Thu, 20 Aug 2020 22:04:23 -0400 Subject: [PATCH 03/20] refactor: TypeScript support --- packages/ipfs/src/core/components/init.js | 6 ++++-- packages/ipfs/src/core/components/start.js | 8 +++++--- packages/ipfs/src/core/index.js | 8 ++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/ipfs/src/core/components/init.js b/packages/ipfs/src/core/components/init.js index b751462c05..24d8e646ff 100644 --- a/packages/ipfs/src/core/components/init.js +++ b/packages/ipfs/src/core/components/init.js @@ -166,12 +166,14 @@ module.exports = ({ }) apiManager.update(api, () => { throw new NotStartedError() }) + + /** @type {typeof api} */ + const initializedApi = apiManager.api + return initializedApi } catch (err) { cancel() throw err } - - return apiManager.api } async function initNewRepo (repo, { privateKey, emptyRepo, algorithm, bits, profiles, config, pass, print }) { diff --git a/packages/ipfs/src/core/components/start.js b/packages/ipfs/src/core/components/start.js index 24d59fd381..d05b7f6dc1 100644 --- a/packages/ipfs/src/core/components/start.js +++ b/packages/ipfs/src/core/components/start.js @@ -143,14 +143,16 @@ module.exports = ({ }) apiManager.update(api, () => undefined) + + /** @type {typeof api} */ + const startedApi = apiManager.api + startPromise.resolve(startedApi) + return startedApi } catch (err) { cancel() startPromise.reject(err) throw err } - - startPromise.resolve(apiManager.api) - return apiManager.api }) function createApi ({ diff --git a/packages/ipfs/src/core/index.js b/packages/ipfs/src/core/index.js index 4f0c79d1f5..859d47cb89 100644 --- a/packages/ipfs/src/core/index.js +++ b/packages/ipfs/src/core/index.js @@ -45,20 +45,20 @@ async function create (options) { const { api } = apiManager.update({ init: Components.init({ apiManager, print, options }), dns: Components.dns(), - isOnline: Components.isOnline({}) + isOnline: Components.isOnline({ libp2p: undefined }) }, async () => { throw new NotInitializedError() }) // eslint-disable-line require-await if (!options.init) { return api } - await api.init() + const initializedApi = await api.init() if (!options.start) { - return api + return initializedApi } - return api.start() + return initializedApi.start() } module.exports = { From 46c73162fa0e0145fdc8c46b9d49078e21c03583 Mon Sep 17 00:00:00 2001 From: Xmader Date: Fri, 21 Aug 2020 00:28:25 -0400 Subject: [PATCH 04/20] docs: add JSDoc --- packages/ipfs/src/core/index.js | 68 ++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/packages/ipfs/src/core/index.js b/packages/ipfs/src/core/index.js index 859d47cb89..32b8f3e99c 100644 --- a/packages/ipfs/src/core/index.js +++ b/packages/ipfs/src/core/index.js @@ -34,6 +34,57 @@ const getDefaultOptions = () => ({ } }) +/** + * @typedef {object} InitOptions + * @property {boolean} [emptyRepo] - Whether to remove built-in assets, like the instructional tour and empty mutable file system, from the repo. (Default: `false`) + * @property {'rsa' | 'ed25519' | 'secp256k1'} [algorithm] - The type of key to use. (Default: `rsa`) + * @property {number} [bits] - Number of bits to use in the generated key pair (rsa only). (Default: `2048`) + * @property {string | import('peer-id')} [privateKey] - A pre-generated private key to use. Can be either a base64 string or a [PeerId](https://github.com/libp2p/js-peer-id) instance. **NOTE: This overrides `bits`.** + * @property {string} [pass] - A passphrase to encrypt keys. You should generally use the [top-level `pass` option](#optionspass) instead of the `init.pass` option (this one will take its value from the top-level option if not set). + * @property {any[]} [profiles] - Apply profile settings to config. + * @property {boolean} [allowNew] - Set to `false` to disallow initialization if the repo does not already exist. (Default: `true`) + * + * @typedef {object} RelayOptions + * @property {boolean} [enabled] - Enable circuit relay dialer and listener. (Default: `true`) + * @property {object} [hop] + * @property {boolean=} [hop.enabled] - Make this node a relay (other nodes can connect *through* it). (Default: `false`) + * @property {boolean=} [hop.active] - Make this an *active* relay node. Active relay nodes will attempt to dial a destination peer even if that peer is not yet connected to the relay. (Default: `false`) + * + * @typedef {object} PreloadOptions + * @property {boolean} [enabled] - Enable content preloading (Default: `true`) + * @property {string[]} [addresses] - Multiaddr API addresses of nodes that should preload content. + * - **NOTE:** nodes specified here should also be added to your node's bootstrap address list at `config.Boostrap`. + * + * @typedef {object} ExperimentalOptions + * @property {boolean} [ipnsPubsub] - Enable pub-sub on IPNS. (Default: `false`) + * @property {boolean} [sharding] - Enable directory sharding. Directories that have many child objects will be represented by multiple DAG nodes instead of just one. It can improve lookup performance when a directory has several thousand files or more. (Default: `false`) + */ + +/** + * Creates and returns a ready to use instance of an IPFS node. + * + * @template {boolean | InitOptions} INIT + * @template {boolean} START + * + * @param {object} [options] - specify advanced configuration + * @param {string | import('ipfs-repo')} [options.repo] - The file path at which to store the IPFS node’s data. Alternatively, you can set up a customized storage system by providing an [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo) instance. (Default: `'~/.jsipfs'` in Node.js, `'ipfs'` in browsers) + * @param {boolean} [options.repoAutoMigrate] - `js-ipfs` comes bundled with a tool that automatically migrates your IPFS repository when a new version is available. (Default: `true`) + * @param {INIT} [options.init] - Perform repo initialization steps when creating the IPFS node. (Default: `true`) + * - Note that *initializing* a repo is different from creating an instance of [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo). The IPFS constructor sets many special properties when initializing a repo, so you should usually not try and call `repoInstance.init()` yourself. + * @param {START} [options.start] - If `false`, do not automatically start the IPFS node. Instead, you’ll need to manually call [`node.start()`](#nodestart) yourself. (Default: `true`) + * @param {string} [options.pass] - A passphrase to encrypt/decrypt your keys. (Default: `null`) + * @param {boolean} [options.silent] - Prevents all logging output from the IPFS node. (Default: `false`) + * @param {RelayOptions} [options.relay] - Configure circuit relay (see the [circuit relay tutorial](https://github.com/ipfs/js-ipfs/tree/master/examples/circuit-relaying) to learn more). (Default: `{ enabled: true, hop: { enabled: false, active: false } }`) + * @param {boolean} [options.offline] - Run ipfs node offline. The node does not connect to the rest of the network but provides a local API. (Default: `false`) + * @param {PreloadOptions} [options.preload] - Configure remote preload nodes. The remote will preload content added on this node, and also attempt to preload objects requested by this node. + * @param {ExperimentalOptions} [options.EXPERIMENTAL] - Enable and configure experimental features. + * @param {object} [options.config] - Modify the default IPFS node config. This object will be *merged* with the default config; it will not replace it. (Default: [`config-nodejs.js`](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs/src/core/runtime/config-nodejs.js) in Node.js, [`config-browser.js`](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs/src/core/runtime/config-browser.js) in browsers) + * @param {object} [options.ipld] - Modify the default IPLD config. This object will be *merged* with the default config; it will not replace it. Check IPLD [docs](https://github.com/ipld/js-ipld#ipld-constructor) for more information on the available options. (Default: [`ipld-nodejs.js`](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs/src/core/runtime/ipld-nodejs.js) in Node.js, [`ipld-browser.js`](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs/src/core/runtime/ipld-browser.js) in browsers) + * @param {object | Function} [options.libp2p] - The libp2p option allows you to build your libp2p node by configuration, or via a bundle function. If you are looking to just modify the below options, using the object format is the quickest way to get the default features of libp2p. If you need to create a more customized libp2p node, such as with custom transports or peer/content routers that need some of the ipfs data on startup, a custom bundle is a great way to achieve this. + * - You can see the bundle in action in the [custom libp2p example](https://github.com/ipfs/js-ipfs/tree/master/examples/custom-libp2p). + * - Please see [libp2p/docs/CONFIGURATION.md](https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md) for the list of options libp2p supports. + * - Default: [`libp2p-nodejs.js`](../src/core/runtime/libp2p-nodejs.js) in Node.js, [`libp2p-browser.js`](../src/core/runtime/libp2p-browser.js) in browsers + */ async function create (options) { options = mergeOptions(getDefaultOptions(), options) @@ -48,17 +99,14 @@ async function create (options) { isOnline: Components.isOnline({ libp2p: undefined }) }, async () => { throw new NotInitializedError() }) // eslint-disable-line require-await - if (!options.init) { - return api - } - - const initializedApi = await api.init() - - if (!options.start) { - return initializedApi - } + const initializedApi = options.init && await api.init() + const startedApi = options.start && await initializedApi.start() - return initializedApi.start() + /** @typedef {true extends NonNullable ? typeof startedApi : typeof initializedApi} _API */ + /** @type {NonNullable extends false ? typeof api : _API} */ + // @ts-ignore + const ipfs = startedApi || initializedApi || api + return ipfs } module.exports = { From 27d618eb233229d2c81e241c646bfa3c9c3fe6e2 Mon Sep 17 00:00:00 2001 From: Xmader Date: Fri, 21 Aug 2020 00:40:42 -0400 Subject: [PATCH 05/20] docs: add JSDoc --- packages/ipfs/src/core/api-manager.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/ipfs/src/core/api-manager.js b/packages/ipfs/src/core/api-manager.js index 5ccc055e98..3041c0a17d 100644 --- a/packages/ipfs/src/core/api-manager.js +++ b/packages/ipfs/src/core/api-manager.js @@ -12,6 +12,11 @@ module.exports = class ApiManager { }) } + /** + * @template A + * @param {A} nextApi + * @returns {{ cancel(): any; api: A; }} + */ update (nextApi, onUndef) { const prevApi = { ...this._api } const prevUndef = this._onUndef From 9bf714ba9834ce58b08ee9d9b422ce375a05a831 Mon Sep 17 00:00:00 2001 From: Xmader Date: Fri, 21 Aug 2020 01:19:58 -0400 Subject: [PATCH 06/20] style: fix linting --- packages/ipfs/src/core/api-manager.js | 2 +- .../ipfs/src/core/components/add-all/index.js | 22 +++++++++---------- packages/ipfs/src/core/components/add.js | 8 +++---- packages/ipfs/src/core/components/start.js | 2 +- packages/ipfs/src/core/index.js | 14 ++++++------ packages/ipfs/src/core/utils.js | 5 ++--- 6 files changed, 26 insertions(+), 27 deletions(-) diff --git a/packages/ipfs/src/core/api-manager.js b/packages/ipfs/src/core/api-manager.js index 3041c0a17d..3c776aab33 100644 --- a/packages/ipfs/src/core/api-manager.js +++ b/packages/ipfs/src/core/api-manager.js @@ -14,7 +14,7 @@ module.exports = class ApiManager { /** * @template A - * @param {A} nextApi + * @param {A} nextApi * @returns {{ cancel(): any; api: A; }} */ update (nextApi, onUndef) { diff --git a/packages/ipfs/src/core/components/add-all/index.js b/packages/ipfs/src/core/components/add-all/index.js index eb6e98b08c..73d8e2a768 100644 --- a/packages/ipfs/src/core/components/add-all/index.js +++ b/packages/ipfs/src/core/components/add-all/index.js @@ -8,25 +8,25 @@ const { withTimeoutOption } = require('../../utils') /** * @typedef {Uint8Array | Blob | String | Iterable | AsyncIterable | ReadableStream} FileContent - * - * @typedef {object} FileObject - * - If no path is specified, then the item will be added to the root level and will be given a name according to it's CID. + * + * @typedef {object} FileObject + * - If no path is specified, then the item will be added to the root level and will be given a name according to it's CID. * - If no content is passed, then the item is treated as an empty directory. * - One of path or content must be passed. * @property {string} [path] - The path you want to the file to be accessible at from the root CID _after_ it has been added * @property {FileContent} [content] - The contents of the file * @property {number | string} [mode] - File mode to store the entry with (see https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation) * @property {UnixTime} [mtime] - The modification time of the entry - * + * * @typedef {FileContent | FileObject} Source * @typedef {Iterable | AsyncIterable | ReadableStream} FileStream - * + * * @typedef {Date | UnixTimeObj | [number, number]} UnixTime - As an array of numbers, it must have two elements, as per the output of [`process.hrtime()`](https://nodejs.org/dist/latest/docs/api/process.html#process_process_hrtime_time). - * + * * @typedef {object} UnixTimeObj * @property {number} secs - the number of seconds since (positive) or before (negative) the Unix Epoch began * @property {number} [nsecs] - the number of nanoseconds since the last full second. - * + * * @typedef {object} UnixFSEntry * @property {string} path * @property {import('cids')} cid @@ -40,10 +40,10 @@ module.exports = ({ block, gcLock, preload, pin, options: constructorOptions }) /** * Import multiple files and data into IPFS. - * - * @param {FileStream} source - * - * @param {object} [options] + * + * @param {FileStream} source + * + * @param {object} [options] * @param {string} [options.chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) * @param {Number} [options.cidVersion] - the CID version to use when storing the data (default: `0`) * @param {boolean} [options.enableShardingExperiment] - allows to create directories with an unlimited number of entries currently size of unixfs directories is limited by the maximum block size. Note that this is an experimental feature (default: `false`) diff --git a/packages/ipfs/src/core/components/add.js b/packages/ipfs/src/core/components/add.js index 125b31f1f2..e6184c576f 100644 --- a/packages/ipfs/src/core/components/add.js +++ b/packages/ipfs/src/core/components/add.js @@ -5,10 +5,10 @@ const last = require('it-last') module.exports = ({ addAll }) => { /** * Import a file or data into IPFS. - * + * * @param {import('./add-all').Source} source - Data to import - * - * @param {object} [options] + * + * @param {object} [options] * @param {String} [options.chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) * @param {Number} [options.cidVersion] - the CID version to use when storing the data (default: `0`) * @param {String} [options.hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) @@ -20,7 +20,7 @@ module.exports = ({ addAll }) => { * @param {boolean} [options.wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - * + * * @returns {Promise} */ async function add (source, options) { // eslint-disable-line require-await diff --git a/packages/ipfs/src/core/components/start.js b/packages/ipfs/src/core/components/start.js index d05b7f6dc1..f90bc7e728 100644 --- a/packages/ipfs/src/core/components/start.js +++ b/packages/ipfs/src/core/components/start.js @@ -143,7 +143,7 @@ module.exports = ({ }) apiManager.update(api, () => undefined) - + /** @type {typeof api} */ const startedApi = apiManager.api startPromise.resolve(startedApi) diff --git a/packages/ipfs/src/core/index.js b/packages/ipfs/src/core/index.js index 32b8f3e99c..b2d5e94680 100644 --- a/packages/ipfs/src/core/index.js +++ b/packages/ipfs/src/core/index.js @@ -43,29 +43,29 @@ const getDefaultOptions = () => ({ * @property {string} [pass] - A passphrase to encrypt keys. You should generally use the [top-level `pass` option](#optionspass) instead of the `init.pass` option (this one will take its value from the top-level option if not set). * @property {any[]} [profiles] - Apply profile settings to config. * @property {boolean} [allowNew] - Set to `false` to disallow initialization if the repo does not already exist. (Default: `true`) - * + * * @typedef {object} RelayOptions * @property {boolean} [enabled] - Enable circuit relay dialer and listener. (Default: `true`) * @property {object} [hop] * @property {boolean=} [hop.enabled] - Make this node a relay (other nodes can connect *through* it). (Default: `false`) * @property {boolean=} [hop.active] - Make this an *active* relay node. Active relay nodes will attempt to dial a destination peer even if that peer is not yet connected to the relay. (Default: `false`) - * + * * @typedef {object} PreloadOptions * @property {boolean} [enabled] - Enable content preloading (Default: `true`) - * @property {string[]} [addresses] - Multiaddr API addresses of nodes that should preload content. + * @property {string[]} [addresses] - Multiaddr API addresses of nodes that should preload content. * - **NOTE:** nodes specified here should also be added to your node's bootstrap address list at `config.Boostrap`. - * + * * @typedef {object} ExperimentalOptions * @property {boolean} [ipnsPubsub] - Enable pub-sub on IPNS. (Default: `false`) * @property {boolean} [sharding] - Enable directory sharding. Directories that have many child objects will be represented by multiple DAG nodes instead of just one. It can improve lookup performance when a directory has several thousand files or more. (Default: `false`) */ /** - * Creates and returns a ready to use instance of an IPFS node. - * + * Creates and returns a ready to use instance of an IPFS node. + * * @template {boolean | InitOptions} INIT * @template {boolean} START - * + * * @param {object} [options] - specify advanced configuration * @param {string | import('ipfs-repo')} [options.repo] - The file path at which to store the IPFS node’s data. Alternatively, you can set up a customized storage system by providing an [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo) instance. (Default: `'~/.jsipfs'` in Node.js, `'ipfs'` in browsers) * @param {boolean} [options.repoAutoMigrate] - `js-ipfs` comes bundled with a tool that automatically migrates your IPFS repository when a new version is available. (Default: `true`) diff --git a/packages/ipfs/src/core/utils.js b/packages/ipfs/src/core/utils.js index d83e677f26..c6d834f300 100644 --- a/packages/ipfs/src/core/utils.js +++ b/packages/ipfs/src/core/utils.js @@ -1,4 +1,3 @@ -'use strict' const isIpfs = require('is-ipfs') const CID = require('cids') @@ -148,8 +147,8 @@ const mapFile = (file, options) => { * @param {(...args: ARGS) => R} fn * @param {number} [optionsArgIndex] */ -function withTimeoutOption(fn, optionsArgIndex) { - return /**@returns {R}*/ (/**@type {ARGS}*/...args) => { +function withTimeoutOption (fn, optionsArgIndex) { + return /** @returns {R} */ (/** @type {ARGS} */...args) => { const options = args[optionsArgIndex == null ? args.length - 1 : optionsArgIndex] if (!options || !options.timeout) return fn(...args) From 9e1a6e4d21404b829289a9fbc9b7ef0fa0954a2d Mon Sep 17 00:00:00 2001 From: Xmader Date: Fri, 21 Aug 2020 01:43:34 -0400 Subject: [PATCH 07/20] style: fix linting --- packages/ipfs/src/core/api-manager.js | 3 +++ packages/ipfs/src/core/components/add.js | 1 + packages/ipfs/src/core/index.js | 1 + packages/ipfs/src/core/utils.js | 2 ++ 4 files changed, 7 insertions(+) diff --git a/packages/ipfs/src/core/api-manager.js b/packages/ipfs/src/core/api-manager.js index 3c776aab33..b0eec6e164 100644 --- a/packages/ipfs/src/core/api-manager.js +++ b/packages/ipfs/src/core/api-manager.js @@ -1,8 +1,10 @@ +/* eslint-disable valid-jsdoc */ 'use strict' module.exports = class ApiManager { constructor () { this._api = {} + /** @type {(prop: PropertyKey) => any} */ this._onUndef = () => undefined this.api = new Proxy(this._api, { get: (_, prop) => { @@ -15,6 +17,7 @@ module.exports = class ApiManager { /** * @template A * @param {A} nextApi + * @param {this['_onUndef']} [onUndef] * @returns {{ cancel(): any; api: A; }} */ update (nextApi, onUndef) { diff --git a/packages/ipfs/src/core/components/add.js b/packages/ipfs/src/core/components/add.js index e6184c576f..26c06b6314 100644 --- a/packages/ipfs/src/core/components/add.js +++ b/packages/ipfs/src/core/components/add.js @@ -1,3 +1,4 @@ +/* eslint-disable valid-jsdoc */ 'use strict' const last = require('it-last') diff --git a/packages/ipfs/src/core/index.js b/packages/ipfs/src/core/index.js index b2d5e94680..7dd594a46e 100644 --- a/packages/ipfs/src/core/index.js +++ b/packages/ipfs/src/core/index.js @@ -1,3 +1,4 @@ +/* eslint-disable valid-jsdoc */ 'use strict' const log = require('debug')('ipfs') diff --git a/packages/ipfs/src/core/utils.js b/packages/ipfs/src/core/utils.js index c6d834f300..08e2514897 100644 --- a/packages/ipfs/src/core/utils.js +++ b/packages/ipfs/src/core/utils.js @@ -1,3 +1,5 @@ +/* eslint-disable valid-jsdoc */ +'use strict' const isIpfs = require('is-ipfs') const CID = require('cids') From 5fd264ccb3a6dc4b873e5d08dc3ff431bec61018 Mon Sep 17 00:00:00 2001 From: Xmader Date: Mon, 24 Aug 2020 01:11:25 -0400 Subject: [PATCH 08/20] refactor: TypeScript support --- packages/ipfs/src/core/api-manager.js | 24 ++++++++++++++----- .../ipfs/src/core/components/add-all/index.js | 2 +- packages/ipfs/src/core/components/add.js | 10 +++++--- .../ipfs/src/core/components/bitswap/stat.js | 2 +- packages/ipfs/src/core/components/block/rm.js | 2 +- packages/ipfs/src/core/index.js | 7 ++++-- packages/ipfs/src/core/utils.js | 17 +++++++++---- 7 files changed, 46 insertions(+), 18 deletions(-) diff --git a/packages/ipfs/src/core/api-manager.js b/packages/ipfs/src/core/api-manager.js index b0eec6e164..30a2ea3ae6 100644 --- a/packages/ipfs/src/core/api-manager.js +++ b/packages/ipfs/src/core/api-manager.js @@ -1,10 +1,22 @@ -/* eslint-disable valid-jsdoc */ 'use strict' module.exports = class ApiManager { + /** + * @callback UndefFn + * @param {PropertyKey} prop + */ + + /** + * @template API + * @typedef {{ cancel(): any; api: API; }} Updated + */ + constructor () { this._api = {} - /** @type {(prop: PropertyKey) => any} */ + /** + * @type {UndefFn} + * @returns {any} + */ this._onUndef = () => undefined this.api = new Proxy(this._api, { get: (_, prop) => { @@ -17,15 +29,15 @@ module.exports = class ApiManager { /** * @template A * @param {A} nextApi - * @param {this['_onUndef']} [onUndef] - * @returns {{ cancel(): any; api: A; }} + * @param {UndefFn} [onUndef] + * @returns {Updated} */ update (nextApi, onUndef) { const prevApi = { ...this._api } const prevUndef = this._onUndef Object.keys(this._api).forEach(k => { delete this._api[k] }) - Object.assign(this._api, nextApi) + const api = Object.assign(this._api, nextApi) if (onUndef) this._onUndef = onUndef - return { cancel: () => this.update(prevApi, prevUndef), api: this.api } + return { cancel: () => this.update(prevApi, prevUndef), api } } } diff --git a/packages/ipfs/src/core/components/add-all/index.js b/packages/ipfs/src/core/components/add-all/index.js index 73d8e2a768..03cd24a0e8 100644 --- a/packages/ipfs/src/core/components/add-all/index.js +++ b/packages/ipfs/src/core/components/add-all/index.js @@ -3,7 +3,7 @@ const importer = require('ipfs-unixfs-importer') const normaliseAddInput = require('ipfs-core-utils/src/files/normalise-input') const { parseChunkerString } = require('./utils') -const pipe = require('it-pipe') +const { pipe } = require('it-pipe') const { withTimeoutOption } = require('../../utils') /** diff --git a/packages/ipfs/src/core/components/add.js b/packages/ipfs/src/core/components/add.js index 26c06b6314..03399dc00c 100644 --- a/packages/ipfs/src/core/components/add.js +++ b/packages/ipfs/src/core/components/add.js @@ -1,13 +1,17 @@ -/* eslint-disable valid-jsdoc */ 'use strict' const last = require('it-last') +/** + * @typedef {import('./add-all').Source} Source + * @typedef {import('./add-all').UnixFSEntry} UnixFSEntry + */ + module.exports = ({ addAll }) => { /** * Import a file or data into IPFS. * - * @param {import('./add-all').Source} source - Data to import + * @param {Source} source - Data to import * * @param {object} [options] * @param {String} [options.chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) @@ -22,7 +26,7 @@ module.exports = ({ addAll }) => { * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) * - * @returns {Promise} + * @returns {Promise} */ async function add (source, options) { // eslint-disable-line require-await return last(addAll(source, options)) diff --git a/packages/ipfs/src/core/components/bitswap/stat.js b/packages/ipfs/src/core/components/bitswap/stat.js index ac716029e8..47ee475142 100644 --- a/packages/ipfs/src/core/components/bitswap/stat.js +++ b/packages/ipfs/src/core/components/bitswap/stat.js @@ -1,6 +1,6 @@ 'use strict' -const Big = require('bignumber.js') +const Big = require('bignumber.js').default const CID = require('cids') const { withTimeoutOption } = require('../../utils') diff --git a/packages/ipfs/src/core/components/block/rm.js b/packages/ipfs/src/core/components/block/rm.js index 406529f9be..1f7e1e6315 100644 --- a/packages/ipfs/src/core/components/block/rm.js +++ b/packages/ipfs/src/core/components/block/rm.js @@ -3,7 +3,7 @@ const CID = require('cids') const errCode = require('err-code') const { parallelMap, filter } = require('streaming-iterables') -const pipe = require('it-pipe') +const { pipe } = require('it-pipe') const { PinTypes } = require('../pin/pin-manager') const { cleanCid } = require('./utils') const { withTimeoutOption } = require('../../utils') diff --git a/packages/ipfs/src/core/index.js b/packages/ipfs/src/core/index.js index 7dd594a46e..692e876404 100644 --- a/packages/ipfs/src/core/index.js +++ b/packages/ipfs/src/core/index.js @@ -1,4 +1,3 @@ -/* eslint-disable valid-jsdoc */ 'use strict' const log = require('debug')('ipfs') @@ -61,6 +60,10 @@ const getDefaultOptions = () => ({ * @property {boolean} [sharding] - Enable directory sharding. Directories that have many child objects will be represented by multiple DAG nodes instead of just one. It can improve lookup performance when a directory has several thousand files or more. (Default: `false`) */ +/** + * @typedef { import('ipfs-repo') } IpfsRepo + */ + /** * Creates and returns a ready to use instance of an IPFS node. * @@ -68,7 +71,7 @@ const getDefaultOptions = () => ({ * @template {boolean} START * * @param {object} [options] - specify advanced configuration - * @param {string | import('ipfs-repo')} [options.repo] - The file path at which to store the IPFS node’s data. Alternatively, you can set up a customized storage system by providing an [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo) instance. (Default: `'~/.jsipfs'` in Node.js, `'ipfs'` in browsers) + * @param {string | IpfsRepo} [options.repo] - The file path at which to store the IPFS node’s data. Alternatively, you can set up a customized storage system by providing an [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo) instance. (Default: `'~/.jsipfs'` in Node.js, `'ipfs'` in browsers) * @param {boolean} [options.repoAutoMigrate] - `js-ipfs` comes bundled with a tool that automatically migrates your IPFS repository when a new version is available. (Default: `true`) * @param {INIT} [options.init] - Perform repo initialization steps when creating the IPFS node. (Default: `true`) * - Note that *initializing* a repo is different from creating an instance of [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo). The IPFS constructor sets many special properties when initializing a repo, so you should usually not try and call `repoInstance.init()` yourself. diff --git a/packages/ipfs/src/core/utils.js b/packages/ipfs/src/core/utils.js index 08e2514897..bd8726633a 100644 --- a/packages/ipfs/src/core/utils.js +++ b/packages/ipfs/src/core/utils.js @@ -1,4 +1,3 @@ -/* eslint-disable valid-jsdoc */ 'use strict' const isIpfs = require('is-ipfs') @@ -145,12 +144,20 @@ const mapFile = (file, options) => { /** * @template {any[]} ARGS - * @template R - The return type of `fn` - * @param {(...args: ARGS) => R} fn + * @template R + * @typedef {(...args: ARGS) => R} Fn + */ + +/** + * @template {any[]} ARGS + * @template {Promise | AsyncGenerator} R - The return type of `fn` + * @param {Fn} fn * @param {number} [optionsArgIndex] + * @returns {Fn} */ function withTimeoutOption (fn, optionsArgIndex) { - return /** @returns {R} */ (/** @type {ARGS} */...args) => { + // eslint-disable-next-line valid-jsdoc + return /** @returns {R} */(/** @type {ARGS} */...args) => { const options = args[optionsArgIndex == null ? args.length - 1 : optionsArgIndex] if (!options || !options.timeout) return fn(...args) @@ -188,6 +195,7 @@ function withTimeoutOption (fn, optionsArgIndex) { } if (fnRes[Symbol.asyncIterator]) { + // @ts-ignore return (async function * () { const it = fnRes[Symbol.asyncIterator]() @@ -217,6 +225,7 @@ function withTimeoutOption (fn, optionsArgIndex) { })() } + // @ts-ignore return (async () => { try { const res = await Promise.race([fnRes, timeoutPromise]) From e0f40d1c92a85fa100907aa5005b78aaef912008 Mon Sep 17 00:00:00 2001 From: Xmader Date: Mon, 24 Aug 2020 02:40:54 -0400 Subject: [PATCH 09/20] refactor: TypeScript support --- packages/ipfs/src/core/components/index.js | 3 +-- packages/ipfs/src/core/components/start.js | 12 ++++++++++-- packages/ipfs/src/core/components/stop.js | 8 +++++--- packages/ipfs/src/core/index.js | 11 ++++++++--- packages/ipfs/src/core/preload.js | 15 +++++++++------ 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/packages/ipfs/src/core/components/index.js b/packages/ipfs/src/core/components/index.js index c5257df661..c8cf1b4434 100644 --- a/packages/ipfs/src/core/components/index.js +++ b/packages/ipfs/src/core/components/index.js @@ -77,8 +77,7 @@ exports.pin = { } exports.ping = require('./ping') exports.pubsub = require('./pubsub') -exports.refs = require('./refs') -exports.refs.local = require('./refs/local') +exports.refs = Object.assign({}, require('./refs'), { local: require('./refs/local') }) exports.repo = { gc: require('./repo/gc'), stat: require('./repo/stat'), diff --git a/packages/ipfs/src/core/components/start.js b/packages/ipfs/src/core/components/start.js index f90bc7e728..800c145700 100644 --- a/packages/ipfs/src/core/components/start.js +++ b/packages/ipfs/src/core/components/start.js @@ -155,6 +155,12 @@ module.exports = ({ } }) +// eslint-disable-next-line valid-jsdoc +/** + * @template LIBP2P + * @template BlockAPI, DagAPI, FilesAPI, PinAPI + * @param {{ [x: string]: any; libp2p: LIBP2P; block: BlockAPI; dag: DagAPI; files: FilesAPI; pin: PinAPI; }} options + */ function createApi ({ apiManager, bitswap, @@ -224,8 +230,10 @@ function createApi ({ resolve: Components.name.resolve({ dns, ipns, peerId, isOnline, options: constructorOptions }) } const resolve = Components.resolve({ name, ipld }) - const refs = Components.refs({ ipld, resolve, preload }) - refs.local = Components.refs.local({ repo }) + const refs = Object.assign({}, + Components.refs({ ipld, resolve, preload }), + { local: Components.refs.local({ repo }) } + ) const pubsubNotEnabled = async () => { // eslint-disable-line require-await throw new NotEnabledError('pubsub not enabled') diff --git a/packages/ipfs/src/core/components/stop.js b/packages/ipfs/src/core/components/stop.js index 41dea112bb..dddd82439f 100644 --- a/packages/ipfs/src/core/components/stop.js +++ b/packages/ipfs/src/core/components/stop.js @@ -18,7 +18,7 @@ module.exports = ({ libp2p, mfsPreload, peerId, - pinManager, + pinManager = {}, preload, print, repo @@ -115,8 +115,10 @@ function createApi ({ const addAll = Components.addAll({ block, preload, pin, gcLock, options: constructorOptions }) const resolve = Components.resolve({ ipld }) - const refs = Components.refs({ ipld, resolve, preload }) - refs.local = Components.refs.local({ repo }) + const refs = Object.assign({}, + Components.refs({ ipld, resolve, preload }), + { local: Components.refs.local({ repo }) } + ) const notStarted = async () => { // eslint-disable-line require-await throw new NotStartedError() diff --git a/packages/ipfs/src/core/index.js b/packages/ipfs/src/core/index.js index 692e876404..ac3d83f2b1 100644 --- a/packages/ipfs/src/core/index.js +++ b/packages/ipfs/src/core/index.js @@ -35,9 +35,11 @@ const getDefaultOptions = () => ({ }) /** + * @typedef {'rsa' | 'ed25519' | 'secp256k1'} KeyType + * * @typedef {object} InitOptions * @property {boolean} [emptyRepo] - Whether to remove built-in assets, like the instructional tour and empty mutable file system, from the repo. (Default: `false`) - * @property {'rsa' | 'ed25519' | 'secp256k1'} [algorithm] - The type of key to use. (Default: `rsa`) + * @property {KeyType} [algorithm] - The type of key to use. (Default: `rsa`) * @property {number} [bits] - Number of bits to use in the generated key pair (rsa only). (Default: `2048`) * @property {string | import('peer-id')} [privateKey] - A pre-generated private key to use. Can be either a base64 string or a [PeerId](https://github.com/libp2p/js-peer-id) instance. **NOTE: This overrides `bits`.** * @property {string} [pass] - A passphrase to encrypt keys. You should generally use the [top-level `pass` option](#optionspass) instead of the `init.pass` option (this one will take its value from the top-level option if not set). @@ -106,8 +108,11 @@ async function create (options) { const initializedApi = options.init && await api.init() const startedApi = options.start && await initializedApi.start() - /** @typedef {true extends NonNullable ? typeof startedApi : typeof initializedApi} _API */ - /** @type {NonNullable extends false ? typeof api : _API} */ + /** + * @template T, THEN, ELSE + * @typedef {NonNullable extends false ? THEN : ELSE} IsFalse + */ + /** @type {IsFalse>} */ // @ts-ignore const ipfs = startedApi || initializedApi || api return ipfs diff --git a/packages/ipfs/src/core/preload.js b/packages/ipfs/src/core/preload.js index 053103c648..190b7d2099 100644 --- a/packages/ipfs/src/core/preload.js +++ b/packages/ipfs/src/core/preload.js @@ -4,11 +4,13 @@ const toUri = require('multiaddr-to-uri') const debug = require('debug') const CID = require('cids') const shuffle = require('array-shuffle') -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') const preload = require('./runtime/preload-nodejs') -const log = debug('ipfs:preload') -log.error = debug('ipfs:preload:error') +const log = Object.assign({}, + debug('ipfs:preload'), + { error: debug('ipfs:preload:error') } +) module.exports = options => { options = options || {} @@ -18,9 +20,10 @@ module.exports = options => { if (!options.enabled || !options.addresses.length) { log('preload disabled') const api = () => {} - api.start = () => {} - api.stop = () => {} - return api + return Object.assign(api, { + start: () => {}, + stop: () => {} + }) } let stopped = true From bef93e21dc5b85033037ec13168131b69685f8b6 Mon Sep 17 00:00:00 2001 From: Xmader Date: Mon, 24 Aug 2020 22:06:38 -0400 Subject: [PATCH 10/20] docs: fix typo --- docs/core-api/REPO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core-api/REPO.md b/docs/core-api/REPO.md index ad79bf8484..a545c9a14e 100644 --- a/docs/core-api/REPO.md +++ b/docs/core-api/REPO.md @@ -68,7 +68,7 @@ An optional object which may have the following keys: | Name | Type | Default | Description | | ---- | ---- | ------- | ----------- | -| options | `boolean` | `false` | Return storage numbers in `MiB` | +| human | `boolean` | `false` | Return storage numbers in `MiB` | | timeout | `Number` | `undefined` | A timeout in ms | | signal | [AbortSignal][] | `undefined` | Can be used to cancel any long running requests started as a result of this call | From df5f618f6281ce2e6bbd6646d66182336448ce1c Mon Sep 17 00:00:00 2001 From: Xmader Date: Mon, 24 Aug 2020 22:23:28 -0400 Subject: [PATCH 11/20] docs: fix `FileContent` type --- docs/core-api/FILES.md | 2 +- packages/ipfs/src/core/components/add-all/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core-api/FILES.md b/docs/core-api/FILES.md index 1f14ee0f2d..eca9d127f6 100644 --- a/docs/core-api/FILES.md +++ b/docs/core-api/FILES.md @@ -143,7 +143,7 @@ One of `path` or `content` _must_ be passed. `FileContent` is one of the following types: ```js -Uint8Array | Blob | String | Iterable | AsyncIterable | ReadableStream +Uint8Array | Blob | String | Iterable | Iterable | AsyncIterable | ReadableStream ``` `UnixTime` is one of the following types: diff --git a/packages/ipfs/src/core/components/add-all/index.js b/packages/ipfs/src/core/components/add-all/index.js index 03cd24a0e8..26c8e2f3a7 100644 --- a/packages/ipfs/src/core/components/add-all/index.js +++ b/packages/ipfs/src/core/components/add-all/index.js @@ -7,7 +7,7 @@ const { pipe } = require('it-pipe') const { withTimeoutOption } = require('../../utils') /** - * @typedef {Uint8Array | Blob | String | Iterable | AsyncIterable | ReadableStream} FileContent + * @typedef {Uint8Array | Blob | String | Iterable | Iterable | AsyncIterable | ReadableStream} FileContent * * @typedef {object} FileObject * - If no path is specified, then the item will be added to the root level and will be given a name according to it's CID. From b56d8f77b4604b7169e1275b1ea1e926ef602bf5 Mon Sep 17 00:00:00 2001 From: Xmader Date: Mon, 24 Aug 2020 23:29:05 -0400 Subject: [PATCH 12/20] fix: ... is not a function --- packages/ipfs/src/core/components/index.js | 2 +- packages/ipfs/src/core/components/start.js | 2 +- packages/ipfs/src/core/components/stop.js | 2 +- packages/ipfs/src/core/preload.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ipfs/src/core/components/index.js b/packages/ipfs/src/core/components/index.js index c8cf1b4434..beb245e975 100644 --- a/packages/ipfs/src/core/components/index.js +++ b/packages/ipfs/src/core/components/index.js @@ -77,7 +77,7 @@ exports.pin = { } exports.ping = require('./ping') exports.pubsub = require('./pubsub') -exports.refs = Object.assign({}, require('./refs'), { local: require('./refs/local') }) +exports.refs = Object.assign(require('./refs'), { local: require('./refs/local') }) exports.repo = { gc: require('./repo/gc'), stat: require('./repo/stat'), diff --git a/packages/ipfs/src/core/components/start.js b/packages/ipfs/src/core/components/start.js index 800c145700..bfdd5852a9 100644 --- a/packages/ipfs/src/core/components/start.js +++ b/packages/ipfs/src/core/components/start.js @@ -230,7 +230,7 @@ function createApi ({ resolve: Components.name.resolve({ dns, ipns, peerId, isOnline, options: constructorOptions }) } const resolve = Components.resolve({ name, ipld }) - const refs = Object.assign({}, + const refs = Object.assign( Components.refs({ ipld, resolve, preload }), { local: Components.refs.local({ repo }) } ) diff --git a/packages/ipfs/src/core/components/stop.js b/packages/ipfs/src/core/components/stop.js index dddd82439f..4660403fb5 100644 --- a/packages/ipfs/src/core/components/stop.js +++ b/packages/ipfs/src/core/components/stop.js @@ -115,7 +115,7 @@ function createApi ({ const addAll = Components.addAll({ block, preload, pin, gcLock, options: constructorOptions }) const resolve = Components.resolve({ ipld }) - const refs = Object.assign({}, + const refs = Object.assign( Components.refs({ ipld, resolve, preload }), { local: Components.refs.local({ repo }) } ) diff --git a/packages/ipfs/src/core/preload.js b/packages/ipfs/src/core/preload.js index 190b7d2099..e763aa4d87 100644 --- a/packages/ipfs/src/core/preload.js +++ b/packages/ipfs/src/core/preload.js @@ -7,7 +7,7 @@ const shuffle = require('array-shuffle') const { AbortController } = require('abort-controller') const preload = require('./runtime/preload-nodejs') -const log = Object.assign({}, +const log = Object.assign( debug('ipfs:preload'), { error: debug('ipfs:preload:error') } ) From 48e5251402e1419d82a90fd287864cb589dde7ed Mon Sep 17 00:00:00 2001 From: Xmader Date: Mon, 24 Aug 2020 23:54:18 -0400 Subject: [PATCH 13/20] fix: keep the original behavior Co-authored-by: Irakli Gozalishvili --- packages/ipfs/src/core/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ipfs/src/core/index.js b/packages/ipfs/src/core/index.js index ac3d83f2b1..e1c6d8bf7d 100644 --- a/packages/ipfs/src/core/index.js +++ b/packages/ipfs/src/core/index.js @@ -106,7 +106,7 @@ async function create (options) { }, async () => { throw new NotInitializedError() }) // eslint-disable-line require-await const initializedApi = options.init && await api.init() - const startedApi = options.start && await initializedApi.start() + const startedApi = options.start && initializedApi && await initializedApi.start() /** * @template T, THEN, ELSE From 040a82b6739c388cfb65f7a50fb7060e2ba81b27 Mon Sep 17 00:00:00 2001 From: Xmader Date: Tue, 25 Aug 2020 16:18:33 -0400 Subject: [PATCH 14/20] docs: fix types --- packages/ipfs/src/core/index.js | 3 ++- packages/ipfs/src/core/utils.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/ipfs/src/core/index.js b/packages/ipfs/src/core/index.js index e1c6d8bf7d..e8c22358b0 100644 --- a/packages/ipfs/src/core/index.js +++ b/packages/ipfs/src/core/index.js @@ -110,7 +110,8 @@ async function create (options) { /** * @template T, THEN, ELSE - * @typedef {NonNullable extends false ? THEN : ELSE} IsFalse + * @typedef {NonNullable extends false + * ? THEN : ELSE } IsFalse */ /** @type {IsFalse>} */ // @ts-ignore diff --git a/packages/ipfs/src/core/utils.js b/packages/ipfs/src/core/utils.js index bd8726633a..7f214fbdef 100644 --- a/packages/ipfs/src/core/utils.js +++ b/packages/ipfs/src/core/utils.js @@ -150,7 +150,7 @@ const mapFile = (file, options) => { /** * @template {any[]} ARGS - * @template {Promise | AsyncGenerator} R - The return type of `fn` + * @template {Promise | AsyncIterable} R - The return type of `fn` * @param {Fn} fn * @param {number} [optionsArgIndex] * @returns {Fn} From 2885568ebcab8c52ebfbf334456f54b365af7e2b Mon Sep 17 00:00:00 2001 From: Xmader Date: Tue, 25 Aug 2020 18:52:16 -0400 Subject: [PATCH 15/20] docs: add JSDoc --- .../ipfs/src/core/components/bitswap/stat.js | 28 +++++++++++++++++-- .../src/core/components/bitswap/unwant.js | 28 +++++++++++++++---- .../components/bitswap/wantlist-for-peer.js | 21 ++++++++++++-- .../src/core/components/bitswap/wantlist.js | 19 +++++++++++-- .../ipfs/src/core/components/block/get.js | 22 +++++++++++++-- .../ipfs/src/core/components/block/put.js | 28 +++++++++++++++++-- 6 files changed, 130 insertions(+), 16 deletions(-) diff --git a/packages/ipfs/src/core/components/bitswap/stat.js b/packages/ipfs/src/core/components/bitswap/stat.js index 47ee475142..7c3ac3ada4 100644 --- a/packages/ipfs/src/core/components/bitswap/stat.js +++ b/packages/ipfs/src/core/components/bitswap/stat.js @@ -4,8 +4,30 @@ const Big = require('bignumber.js').default const CID = require('cids') const { withTimeoutOption } = require('../../utils') +/** + * @typedef {object} BitswapStats - An object that contains information about the bitswap agent + * @property {number} provideBufLen - an integer + * @property {import('cids')[]} wantlist + * @property {string[]} peers - array of peer IDs as Strings + * @property {Big} blocksReceived + * @property {Big} dataReceived + * @property {Big} blocksSent + * @property {Big} dataSent + * @property {Big} dupBlksReceived + * @property {Big} dupDataReceived + */ + module.exports = ({ bitswap }) => { - return withTimeoutOption(async function stat () { // eslint-disable-line require-await + /** + * Show diagnostic information on the bitswap agent. + * + * @param {object} [options] + * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) + * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) + * + * @returns {Promise} + */ + async function stat (options) { // eslint-disable-line require-await, @typescript-eslint/no-unused-vars const snapshot = bitswap.stat().snapshot return { @@ -19,5 +41,7 @@ module.exports = ({ bitswap }) => { blocksSent: new Big(snapshot.blocksSent), dataSent: new Big(snapshot.dataSent) } - }) + } + + return withTimeoutOption(stat) } diff --git a/packages/ipfs/src/core/components/bitswap/unwant.js b/packages/ipfs/src/core/components/bitswap/unwant.js index 6845e85fd9..1e10e7f6f0 100644 --- a/packages/ipfs/src/core/components/bitswap/unwant.js +++ b/packages/ipfs/src/core/components/bitswap/unwant.js @@ -5,17 +5,33 @@ const errCode = require('err-code') const { withTimeoutOption } = require('../../utils') module.exports = ({ bitswap }) => { - return withTimeoutOption(async function unwant (keys, options) { // eslint-disable-line require-await - if (!Array.isArray(keys)) { - keys = [keys] + /** + * @typedef {import('cids')} CID + */ + + /** + * Removes one or more CIDs from the wantlist + * + * @param {CID | CID[]} cids - The CIDs to remove from the wantlist + * @param {object} [options] + * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) + * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) + * + * @returns {Promise} - A promise that resolves once the request is complete + */ + async function unwant (cids, options) { // eslint-disable-line require-await + if (!Array.isArray(cids)) { + cids = [cids] } try { - keys = keys.map((key) => new CID(key)) + cids = cids.map((cid) => new CID(cid)) } catch (err) { throw errCode(err, 'ERR_INVALID_CID') } - return bitswap.unwant(keys, options) - }) + return bitswap.unwant(cids, options) + } + + return withTimeoutOption(unwant) } diff --git a/packages/ipfs/src/core/components/bitswap/wantlist-for-peer.js b/packages/ipfs/src/core/components/bitswap/wantlist-for-peer.js index 4eb4092cd3..d64428e636 100644 --- a/packages/ipfs/src/core/components/bitswap/wantlist-for-peer.js +++ b/packages/ipfs/src/core/components/bitswap/wantlist-for-peer.js @@ -4,9 +4,26 @@ const PeerId = require('peer-id') const { withTimeoutOption } = require('../../utils') module.exports = ({ bitswap }) => { - return withTimeoutOption(async function wantlistForPeer (peerId, options = {}) { // eslint-disable-line require-await + /** + * @typedef {import('cids')} CID + * @typedef {import('peer-id')} PeerId + */ + + /** + * Returns the wantlist for a connected peer + * + * @param {PeerId | CID | string | Buffer} peerId - A peer ID to return the wantlist for + * @param {object} [options] + * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) + * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) + * + * @returns {Promise} - An array of CIDs currently in the wantlist + */ + async function wantlistForPeer (peerId, options = {}) { // eslint-disable-line require-await const list = bitswap.wantlistForPeer(PeerId.createFromCID(peerId), options) return Array.from(list).map(e => e[1].cid) - }) + } + + return withTimeoutOption(wantlistForPeer) } diff --git a/packages/ipfs/src/core/components/bitswap/wantlist.js b/packages/ipfs/src/core/components/bitswap/wantlist.js index 13930dd166..a4b67391c4 100644 --- a/packages/ipfs/src/core/components/bitswap/wantlist.js +++ b/packages/ipfs/src/core/components/bitswap/wantlist.js @@ -3,9 +3,24 @@ const { withTimeoutOption } = require('../../utils') module.exports = ({ bitswap }) => { - return withTimeoutOption(async function wantlist (options = {}) { // eslint-disable-line require-await + /** + * @typedef {import('cids')} CID + */ + + /** + * Returns the wantlist for your node + * + * @param {object} [options] + * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) + * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) + * + * @returns {Promise} - An array of CIDs currently in the wantlist + */ + async function wantlist (options = {}) { // eslint-disable-line require-await const list = bitswap.getWantlist(options) return Array.from(list).map(e => e[1].cid) - }) + } + + return withTimeoutOption(wantlist) } diff --git a/packages/ipfs/src/core/components/block/get.js b/packages/ipfs/src/core/components/block/get.js index 48e17c9af6..1a26a9bac0 100644 --- a/packages/ipfs/src/core/components/block/get.js +++ b/packages/ipfs/src/core/components/block/get.js @@ -4,7 +4,23 @@ const { cleanCid } = require('./utils') const { withTimeoutOption } = require('../../utils') module.exports = ({ blockService, preload }) => { - return withTimeoutOption(async function get (cid, options) { // eslint-disable-line require-await + /** + * @typedef {import('cids')} CID + * @typedef {import('ipld-block')} Block + */ + + /** + * Get a raw IPFS block. + * + * @param {CID | string | Buffer} cid - A CID that corresponds to the desired block + * @param {object} [options] + * @param {boolean} [options.preload] - (default: `true`) + * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) + * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) + * + * @returns {Promise} - A Block type object, containing both the data and the hash of the block + */ + async function get (cid, options) { // eslint-disable-line require-await options = options || {} cid = cleanCid(cid) @@ -13,5 +29,7 @@ module.exports = ({ blockService, preload }) => { } return blockService.get(cid, options) - }) + } + + return withTimeoutOption(get) } diff --git a/packages/ipfs/src/core/components/block/put.js b/packages/ipfs/src/core/components/block/put.js index 6d41c7bdd4..282d32a812 100644 --- a/packages/ipfs/src/core/components/block/put.js +++ b/packages/ipfs/src/core/components/block/put.js @@ -7,7 +7,29 @@ const isIPFS = require('is-ipfs') const { withTimeoutOption } = require('../../utils') module.exports = ({ blockService, pin, gcLock, preload }) => { - return withTimeoutOption(async function put (block, options) { + /** + * @typedef {import('cids')} CID + * @typedef {import('ipld-block')} Block + */ + + /** + * Stores input as an IPFS block. + * + * @param {Buffer | Block} block - The block or data to store + * @param {object} [options] - **Note:** If you pass a `Block` instance as the block parameter, you don't need to pass options, as the block instance will carry the CID value as a property. + * @param {CID} [options.cid] - A CID to store the block under (default: `undefined`) + * @param {string} [options.format] - The codec to use to create the CID (default: `'dag-pb'`) + * @param {string} [options.mhtype] - The hashing algorithm to use to create the CID (default: `'sha2-256'`) + * @param {number} [options.mhlen] + * @param {number} [options.version] - The version to use to create the CID (default: `0`) + * @param {boolean} [options.pin] - If true, pin added blocks recursively (default: `false`) + * @param {boolean} [options.preload] - (default: `true`) + * @param {number} [options.timeout] - A timeout in ms (default: `undefined`) + * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) + * + * @returns {Promise} - A Block type object, containing both the data and the hash of the block + */ + async function put (block, options) { options = options || {} if (Array.isArray(block)) { @@ -58,5 +80,7 @@ module.exports = ({ blockService, pin, gcLock, preload }) => { } finally { release() } - }) + } + + return withTimeoutOption(put) } From 14f7dbb21a0be05255ceca24e2d132953818f111 Mon Sep 17 00:00:00 2001 From: Xmader Date: Mon, 31 Aug 2020 23:11:47 -0400 Subject: [PATCH 16/20] docs: TypeScript support --- packages/ipfs-http-client/package.json | 3 ++- packages/ipfs-http-client/src/lib/configure.js | 15 +++++++++++++-- .../src/lib/to-url-search-params.js | 4 ++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/ipfs-http-client/package.json b/packages/ipfs-http-client/package.json index fdbf0bf64d..3526a6912e 100644 --- a/packages/ipfs-http-client/package.json +++ b/packages/ipfs-http-client/package.json @@ -184,6 +184,7 @@ "shunkin ", "victorbjelkholm ", "Łukasz Magiera ", - "Łukasz Magiera " + "Łukasz Magiera ", + "Xmader " ] } diff --git a/packages/ipfs-http-client/src/lib/configure.js b/packages/ipfs-http-client/src/lib/configure.js index 49b2d2f5a3..6396c05d1d 100644 --- a/packages/ipfs-http-client/src/lib/configure.js +++ b/packages/ipfs-http-client/src/lib/configure.js @@ -9,8 +9,19 @@ const Client = require('./core') */ /** - * @param {function(Client, ClientOptions): void} fn - * @returns {function(ClientOptions): void} + * @template T + * @typedef {(client: Client, clientOptions: ClientOptions) => T} Fn + */ + +/** + * @template T + * @typedef {(clientOptions: ClientOptions) => T} Factory + */ + +/** + * @template T + * @param {Fn} fn + * @returns {Factory} */ const configure = (fn) => { return (options) => { diff --git a/packages/ipfs-http-client/src/lib/to-url-search-params.js b/packages/ipfs-http-client/src/lib/to-url-search-params.js index 1e0bbeb4b9..10f12d83d0 100644 --- a/packages/ipfs-http-client/src/lib/to-url-search-params.js +++ b/packages/ipfs-http-client/src/lib/to-url-search-params.js @@ -3,6 +3,10 @@ const modeToString = require('./mode-to-string') const mtimeToObject = require('./mtime-to-object') +/** + * @param {object} params + * @returns {URLSearchParams} + */ module.exports = ({ arg, searchParams, hashAlg, mtime, mode, ...options } = {}) => { if (searchParams) { options = { From 09d0bbbe039ed93593cba263902a3f2185d898b4 Mon Sep 17 00:00:00 2001 From: Xmader Date: Mon, 31 Aug 2020 23:51:41 -0400 Subject: [PATCH 17/20] refactor: reusable type definitions for multiple packages --- packages/ipfs-http-client/src/add-all.js | 15 ++++++- packages/ipfs-http-client/src/index.js | 9 ++++ .../ipfs/src/core/components/add-all/index.js | 45 ++++++++++--------- packages/ipfs/src/core/utils.js | 6 +++ packages/ipfs/src/index.js | 5 +++ 5 files changed, 59 insertions(+), 21 deletions(-) diff --git a/packages/ipfs-http-client/src/add-all.js b/packages/ipfs-http-client/src/add-all.js index 7e819ebd24..e706d2af18 100644 --- a/packages/ipfs-http-client/src/add-all.js +++ b/packages/ipfs-http-client/src/add-all.js @@ -9,7 +9,11 @@ const anySignal = require('any-signal') const AbortController = require('abort-controller') module.exports = configure((api) => { - return async function * addAll (input, options = {}) { + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../ipfs/src/core/components/add-all').AddAll} + */ + async function * addAll (input, options = {}) { const progressFn = options.progress // allow aborting requests on body errors @@ -39,8 +43,16 @@ module.exports = configure((api) => { } } } + return addAll }) +/** + * @typedef {import('../../ipfs/src/core/components/add-all').UnixFSEntry} UnixFSEntry + */ + +/** + * @returns {UnixFSEntry} + */ function toCoreInterface ({ name, hash, size, mode, mtime, mtimeNsecs }) { const output = { path: name, @@ -59,5 +71,6 @@ function toCoreInterface ({ name, hash, size, mode, mtime, mtimeNsecs }) { } } + // @ts-ignore return output } diff --git a/packages/ipfs-http-client/src/index.js b/packages/ipfs-http-client/src/index.js index aeb82ee703..d992e2557a 100644 --- a/packages/ipfs-http-client/src/index.js +++ b/packages/ipfs-http-client/src/index.js @@ -13,6 +13,15 @@ const urlSource = require('ipfs-utils/src/files/url-source') * @typedef { import("./lib/core").ClientOptions } ClientOptions */ +/** + * @typedef {object} HttpOptions + * @property {Headers | Record} [headers] - An object or [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) instance that can be used to set custom HTTP headers. Note that this option can also be [configured globally](#custom-headers) via the constructor options. + * @property {URLSearchParams | Record} [searchParams] - An object or [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) instance that can be used to add additional query parameters to the query string sent with each request. + * @property {object} [ipld] + * @property {any[]} [ipld.formats] - An array of additional [IPLD formats](https://github.com/ipld/interface-ipld-format) to support + * @property {(format: string) => Promise} [ipld.loadFormat] - an async function that takes the name of an [IPLD format](https://github.com/ipld/interface-ipld-format) as a string and should return the implementation of that codec + */ + /** * * @param {ClientOptions } options diff --git a/packages/ipfs/src/core/components/add-all/index.js b/packages/ipfs/src/core/components/add-all/index.js index 26c8e2f3a7..83aa120bac 100644 --- a/packages/ipfs/src/core/components/add-all/index.js +++ b/packages/ipfs/src/core/components/add-all/index.js @@ -35,30 +35,35 @@ const { withTimeoutOption } = require('../../utils') * @property {number} size */ +/** + * @typedef {object} AddAllOptions + * @property {string} [chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) + * @property {Number} [cidVersion] - the CID version to use when storing the data (default: `0`) + * @property {boolean} [enableShardingExperiment] - allows to create directories with an unlimited number of entries currently size of unixfs directories is limited by the maximum block size. Note that this is an experimental feature (default: `false`) + * @property {String} [hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) + * @property {boolean} [onlyHash] - If true, will not add blocks to the blockstore (default: `false`) + * @property {boolean} [pin] - pin this object when adding (default: `true`) + * @property {function} [progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) + * @property {boolean} [rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) + * @property {Number} [shardSplitThreshold] - Directories with more than this number of files will be created as HAMT-sharded directories (default: `1000`) + * @property {boolean} [trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) + * @property {boolean} [wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) + */ + +/** + * @template {Record} ExtraOptions + * @callback AddAll - Import multiple files and data into IPFS. + * @param {FileStream} source + * @param {AddAllOptions & import('../../utils').AbortOptions & ExtraOptions} [options] + * @returns {AsyncIterable} + */ + module.exports = ({ block, gcLock, preload, pin, options: constructorOptions }) => { const isShardingEnabled = constructorOptions.EXPERIMENTAL && constructorOptions.EXPERIMENTAL.sharding + // eslint-disable-next-line valid-jsdoc /** - * Import multiple files and data into IPFS. - * - * @param {FileStream} source - * - * @param {object} [options] - * @param {string} [options.chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) - * @param {Number} [options.cidVersion] - the CID version to use when storing the data (default: `0`) - * @param {boolean} [options.enableShardingExperiment] - allows to create directories with an unlimited number of entries currently size of unixfs directories is limited by the maximum block size. Note that this is an experimental feature (default: `false`) - * @param {String} [options.hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) - * @param {boolean} [options.onlyHash] - If true, will not add blocks to the blockstore (default: `false`) - * @param {boolean} [options.pin] - pin this object when adding (default: `true`) - * @param {function} [options.progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) - * @param {boolean} [options.rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) - * @param {Number} [options.shardSplitThreshold] - Directories with more than this number of files will be created as HAMT-sharded directories (default: `1000`) - * @param {boolean} [options.trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) - * @param {boolean} [options.wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) - * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) - * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - - * @returns {AsyncIterable} + * @type {AddAll<{}>} */ async function * addAll (source, options) { options = options || {} diff --git a/packages/ipfs/src/core/utils.js b/packages/ipfs/src/core/utils.js index 7f214fbdef..567bab3c1d 100644 --- a/packages/ipfs/src/core/utils.js +++ b/packages/ipfs/src/core/utils.js @@ -148,6 +148,12 @@ const mapFile = (file, options) => { * @typedef {(...args: ARGS) => R} Fn */ +/** + * @typedef {object} AbortOptions + * @property {number} [timeout] - A timeout in ms + * @property {AbortSignal} [signal] - Can be used to cancel any long running requests started as a result of this call + */ + /** * @template {any[]} ARGS * @template {Promise | AsyncIterable} R - The return type of `fn` diff --git a/packages/ipfs/src/index.js b/packages/ipfs/src/index.js index 8140941bf4..cb336d3935 100644 --- a/packages/ipfs/src/index.js +++ b/packages/ipfs/src/index.js @@ -2,4 +2,9 @@ const IPFS = require('./core') +/** + * @typedef { ReturnType extends Promise + * ? U : never } IPFS + */ + module.exports = IPFS From f62cef7cbb772ab30e04aed1dc5641c9ee0375eb Mon Sep 17 00:00:00 2001 From: Xmader Date: Tue, 1 Sep 2020 00:49:57 -0400 Subject: [PATCH 18/20] refactor: reusable type definitions for multiple packages --- packages/ipfs-http-client/src/add.js | 8 ++- packages/ipfs-http-client/src/bitswap/stat.js | 7 ++- .../ipfs-http-client/src/bitswap/unwant.js | 7 ++- .../src/bitswap/wantlist-for-peer.js | 7 ++- .../ipfs-http-client/src/bitswap/wantlist.js | 7 ++- packages/ipfs-http-client/src/block/get.js | 7 ++- packages/ipfs-http-client/src/block/put.js | 4 ++ .../ipfs/src/core/components/add-all/index.js | 17 ++----- packages/ipfs/src/core/components/add.js | 42 +++++++++------- .../ipfs/src/core/components/bitswap/stat.js | 17 ++++--- .../src/core/components/bitswap/unwant.js | 27 +++++----- .../components/bitswap/wantlist-for-peer.js | 29 ++++++----- .../src/core/components/bitswap/wantlist.js | 25 +++++----- .../ipfs/src/core/components/block/get.js | 35 +++++++------ .../ipfs/src/core/components/block/put.js | 49 +++++++++++-------- 15 files changed, 175 insertions(+), 113 deletions(-) diff --git a/packages/ipfs-http-client/src/add.js b/packages/ipfs-http-client/src/add.js index 3190b9a7d9..8f04293012 100644 --- a/packages/ipfs-http-client/src/add.js +++ b/packages/ipfs-http-client/src/add.js @@ -8,8 +8,14 @@ module.exports = (options) => { const all = addAll(options) return configure(() => { - return async function add (input, options = {}) { // eslint-disable-line require-await + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../ipfs/src/core/components/add').Add} + */ + async function add (input, options = {}) { // eslint-disable-line require-await + // @ts-ignore return last(all(input, options)) } + return add })(options) } diff --git a/packages/ipfs-http-client/src/bitswap/stat.js b/packages/ipfs-http-client/src/bitswap/stat.js index ec27458969..8f1b64afad 100644 --- a/packages/ipfs-http-client/src/bitswap/stat.js +++ b/packages/ipfs-http-client/src/bitswap/stat.js @@ -6,7 +6,11 @@ const configure = require('../lib/configure') const toUrlSearchParams = require('../lib/to-url-search-params') module.exports = configure(api => { - return async (options = {}) => { + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../../ipfs/src/core/components/bitswap/stat').Stat} + */ + async function stat (options = {}) { const res = await api.post('bitswap/stat', { searchParams: toUrlSearchParams(options), timeout: options.timeout, @@ -16,6 +20,7 @@ module.exports = configure(api => { return toCoreInterface(await res.json()) } + return stat }) function toCoreInterface (res) { diff --git a/packages/ipfs-http-client/src/bitswap/unwant.js b/packages/ipfs-http-client/src/bitswap/unwant.js index b9706cebc4..602776e7c4 100644 --- a/packages/ipfs-http-client/src/bitswap/unwant.js +++ b/packages/ipfs-http-client/src/bitswap/unwant.js @@ -5,7 +5,11 @@ const configure = require('../lib/configure') const toUrlSearchParams = require('../lib/to-url-search-params') module.exports = configure(api => { - return async (cid, options = {}) => { + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../../ipfs/src/core/components/bitswap/unwant').Unwant} + */ + async function unwant (cid, options = {}) { const res = await api.post('bitswap/unwant', { timeout: options.timeout, signal: options.signal, @@ -18,4 +22,5 @@ module.exports = configure(api => { return res.json() } + return unwant }) diff --git a/packages/ipfs-http-client/src/bitswap/wantlist-for-peer.js b/packages/ipfs-http-client/src/bitswap/wantlist-for-peer.js index b777ee7d6c..7d0599a380 100644 --- a/packages/ipfs-http-client/src/bitswap/wantlist-for-peer.js +++ b/packages/ipfs-http-client/src/bitswap/wantlist-for-peer.js @@ -5,7 +5,11 @@ const configure = require('../lib/configure') const toUrlSearchParams = require('../lib/to-url-search-params') module.exports = configure(api => { - return async (peerId, options = {}) => { + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../../ipfs/src/core/components/bitswap/wantlist-for-peer').WantlistForPeer} + */ + async function wantlistForPeer (peerId, options = {}) { peerId = typeof peerId === 'string' ? peerId : new CID(peerId).toString() const res = await (await api.post('bitswap/wantlist', { @@ -20,4 +24,5 @@ module.exports = configure(api => { return (res.Keys || []).map(k => new CID(k['/'])) } + return wantlistForPeer }) diff --git a/packages/ipfs-http-client/src/bitswap/wantlist.js b/packages/ipfs-http-client/src/bitswap/wantlist.js index 2599c7ed79..96f33cad91 100644 --- a/packages/ipfs-http-client/src/bitswap/wantlist.js +++ b/packages/ipfs-http-client/src/bitswap/wantlist.js @@ -5,7 +5,11 @@ const configure = require('../lib/configure') const toUrlSearchParams = require('../lib/to-url-search-params') module.exports = configure(api => { - return async (options = {}) => { + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../../ipfs/src/core/components/bitswap/wantlist').WantlistFn} + */ + async function wantlist (options = {}) { const res = await (await api.post('bitswap/wantlist', { timeout: options.timeout, signal: options.signal, @@ -15,4 +19,5 @@ module.exports = configure(api => { return (res.Keys || []).map(k => new CID(k['/'])) } + return wantlist }) diff --git a/packages/ipfs-http-client/src/block/get.js b/packages/ipfs-http-client/src/block/get.js index 5564aef09a..7cb45ba149 100644 --- a/packages/ipfs-http-client/src/block/get.js +++ b/packages/ipfs-http-client/src/block/get.js @@ -7,7 +7,11 @@ const configure = require('../lib/configure') const toUrlSearchParams = require('../lib/to-url-search-params') module.exports = configure(api => { - return async (cid, options = {}) => { + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../../ipfs/src/core/components/block/get').BlockGet} + */ + async function get (cid, options = {}) { cid = new CID(cid) const res = await api.post('block/get', { @@ -22,4 +26,5 @@ module.exports = configure(api => { return new Block(Buffer.from(await res.arrayBuffer()), cid) } + return get }) diff --git a/packages/ipfs-http-client/src/block/put.js b/packages/ipfs-http-client/src/block/put.js index 09888a815e..2ab691f886 100644 --- a/packages/ipfs-http-client/src/block/put.js +++ b/packages/ipfs-http-client/src/block/put.js @@ -10,6 +10,10 @@ const anySignal = require('any-signal') const AbortController = require('abort-controller') module.exports = configure(api => { + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../../ipfs/src/core/components/block/put').BlockPut} + */ async function put (data, options = {}) { if (Block.isBlock(data)) { const { name, length } = multihash.decode(data.cid.multihash) diff --git a/packages/ipfs/src/core/components/add-all/index.js b/packages/ipfs/src/core/components/add-all/index.js index 83aa120bac..02da2817c4 100644 --- a/packages/ipfs/src/core/components/add-all/index.js +++ b/packages/ipfs/src/core/components/add-all/index.js @@ -36,23 +36,16 @@ const { withTimeoutOption } = require('../../utils') */ /** - * @typedef {object} AddAllOptions - * @property {string} [chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) - * @property {Number} [cidVersion] - the CID version to use when storing the data (default: `0`) + * @typedef {import('../add').AddOptions & _AddAllOptions} AddAllOptions + * @typedef {object} _AddAllOptions * @property {boolean} [enableShardingExperiment] - allows to create directories with an unlimited number of entries currently size of unixfs directories is limited by the maximum block size. Note that this is an experimental feature (default: `false`) - * @property {String} [hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) - * @property {boolean} [onlyHash] - If true, will not add blocks to the blockstore (default: `false`) - * @property {boolean} [pin] - pin this object when adding (default: `true`) - * @property {function} [progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) - * @property {boolean} [rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) - * @property {Number} [shardSplitThreshold] - Directories with more than this number of files will be created as HAMT-sharded directories (default: `1000`) - * @property {boolean} [trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) - * @property {boolean} [wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) + * @property {number} [shardSplitThreshold] - Directories with more than this number of files will be created as HAMT-sharded directories (default: `1000`) */ /** + * Import multiple files and data into IPFS. * @template {Record} ExtraOptions - * @callback AddAll - Import multiple files and data into IPFS. + * @callback AddAll * @param {FileStream} source * @param {AddAllOptions & import('../../utils').AbortOptions & ExtraOptions} [options] * @returns {AsyncIterable} diff --git a/packages/ipfs/src/core/components/add.js b/packages/ipfs/src/core/components/add.js index 03399dc00c..21fc461cb0 100644 --- a/packages/ipfs/src/core/components/add.js +++ b/packages/ipfs/src/core/components/add.js @@ -7,26 +7,32 @@ const last = require('it-last') * @typedef {import('./add-all').UnixFSEntry} UnixFSEntry */ +/** + * @typedef {object} AddOptions + * @property {string} [chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) + * @property {number} [cidVersion] - the CID version to use when storing the data (default: `0`) + * @property {string} [hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) + * @property {boolean} [onlyHash] - If true, will not add blocks to the blockstore (default: `false`) + * @property {boolean} [pin] - pin this object when adding (default: `true`) + * @property {function} [progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) + * @property {boolean} [rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) + * @property {boolean} [trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) + * @property {boolean} [wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) + */ + +/** + * Import a file or data into IPFS. + * @template {Record} ExtraOptions + * @callback Add + * @param {Source} source - Data to import + * @param {AddOptions & import('../utils').AbortOptions & ExtraOptions} [options] + * @returns {Promise} + */ + module.exports = ({ addAll }) => { + // eslint-disable-next-line valid-jsdoc /** - * Import a file or data into IPFS. - * - * @param {Source} source - Data to import - * - * @param {object} [options] - * @param {String} [options.chunker] - chunking algorithm used to build ipfs DAGs (default: `'size-262144'`) - * @param {Number} [options.cidVersion] - the CID version to use when storing the data (default: `0`) - * @param {String} [options.hashAlg] - multihash hashing algorithm to use (default: `'sha2-256'`) - * @param {boolean} [options.onlyHash] - If true, will not add blocks to the blockstore (default: `false`) - * @param {boolean} [options.pin] - pin this object when adding (default: `true`) - * @param {function} [options.progress] - a function that will be called with the byte length of chunks as a file is added to ipfs (default: `undefined`) - * @param {boolean} [options.rawLeaves] - if true, DAG leaves will contain raw file data and not be wrapped in a protobuf (default: `false`) - * @param {boolean} [options.trickle] - if true will use the [trickle DAG](https://godoc.org/github.com/ipsn/go-ipfs/gxlibs/github.com/ipfs/go-unixfs/importer/trickle) format for DAG generation (default: `false`) - * @param {boolean} [options.wrapWithDirectory] - Adds a wrapping node around the content (default: `false`) - * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) - * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - * - * @returns {Promise} + * @type {Add<{}>} */ async function add (source, options) { // eslint-disable-line require-await return last(addAll(source, options)) diff --git a/packages/ipfs/src/core/components/bitswap/stat.js b/packages/ipfs/src/core/components/bitswap/stat.js index 7c3ac3ada4..2b009d17fa 100644 --- a/packages/ipfs/src/core/components/bitswap/stat.js +++ b/packages/ipfs/src/core/components/bitswap/stat.js @@ -17,15 +17,18 @@ const { withTimeoutOption } = require('../../utils') * @property {Big} dupDataReceived */ +/** + * Show diagnostic information on the bitswap agent. + * @template {Record} ExtraOptions + * @callback Stat + * @param {import('../../utils').AbortOptions & ExtraOptions} [options] + * @returns {Promise} + */ + module.exports = ({ bitswap }) => { + // eslint-disable-next-line valid-jsdoc /** - * Show diagnostic information on the bitswap agent. - * - * @param {object} [options] - * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) - * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - * - * @returns {Promise} + * @type {Stat<{}>} */ async function stat (options) { // eslint-disable-line require-await, @typescript-eslint/no-unused-vars const snapshot = bitswap.stat().snapshot diff --git a/packages/ipfs/src/core/components/bitswap/unwant.js b/packages/ipfs/src/core/components/bitswap/unwant.js index 1e10e7f6f0..8eadc17461 100644 --- a/packages/ipfs/src/core/components/bitswap/unwant.js +++ b/packages/ipfs/src/core/components/bitswap/unwant.js @@ -4,20 +4,23 @@ const CID = require('cids') const errCode = require('err-code') const { withTimeoutOption } = require('../../utils') -module.exports = ({ bitswap }) => { - /** - * @typedef {import('cids')} CID - */ +/** + * @typedef {import('cids')} CID + */ +/** + * Removes one or more CIDs from the wantlist + * @template {Record} ExtraOptions + * @callback Unwant + * @param {CID | CID[]} cids - The CIDs to remove from the wantlist + * @param {import('../../utils').AbortOptions & ExtraOptions} [options] + * @returns {Promise} - A promise that resolves once the request is complete + */ + +module.exports = ({ bitswap }) => { + // eslint-disable-next-line valid-jsdoc /** - * Removes one or more CIDs from the wantlist - * - * @param {CID | CID[]} cids - The CIDs to remove from the wantlist - * @param {object} [options] - * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) - * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - * - * @returns {Promise} - A promise that resolves once the request is complete + * @type {Unwant<{}>} */ async function unwant (cids, options) { // eslint-disable-line require-await if (!Array.isArray(cids)) { diff --git a/packages/ipfs/src/core/components/bitswap/wantlist-for-peer.js b/packages/ipfs/src/core/components/bitswap/wantlist-for-peer.js index d64428e636..745c60bd15 100644 --- a/packages/ipfs/src/core/components/bitswap/wantlist-for-peer.js +++ b/packages/ipfs/src/core/components/bitswap/wantlist-for-peer.js @@ -3,21 +3,24 @@ const PeerId = require('peer-id') const { withTimeoutOption } = require('../../utils') -module.exports = ({ bitswap }) => { - /** - * @typedef {import('cids')} CID - * @typedef {import('peer-id')} PeerId - */ +/** + * @typedef {import('cids')} CID + * @typedef {import('peer-id')} PeerId + */ +/** + * Returns the wantlist for a connected peer + * @template {Record} ExtraOptions + * @callback WantlistForPeer + * @param {PeerId | CID | string | Buffer} peerId - A peer ID to return the wantlist for\ + * @param {import('../../utils').AbortOptions & ExtraOptions} [options] + * @returns {Promise} - An array of CIDs currently in the wantlist + */ + +module.exports = ({ bitswap }) => { + // eslint-disable-next-line valid-jsdoc /** - * Returns the wantlist for a connected peer - * - * @param {PeerId | CID | string | Buffer} peerId - A peer ID to return the wantlist for - * @param {object} [options] - * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) - * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - * - * @returns {Promise} - An array of CIDs currently in the wantlist + * @type {WantlistForPeer<{}>} */ async function wantlistForPeer (peerId, options = {}) { // eslint-disable-line require-await const list = bitswap.wantlistForPeer(PeerId.createFromCID(peerId), options) diff --git a/packages/ipfs/src/core/components/bitswap/wantlist.js b/packages/ipfs/src/core/components/bitswap/wantlist.js index a4b67391c4..4347df7760 100644 --- a/packages/ipfs/src/core/components/bitswap/wantlist.js +++ b/packages/ipfs/src/core/components/bitswap/wantlist.js @@ -2,19 +2,22 @@ const { withTimeoutOption } = require('../../utils') -module.exports = ({ bitswap }) => { - /** - * @typedef {import('cids')} CID - */ +/** + * @typedef {import('cids')} CID + */ +/** + * Returns the wantlist for your node + * @template {Record} ExtraOptions + * @callback WantlistFn + * @param {import('../../utils').AbortOptions & ExtraOptions} [options] + * @returns {Promise} - An array of CIDs currently in the wantlist + */ + +module.exports = ({ bitswap }) => { + // eslint-disable-next-line valid-jsdoc /** - * Returns the wantlist for your node - * - * @param {object} [options] - * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) - * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - * - * @returns {Promise} - An array of CIDs currently in the wantlist + * @type {WantlistFn<{}>} */ async function wantlist (options = {}) { // eslint-disable-line require-await const list = bitswap.getWantlist(options) diff --git a/packages/ipfs/src/core/components/block/get.js b/packages/ipfs/src/core/components/block/get.js index 1a26a9bac0..5a2c12e879 100644 --- a/packages/ipfs/src/core/components/block/get.js +++ b/packages/ipfs/src/core/components/block/get.js @@ -3,22 +3,29 @@ const { cleanCid } = require('./utils') const { withTimeoutOption } = require('../../utils') -module.exports = ({ blockService, preload }) => { - /** - * @typedef {import('cids')} CID - * @typedef {import('ipld-block')} Block - */ +/** + * @typedef {import('cids')} CID + * @typedef {import('ipld-block')} Block + */ +/** + * @typedef {object} PreloadOptions + * @property {boolean} [preload] - (default: `true`) + */ + +/** + * Get a raw IPFS block. + * @template {Record} ExtraOptions + * @callback BlockGet + * @param {CID | string | Buffer} cid - A CID that corresponds to the desired block + * @param {import('../../utils').AbortOptions & ExtraOptions} [options] + * @returns {Promise} - A Block type object, containing both the data and the hash of the block + */ + +module.exports = ({ blockService, preload }) => { + // eslint-disable-next-line valid-jsdoc /** - * Get a raw IPFS block. - * - * @param {CID | string | Buffer} cid - A CID that corresponds to the desired block - * @param {object} [options] - * @param {boolean} [options.preload] - (default: `true`) - * @param {Number} [options.timeout] - A timeout in ms (default: `undefined`) - * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - * - * @returns {Promise} - A Block type object, containing both the data and the hash of the block + * @type {BlockGet} */ async function get (cid, options) { // eslint-disable-line require-await options = options || {} diff --git a/packages/ipfs/src/core/components/block/put.js b/packages/ipfs/src/core/components/block/put.js index 282d32a812..700b256730 100644 --- a/packages/ipfs/src/core/components/block/put.js +++ b/packages/ipfs/src/core/components/block/put.js @@ -6,28 +6,35 @@ const CID = require('cids') const isIPFS = require('is-ipfs') const { withTimeoutOption } = require('../../utils') -module.exports = ({ blockService, pin, gcLock, preload }) => { - /** - * @typedef {import('cids')} CID - * @typedef {import('ipld-block')} Block - */ +/** + * @typedef {import('cids')} CID + * @typedef {import('ipld-block')} Block + * @typedef {0 | 1} CidVersion + */ + +/** + * @typedef {object} BlockPutOptions + * @property {CID} [cid] - A CID to store the block under (default: `undefined`) + * @property {string} [format] - The codec to use to create the CID (default: `'dag-pb'`) + * @property {string} [mhtype] - The hashing algorithm to use to create the CID (default: `'sha2-256'`) + * @property {number} [mhlen] + * @property {CidVersion} [version] - The version to use to create the CID (default: `0`) + * @property {boolean} [pin] - If true, pin added blocks recursively (default: `false`) + */ +/** + * Stores input as an IPFS block. + * @template {Record} ExtraOptions + * @callback BlockPut + * @param {Buffer | Block} block - The block or data to store + * @param {BlockPutOptions & import('../../utils').AbortOptions & ExtraOptions} [options] - **Note:** If you pass a `Block` instance as the block parameter, you don't need to pass options, as the block instance will carry the CID value as a property. + * @returns {Promise} - A Block type object, containing both the data and the hash of the block + */ + +module.exports = ({ blockService, pin, gcLock, preload }) => { + // eslint-disable-next-line valid-jsdoc /** - * Stores input as an IPFS block. - * - * @param {Buffer | Block} block - The block or data to store - * @param {object} [options] - **Note:** If you pass a `Block` instance as the block parameter, you don't need to pass options, as the block instance will carry the CID value as a property. - * @param {CID} [options.cid] - A CID to store the block under (default: `undefined`) - * @param {string} [options.format] - The codec to use to create the CID (default: `'dag-pb'`) - * @param {string} [options.mhtype] - The hashing algorithm to use to create the CID (default: `'sha2-256'`) - * @param {number} [options.mhlen] - * @param {number} [options.version] - The version to use to create the CID (default: `0`) - * @param {boolean} [options.pin] - If true, pin added blocks recursively (default: `false`) - * @param {boolean} [options.preload] - (default: `true`) - * @param {number} [options.timeout] - A timeout in ms (default: `undefined`) - * @param {AbortSignal} [options.signal] - Can be used to cancel any long running requests started as a result of this call (default: `undefined`) - * - * @returns {Promise} - A Block type object, containing both the data and the hash of the block + * @type {BlockPut} */ async function put (block, options) { options = options || {} @@ -42,6 +49,8 @@ module.exports = ({ blockService, pin, gcLock, preload }) => { } else { const mhtype = options.mhtype || 'sha2-256' const format = options.format || 'dag-pb' + + /** @type {CidVersion} */ let cidVersion if (options.version == null) { From 2442d964ef30e5a0a76d21f5a156e12aa3698ac0 Mon Sep 17 00:00:00 2001 From: Xmader Date: Tue, 1 Sep 2020 15:40:58 -0400 Subject: [PATCH 19/20] refactor: TypeScript support --- packages/ipfs-http-client/src/add-all.js | 2 +- packages/ipfs-http-client/src/block/put.js | 2 +- packages/ipfs-http-client/src/config/replace.js | 2 +- packages/ipfs-http-client/src/dag/put.js | 2 +- packages/ipfs-http-client/src/files/write.js | 2 +- packages/ipfs-http-client/src/object/patch/append-data.js | 2 +- packages/ipfs-http-client/src/object/patch/set-data.js | 2 +- packages/ipfs-http-client/src/object/put.js | 2 +- packages/ipfs-http-client/src/pubsub/publish.js | 2 +- packages/ipfs-http-client/src/pubsub/subscription-tracker.js | 2 +- packages/ipfs/src/core/components/files/chmod.js | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/ipfs-http-client/src/add-all.js b/packages/ipfs-http-client/src/add-all.js index e706d2af18..0cd1f55d87 100644 --- a/packages/ipfs-http-client/src/add-all.js +++ b/packages/ipfs-http-client/src/add-all.js @@ -6,7 +6,7 @@ const configure = require('./lib/configure') const multipartRequest = require('./lib/multipart-request') const toUrlSearchParams = require('./lib/to-url-search-params') const anySignal = require('any-signal') -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') module.exports = configure((api) => { // eslint-disable-next-line valid-jsdoc diff --git a/packages/ipfs-http-client/src/block/put.js b/packages/ipfs-http-client/src/block/put.js index 2ab691f886..5d3f62803a 100644 --- a/packages/ipfs-http-client/src/block/put.js +++ b/packages/ipfs-http-client/src/block/put.js @@ -7,7 +7,7 @@ const multipartRequest = require('../lib/multipart-request') const configure = require('../lib/configure') const toUrlSearchParams = require('../lib/to-url-search-params') const anySignal = require('any-signal') -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') module.exports = configure(api => { // eslint-disable-next-line valid-jsdoc diff --git a/packages/ipfs-http-client/src/config/replace.js b/packages/ipfs-http-client/src/config/replace.js index 57fce31db6..b8726e9537 100644 --- a/packages/ipfs-http-client/src/config/replace.js +++ b/packages/ipfs-http-client/src/config/replace.js @@ -5,7 +5,7 @@ const multipartRequest = require('../lib/multipart-request') const configure = require('../lib/configure') const toUrlSearchParams = require('../lib/to-url-search-params') const anySignal = require('any-signal') -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') module.exports = configure(api => { return async (config, options = {}) => { diff --git a/packages/ipfs-http-client/src/dag/put.js b/packages/ipfs-http-client/src/dag/put.js index e4f261c632..d0a395b435 100644 --- a/packages/ipfs-http-client/src/dag/put.js +++ b/packages/ipfs-http-client/src/dag/put.js @@ -9,7 +9,7 @@ const configure = require('../lib/configure') const multipartRequest = require('../lib/multipart-request') const toUrlSearchParams = require('../lib/to-url-search-params') const anySignal = require('any-signal') -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') const multicodec = require('multicodec') module.exports = configure((api, opts) => { diff --git a/packages/ipfs-http-client/src/files/write.js b/packages/ipfs-http-client/src/files/write.js index c3e72c9bb3..0fcbbec808 100644 --- a/packages/ipfs-http-client/src/files/write.js +++ b/packages/ipfs-http-client/src/files/write.js @@ -6,7 +6,7 @@ const configure = require('../lib/configure') const multipartRequest = require('../lib/multipart-request') const toUrlSearchParams = require('../lib/to-url-search-params') const anySignal = require('any-signal') -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') module.exports = configure(api => { return async (path, input, options = {}) => { diff --git a/packages/ipfs-http-client/src/object/patch/append-data.js b/packages/ipfs-http-client/src/object/patch/append-data.js index 0ef14f9a54..d6abee5c5f 100644 --- a/packages/ipfs-http-client/src/object/patch/append-data.js +++ b/packages/ipfs-http-client/src/object/patch/append-data.js @@ -6,7 +6,7 @@ const multipartRequest = require('../../lib/multipart-request') const configure = require('../../lib/configure') const toUrlSearchParams = require('../../lib/to-url-search-params') const anySignal = require('any-signal') -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') module.exports = configure(api => { return async (cid, data, options = {}) => { diff --git a/packages/ipfs-http-client/src/object/patch/set-data.js b/packages/ipfs-http-client/src/object/patch/set-data.js index 9609dff3a2..0d1575d69b 100644 --- a/packages/ipfs-http-client/src/object/patch/set-data.js +++ b/packages/ipfs-http-client/src/object/patch/set-data.js @@ -6,7 +6,7 @@ const multipartRequest = require('../../lib/multipart-request') const configure = require('../../lib/configure') const toUrlSearchParams = require('../../lib/to-url-search-params') const anySignal = require('any-signal') -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') module.exports = configure(api => { return async (cid, data, options = {}) => { diff --git a/packages/ipfs-http-client/src/object/put.js b/packages/ipfs-http-client/src/object/put.js index 34bf8eebe5..003c61dd01 100644 --- a/packages/ipfs-http-client/src/object/put.js +++ b/packages/ipfs-http-client/src/object/put.js @@ -7,7 +7,7 @@ const multipartRequest = require('../lib/multipart-request') const configure = require('../lib/configure') const toUrlSearchParams = require('../lib/to-url-search-params') const anySignal = require('any-signal') -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') module.exports = configure(api => { return async (obj, options = {}) => { diff --git a/packages/ipfs-http-client/src/pubsub/publish.js b/packages/ipfs-http-client/src/pubsub/publish.js index 0b24f4fc28..9ec83bc691 100644 --- a/packages/ipfs-http-client/src/pubsub/publish.js +++ b/packages/ipfs-http-client/src/pubsub/publish.js @@ -4,7 +4,7 @@ const configure = require('../lib/configure') const toUrlSearchParams = require('../lib/to-url-search-params') const multipartRequest = require('../lib/multipart-request') const anySignal = require('any-signal') -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') module.exports = configure(api => { return async (topic, data, options = {}) => { diff --git a/packages/ipfs-http-client/src/pubsub/subscription-tracker.js b/packages/ipfs-http-client/src/pubsub/subscription-tracker.js index 191f832cec..d5640bdd1a 100644 --- a/packages/ipfs-http-client/src/pubsub/subscription-tracker.js +++ b/packages/ipfs-http-client/src/pubsub/subscription-tracker.js @@ -1,6 +1,6 @@ 'use strict' -const AbortController = require('abort-controller') +const { AbortController } = require('abort-controller') class SubscriptionTracker { constructor () { diff --git a/packages/ipfs/src/core/components/files/chmod.js b/packages/ipfs/src/core/components/files/chmod.js index ef9838acb9..c814b11f5c 100644 --- a/packages/ipfs/src/core/components/files/chmod.js +++ b/packages/ipfs/src/core/components/files/chmod.js @@ -12,7 +12,7 @@ const updateMfsRoot = require('./utils/update-mfs-root') const { DAGNode } = require('ipld-dag-pb') const mc = require('multicodec') const mh = require('multihashing-async').multihash -const pipe = require('it-pipe') +const { pipe } = require('it-pipe') const importer = require('ipfs-unixfs-importer') const exporter = require('ipfs-unixfs-exporter') const last = require('it-last') From e9342d7c7f1080eb593a10c72c44f9af1743c947 Mon Sep 17 00:00:00 2001 From: Xmader Date: Wed, 2 Sep 2020 18:15:42 -0400 Subject: [PATCH 20/20] refactor: TypeScript support --- packages/ipfs-http-client/src/add.js | 8 ++++++ packages/ipfs-http-client/src/id.js | 7 ++++- packages/ipfs-http-client/src/index.js | 5 ++-- packages/ipfs-http-client/src/resolve.js | 7 ++++- packages/ipfs-http-client/src/version.js | 7 ++++- packages/ipfs/src/core/components/id.js | 27 ++++++++++++++++++-- packages/ipfs/src/core/components/resolve.js | 23 ++++++++++++----- packages/ipfs/src/core/components/version.js | 27 ++++++++++++++++++-- 8 files changed, 94 insertions(+), 17 deletions(-) diff --git a/packages/ipfs-http-client/src/add.js b/packages/ipfs-http-client/src/add.js index 8f04293012..7770be5843 100644 --- a/packages/ipfs-http-client/src/add.js +++ b/packages/ipfs-http-client/src/add.js @@ -4,6 +4,14 @@ const addAll = require('./add-all') const last = require('it-last') const configure = require('./lib/configure') +/** + * @typedef {import("./lib/core").ClientOptions} ClientOptions + */ + +// eslint-disable-next-line valid-jsdoc +/** + * @param {ClientOptions} options + */ module.exports = (options) => { const all = addAll(options) diff --git a/packages/ipfs-http-client/src/id.js b/packages/ipfs-http-client/src/id.js index e868460766..a4e86eb022 100644 --- a/packages/ipfs-http-client/src/id.js +++ b/packages/ipfs-http-client/src/id.js @@ -6,7 +6,11 @@ const configure = require('./lib/configure') const toUrlSearchParams = require('./lib/to-url-search-params') module.exports = configure(api => { - return async (options = {}) => { + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../ipfs/src/core/components/id').Id} + */ + async function id (options = {}) { const res = await api.post('id', { timeout: options.timeout, signal: options.signal, @@ -23,4 +27,5 @@ module.exports = configure(api => { return output } + return id }) diff --git a/packages/ipfs-http-client/src/index.js b/packages/ipfs-http-client/src/index.js index a7bdb6ab70..acd27d14f8 100644 --- a/packages/ipfs-http-client/src/index.js +++ b/packages/ipfs-http-client/src/index.js @@ -22,10 +22,9 @@ const urlSource = require('ipfs-utils/src/files/url-source') * @property {(format: string) => Promise} [ipld.loadFormat] - an async function that takes the name of an [IPLD format](https://github.com/ipld/interface-ipld-format) as a string and should return the implementation of that codec */ +// eslint-disable-next-line valid-jsdoc /** - * - * @param {ClientOptions } options - * @return {Object} + * @param {ClientOptions} options */ function ipfsClient (options = {}) { return { diff --git a/packages/ipfs-http-client/src/resolve.js b/packages/ipfs-http-client/src/resolve.js index a7635dad13..1dbac9256e 100644 --- a/packages/ipfs-http-client/src/resolve.js +++ b/packages/ipfs-http-client/src/resolve.js @@ -4,7 +4,11 @@ const configure = require('./lib/configure') const toUrlSearchParams = require('./lib/to-url-search-params') module.exports = configure(api => { - return async (path, options = {}) => { + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../ipfs/src/core/components/resolve').Resolve} + */ + async function resolve (path, options = {}) { const res = await api.post('resolve', { timeout: options.timeout, signal: options.signal, @@ -17,4 +21,5 @@ module.exports = configure(api => { const { Path } = await res.json() return Path } + return resolve }) diff --git a/packages/ipfs-http-client/src/version.js b/packages/ipfs-http-client/src/version.js index 28c49101bd..67d1ab314b 100644 --- a/packages/ipfs-http-client/src/version.js +++ b/packages/ipfs-http-client/src/version.js @@ -5,7 +5,11 @@ const configure = require('./lib/configure') const toUrlSearchParams = require('./lib/to-url-search-params') module.exports = configure(api => { - return async (options = {}) => { + // eslint-disable-next-line valid-jsdoc + /** + * @type {import('../../ipfs/src/core/components/version').Version} + */ + async function version (options = {}) { const res = await api.post('version', { timeout: options.timeout, signal: options.signal, @@ -16,4 +20,5 @@ module.exports = configure(api => { return toCamel(data) } + return version }) diff --git a/packages/ipfs/src/core/components/id.js b/packages/ipfs/src/core/components/id.js index 29dd07ff2d..bebdd86379 100644 --- a/packages/ipfs/src/core/components/id.js +++ b/packages/ipfs/src/core/components/id.js @@ -5,8 +5,30 @@ const multiaddr = require('multiaddr') const { withTimeoutOption } = require('../utils') const uint8ArrayToString = require('uint8arrays/to-string') +/** + * @typedef {object} PeerIdObj - An object with the Peer identity + * @property {string} id - the Peer ID + * @property {string} publicKey - the public key of the peer as a base64 encoded string + * @property {import('multiaddr')[]} addresses - A list of multiaddrs this node is listening on + * @property {string} agentVersion - The agent version + * @property {string} protocolVersion - The supported protocol version + * @property {string[]} protocols - The supported protocols + */ + +/** + * Returns the identity of the Peer + * @template {Record} ExtraOptions + * @callback Id + * @param {import('../utils').AbortOptions & ExtraOptions} [options] + * @returns {Promise} + */ + module.exports = ({ peerId, libp2p }) => { - return withTimeoutOption(async function id () { // eslint-disable-line require-await + // eslint-disable-next-line valid-jsdoc + /** + * @type {Id<{}>} + */ + async function id (options) { // eslint-disable-line require-await, @typescript-eslint/no-unused-vars const id = peerId.toB58String() let addresses = [] let protocols = [] @@ -38,5 +60,6 @@ module.exports = ({ peerId, libp2p }) => { protocolVersion: '9000', protocols: protocols.sort() } - }) + } + return withTimeoutOption(id) } diff --git a/packages/ipfs/src/core/components/resolve.js b/packages/ipfs/src/core/components/resolve.js index b55a375ec8..b56d381140 100644 --- a/packages/ipfs/src/core/components/resolve.js +++ b/packages/ipfs/src/core/components/resolve.js @@ -6,21 +6,30 @@ const { cidToString } = require('../../utils/cid') const { withTimeoutOption } = require('../utils') /** - * @typedef {Object} ResolveOptions - * @prop {string} cidBase - Multibase codec name the CID in the resolved path will be encoded with - * @prop {boolean} [recursive=true] - Resolve until the result is an IPFS name - * + * @typedef {object} ResolveOptions + * @property {string} [cidBase='base58btc'] - Multibase codec name the CID in the resolved path will be encoded with + * @property {boolean} [recursive=true] - Resolve until the result is an IPFS name */ -/** @typedef {(path: string, options?: ResolveOptions) => Promise} Resolve */ +/** + * Resolve the value of names to IPFS + * + * There are a number of mutable name protocols that can link among themselves and into IPNS. For example IPNS references can (currently) point at an IPFS object, and DNS links can point at other DNS links, IPNS entries, or IPFS objects. This command accepts any of these identifiers and resolves them to the referenced item. + * + * @template {Record} ExtraOptions + * @callback Resolve + * @param {string} path - The name to resolve + * @param {ResolveOptions & import('../utils').AbortOptions & ExtraOptions} [options] + * @returns {Promise} - A string representing the resolved name + */ /** * IPFS Resolve factory * - * @param {Object} config + * @param {object} config * @param {IPLD} config.ipld - An instance of IPLD * @param {NameApi} [config.name] - An IPFS core interface name API - * @returns {Resolve} + * @returns {Resolve<{}>} */ module.exports = ({ ipld, name }) => { return withTimeoutOption(async function resolve (path, opts) { diff --git a/packages/ipfs/src/core/components/version.js b/packages/ipfs/src/core/components/version.js index 77153e8541..acffb6d727 100644 --- a/packages/ipfs/src/core/components/version.js +++ b/packages/ipfs/src/core/components/version.js @@ -3,8 +3,29 @@ const pkg = require('../../../package.json') const { withTimeoutOption } = require('../utils') +/** + * @typedef {object} VersionObj - An object with the version of the implementation, the commit and the Repo. `js-ipfs` instances will also return the version of `interface-ipfs-core` and `ipfs-http-client` supported by this node + * @property {string} version + * @property {string} repo + * @property {string} [commit] + * @property {string} [interface-ipfs-core] + * @property {string} [ipfs-http-client] + */ + +/** + * Returns the implementation version + * @template {Record} ExtraOptions + * @callback Version + * @param {import('../utils').AbortOptions & ExtraOptions} [options] + * @returns {Promise} + */ + module.exports = ({ repo }) => { - return withTimeoutOption(async function version (options) { + // eslint-disable-next-line valid-jsdoc + /** + * @type {Version<{}>} + */ + async function version (options) { const repoVersion = await repo.version.get(options) return { @@ -14,5 +35,7 @@ module.exports = ({ repo }) => { 'interface-ipfs-core': pkg.devDependencies['interface-ipfs-core'], 'ipfs-http-client': pkg.dependencies['ipfs-http-client'] } - }) + } + + return withTimeoutOption(version) }