UNPKG

ipfs-http-client

Version:
150 lines (143 loc) 5.1 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var multiaddr = require('multiaddr'); var env_js = require('ipfs-utils/src/env.js'); var parseDuration = require('parse-duration'); var debug = require('debug'); var HTTP = require('ipfs-utils/src/http.js'); var mergeOpts = require('merge-options'); var toUrlString = require('ipfs-core-utils/to-url-string'); var getAgent = require('ipfs-core-utils/agent'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var parseDuration__default = /*#__PURE__*/_interopDefaultLegacy(parseDuration); var debug__default = /*#__PURE__*/_interopDefaultLegacy(debug); var HTTP__default = /*#__PURE__*/_interopDefaultLegacy(HTTP); var mergeOpts__default = /*#__PURE__*/_interopDefaultLegacy(mergeOpts); var getAgent__default = /*#__PURE__*/_interopDefaultLegacy(getAgent); const log = debug__default["default"]('ipfs-http-client:lib:error-handler'); const merge = mergeOpts__default["default"].bind({ ignoreUndefined: true }); const DEFAULT_PROTOCOL = env_js.isBrowser || env_js.isWebWorker ? location.protocol : 'http'; const DEFAULT_HOST = env_js.isBrowser || env_js.isWebWorker ? location.hostname : 'localhost'; const DEFAULT_PORT = env_js.isBrowser || env_js.isWebWorker ? location.port : '5001'; const normalizeOptions = (options = {}) => { let url; let opts = {}; let agent; if (typeof options === 'string' || multiaddr.Multiaddr.isMultiaddr(options)) { url = new URL(toUrlString.toUrlString(options)); } else if (options instanceof URL) { url = options; } else if (typeof options.url === 'string' || multiaddr.Multiaddr.isMultiaddr(options.url)) { url = new URL(toUrlString.toUrlString(options.url)); opts = options; } else if (options.url instanceof URL) { url = options.url; opts = options; } else { opts = options || {}; const protocol = (opts.protocol || DEFAULT_PROTOCOL).replace(':', ''); const host = (opts.host || DEFAULT_HOST).split(':')[0]; const port = opts.port || DEFAULT_PORT; url = new URL(`${ protocol }://${ host }:${ port }`); } if (opts.apiPath) { url.pathname = opts.apiPath; } else if (url.pathname === '/' || url.pathname === undefined) { url.pathname = 'api/v0'; } if (env_js.isNode) { const Agent = getAgent__default["default"](url); agent = opts.agent || new Agent({ keepAlive: true, maxSockets: 6 }); } return { ...opts, host: url.host, protocol: url.protocol.replace(':', ''), port: Number(url.port), apiPath: url.pathname, url, agent }; }; const errorHandler = async response => { let msg; try { if ((response.headers.get('Content-Type') || '').startsWith('application/json')) { const data = await response.json(); log(data); msg = data.Message || data.message; } else { msg = await response.text(); } } catch (err) { log('Failed to parse error response', err); msg = err.message; } let error = new HTTP__default["default"].HTTPError(response); if (msg) { if (msg.includes('deadline has elapsed')) { error = new HTTP__default["default"].TimeoutError(); } if (msg && msg.includes('context deadline exceeded')) { error = new HTTP__default["default"].TimeoutError(); } } if (msg && msg.includes('request timed out')) { error = new HTTP__default["default"].TimeoutError(); } if (msg) { error.message = msg; } throw error; }; const KEBAB_REGEX = /[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g; const kebabCase = str => { return str.replace(KEBAB_REGEX, function (match) { return '-' + match.toLowerCase(); }); }; const parseTimeout = value => { return typeof value === 'string' ? parseDuration__default["default"](value) : value; }; class Client extends HTTP__default["default"] { constructor(options = {}) { const opts = normalizeOptions(options); super({ timeout: parseTimeout(opts.timeout || 0) || undefined, headers: opts.headers, base: `${ opts.url }`, handleError: errorHandler, transformSearchParams: search => { const out = new URLSearchParams(); for (const [key, value] of search) { if (value !== 'undefined' && value !== 'null' && key !== 'signal') { out.append(kebabCase(key), value); } if (key === 'timeout' && !isNaN(value)) { out.append(kebabCase(key), value); } } return out; }, agent: opts.agent }); delete this.get; delete this.put; delete this.delete; delete this.options; const fetch = this.fetch; this.fetch = (resource, options = {}) => { if (typeof resource === 'string' && !resource.startsWith('/')) { resource = `${ opts.url }/${ resource }`; } return fetch.call(this, resource, merge(options, { method: 'POST' })); }; } } const HTTPError = HTTP__default["default"].HTTPError; exports.Client = Client; exports.HTTPError = HTTPError; exports.errorHandler = errorHandler;