diff --git a/packages/ipfs-core-utils/package.json b/packages/ipfs-core-utils/package.json index db583a2ca9..24009e3a9a 100644 --- a/packages/ipfs-core-utils/package.json +++ b/packages/ipfs-core-utils/package.json @@ -44,6 +44,7 @@ "cids": "^1.0.0", "err-code": "^2.0.3", "ipfs-utils": "^5.0.0", + "ipfs-interface": "^0.1.0", "it-all": "^1.0.4", "it-map": "^1.0.4", "it-peekable": "^1.0.1", diff --git a/packages/ipfs-core-utils/src/files/format-mode.js b/packages/ipfs-core-utils/src/files/format-mode.js index 452aa182b5..79f739e68a 100644 --- a/packages/ipfs-core-utils/src/files/format-mode.js +++ b/packages/ipfs-core-utils/src/files/format-mode.js @@ -26,7 +26,7 @@ function checkPermission (mode, perm, type, output) { /** * - * @param {Mode} mode + * @param {import('ipfs-interface/src/files').Mode} mode * @param {boolean} isDirectory * @returns {string} */ @@ -70,7 +70,3 @@ function formatMode (mode, isDirectory) { } module.exports = formatMode - -/** - * @typedef {number} Mode - */ diff --git a/packages/ipfs-core-utils/src/files/format-mtime.js b/packages/ipfs-core-utils/src/files/format-mtime.js index 13f6e9e2d3..64048792fa 100644 --- a/packages/ipfs-core-utils/src/files/format-mtime.js +++ b/packages/ipfs-core-utils/src/files/format-mtime.js @@ -1,7 +1,7 @@ 'use strict' /** - * @param {MTime} mtime + * @param {import('ipfs-interface/src/files').MTime} mtime * @returns {string} */ function formatMtime (mtime) { @@ -22,12 +22,4 @@ function formatMtime (mtime) { }) } -/** - * @typedef {object} MTime - * @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. - */ - module.exports = formatMtime diff --git a/packages/ipfs-core-utils/src/files/normalise-input/index.browser.js b/packages/ipfs-core-utils/src/files/normalise-input/index.browser.js index 98e4145dce..02dd7f3270 100644 --- a/packages/ipfs-core-utils/src/files/normalise-input/index.browser.js +++ b/packages/ipfs-core-utils/src/files/normalise-input/index.browser.js @@ -12,7 +12,7 @@ const normaliseInput = require('./normalise-input') * * See https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md#ipfsadddata-options * - * @param {import('./normalise-input').Source} input - * @returns {AsyncIterable>} + * @param {import('ipfs-interface/src/files').ImportSource} input + * @returns {AsyncIterable>} */ module.exports = (input) => normaliseInput(input, normaliseContent) diff --git a/packages/ipfs-core-utils/src/files/normalise-input/index.js b/packages/ipfs-core-utils/src/files/normalise-input/index.js index d6b987807c..3c70f7394e 100644 --- a/packages/ipfs-core-utils/src/files/normalise-input/index.js +++ b/packages/ipfs-core-utils/src/files/normalise-input/index.js @@ -12,7 +12,7 @@ const normaliseInput = require('./normalise-input') * * See https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md#ipfsadddata-options * - * @param {import('./normalise-input').Source} input - * @returns {AsyncIterable>>} + * @param {import('ipfs-interface/src/files').ImportSource} input + * @returns {AsyncIterable>>} */ module.exports = (input) => normaliseInput(input, normaliseContent) diff --git a/packages/ipfs-core-utils/src/files/normalise-input/normalise-input.js b/packages/ipfs-core-utils/src/files/normalise-input/normalise-input.js index 4a6e8c6d82..cf006e76dd 100644 --- a/packages/ipfs-core-utils/src/files/normalise-input/normalise-input.js +++ b/packages/ipfs-core-utils/src/files/normalise-input/normalise-input.js @@ -15,11 +15,14 @@ const { // eslint-disable-next-line complexity +/** + * @typedef {import('ipfs-interface/src/files').ToContent} ToContent + */ /** * @template {Blob|AsyncIterable} Content - * @param {Source} input + * @param {import('ipfs-interface/src/files').ImportSource} input * @param {(content:ToContent) => Content|Promise} normaliseContent - * @returns {AsyncIterable>} + * @returns {AsyncIterable>} */ // eslint-disable-next-line complexity module.exports = async function * normaliseInput (input, normaliseContent) { @@ -100,9 +103,9 @@ module.exports = async function * normaliseInput (input, normaliseContent) { /** * @template {Blob|AsyncIterable} Content - * @param {ToFile} input + * @param {import('ipfs-interface/src/files').ToEntry} input * @param {(content:ToContent) => Content|Promise} normaliseContent - * @returns {Promise>} + * @returns {Promise>} */ async function toFileObject (input, normaliseContent) { // @ts-ignore - Those properties don't exist on most input types @@ -119,42 +122,3 @@ async function toFileObject (input, normaliseContent) { return file } - -/** - * @typedef {import('../format-mtime').MTime} MTime - * @typedef {import('../format-mode').Mode} Mode - * @typedef {Object} Directory - * @property {string} path - * @property {Mode} [mode] - * @property {MTime} [mtime] - * @property {undefined} [content] - * - * @typedef {Object} FileInput - * @property {string} [path] - * @property {ToContent} [content] - * @property {number | string} [mode] - * @property {UnixTime} [mtime] - * - * @typedef {Date | MTime | HRTime} UnixTime - * - * Time representation as tuple of two integers, as per the output of - * [`process.hrtime()`](https://nodejs.org/dist/latest/docs/api/process.html#process_process_hrtime_time). - * @typedef {[number, number]} HRTime - * - * @typedef {string|InstanceType|ArrayBufferView|ArrayBuffer|Blob|Iterable | AsyncIterable | ReadableStream} ToContent - * @typedef {ToContent|FileInput} ToFile - * @typedef {Iterable | AsyncIterable | ReadableStream} Source - */ -/** - * @template {AsyncIterable|Blob} Content - * @typedef {Object} File - * @property {string} path - * @property {Mode} [mode] - * @property {MTime} [mtime] - * @property {Content} [content] - */ - -/** - * @template {AsyncIterable|Blob} Content - * @typedef {File|Directory} Entry - */ diff --git a/packages/ipfs-core-utils/src/files/normalise-input/utils.js b/packages/ipfs-core-utils/src/files/normalise-input/utils.js index dabc6e5a6f..06f26096f9 100644 --- a/packages/ipfs-core-utils/src/files/normalise-input/utils.js +++ b/packages/ipfs-core-utils/src/files/normalise-input/utils.js @@ -22,7 +22,7 @@ function isBlob (obj) { * An object with a path or content property * * @param {any} obj - * @returns {obj is import('./normalise-input').FileInput} + * @returns {obj is import('ipfs-interface/src/files').ToEntry} */ function isFileObject (obj) { return typeof obj === 'object' && (obj.path || obj.content) diff --git a/packages/ipfs-core/package.json b/packages/ipfs-core/package.json index a4269322a5..054f459610 100644 --- a/packages/ipfs-core/package.json +++ b/packages/ipfs-core/package.json @@ -71,6 +71,7 @@ "ipfs-bitswap": "^4.0.0", "ipfs-block-service": "^0.18.0", "ipfs-core-utils": "^0.5.3", + "ipfs-interface": "^0.1.0", "ipfs-repo": "^7.0.0", "ipfs-unixfs": "^2.0.3", "ipfs-unixfs-exporter": "^3.0.4", diff --git a/packages/ipfs-core/src/components/add-all/index.js b/packages/ipfs-core/src/components/add-all/index.js index eb5077c824..5c163f944d 100644 --- a/packages/ipfs-core/src/components/add-all/index.js +++ b/packages/ipfs-core/src/components/add-all/index.js @@ -13,17 +13,12 @@ const mergeOptions = require('merge-options').bind({ ignoreUndefined: true }) * @param {import('..').GCLock} config.gcLock * @param {import('..').Preload} config.preload * @param {import('..').Pin} config.pin - * @param {ShardingOptions} [config.options] + * @param {import('ipfs-interface/src/root').ShardingOptions} [config.options] */ module.exports = ({ block, gcLock, preload, pin, options }) => { const isShardingEnabled = options && options.sharding - /** - * Import multiple files and data into IPFS. - * - * @param {FileStream} source - * @param {AddAllOptions & AbortOptions} [options] - * @returns {AsyncIterable} - */ + + /** @type {import('ipfs-interface/src/root').AddAll} */ async function * addAll (source, options = {}) { const opts = mergeOptions({ shardSplitThreshold: isShardingEnabled ? 1000 : Infinity, @@ -169,43 +164,3 @@ function pinFile (pin, opts) { } } } - -/** - * @typedef {object} UnixFSEntry - * @property {string} path - * @property {CID} cid - * @property {number} [mode] - * @property {MTime} [mtime] - * @property {number} size - * - * @typedef {Object} AddAllOptions - * @property {string} [chunker='size-262144'] - Chunking algorithm used to build - * ipfs DAGs. - * @property {0|1} [cidVersion=0] - The CID version to use when storing the data. - * @property {boolean} [enableShardingExperiment=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. - * @property {string} [hashAlg='sha2-256'] - Multihash hashing algorithm to use. - * @property {boolean} [onlyHash=false] - If true, will not add blocks to the - * blockstore. - * @property {boolean} [pin=true] - Pin this object when adding. - * @property {(bytes:number, path:string) => void} [progress] - a function that will be called with the number of bytes added as a file is added to ipfs and the path of the file being added - * @property {boolean} [rawLeaves=false] - If true, DAG leaves will contain raw - * file data and not be wrapped in a protobuf. - * @property {number} [shardSplitThreshold=1000] - Directories with more than this - * number of files will be created as HAMT-sharded directories. - * @property {boolean} [trickle=false] - 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. - * @property {boolean} [wrapWithDirectory=false] - Adds a wrapping node around - * the content. - * - * @typedef {import('ipfs-core-utils/src/files/normalise-input/normalise-input').Source} FileStream - * @typedef {import('../../utils').MTime} MTime - * @typedef {import('../../utils').AbortOptions} AbortOptions - * @typedef {import('..').CID} CID - * - * @typedef {Object} ShardingOptions - * @property {boolean} [sharding] - */ diff --git a/packages/ipfs-core/src/components/add.js b/packages/ipfs-core/src/components/add.js index 7334071e7c..b71ea1d596 100644 --- a/packages/ipfs-core/src/components/add.js +++ b/packages/ipfs-core/src/components/add.js @@ -2,39 +2,25 @@ const last = require('it-last') +/** + * @param {Object} config + * @param {import('ipfs-interface/src/root').AddAll} config.addAll + */ module.exports = ({ addAll }) => { - /** - * Import a file or data into IPFS. - * - * @param {Source} source - * @param {AddOptions & AbortOptions} [options] - * @returns {AddResult} - */ - async function add (source, options) { // eslint-disable-line require-await - /** @type {UnixFSEntry} - Could be undefined if empty */ - const result = (await last(addAll(source, options))) + /** @type {import('ipfs-interface/src/root').Add} */ + async function add (entry, options) { + /** @type {import('ipfs-interface/src/files').ImportSource} */ + const source = (entry) // + const result = await last(addAll(source, options)) + // Note this should never happen as `addAll` should yield at least one item + // but to satisfy type checker we perfom this check and for good measure + // throw an error in case it does happen. + if (result == null) { + throw Error('Failed to add a file, if you see this please report a bug') + } + return result } + return add } - -/** - * @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 {(bytes:number, path:string) => void} [progress] - a function that will be called with the number of bytes added as a file is added to ipfs and the path of the file being added - * @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`) - * - * @typedef {Promise} AddResult - * - * @typedef {import('ipfs-core-utils/src/files/normalise-input/normalise-input').FileInput} Source - * - * @typedef {import('./add-all').UnixFSEntry} UnixFSEntry - * - * @typedef {import('../utils').AbortOptions} AbortOptions - */ diff --git a/packages/ipfs-core/src/components/cat.js b/packages/ipfs-core/src/components/cat.js index 6c47032286..c76029b5ce 100644 --- a/packages/ipfs-core/src/components/cat.js +++ b/packages/ipfs-core/src/components/cat.js @@ -10,13 +10,7 @@ const withTimeoutOption = require('ipfs-core-utils/src/with-timeout-option') * @param {import('.').Preload} config.preload */ module.exports = function ({ ipld, preload }) { - /** - * Returns content of the file addressed by a valid IPFS Path or CID. - * - * @param {CID|string} ipfsPath - An IPFS path or CID to export - * @param {Options} [options] - * @returns {AsyncIterable} - */ + /** @type {import('ipfs-interface/src/root').Cat} */ async function * cat (ipfsPath, options = {}) { ipfsPath = normalizeCidPath(ipfsPath) @@ -41,16 +35,3 @@ module.exports = function ({ ipld, preload }) { return withTimeoutOption(cat) } - -/** - * @typedef {CatOptions & AbortOptions} Options - * - * @typedef {Object} CatOptions - * @property {number} [offset] - An offset to start reading the file from - * @property {number} [length] - An optional max length to read from the file - * @property {boolean} [preload] - * - * @typedef {import('../utils').AbortOptions} AbortOptions - * - * @typedef {import('.').CID} CID - */ diff --git a/packages/ipfs-core/src/components/files/mkdir.js b/packages/ipfs-core/src/components/files/mkdir.js index 22f0b8cfc1..b44ed06a14 100644 --- a/packages/ipfs-core/src/components/files/mkdir.js +++ b/packages/ipfs-core/src/components/files/mkdir.js @@ -143,14 +143,16 @@ const addEmptyDir = async (context, childName, emptyDir, parent, trail, options) /** * @typedef {Object} MkdirOptions * @property {boolean} [parents=false] - If true, create intermediate directories - * @property {number} [mode] - An integer that represents the file mode - * @property {Mtime|Hrtime|Date} [mtime] - A Date object, an object with `{ secs, nsecs }` properties where secs is the number of seconds since (positive) or before (negative) the Unix Epoch began and nsecs is the number of nanoseconds since the last full second, or the output of `process.hrtime() + * @property {ToMode} [mode] - An integer that represents the file mode + * @property {ToMTime} [mtime] - A Date object, an object with `{ secs, nsecs }` properties where secs is the number of seconds since (positive) or before (negative) the Unix Epoch began and nsecs is the number of nanoseconds since the last full second, or the output of `process.hrtime() * @property {boolean} [flush] - If true the changes will be immediately flushed to disk * @property {string} [hashAlg='sha2-256'] - The hash algorithm to use for any updated entries - * @property {0|1} [cidVersion=0] - The CID version to use for any updated entries + * @property {CIDVersion} [cidVersion=0] - The CID version to use for any updated entries * * @typedef {import('cids')} CID - * @typedef {import('../../utils').AbortOptions} AbortOptions - * @typedef {import('../../utils').Mtime} Mtime - * @typedef {import('../../utils').Hrtime} Hrtime + * @typedef {import('cids').CIDVersion} CIDVersion + * @typedef {import('ipfs-interface/src/basic').AbortOptions} AbortOptions + * @typedef {import('ipfs-interface/src/files').MTime} Mtime + * @typedef {import('ipfs-interface/src/files').ToMTime} ToMTime + * @typedef {import('ipfs-interface/src/files').ToMode} ToMode */ diff --git a/packages/ipfs-core/src/components/files/stat.js b/packages/ipfs-core/src/components/files/stat.js index 4b83a664ff..c35c6eb761 100644 --- a/packages/ipfs-core/src/components/files/stat.js +++ b/packages/ipfs-core/src/components/files/stat.js @@ -180,8 +180,8 @@ const statters = { * @property {number} [sizeLocal] - An integer indicating the cumulative size of * the data present locally. * @property {number} [mode] - File mode - * @property {import('../add-all').MTime} [mtime] - Modification time + * @property {import('ipfs-interface/src/files').MTime} [mtime] - Modification time * - * @typedef {import('..').CID} CID - * @typedef {import('../../utils').AbortOptions} AbortOptions + * @typedef {import('cids')} CID + * @typedef {import('ipfs-interface/src/basic').AbortOptions} AbortOptions */ diff --git a/packages/ipfs-core/src/components/files/touch.js b/packages/ipfs-core/src/components/files/touch.js index 6d889ba07b..0a4b5769cd 100644 --- a/packages/ipfs-core/src/components/files/touch.js +++ b/packages/ipfs-core/src/components/files/touch.js @@ -15,7 +15,7 @@ const mh = require('multihashing-async').multihash const withTimeoutOption = require('ipfs-core-utils/src/with-timeout-option') const defaultOptions = { - /** @type {UnixTime|undefined} */ + /** @type {ToMTime|undefined} */ mtime: undefined, flush: true, shardSplitThreshold: 1000, @@ -121,14 +121,12 @@ module.exports = (context) => { /** * @typedef {Object} TouchOptions - * @property {UnixTime} [mtime] - A Date object, an object with `{ secs, nsecs }` properties where secs is the number of seconds since (positive) or before (negative) the Unix Epoch began and nsecs is the number of nanoseconds since the last full second, or the output of `process.hrtime()` + * @property {ToMTime} [mtime] - A Date object, an object with `{ secs, nsecs }` properties where secs is the number of seconds since (positive) or before (negative) the Unix Epoch began and nsecs is the number of nanoseconds since the last full second, or the output of `process.hrtime()` * @property {boolean} [flush=false] - If true the changes will be immediately flushed to disk * @property {string} [hashAlg='sha2-256'] - The hash algorithm to use for any updated entries - * @property {0|1} [cidVersion] - The CID version to use for any updated entries + * @property {import('cids').CIDVersion} [cidVersion] - The CID version to use for any updated entries * * @typedef {import('cids')} CID - * @typedef {import('../../utils').AbortOptions} AbortOptions - * @typedef {import('../../utils').Mtime} Mtime - * @typedef {import('../../utils').Hrtime} Hrtime - * @typedef {import('ipfs-core-utils/src/files/normalise-input/normalise-input').UnixTime} UnixTime + * @typedef {import('ipfs-interface/src/basic').AbortOptions} AbortOptions + * @typedef {import('ipfs-interface/src/files').ToMTime} ToMTime */ diff --git a/packages/ipfs-core/src/components/files/write.js b/packages/ipfs-core/src/components/files/write.js index f65987c7a7..a8940d93c3 100644 --- a/packages/ipfs-core/src/components/files/write.js +++ b/packages/ipfs-core/src/components/files/write.js @@ -299,13 +299,11 @@ const countBytesStreamed = async function * (source, notify) { * @property {boolean} [parents=false] - Create intermediate MFS paths if they do not exist * @property {boolean} [truncate=false] - Truncate the file at the MFS path if it would have been larger than the passed content * @property {boolean} [rawLeaves=false] - If true, DAG leaves will contain raw file data and not be wrapped in a protobuf - * @property {number} [mode] - An integer that represents the file mode - * @property {Mtime|Hrtime|Date} [mtime] - A Date object, an object with `{ secs, nsecs }` properties where secs is the number of seconds since (positive) or before (negative) the Unix Epoch began and nsecs is the number of nanoseconds since the last full second, or the output of `process.hrtime() + * @property {import('ipfs-interface/src/files').ToMode} [mode] - An integer that represents the file mode + * @property {import('ipfs-interface/src/files').ToMTime} [mtime] - A Date object, an object with `{ secs, nsecs }` properties where secs is the number of seconds since (positive) or before (negative) the Unix Epoch began and nsecs is the number of nanoseconds since the last full second, or the output of `process.hrtime() * @property {boolean} [flush] - If true the changes will be immediately flushed to disk * @property {string} [hashAlg='sha2-256'] - The hash algorithm to use for any updated entries * @property {0|1} [cidVersion=0] - The CID version to use for any updated entries * * @typedef {import('../../utils').AbortOptions} AbortOptions - * @typedef {import('../../utils').Mtime} Mtime - * @typedef {import('../../utils').Hrtime} Hrtime */ diff --git a/packages/ipfs-core/src/components/get.js b/packages/ipfs-core/src/components/get.js index 1b614136c9..166427557a 100644 --- a/packages/ipfs-core/src/components/get.js +++ b/packages/ipfs-core/src/components/get.js @@ -11,13 +11,7 @@ const withTimeoutOption = require('ipfs-core-utils/src/with-timeout-option') * @param {import('.').Preload} config.preload */ module.exports = function ({ ipld, preload }) { - /** - * Fetch a file or an entire directory tree from IPFS that is addressed by a valid IPFS Path. - * - * @param {CID|string} ipfsPath - An IPFS path or CID to export - * @param {Options} [options] - * @returns {AsyncIterable} - */ + /** @type {import('ipfs-interface/src/root').Get} */ async function * get (ipfsPath, options = {}) { if (options.preload !== false) { let pathComponents @@ -41,14 +35,3 @@ module.exports = function ({ ipld, preload }) { return withTimeoutOption(get) } - -/** - * @typedef {GetOptions & AbortOptions} Options - * - * @typedef {Object} GetOptions - * @property {boolean} [preload] - * - * @typedef {import('.').CID} CID - * @typedef {import('../utils').AbortOptions} AbortOptions - * @typedef {import('../utils').IPFSEntry} IPFSEntry - */ diff --git a/packages/ipfs-core/src/components/ls.js b/packages/ipfs-core/src/components/ls.js index 1fe0234f2c..ae661f7f30 100644 --- a/packages/ipfs-core/src/components/ls.js +++ b/packages/ipfs-core/src/components/ls.js @@ -7,17 +7,11 @@ const withTimeoutOption = require('ipfs-core-utils/src/with-timeout-option') /** * @param {Object} config - * @param {import('./root').IPLD} config.ipld - * @param {import('./root').Preload} config.preload + * @param {import('.').IPLD} config.ipld + * @param {import('.').Preload} config.preload */ module.exports = function ({ ipld, preload }) { - /** - * Lists a directory from IPFS that is addressed by a valid IPFS Path. - * - * @param {string|CID} ipfsPath - An IPFS path or CID to list - * @param {Options} options - * @returns {AsyncIterable} - */ + /** @type {import('ipfs-interface/src/root').List} */ async function * ls (ipfsPath, options = {}) { const path = normalizeCidPath(ipfsPath) const recursive = options.recursive @@ -66,18 +60,3 @@ module.exports = function ({ ipld, preload }) { return withTimeoutOption(ls) } - -/** - * @typedef {import('../utils').IPFSEntry} LSEntry - * - * @typedef {LSOptions & AbortOptions} Options - * - * @typedef {Object} LSOptions - * @property {boolean} [recursive] - * @property {boolean} [preload] - * @property {boolean} [includeContent] - * - * @typedef {import('../utils').AbortOptions} AbortOptions - * - * @typedef {import('.').CID} CID - */ diff --git a/packages/ipfs-core/src/components/root.js b/packages/ipfs-core/src/components/root.js index bb89644d4f..ed2c9ebac5 100644 --- a/packages/ipfs-core/src/components/root.js +++ b/packages/ipfs-core/src/components/root.js @@ -6,15 +6,19 @@ const createCatAPI = require('./cat') const createGetAPI = require('./get') const createLsAPI = require('./ls') -class RootAPI { +/** + * @typedef {import('ipfs-interface').RootAPI} RootAPI + * @implements {RootAPI} + */ +class Root { /** * @param {Object} config - * @param {Block} config.block - * @param {Pin} config.pin - * @param {GCLock} config.gcLock - * @param {Preload} config.preload - * @param {IPLD} config.ipld - * @param {ShardingOptions} [config.options] + * @param {import('.').Block} config.block + * @param {import('.').Pin} config.pin + * @param {import('.').GCLock} config.gcLock + * @param {import('.').Preload} config.preload + * @param {import('.').IPLD} config.ipld + * @param {import('ipfs-interface/src/root').ShardingOptions} [config.options] */ constructor ({ preload, gcLock, pin, block, ipld, options }) { const addAll = createAddAllAPI({ @@ -33,13 +37,4 @@ class RootAPI { } } -module.exports = RootAPI - -/** - * @typedef {import('.').Block} Block - * @typedef {import('.').Pin} Pin - * @typedef {import('.').GCLock} GCLock - * @typedef {import('.').IPLD} IPLD - * @typedef {import('.').Preload} Preload - * @typedef {import('./add-all').ShardingOptions} ShardingOptions - */ +module.exports = Root diff --git a/packages/ipfs-core/src/utils.js b/packages/ipfs-core/src/utils.js index 6846006bf6..7b20fe79f1 100644 --- a/packages/ipfs-core/src/utils.js +++ b/packages/ipfs-core/src/utils.js @@ -97,6 +97,11 @@ const resolvePath = async function (dag, ipfsPath, options = {}) { } /** + * @typedef {import('ipfs-interface/src/files').InputFile} InputFile + * @typedef {import('ipfs-interface/src/files').UnixFSFile} UnixFSFile + * @typedef {import('ipfs-interface/src/files').IPFSEntry} IPFSEntry + * @typedef {import('ipfs-interface').AbortOptions} AbortOptions + * * @param {InputFile|UnixFSFile} file * @param {Object} [options] * @param {boolean} [options.includeContent] @@ -121,6 +126,7 @@ const mapFile = (file, options = {}) => { output.size = file.unixfs.fileSize() if (options.includeContent) { + // @ts-expect-error - content is readonly output.content = file.content() } } @@ -132,92 +138,6 @@ const mapFile = (file, options = {}) => { return output } -/** - * @typedef {Object} File - * @property {'file'} type - * @property {CID} cid - * @property {string} name - * @property {string} path - File path - * @property {AsyncIterable} [content] - File content - * @property {number} [mode] - * @property {MTime} [mtime] - * @property {number} size - * @property {number} depth - * - * @typedef {Object} Directory - * @property {'dir'} type - * @property {CID} cid - * @property {string} name - * @property {string} path - Directory path - * @property {number} [mode] - * @property {MTime} [mtime] - * @property {number} size - * @property {number} depth - * - * @typedef {File|Directory} IPFSEntry - * - * @typedef {Object} BaseFile - * @property {CID} cid - * @property {string} path - * @property {string} name - * - * @typedef {Object} InputFileExt - * @property {undefined} [unixfs] - * - * @typedef {BaseFile & InputFileExt} InputFile - * - * @typedef {Object} UnixFSeExt - * @property {() => AsyncIterable} content - * @property {UnixFS} unixfs - * - * @typedef {BaseFile & UnixFSeExt} UnixFSFile - * - * - * @typedef {Object} UnixFS - * @property {'directory'|'file'|'dir'} type - * @property {() => number} fileSize - * @property {() => AsyncIterable} content - * @property {number} mode - * @property {MTime} mtime - * - * @typedef {object} MTime - * @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. - */ - -/** - * @template {any[]} ARGS - * @template R - * @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 - */ - -/** - * @typedef {Object} Mtime - * @property {number} [secs] - * @property {number} [nsecs] - */ - -/** - * @typedef {[number, number]} Hrtime - */ - -/** - * @typedef {Object} PreloadOptions - * @property {boolean} [preload=true] - */ - -/** - * @template {Record} ExtraOptions - */ - const withTimeout = withTimeoutOption( /** * @template T diff --git a/packages/ipfs-http-client/package.json b/packages/ipfs-http-client/package.json index 315abda5e0..b131c5f682 100644 --- a/packages/ipfs-http-client/package.json +++ b/packages/ipfs-http-client/package.json @@ -57,6 +57,7 @@ "form-data": "^3.0.0", "ipfs-core-utils": "^0.5.3", "ipfs-utils": "^5.0.0", + "ipfs-interface": "^0.1.0", "ipld-block": "^0.11.0", "ipld-dag-cbor": "^0.17.0", "ipld-dag-pb": "^0.20.0", diff --git a/packages/ipfs-http-client/src/add-all.js b/packages/ipfs-http-client/src/add-all.js index 49be9c7530..d4bd6b3a6f 100644 --- a/packages/ipfs-http-client/src/add-all.js +++ b/packages/ipfs-http-client/src/add-all.js @@ -98,7 +98,7 @@ const createOnUploadPrgress = (size, parts, progress) => { /** * @param {any} input - * @returns {UnixFSEntry} + * @returns {import('ipfs-interface/src/files').UnixFSEntry} */ function toCoreInterface ({ name, hash, size, mode, mtime, mtimeNsecs }) { const output = { @@ -121,7 +121,3 @@ function toCoreInterface ({ name, hash, size, mode, mtime, mtimeNsecs }) { // @ts-ignore return output } - -/** - * @typedef {import('ipfs-core/src/components/add-all/index').UnixFSEntry} UnixFSEntry - */ diff --git a/packages/ipfs-interface/COPYRIGHT b/packages/ipfs-interface/COPYRIGHT new file mode 100644 index 0000000000..e085a877e2 --- /dev/null +++ b/packages/ipfs-interface/COPYRIGHT @@ -0,0 +1,5 @@ +This project is transitioning from an MIT-only license to a dual MIT/Apache-2.0 license. +Unless otherwise noted, all code contributed prior to 2019-11-21 and not contributed by +a user listed in [this signoff issue](https://github.com/ipfs/js-ipfs/issues/2624) is +licensed under MIT-only. All new contributions (and past contributions since 2019-11-21) +are licensed under a dual MIT/Apache-2.0 license. diff --git a/packages/ipfs-interface/LICENSE-APACHE b/packages/ipfs-interface/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/ipfs-interface/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/ipfs-interface/LICENSE-MIT b/packages/ipfs-interface/LICENSE-MIT new file mode 100644 index 0000000000..749aa1ecd9 --- /dev/null +++ b/packages/ipfs-interface/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/ipfs-interface/README.md b/packages/ipfs-interface/README.md new file mode 100644 index 0000000000..56a97538fa --- /dev/null +++ b/packages/ipfs-interface/README.md @@ -0,0 +1,82 @@ +# ipfs-interface + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![Dependency Status](https://david-dm.org/ipfs/js-ipfs/status.svg?style=flat-square&path=packages/interface-ipfs-core)](https://david-dm.org/ipfs/js-ipfs?path=packages/interface-ipfs-core) + +> IPFS interface definitions used by implementations for API compatibility. + +## Lead Maintainer + +[Alex Potsides](http://github.com/achingbrain) + +## Table of Contents + +- [Background](#background) +- [Install](#install) +- [Usage](#usage) +- [Validation](#validation) +- [Contribute](#contribute) + - [Want to hack on IPFS?](#want-to-hack-on-ipfs) +- [License](#license) + +## Background + +The primary goal of this module is to define and ensure that IPFS core implementations and their respective HTTP client libraries implement the same interface, so that developers can quickly change between a local and a remote node without having to change their applications. + +It offers set of typescript interface definitions that implementations can claim compatibility with and use typescript to validate those claims. + +## Install + +In JavaScript land: + +```console +$ npm install ipfs-interface +``` + +## Usage + +Install `ipfs-interface` as one of the dependencies of your project and use it to ensure your implementations API compatibility: + +### In [JSDoc syntax](https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html) + +```js +/** + * @implements {import('ipfs-interface').RootAPI} + */ +class Root { + // your implementation goes here +} +``` + +### In Typescript + +```ts +import { RootAPI } from 'ipfs-interface' +class Root implements RootAPI { + // your implementation goes here +} +``` + +## Validation + +In order to validate API compatibility you can run [typescript](https://www.typescriptlang.org/) over your implementation which will point out all the API compatibilities if there are some. + + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/js-ipfs/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) + +## License + +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fipfs%2Fjs-ipfs.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fipfs%2Fjs-ipfs?ref=badge_large) + +[![](https://github.com/ipfs/js-ipfs/raw/master/packages/ipfs-interface/img/badge.png)](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-interface) diff --git a/packages/ipfs-interface/package.json b/packages/ipfs-interface/package.json new file mode 100644 index 0000000000..2703960bcb --- /dev/null +++ b/packages/ipfs-interface/package.json @@ -0,0 +1,44 @@ +{ + "name": "ipfs-interface", + "version": "0.1.0", + "description": "IPFS interface definitions used by implementations for API compatibility.", + "leadMaintainer": "Alex Potsides ", + "types": "src/index.ts", + "homepage": "https://github.com/ipfs/js-ipfs/tree/master/packages/interface-ipfs-core#readme", + "bugs": "https://github.com/ipfs/js-ipfs/issues", + "scripts": { + "lint": "aegir lint", + "test": "aegir ts -p check", + "dep-check": "aegir dep-check" + }, + "types": "src/index.ts", + "files": [ + "src" + ], + "eslintConfig": { + "extends": "ipfs" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ipfs/js-ipfs.git" + }, + "keywords": [ + "IPFS", + "types", + "interface", + "API" + ], + "license": "(Apache-2.0 OR MIT)", + "dependencies": { + "cids": "^1.0.0", + "multiaddr": "^8.0.0", + "peer-id": "^0.14.1" + }, + "devDependencies": { + "aegir": "^29.2.2", + "typescript": "4.0.x" + }, + "contributors": [ + "Irakli Gozalishvili " + ] +} diff --git a/packages/ipfs-interface/src/basic.ts b/packages/ipfs-interface/src/basic.ts new file mode 100644 index 0000000000..fa7db76086 --- /dev/null +++ b/packages/ipfs-interface/src/basic.ts @@ -0,0 +1,31 @@ +/** + * Common options across all cancellable requests. + */ +export interface AbortOptions { + /** + * Can be provided to a function that starts a long running task, which will + * be aborted when signal is triggered. + */ + signal?: AbortSignal + /** + * Can be provided to a function that starts a long running task, which will + * be aborted after provided timeout (in ms). + */ + timeout?: number +} + +/** + * Represents a value that you can await on, which is either value or a promise + * of one. + */ +export type Await = + | T + | Promise + +/** + * Represents an iterable that can be used in `for await` loops, that is either + * iterable or an async iterable. + */ +export type AwaitIterable = + | Iterable + | AsyncIterable diff --git a/packages/ipfs-interface/src/files.ts b/packages/ipfs-interface/src/files.ts new file mode 100644 index 0000000000..ad13810d62 --- /dev/null +++ b/packages/ipfs-interface/src/files.ts @@ -0,0 +1,211 @@ +import CID from 'cids' +import { AwaitIterable } from './basic' + +export type Entry|Blob> = + | FileEntry + | DirectoryEntry + +export interface BaseEntry { + path: string + mode?: Mode + mtime?: MTime +} +export interface FileEntry |Blob> extends BaseEntry { + content?: Content +} + +export interface DirectoryEntry extends BaseEntry { + content?: void +} + +export type ImportSource = +| AwaitIterable +| ReadableStream + +export type ToEntry = + | ToFile + | ToDirectory + | ToContent + +export interface ToFile extends ToFileMetadata { + path?: string + content: ToContent +} + +export interface ToDirectory extends ToFileMetadata { + path: string + content?: void +} + +export interface ToFileMetadata { + mode?: ToMode + mtime?: ToMTime +} + +/** + * File content in arbitrary (supported) represenation. It is used in input + * positions and is usually normalized to `Blob` in browser contexts and + * `AsyncIterable` in node. + */ +export type ToContent = + | string + | InstanceType + | ArrayBufferView + | ArrayBuffer + | Blob + | AwaitIterable + | ReadableStream + +/** + * Timestamp representation in arbitrary (supported) in representations. It is + * used in input positions and usurally get's normalised to `MTime` before use. + */ +export type ToMTime = + | Date + | HRTime + | MTimeLike + +export type ToMode = + | string + | number + +export interface File { + readonly type: 'file' + readonly cid: CID + readonly name: string + + /** + * File path + */ + readonly path: string + /** + * File content + */ + readonly content?: AsyncIterable + mode?: Mode + mtime?: MTime + size?: number + depth?: number +} + +export interface Directory { + type: 'dir', + cid: CID + name: string + /** + * Directory path + */ + path: string + mode?: Mode + mtime?: MTime + size?: number + depth?: number +} + +export type IPFSEntry = File | Directory + +export interface BaseFile { + cid: CID + path: string + name: string +} + +export interface InputFile extends BaseFile { + unixfs: void +} + +export interface UnixFSFile extends BaseFile { + content(): AsyncIterable + unixfs: UnixFS +} + +export interface UnixFSEntry { + path: string + cid: CID + mode: Mode + mtime: MTime + size: number +} + +export interface MTime { + /** + * The number of seconds since(positive) or before (negative) the Unix Epoch + * began. + */ + readonly secs: number + + /** + * The number of nanoseconds since the last full second + */ + readonly nsecs: number +} + +export interface MTimeLike { + /** + * The number of seconds since(positive) or before (negative) the Unix Epoch + * began. + */ + secs: number + + /** + * The number of nanoseconds since the last full second + */ + nsecs?: number +} + +interface UnixFS { + readonly type: 'directory' | 'file' | 'dir' + readonly mode: Mode + readonly mtime: MTime + + fileSize(): number + content(): AsyncIterable +} + +/** + * Time representation as tuple of two integers, as per the output of + * [`process.hrtime()`](https://nodejs.org/dist/latest/docs/api/process.html#process_process_hrtime_time). + */ +type HRTime = [number, number] + +// It's just a named type alias, but it better captures intent. +export type Mode = number + +/** + * @typedef {import('../format-mtime').MTime} MTime + * @typedef {import('../format-mode').Mode} Mode + * @typedef {Object} Directory + * @property {string} path + * @property {Mode} [mode] + * @property {MTime} [mtime] + * @property {undefined} [content] + * + * @typedef {Object} FileInput + * @property {string} [path] + * @property {ToContent} [content] + * @property {number | string} [mode] + * @property {UnixTime} [mtime] + * + * @typedef {Date | MTime | HRTime} UnixTime + * + * Time representation as tuple of two integers, as per the output of + * [`process.hrtime()`](https://nodejs.org/dist/latest/docs/api/process.html#process_process_hrtime_time). + * @typedef {[number, number]} HRTime + * + * @typedef {string|InstanceType|ArrayBufferView|ArrayBuffer|Blob|Iterable | AsyncIterable | ReadableStream} ToContent + * @typedef {ToContent|FileInput} ToFile + * @typedef {Iterable | AsyncIterable | ReadableStream} Source + */ +/** + * @template {AsyncIterable|Blob} Content + * @typedef {Object} File + * @property {string} path + * @property {Mode} [mode] + * @property {MTime} [mtime] + * @property {Content} [content] + */ + +/** + * @template {AsyncIterable|Blob} Content + * @typedef {File|Directory} Entry + */ diff --git a/packages/ipfs-interface/src/index.ts b/packages/ipfs-interface/src/index.ts new file mode 100644 index 0000000000..c9be30e9cc --- /dev/null +++ b/packages/ipfs-interface/src/index.ts @@ -0,0 +1,10 @@ +import { RootAPI } from './root' +import { AbortOptions, Await, AwaitIterable } from './basic' + +export { + RootAPI, + + AbortOptions, + Await, + AwaitIterable +} diff --git a/packages/ipfs-interface/src/preload.ts b/packages/ipfs-interface/src/preload.ts new file mode 100644 index 0000000000..ea62ac506d --- /dev/null +++ b/packages/ipfs-interface/src/preload.ts @@ -0,0 +1,3 @@ +export interface Options { + preload?: boolean +} diff --git a/packages/ipfs-interface/src/root.ts b/packages/ipfs-interface/src/root.ts new file mode 100644 index 0000000000..5cc4dca4e5 --- /dev/null +++ b/packages/ipfs-interface/src/root.ts @@ -0,0 +1,143 @@ +import { AbortOptions } from './basic' +import { Options as PreloadOptions } from './preload' +import { ImportSource, IPFSEntry, ToEntry, UnixFSEntry } from './files' +import CID, { CIDVersion } from 'cids' + +export interface RootAPI { + add: Add + addAll: AddAll + cat: Cat + get: Get +} + +/** + * Import a file or data into IPFS. + */ +export interface Add { + (entry: ToEntry, options?: AddOptions): Promise +} + +export interface AddOptions extends AbortOptions { + /** + * Chunking algorithm used to build ipfs DAGs. (defaults to 'size-262144') + */ + chunker?: string + /** + * The CID version to use when storing the data + */ + cidVersion?: CIDVersion + + /** + * Multihash hashing algorithm to use. (Defaults to 'sha2-256') + */ + hashAlg?: string + + /** + * If true, will not add blocks to the blockstore. (Defaults to `false`) + */ + onlyHash?: boolean + + /** + * Pin this object when adding. (Defaults to `true`) + */ + pin?: boolean + + /** + * A function that will be called with the number of bytes added as a file is + * added to ipfs and the path of the file being added. + * + * **Note** It will not be called for directory entries. + */ + progress?: (bytes: number, path: string) => void + + /** + * If true, DAG leaves will contain raw file data and not be wrapped in a + * protobuf. (Defaults to `false`) + */ + rawLeaves?: boolean + + /** + * 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. (Defaults to `false`). + */ + trickle?: boolean + + /** + * Adds a wrapping node around the content. (Defaults to `false`) + */ + wrapWithDirectory?: boolean + +} + +/** + * Import multiple files and data into IPFS. + */ +export interface AddAll { + (source: ImportSource, options?: AddAllOptions & AbortOptions): AsyncIterable +} + +export interface AddAllOptions extends AddOptions { + + /** + * 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. (Defaults to `false`) + */ + enableShardingExperiment?: boolean + + /** + * Directories with more than this number of files will be created as HAMT - + * sharded directories. (Defaults to 1000) + */ + shardSplitThreshold?: number +} + +export interface ShardingOptions { + sharding?: boolean +} + +/** + * Returns content of the file addressed by a valid IPFS Path or CID. + */ +export interface Cat { + (ipfsPath: IPFSPath, options?:CatOptions): AsyncIterable +} + +export interface CatOptions extends AbortOptions, PreloadOptions { + /** + * An offset to start reading the file from + */ + offset?: number + /** + * An optional max length to read from the file + */ + length?: number +} + +/** + * Fetch a file or an entire directory tree from IPFS that is addressed by a + * valid IPFS Path. + */ +export interface Get { + (ipfsPath: IPFSPath, options?: GetOptions): AsyncIterable +} + +export interface GetOptions extends AbortOptions, PreloadOptions {} + +export interface List { + /** + * Lists a directory from IPFS that is addressed by a valid IPFS Path. + */ + (ipfsPath: IPFSPath, options?: ListOptions): AsyncIterable +} + +export interface ListOptions extends AbortOptions, PreloadOptions { + recursive?: boolean, + includeContent?: boolean +} + +/** + * An IPFS path or CID + */ +export type IPFSPath = CID | string diff --git a/packages/ipfs-interface/tsconfig.json b/packages/ipfs-interface/tsconfig.json new file mode 100644 index 0000000000..f090f172de --- /dev/null +++ b/packages/ipfs-interface/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "noImplicitAny": true + }, + "include": [ + "src" + ] +} diff --git a/packages/ipfs-message-port-client/package.json b/packages/ipfs-message-port-client/package.json index 6319b4d411..af99e59b27 100644 --- a/packages/ipfs-message-port-client/package.json +++ b/packages/ipfs-message-port-client/package.json @@ -43,7 +43,8 @@ }, "dependencies": { "browser-readablestream-to-it": "^1.0.1", - "ipfs-message-port-protocol": "^0.4.2" + "ipfs-message-port-protocol": "^0.4.2", + "ipfs-interface": "^0.1.0" }, "devDependencies": { "aegir": "^29.2.2", diff --git a/packages/ipfs-message-port-client/src/core.js b/packages/ipfs-message-port-client/src/core.js index cddac962a2..deb840973d 100644 --- a/packages/ipfs-message-port-client/src/core.js +++ b/packages/ipfs-message-port-client/src/core.js @@ -161,7 +161,7 @@ class CoreClient extends Client { * Decodes values yield by `ipfs.add`. * * @param {AddedEntry} data - * @returns {import('ipfs-core/src/components/add-all').UnixFSEntry} + * @returns {import('ipfs-interface/src/files').UnixFSEntry} */ const decodeAddedData = ({ path, cid, mode, mtime, size }) => { return { diff --git a/tsconfig.json b/tsconfig.json index a5f6d1a969..79830608ac 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,7 +24,7 @@ "stripInternal": true, "resolveJsonModule": true, "incremental": true, - "baseUrl": "packages", + "baseUrl": ".", "paths": { "interface-ipfs-core/*": [ "interface-ipfs-core/*"