nftstorage.link
Version:
Utilities for working with the NFT.Storage IPFS Edge Gateway
1 lines • 7.4 kB
Source Map (JSON)
{"version":3,"file":"gateway.cjs","sources":["../../src/gateway.js"],"sourcesContent":["const API_URL = 'https://api.nftstoragestatus.com'\nconst MAX_AGE = 60000\nconst GATEWAY_URL = 'https://nftstorage.link'\nconst FALLBACK_GATEWAY_URL = 'https://dweb.link'\n\n/**\n * @typedef {Object} IGatewayStatusChecker Checks the status of an IPFS gateway.\n * @property {URL} gatewayURL Base URL of the IPFS gateway status is being checked for.\n * @property {() => Promise<boolean>} ok Determines if the status of the gateway is OK or not.\n */\n\n/**\n * Check the status of a gateway and cache the result for a period of time.\n * @implements {IGatewayStatusChecker}\n */\nexport class GatewayStatusChecker {\n /**\n * @param {Object} [config]\n * @param {string|URL} [config.apiURL] Gateway status API URL.\n * @param {string|URL} [config.gatewayURL] Base URL of the IPFS gateway status is being checked for.\n * @param {number} [config.maxAge] Time in ms after which a status value is stale.\n * @param {globalThis.fetch} [config.fetch] Custom fetch API implementation.\n */\n constructor(config) {\n config = config || {}\n /** @private */\n this._apiURL = config.apiURL || API_URL\n /** @private */\n this._gatewayURL = new URL(config.gatewayURL || GATEWAY_URL)\n /** @private */\n this._maxAge = config.maxAge || MAX_AGE\n /** @private */\n this._fetch = config.fetch\n /* c8 ignore next 3 */\n if (!this._fetch && globalThis.fetch) {\n this._fetch = globalThis.fetch.bind(globalThis)\n }\n /** @private */\n this._lastCheck = 0\n /**\n * @type {Promise<boolean>|null}\n * @private\n */\n this._request = null\n }\n\n get gatewayURL() {\n return this._gatewayURL\n }\n\n /**\n * Determine if the status of the gateway is OK or not.\n */\n ok() {\n const now = Date.now()\n if (!this._request || now - this._lastCheck > this._maxAge) {\n this._request = (async () => {\n this._lastCheck = now\n try {\n const fetch = this._fetch\n /* c8 ignore next 1 */\n if (!fetch) throw new Error('missing fetch implementation')\n const res = await fetch(this._apiURL.toString())\n const data = await res.json()\n return data.status === 'ok'\n } catch (err) {\n console.warn('Failed to fetch gateway status:', err)\n return false\n }\n })()\n }\n return this._request\n }\n}\n\nconst defaultStatusChecker = new GatewayStatusChecker()\n\n/**\n * Get a gateway URL, given a CID, CID+path, IPFS path or an IPFS gateway URL.\n * If the status of the nftstorage.link gateway is known to be good (according\n * to the status checker) then return a URL that uses nftstorage.link, otherwise\n * return an URL that uses dweb.link (or the optional passed fallback gateway\n * URL).\n *\n * @param {string|URL} cidPath\n * @param {Object} [options]\n * @param {IGatewayStatusChecker} [options.statusChecker]\n * @param {string|URL} [options.fallbackGatewayURL]\n */\nexport async function getGatewayURL(cidPath, options) {\n /* c8 ignore next 2 */\n options = options || {}\n const statusChecker = options.statusChecker || defaultStatusChecker\n const fallbackGatewayURL = options.fallbackGatewayURL || FALLBACK_GATEWAY_URL\n const isOk = await statusChecker.ok()\n let { protocol, hostname, pathname, search, hash } = new URL(\n cidPath,\n statusChecker.gatewayURL\n )\n if (protocol === 'ipfs:' || protocol === 'ipns:') {\n // differences in parsing behaviour between Node.js and Chrome URL:\n // in one impl, hostname is 'bafyrei...', pathname is '/path' and in the\n // other, hostname is '', pathname is '//bafyrei.../path'.\n /* c8 ignore next 1 */\n pathname = hostname ? `/${hostname}${pathname}` : pathname.slice(1)\n pathname = `/${protocol.slice(0, -1)}${pathname}`\n } else if (!pathname.startsWith('/ipfs') && !pathname.startsWith('/ipns')) {\n const hostParts = hostname.split('.') // subdomain gateway URL?\n pathname =\n hostParts[1] === 'ipfs' || hostParts[1] === 'ipns'\n ? `/${hostParts[1]}/${hostParts[0]}${pathname === '/' ? '' : pathname}`\n : `/ipfs${pathname}`\n }\n const base = isOk ? statusChecker.gatewayURL : fallbackGatewayURL\n return new URL(`${pathname}${search}${hash}`, base)\n}\n"],"names":[],"mappings":"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"}