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 20.1 kB
{"version":3,"file":"token.cjs","sources":["../../src/token.js"],"sourcesContent":["import { pack } from 'ipfs-car/pack'\nimport { CID } from 'multiformats/cid'\nimport * as Block from 'multiformats/block'\nimport { sha256 } from 'multiformats/hashes/sha2'\nimport * as dagCbor from '@ipld/dag-cbor'\nimport { Blob, FormData, Blockstore } from './platform.js'\nimport { toGatewayURL, GATEWAY } from './gateway.js'\nimport { BlockstoreCarReader } from './bs-car-reader.js'\n\n/**\n * @typedef {import('./gateway.js').GatewayURLOptions} EmbedOptions\n * @typedef {import('./lib/interface.js').TokenInput} TokenInput\n * @typedef {import('ipfs-car/blockstore').Blockstore} Blockstore\n */\n\n/**\n * @template T\n * @typedef {import('./lib/interface.js').Encoded<T, [[Blob, URL]]>} EncodedBlobUrl\n */\n\n/**\n * @template G\n * @typedef {import('./lib/interface.js').Encoded<G, [[Blob, Blob]]>} EncodedBlobBlob\n */\n\n/**\n * @template {import('./lib/interface.js').TokenInput} T\n * @typedef {import('./lib/interface.js').Token<T>} TokenType\n */\n\n/**\n * @template {TokenInput} T\n * @implements {TokenType<T>}\n */\nexport class Token {\n /**\n * @param {import('./lib/interface.js').CIDString} ipnft\n * @param {import('./lib/interface.js').EncodedURL} url\n * @param {import('./lib/interface.js').Encoded<T, [[Blob, URL]]>} data\n */\n constructor(ipnft, url, data) {\n /** @readonly */\n this.ipnft = ipnft\n /** @readonly */\n this.url = url\n /** @readonly */\n this.data = data\n\n Object.defineProperties(this, {\n ipnft: { enumerable: true, writable: false },\n url: { enumerable: true, writable: false },\n data: { enumerable: false, writable: false },\n })\n }\n /**\n * @returns {import('./lib/interface.js').Encoded<T, [[Blob, URL]]>}\n */\n embed() {\n return Token.embed(this)\n }\n\n /**\n * @template {TokenInput} T\n * @param {{data: import('./lib/interface.js').Encoded<T, [[Blob, URL]]>}} token\n * @returns {import('./lib/interface.js').Encoded<T, [[Blob, URL]]>}\n */\n static embed({ data }) {\n return embed(data, { gateway: GATEWAY })\n }\n\n /**\n * Takes token input, encodes it as a DAG, wraps it in a CAR and creates a new\n * Token instance from it. Where values are discovered `Blob` (or `File`)\n * objects in the given input, they are replaced with IPFS URLs (an `ipfs://`\n * prefixed CID with an optional path).\n *\n * @example\n * ```js\n * const cat = new File(['...'], 'cat.png')\n * const kitty = new File(['...'], 'kitty.png')\n * const { token, car } = await Token.encode({\n * name: 'hello'\n * image: cat\n * properties: {\n * extra: {\n * image: kitty\n * }\n * }\n * })\n * ```\n *\n * @template {TokenInput} T\n * @param {T} input\n * @returns {Promise<{ cid: CID, token: TokenType<T>, car: import('./lib/interface.js').CarReader }>}\n */\n static async encode(input) {\n const blockstore = new Blockstore()\n const [blobs, meta] = mapTokenInputBlobs(input)\n /** @type {EncodedBlobUrl<T>} */\n const data = JSON.parse(JSON.stringify(meta))\n /** @type {import('./lib/interface.js').Encoded<T, [[Blob, CID]]>} */\n const dag = JSON.parse(JSON.stringify(meta))\n\n for (const [dotPath, blob] of blobs.entries()) {\n /** @type {string|undefined} */\n // @ts-ignore blob may be a File!\n const name = blob.name || 'blob'\n /** @type {import('./platform.js').ReadableStream} */\n let content\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 use blob.stream().\n /* c8 ignore next 5 */\n if (parseInt(globalThis.process?.versions?.node) > 18) {\n content = new Uint8Array(await blob.arrayBuffer())\n } else {\n content = blob.stream()\n }\n const { root: cid } = await pack({\n input: [{ path: name, content }],\n blockstore,\n wrapWithDirectory: true,\n })\n\n const href = new URL(`ipfs://${cid}/${name}`)\n const path = dotPath.split('.')\n setIn(data, path, href)\n setIn(dag, path, cid)\n }\n\n const { root: metadataJsonCid } = await pack({\n input: [{ path: 'metadata.json', content: JSON.stringify(data) }],\n blockstore,\n wrapWithDirectory: false,\n })\n\n const block = await Block.encode({\n value: {\n ...dag,\n 'metadata.json': metadataJsonCid,\n type: 'nft',\n },\n codec: dagCbor,\n hasher: sha256,\n })\n await blockstore.put(block.cid, block.bytes)\n\n return {\n cid: block.cid,\n token: new Token(\n block.cid.toString(),\n `ipfs://${block.cid}/metadata.json`,\n data\n ),\n car: new BlockstoreCarReader(1, [block.cid], blockstore),\n }\n }\n}\n\n/**\n * @template T\n * @param {EncodedBlobUrl<T>} input\n * @param {EmbedOptions} options\n * @returns {EncodedBlobUrl<T>}\n */\nexport const embed = (input, options) =>\n mapWith(input, isURL, embedURL, options)\n\n/**\n * @template {TokenInput} T\n * @param {import('./lib/interface.js').EncodedToken<T>} value\n * @param {Set<string>} paths - Paths were to expect EncodedURLs\n * @returns {Token<T>}\n */\nexport const decode = ({ ipnft, url, data }, paths) =>\n new Token(ipnft, url, mapWith(data, isEncodedURL, decodeURL, paths))\n\n/**\n * @param {any} value\n * @returns {value is URL}\n */\nconst isURL = (value) => value instanceof URL\n\n/**\n * @template State\n * @param {State} state\n * @param {import('./lib/interface.js').EncodedURL} url\n * @returns {[State, URL]}\n */\nconst decodeURL = (state, url) => [state, new URL(url)]\n\n/**\n * @param {EmbedOptions} context\n * @param {URL} url\n * @returns {[EmbedOptions, URL]}\n */\nconst embedURL = (context, url) => [context, toGatewayURL(url, context)]\n\n/**\n * @param {any} value\n * @returns {value is object}\n */\nconst isObject = (value) => typeof value === 'object' && value != null\n\n/**\n * @param {any} value\n * @param {Set<string>} assetPaths\n * @param {PropertyKey[]} path\n * @returns {value is import('./lib/interface.js').EncodedURL}\n */\nconst isEncodedURL = (value, assetPaths, path) =>\n typeof value === 'string' && assetPaths.has(path.join('.'))\n\n/**\n * Takes token input and encodes it into\n * [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData)\n * object where form field values are discovered `Blob` (or `File`) objects in\n * the given token and field keys are `.` joined paths where they were discoverd\n * in the token. Additionally encoded `FormData` will also have a field\n * named `meta` containing JSON serialized token with blobs and file values\n * `null` set to null (this allows backend to injest all of the files from\n * `multipart/form-data` request and update provided \"meta\" data with\n * corresponding file ipfs:// URLs)\n *\n * @example\n * ```js\n * const cat = new File([], 'cat.png')\n * const kitty = new File([], 'kitty.png')\n * const form = encode({\n * name: 'hello'\n * image: cat\n * properties: {\n * extra: {\n * image: kitty\n * }\n * }\n * })\n * [...form.entries()] //>\n * // [\n * // ['image', cat],\n * // ['properties.extra.image', kitty],\n * // ['meta', '{\"name\":\"hello\",image:null,\"properties\":{\"extra\":{\"kitty\": null}}}']\n * // ]\n * ```\n *\n * @template {TokenInput} T\n * @param {EncodedBlobBlob<T>} input\n * @returns {FormData}\n */\nexport const encode = (input) => {\n const [map, meta] = mapValueWith(input, isBlob, encodeBlob, new Map(), [])\n const form = new FormData()\n for (const [k, v] of map.entries()) {\n form.set(k, v)\n }\n form.set('meta', JSON.stringify(meta))\n return form\n}\n\n/**\n * @param {Map<string, Blob>} data\n * @param {Blob} blob\n * @param {PropertyKey[]} path\n * @returns {[Map<string, Blob>, void]}\n */\nconst encodeBlob = (data, blob, path) => {\n data.set(path.join('.'), blob)\n return [data, undefined]\n}\n\n/**\n * @param {any} value\n * @returns {value is Blob}\n */\nconst isBlob = (value) => value instanceof Blob\n\n/**\n * @template {TokenInput} T\n * @param {EncodedBlobBlob<T>} input\n */\nconst mapTokenInputBlobs = (input) => {\n return mapValueWith(input, isBlob, encodeBlob, new Map(), [])\n}\n\n/**\n * Substitues values in the given `input` that match `p(value) == true` with\n * `f(value, context, path)` where `context` is whatever you pass (usually\n * a mutable state) and `path` is a array of keys / indexes where the value\n * was encountered.\n *\n * @template T, I, X, O, State\n * @param {import('./lib/interface.js').Encoded<T, [[I, X]]>} input - Arbitrary input.\n * @param {(input:any, state:State, path:PropertyKey[]) => input is X} p - Predicate function to determine\n * which values to swap.\n * @param {(state:State, input:X, path:PropertyKey[]) => [State, O]} f - Function\n * that swaps matching values.\n * @param {State} state - Some additional context you need in the process.\n * likey you'll start with `[]`.\n * @returns {import('./lib/interface.js').Encoded<T, [[I, O]]>}\n */\nexport const mapWith = (input, p, f, state) => {\n const [, output] = mapValueWith(input, p, f, state, [])\n return output\n}\n\n/**\n * @template T, I, X, O, State\n * @param {import('./lib/interface.js').Encoded<T, [[I, X]]>} input - Arbitrary input.\n * @param {(input:any, state:State, path:PropertyKey[]) => input is X} p - Predicate function to determine\n * which values to swap.\n * @param {(state:State, input:X, path:PropertyKey[]) => [State, O]} f - Function\n * that swaps matching values.\n * @param {State} state - Some additional context you need in the process.\n * @param {PropertyKey[]} path - Path where the value was encountered. Most\n * likey you'll start with `[]`.\n * @returns {[State, import('./lib/interface.js').Encoded<T, [[I, O]]>]}\n */\nconst mapValueWith = (input, p, f, state, path) =>\n p(input, state, path)\n ? f(state, input, path)\n : Array.isArray(input)\n ? mapArrayWith(input, p, f, state, path)\n : isObject(input)\n ? mapObjectWith(input, p, f, state, path)\n : [state, /** @type {any} */ (input)]\n\n/**\n * Just like `mapWith` except\n *\n * @template State, T, I, X, O\n * @param {import('./lib/interface.js').Encoded<T, [[I, X]]>} input\n * @param {(input:any, state:State, path:PropertyKey[]) => input is X} p\n * @param {(state: State, input:X, path:PropertyKey[]) => [State, O]} f\n * @param {State} init\n * @param {PropertyKey[]} path\n * @returns {[State, import('./lib/interface.js').Encoded<T, [[I, O]]>]}\n */\nconst mapObjectWith = (input, p, f, init, path) => {\n let state = init\n const output =\n /** @type {import('./lib/interface.js').Encoded<T, [[I, O]]>} */ ({})\n for (const [key, value] of Object.entries(input)) {\n const [next, out] = mapValueWith(value, p, f, state, [...path, key])\n // @ts-ignore\n output[key] = out\n state = next\n }\n return [state, output]\n}\n\n/**\n * Just like `mapWith` except for Arrays.\n *\n * @template I, X, O, State\n * @template {any[]} T\n * @param {T} input\n * @param {(input:any, state:State, path:PropertyKey[]) => input is X} p\n * @param {(state: State, input:X, path:PropertyKey[]) => [State, O]} f\n * @param {State} init\n * @param {PropertyKey[]} path\n * @returns {[State, import('./lib/interface.js').Encoded<T, [[I, O]]>]}\n */\nconst mapArrayWith = (input, p, f, init, path) => {\n const output = /** @type {unknown[]} */ ([])\n\n let state = init\n for (const [index, element] of input.entries()) {\n const [next, out] = mapValueWith(element, p, f, state, [...path, index])\n output[index] = out\n state = next\n }\n\n return [\n state,\n /** @type {import('./lib/interface.js').Encoded<T, [[I, O]]>} */ (output),\n ]\n}\n\n/**\n * Sets a given `value` at the given `path` on a passed `object`.\n *\n * @example\n * ```js\n * const obj = { a: { b: { c: 1 }}}\n * setIn(obj, ['a', 'b', 'c'], 5)\n * obj.a.b.c //> 5\n * ```\n *\n * @template V\n * @param {any} object\n * @param {string[]} path\n * @param {V} value\n */\nconst setIn = (object, path, value) => {\n const n = path.length - 1\n let target = object\n for (let [index, key] of path.entries()) {\n if (index === n) {\n target[key] = value\n } else {\n target = target[key]\n }\n }\n}\n"],"names":["GATEWAY","Blockstore","pack","Block","dagCbor","sha256","BlockstoreCarReader","toGatewayURL","FormData","Blob"],"mappings":"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"}