UNPKG

nft.storage

Version:

A client library for the https://nft.storage/ service. It provides a convenient interface for working with the HTTP API from a web browser or Node.js

1 lines 40.4 kB
{"version":3,"file":"lib.cjs","sources":["../../src/lib.js"],"sourcesContent":["/**\n * A client library for the https://nft.storage/ service. It provides a convenient\n * interface for working with the [Raw HTTP API](https://nft.storage/#api-docs)\n * from a web browser or [Node.js](https://nodejs.org/) and comes bundled with\n * TS for out-of-the box type inference and better IntelliSense.\n *\n * @example\n * ```js\n * import { NFTStorage, File, Blob } from \"nft.storage\"\n * const client = new NFTStorage({ token: API_TOKEN })\n *\n * const cid = await client.storeBlob(new Blob(['hello world']))\n * ```\n * @module\n */\n\nimport { transform } from 'streaming-iterables'\nimport pRetry, { AbortError } from 'p-retry'\nimport { TreewalkCarSplitter } from 'carbites/treewalk'\nimport { pack } from 'ipfs-car/pack'\nimport { CID } from 'multiformats/cid'\nimport throttledQueue from 'throttled-queue'\nimport * as Token from './token.js'\nimport { fetch, File, Blob, FormData, Blockstore } from './platform.js'\nimport { toGatewayURL } from './gateway.js'\nimport { BlockstoreCarReader } from './bs-car-reader.js'\nimport pipe from 'it-pipe'\n\nconst MAX_STORE_RETRIES = 5\nconst MAX_CONCURRENT_UPLOADS = 3\nconst MAX_CHUNK_SIZE = 1024 * 1024 * 50 // chunk to ~50MB CARs\nconst RATE_LIMIT_REQUESTS = 30\nconst RATE_LIMIT_PERIOD = 10 * 1000\n\n/**\n * @typedef {import('./lib/interface.js').Service} Service\n * @typedef {import('./lib/interface.js').CIDString} CIDString\n * @typedef {import('./lib/interface.js').Deal} Deal\n * @typedef {import('./lib/interface.js').FileObject} FileObject\n * @typedef {import('./lib/interface.js').FilesSource} FilesSource\n * @typedef {import('./lib/interface.js').Pin} Pin\n * @typedef {import('./lib/interface.js').CarReader} CarReader\n * @typedef {import('ipfs-car/blockstore').Blockstore} BlockstoreI\n * @typedef {import('./lib/interface.js').RateLimiter} RateLimiter\n * @typedef {import('./lib/interface.js').RequestOptions} RequestOptions\n */\n\n/**\n * @returns {RateLimiter}\n */\nexport function createRateLimiter() {\n const throttle = throttledQueue(RATE_LIMIT_REQUESTS, RATE_LIMIT_PERIOD)\n return () => throttle(() => {})\n}\n\n/**\n * Rate limiter used by static API if no rate limiter is passed. Note that each\n * instance of the NFTStorage class gets it's own limiter if none is passed.\n * This is because rate limits are enforced per API token.\n */\nconst globalRateLimiter = createRateLimiter()\n\n/**\n * @template {import('./lib/interface.js').TokenInput} T\n * @typedef {import('./lib/interface.js').Token<T>} TokenType\n */\n\n/**\n * @implements {Service}\n */\nclass NFTStorage {\n /**\n * Constructs a client bound to the given `options.token` and\n * `options.endpoint`.\n *\n * @example\n * ```js\n * import { NFTStorage, File, Blob } from \"nft.storage\"\n * const client = new NFTStorage({ token: API_TOKEN })\n *\n * const cid = await client.storeBlob(new Blob(['hello world']))\n * ```\n * Optionally you could pass an alternative API endpoint (e.g. for testing)\n * @example\n * ```js\n * import { NFTStorage } from \"nft.storage\"\n * const client = new NFTStorage({\n * token: API_TOKEN\n * endpoint: new URL('http://localhost:8080/')\n * })\n * ```\n *\n * @param {{token: string, endpoint?: URL, rateLimiter?: RateLimiter, did?: string}} options\n */\n constructor({\n token,\n did,\n endpoint = new URL('https://api.nft.storage'),\n rateLimiter,\n }) {\n /**\n * Authorization token.\n *\n * @readonly\n */\n this.token = token\n /**\n * Service API endpoint `URL`.\n * @readonly\n */\n this.endpoint = endpoint\n /**\n * @readonly\n */\n this.rateLimiter = rateLimiter || createRateLimiter()\n\n /**\n * @readonly\n */\n this.did = did\n }\n\n /**\n * @hidden\n * @param {object} options\n * @param {string} options.token\n * @param {string} [options.did]\n */\n static auth({ token, did }) {\n if (!token) throw new Error('missing token')\n return {\n Authorization: `Bearer ${token}`,\n 'X-Client': 'nft.storage/js',\n ...(did ? { 'x-agent-did': did } : {}),\n }\n }\n\n /**\n * Stores a single file and returns its CID.\n *\n * @param {Service} service\n * @param {Blob} blob\n * @param {RequestOptions} [options]\n * @returns {Promise<CIDString>}\n */\n static async storeBlob(service, blob, options) {\n const blockstore = new Blockstore()\n let cidString\n\n try {\n const { cid, car } = await NFTStorage.encodeBlob(blob, { blockstore })\n await NFTStorage.storeCar(service, car, options)\n cidString = cid.toString()\n } finally {\n await blockstore.close()\n }\n\n return cidString\n }\n\n /**\n * Stores a CAR file and returns its root CID.\n *\n * @param {Service} service\n * @param {Blob|CarReader} car\n * @param {import('./lib/interface.js').CarStorerOptions} [options]\n * @returns {Promise<CIDString>}\n */\n static async storeCar(\n { endpoint, rateLimiter = globalRateLimiter, ...token },\n car,\n { onStoredChunk, maxRetries, maxChunkSize, decoders, signal } = {}\n ) {\n const url = new URL('upload/', endpoint)\n const headers = {\n ...NFTStorage.auth(token),\n 'Content-Type': 'application/car',\n }\n const targetSize = maxChunkSize || MAX_CHUNK_SIZE\n const splitter =\n car instanceof Blob\n ? await TreewalkCarSplitter.fromBlob(car, targetSize, { decoders })\n : new TreewalkCarSplitter(car, targetSize, { decoders })\n\n const upload = transform(\n MAX_CONCURRENT_UPLOADS,\n async function (/** @type {AsyncIterable<Uint8Array>} */ car) {\n const carParts = []\n for await (const part of car) {\n carParts.push(part)\n }\n const carFile = new Blob(carParts, { type: 'application/car' })\n /** @type {Blob|ArrayBuffer} */\n let body = carFile\n // FIXME: should not be necessary to await arrayBuffer()!\n // Node.js 20 hangs reading the stream (it never ends) but in\n // older node versions and the browser it is fine to pass a blob.\n /* c8 ignore next 3 */\n if (parseInt(globalThis.process?.versions?.node) > 18) {\n body = await body.arrayBuffer()\n }\n const cid = await pRetry(\n async () => {\n await rateLimiter()\n /** @type {Response} */\n let response\n try {\n response = await fetch(url.toString(), {\n method: 'POST',\n headers,\n body,\n signal,\n })\n } catch (/** @type {any} */ err) {\n // TODO: remove me and test when client accepts custom fetch impl\n /* c8 ignore next 1 */\n throw signal && signal.aborted ? new AbortError(err) : err\n }\n /* c8 ignore next 3 */\n if (response.status === 429) {\n throw new Error('rate limited')\n }\n const result = await response.json()\n if (!result.ok) {\n // do not retry if unauthorized - will not succeed\n if (response.status === 401) {\n throw new AbortError(result.error.message)\n }\n throw new Error(result.error.message)\n }\n return result.value.cid\n },\n {\n retries: maxRetries == null ? MAX_STORE_RETRIES : maxRetries,\n }\n )\n onStoredChunk && onStoredChunk(carFile.size)\n return cid\n }\n )\n\n let root\n for await (const cid of upload(splitter.cars())) {\n root = cid\n }\n\n return /** @type {CIDString} */ (root)\n }\n\n /**\n * Stores a directory of files and returns a CID. Provided files **MUST**\n * be within the same directory, otherwise error is raised e.g. `foo/bar.png`,\n * `foo/bla/baz.json` is ok but `foo/bar.png`, `bla/baz.json` is not.\n *\n * @param {Service} service\n * @param {FilesSource} filesSource\n * @param {RequestOptions} [options]\n * @returns {Promise<CIDString>}\n */\n static async storeDirectory(service, filesSource, options) {\n const blockstore = new Blockstore()\n let cidString\n try {\n const { cid, car } = await NFTStorage.encodeDirectory(filesSource, {\n blockstore,\n })\n await NFTStorage.storeCar(service, car, options)\n cidString = cid.toString()\n } finally {\n await blockstore.close()\n }\n\n return cidString\n }\n\n /**\n * Stores the given token and all resources it references (in the form of a\n * File or a Blob) along with a metadata JSON as specificed in ERC-1155. The\n * `token.image` must be either a `File` or a `Blob` instance, which will be\n * stored and the corresponding content address URL will be saved in the\n * metadata JSON file under `image` field.\n *\n * If `token.properties` contains properties with `File` or `Blob` values,\n * those also get stored and their URLs will be saved in the metadata JSON\n * file in their place.\n *\n * Note: URLs for `File` objects will retain file names e.g. in case of\n * `new File([bytes], 'cat.png', { type: 'image/png' })` will be transformed\n * into a URL that looks like `ipfs://bafy...hash/image/cat.png`. For `Blob`\n * objects, the URL will not have a file name name or mime type, instead it\n * will be transformed into a URL that looks like\n * `ipfs://bafy...hash/image/blob`.\n *\n * @template {import('./lib/interface.js').TokenInput} T\n * @param {Service} service\n * @param {T} metadata\n * @param {RequestOptions} [options]\n * @returns {Promise<TokenType<T>>}\n */\n static async store(service, metadata, options) {\n const { token, car } = await NFTStorage.encodeNFT(metadata)\n await NFTStorage.storeCar(service, car, options)\n return token\n }\n\n /**\n * Returns current status of the stored NFT by its CID. Note the NFT must\n * have previously been stored by this account.\n *\n * @param {Service} service\n * @param {string} cid\n * @param {RequestOptions} [options]\n * @returns {Promise<import('./lib/interface.js').StatusResult>}\n */\n static async status(\n { endpoint, rateLimiter = globalRateLimiter, ...token },\n cid,\n options\n ) {\n const url = new URL(`${cid}/`, endpoint)\n await rateLimiter()\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: NFTStorage.auth(token),\n signal: options && options.signal,\n })\n /* c8 ignore next 3 */\n if (response.status === 429) {\n throw new Error('rate limited')\n }\n const result = await response.json()\n\n if (result.ok) {\n return {\n cid: result.value.cid,\n deals: decodeDeals(result.value.deals),\n size: result.value.size,\n pin: decodePin(result.value.pin),\n created: new Date(result.value.created),\n }\n } else {\n throw new Error(result.error.message)\n }\n }\n\n /**\n * Check if a CID of an NFT is being stored by NFT.Storage.\n *\n * @param {import('./lib/interface.js').PublicService} service\n * @param {string} cid\n * @param {RequestOptions} [options]\n * @returns {Promise<import('./lib/interface.js').CheckResult>}\n */\n static async check(\n { endpoint, rateLimiter = globalRateLimiter },\n cid,\n options\n ) {\n const url = new URL(`check/${cid}/`, endpoint)\n await rateLimiter()\n const response = await fetch(url.toString(), {\n signal: options && options.signal,\n })\n /* c8 ignore next 3 */\n if (response.status === 429) {\n throw new Error('rate limited')\n }\n const result = await response.json()\n\n if (result.ok) {\n return {\n cid: result.value.cid,\n deals: decodeDeals(result.value.deals),\n pin: result.value.pin,\n }\n } else {\n throw new Error(result.error.message)\n }\n }\n\n /**\n * Removes stored content by its CID from this account. Please note that\n * even if content is removed from the service other nodes that have\n * replicated it might still continue providing it.\n *\n * @param {Service} service\n * @param {string} cid\n * @param {RequestOptions} [options]\n * @returns {Promise<void>}\n */\n static async delete(\n { endpoint, rateLimiter = globalRateLimiter, ...token },\n cid,\n options\n ) {\n const url = new URL(`${cid}/`, endpoint)\n await rateLimiter()\n const response = await fetch(url.toString(), {\n method: 'DELETE',\n headers: NFTStorage.auth(token),\n signal: options && options.signal,\n })\n /* c8 ignore next 3 */\n if (response.status === 429) {\n throw new Error('rate limited')\n }\n const result = await response.json()\n if (!result.ok) {\n throw new Error(result.error.message)\n }\n }\n\n /**\n * Encodes the given token and all resources it references (in the form of a\n * File or a Blob) along with a metadata JSON as specificed in ERC-1155 to a\n * CAR file. The `token.image` must be either a `File` or a `Blob` instance,\n * which will be stored and the corresponding content address URL will be\n * saved in the metadata JSON file under `image` field.\n *\n * If `token.properties` contains properties with `File` or `Blob` values,\n * those also get stored and their URLs will be saved in the metadata JSON\n * file in their place.\n *\n * Note: URLs for `File` objects will retain file names e.g. in case of\n * `new File([bytes], 'cat.png', { type: 'image/png' })` will be transformed\n * into a URL that looks like `ipfs://bafy...hash/image/cat.png`. For `Blob`\n * objects, the URL will not have a file name name or mime type, instead it\n * will be transformed into a URL that looks like\n * `ipfs://bafy...hash/image/blob`.\n *\n * @example\n * ```js\n * const { token, car } = await NFTStorage.encodeNFT({\n * name: 'nft.storage store test',\n * description: 'Test ERC-1155 compatible metadata.',\n * image: new File(['<DATA>'], 'pinpie.jpg', { type: 'image/jpg' }),\n * properties: {\n * custom: 'Custom data can appear here, files are auto uploaded.',\n * file: new File(['<DATA>'], 'README.md', { type: 'text/plain' }),\n * }\n * })\n *\n * console.log('IPFS URL for the metadata:', token.url)\n * console.log('metadata.json contents:\\n', token.data)\n * console.log('metadata.json with IPFS gateway URLs:\\n', token.embed())\n *\n * // Now store the CAR file on NFT.Storage\n * await client.storeCar(car)\n * ```\n *\n * @template {import('./lib/interface.js').TokenInput} T\n * @param {T} input\n * @returns {Promise<{ cid: CID, token: TokenType<T>, car: CarReader }>}\n */\n static async encodeNFT(input) {\n validateERC1155(input)\n return Token.Token.encode(input)\n }\n\n /**\n * Encodes a single file to a CAR file and also returns its root CID.\n *\n * @example\n * ```js\n * const content = new Blob(['hello world'])\n * const { cid, car } = await NFTStorage.encodeBlob(content)\n *\n * // Root CID of the file\n * console.log(cid.toString())\n *\n * // Now store the CAR file on NFT.Storage\n * await client.storeCar(car)\n * ```\n *\n * @param {Blob} blob\n * @param {object} [options]\n * @param {BlockstoreI} [options.blockstore]\n * @returns {Promise<{ cid: CID, car: CarReader }>}\n */\n static async encodeBlob(blob, { blockstore } = {}) {\n if (blob.size === 0) {\n throw new Error('Content size is 0, make sure to provide some content')\n }\n return packCar([toImportCandidate('blob', blob)], {\n blockstore,\n wrapWithDirectory: false,\n })\n }\n\n /**\n * Encodes a directory of files to a CAR file and also returns the root CID.\n * Provided files **MUST** be within the same directory, otherwise error is\n * raised e.g. `foo/bar.png`, `foo/bla/baz.json` is ok but `foo/bar.png`,\n * `bla/baz.json` is not.\n *\n * @example\n * ```js\n * const { cid, car } = await NFTStorage.encodeDirectory([\n * new File(['hello world'], 'hello.txt'),\n * new File([JSON.stringify({'from': 'incognito'}, null, 2)], 'metadata.json')\n * ])\n *\n * // Root CID of the directory\n * console.log(cid.toString())\n *\n * // Now store the CAR file on NFT.Storage\n * await client.storeCar(car)\n * ```\n *\n * @param {FilesSource} files\n * @param {object} [options]\n * @param {BlockstoreI} [options.blockstore]\n * @returns {Promise<{ cid: CID, car: CarReader }>}\n */\n static async encodeDirectory(files, { blockstore } = {}) {\n let size = 0\n const input = pipe(files, async function* (files) {\n for await (const file of files) {\n yield toImportCandidate(file.name, file)\n size += file.size\n }\n })\n const packed = await packCar(input, {\n blockstore,\n wrapWithDirectory: true,\n })\n if (size === 0) {\n throw new Error(\n 'Total size of files should exceed 0, make sure to provide some content'\n )\n }\n return packed\n }\n\n // Just a sugar so you don't have to pass around endpoint and token around.\n\n /**\n * Stores a single file and returns the corresponding Content Identifier (CID).\n * Takes a [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob)\n * or a [File](https://developer.mozilla.org/en-US/docs/Web/API/File). Note\n * that no file name or file metadata is retained.\n *\n * @example\n * ```js\n * const content = new Blob(['hello world'])\n * const cid = await client.storeBlob(content)\n * cid //> 'zdj7Wn9FQAURCP6MbwcWuzi7u65kAsXCdjNTkhbJcoaXBusq9'\n * ```\n *\n * @param {Blob} blob\n * @param {RequestOptions} [options]\n */\n storeBlob(blob, options) {\n return NFTStorage.storeBlob(this, blob, options)\n }\n\n /**\n * Stores files encoded as a single [Content Addressed Archive\n * (CAR)](https://github.com/ipld/specs/blob/master/block-layer/content-addressable-archives.md).\n *\n * Takes a [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob)\n * or a [File](https://developer.mozilla.org/en-US/docs/Web/API/File).\n *\n * Returns the corresponding Content Identifier (CID).\n *\n * See the [`ipfs-car` docs](https://www.npmjs.com/package/ipfs-car) for more\n * details on packing a CAR file.\n *\n * @example\n * ```js\n * import { pack } from 'ipfs-car/pack'\n * import { CarReader } from '@ipld/car'\n * const { out, root } = await pack({\n * input: fs.createReadStream('pinpie.pdf')\n * })\n * const expectedCid = root.toString()\n * const carReader = await CarReader.fromIterable(out)\n * const cid = await storage.storeCar(carReader)\n * console.assert(cid === expectedCid)\n * ```\n *\n * @example\n * ```\n * import { packToBlob } from 'ipfs-car/pack/blob'\n * const data = 'Hello world'\n * const { root, car } = await packToBlob({ input: [new TextEncoder().encode(data)] })\n * const expectedCid = root.toString()\n * const cid = await client.storeCar(car)\n * console.assert(cid === expectedCid)\n * ```\n * @param {Blob|CarReader} car\n * @param {import('./lib/interface.js').CarStorerOptions} [options]\n */\n storeCar(car, options) {\n return NFTStorage.storeCar(this, car, options)\n }\n\n /**\n * Stores a directory of files and returns a CID for the directory.\n *\n * @example\n * ```js\n * const cid = await client.storeDirectory([\n * new File(['hello world'], 'hello.txt'),\n * new File([JSON.stringify({'from': 'incognito'}, null, 2)], 'metadata.json')\n * ])\n * cid //>\n * ```\n *\n * Argument can be a [FileList](https://developer.mozilla.org/en-US/docs/Web/API/FileList)\n * instance as well, in which case directory structure will be retained.\n *\n * @param {FilesSource} files\n * @param {RequestOptions} [options]\n */\n storeDirectory(files, options) {\n return NFTStorage.storeDirectory(this, files, options)\n }\n\n /**\n * Returns current status of the stored NFT by its CID. Note the NFT must\n * have previously been stored by this account.\n *\n * @example\n * ```js\n * const status = await client.status('zdj7Wn9FQAURCP6MbwcWuzi7u65kAsXCdjNTkhbJcoaXBusq9')\n * ```\n *\n * @param {string} cid\n * @param {RequestOptions} [options]\n */\n status(cid, options) {\n return NFTStorage.status(this, cid, options)\n }\n\n /**\n * Removes stored content by its CID from the service.\n *\n * > Please note that even if content is removed from the service other nodes\n * that have replicated it might still continue providing it.\n *\n * @example\n * ```js\n * await client.delete('zdj7Wn9FQAURCP6MbwcWuzi7u65kAsXCdjNTkhbJcoaXBusq9')\n * ```\n *\n * @param {string} cid\n * @param {RequestOptions} [options]\n */\n delete(cid, options) {\n return NFTStorage.delete(this, cid, options)\n }\n\n /**\n * Check if a CID of an NFT is being stored by nft.storage. Throws if the NFT\n * was not found.\n *\n * @example\n * ```js\n * const status = await client.check('zdj7Wn9FQAURCP6MbwcWuzi7u65kAsXCdjNTkhbJcoaXBusq9')\n * ```\n *\n * @param {string} cid\n * @param {RequestOptions} [options]\n */\n check(cid, options) {\n return NFTStorage.check(this, cid, options)\n }\n\n /**\n * Stores the given token and all resources it references (in the form of a\n * File or a Blob) along with a metadata JSON as specificed in\n * [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155#metadata). The\n * `token.image` must be either a `File` or a `Blob` instance, which will be\n * stored and the corresponding content address URL will be saved in the\n * metadata JSON file under `image` field.\n *\n * If `token.properties` contains properties with `File` or `Blob` values,\n * those also get stored and their URLs will be saved in the metadata JSON\n * file in their place.\n *\n * Note: URLs for `File` objects will retain file names e.g. in case of\n * `new File([bytes], 'cat.png', { type: 'image/png' })` will be transformed\n * into a URL that looks like `ipfs://bafy...hash/image/cat.png`. For `Blob`\n * objects, the URL will not have a file name name or mime type, instead it\n * will be transformed into a URL that looks like\n * `ipfs://bafy...hash/image/blob`.\n *\n * @example\n * ```js\n * const metadata = await client.store({\n * name: 'nft.storage store test',\n * description: 'Test ERC-1155 compatible metadata.',\n * image: new File(['<DATA>'], 'pinpie.jpg', { type: 'image/jpg' }),\n * properties: {\n * custom: 'Custom data can appear here, files are auto uploaded.',\n * file: new File(['<DATA>'], 'README.md', { type: 'text/plain' }),\n * }\n * })\n *\n * console.log('IPFS URL for the metadata:', metadata.url)\n * console.log('metadata.json contents:\\n', metadata.data)\n * console.log('metadata.json with IPFS gateway URLs:\\n', metadata.embed())\n * ```\n *\n * @template {import('./lib/interface.js').TokenInput} T\n * @param {T} token\n * @param {RequestOptions} [options]\n */\n store(token, options) {\n return NFTStorage.store(this, token, options)\n }\n}\n\n/**\n * Cast an iterable to an asyncIterable\n * @template T\n * @param {Iterable<T>} iterable\n * @returns {AsyncIterable<T>}\n */\nexport function toAsyncIterable(iterable) {\n return (async function* () {\n for (const item of iterable) {\n yield item\n }\n })()\n}\n\n/**\n * @template {import('./lib/interface.js').TokenInput} T\n * @param {T} metadata\n */\nconst validateERC1155 = ({ name, description, image, decimals }) => {\n // Just validate that expected fields are present\n if (typeof name !== 'string') {\n throw new TypeError(\n 'string property `name` identifying the asset is required'\n )\n }\n if (typeof description !== 'string') {\n throw new TypeError(\n 'string property `description` describing asset is required'\n )\n }\n if (!(image instanceof Blob)) {\n throw new TypeError('property `image` must be a Blob or File object')\n } else if (!image.type.startsWith('image/')) {\n console.warn(`According to ERC721 Metadata JSON Schema 'image' must have 'image/*' mime type.\n\nFor better interoperability we would highly recommend storing content with different mime type under 'properties' namespace e.g. \\`properties: { video: file }\\` and using 'image' field for storing a preview image for it instead.\n\nFor more context please see ERC-721 specification https://eips.ethereum.org/EIPS/eip-721`)\n }\n\n if (typeof decimals !== 'undefined' && typeof decimals !== 'number') {\n throw new TypeError('property `decimals` must be an integer value')\n }\n}\n\n/**\n * @param {import('ipfs-car/pack').ImportCandidateStream|Array<{ path: string, content: import('./platform.js').ReadableStream }>} input\n * @param {object} [options]\n * @param {BlockstoreI} [options.blockstore]\n * @param {boolean} [options.wrapWithDirectory]\n */\nconst packCar = async (input, { blockstore, wrapWithDirectory } = {}) => {\n /* c8 ignore next 1 */\n blockstore = blockstore || new Blockstore()\n const { root: cid } = await pack({ input, blockstore, wrapWithDirectory })\n const car = new BlockstoreCarReader(1, [cid], blockstore)\n return { cid, car }\n}\n\n/**\n * @param {Deal[]} deals\n * @returns {Deal[]}\n */\nconst decodeDeals = (deals) =>\n deals.map((deal) => {\n const { dealActivation, dealExpiration, lastChanged } = {\n dealExpiration: null,\n dealActivation: null,\n ...deal,\n }\n\n return {\n ...deal,\n lastChanged: new Date(lastChanged),\n ...(dealActivation && { dealActivation: new Date(dealActivation) }),\n ...(dealExpiration && { dealExpiration: new Date(dealExpiration) }),\n }\n })\n\n/**\n * @param {Pin} pin\n * @returns {Pin}\n */\nconst decodePin = (pin) => ({ ...pin, created: new Date(pin.created) })\n\n/**\n * Convert the passed blob to an \"import candidate\" - an object suitable for\n * passing to the ipfs-unixfs-importer. Note: content is an accessor so that\n * the stream is created only when needed.\n *\n * @param {string} path\n * @param {Pick<Blob, 'stream'>|{ stream: () => AsyncIterable<Uint8Array> }} blob\n * @returns {import('ipfs-core-types/src/utils.js').ImportCandidate}\n */\nfunction toImportCandidate(path, blob) {\n /** @type {AsyncIterable<Uint8Array>} */\n let stream\n return {\n path,\n get content() {\n stream = stream || blob.stream()\n return stream\n },\n }\n}\n\nexport { NFTStorage, File, Blob, FormData, toGatewayURL, Token }\n"],"names":["throttledQueue","Blockstore","Blob","TreewalkCarSplitter","transform","pRetry","fetch","AbortError","Token.Token","pipe","pack","BlockstoreCarReader"],"mappings":"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A;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE;AACzB,IAAI,OAAO,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC;AAClD,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE;AACjC,IAAI,OAAO,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC;AAC1D,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE;AACvB,IAAI,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC;AAChD,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE;AACvB,IAAI,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC;AAChD,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE;AACtB,IAAI,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC;AAC/C,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC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"}