UNPKG

@helia/verified-fetch

Version:

A fetch-like API for obtaining verified & trustless IPFS content on the web

176 lines 5.44 kB
function setField(response, name, value) { Object.defineProperty(response, name, { enumerable: true, configurable: false, set: () => { }, get: () => value }); } function setType(response, value) { setField(response, 'type', value); } function setUrl(response, value) { setField(response, 'url', value); } function setRedirected(response) { setField(response, 'redirected', true); } export function okResponse(url, body, init) { const response = new Response(body, { ...(init ?? {}), status: 200, statusText: 'OK' }); if (init?.redirected === true) { setRedirected(response); } setType(response, 'basic'); setUrl(response, url); return response; } export function badGatewayResponse(url, body, init) { const response = new Response(body, { ...(init ?? {}), status: 502, statusText: 'Bad Gateway' }); setType(response, 'basic'); setUrl(response, url); return response; } export function notSupportedResponse(url, body, init) { const response = new Response(body, { ...(init ?? {}), status: 501, statusText: 'Not Implemented' }); response.headers.set('X-Content-Type-Options', 'nosniff'); // see https://specs.ipfs.tech/http-gateways/path-gateway/#x-content-type-options-response-header setType(response, 'basic'); setUrl(response, url); return response; } export function notAcceptableResponse(url, body, init) { const response = new Response(body, { ...(init ?? {}), status: 406, statusText: 'Not Acceptable' }); setType(response, 'basic'); setUrl(response, url); return response; } export function notFoundResponse(url, body, init) { const response = new Response(body, { ...(init ?? {}), status: 404, statusText: 'Not Found' }); setType(response, 'basic'); setUrl(response, url); return response; } function isArrayOfErrors(body) { return Array.isArray(body) && body.every(e => e instanceof Error); } export function badRequestResponse(url, errors, init) { // stacktrace of the single error, or the stacktrace of the last error in the array let stack; let convertedErrors; if (isArrayOfErrors(errors)) { stack = errors[errors.length - 1].stack; convertedErrors = errors.map(e => ({ message: e.message, stack: e.stack ?? '' })); } else if (errors instanceof Error) { stack = errors.stack; convertedErrors = [{ message: errors.message, stack: errors.stack ?? '' }]; } const bodyJson = JSON.stringify({ stack, errors: convertedErrors }); const response = new Response(bodyJson, { status: 400, statusText: 'Bad Request', ...(init ?? {}), headers: { ...(init?.headers ?? {}), 'Content-Type': 'application/json' } }); setType(response, 'basic'); setUrl(response, url); return response; } export function movedPermanentlyResponse(url, location, init) { const response = new Response(null, { ...(init ?? {}), status: 301, statusText: 'Moved Permanently', headers: { ...(init?.headers ?? {}), location } }); setType(response, 'basic'); setUrl(response, url); return response; } export function okRangeResponse(url, body, { byteRangeContext, log }, init) { if (!byteRangeContext.isRangeRequest) { return okResponse(url, body, init); } if (!byteRangeContext.isValidRangeRequest) { return badRangeResponse(url, body, init); } let response; try { // Create headers object with any initial headers from init const headers = new Headers(init?.headers); // For multipart responses, we should use the content-type header instead of content-range const multipartContentType = byteRangeContext.getContentType(); if (multipartContentType != null) { headers.set('content-type', multipartContentType); } else { if (byteRangeContext.isMultiRangeRequest) { headers.set('content-type', 'multipart/byteranges'); } else { headers.set('content-range', byteRangeContext.contentRangeHeaderValue); } } response = new Response(body, { ...(init ?? {}), status: 206, statusText: 'Partial Content', headers }); } catch (e) { log?.error('failed to create range response', e); return badRangeResponse(url, body, init); } if (init?.redirected === true) { setRedirected(response); } setType(response, 'basic'); setUrl(response, url); return response; } /** * We likely need to catch errors handled by upstream helia libraries if range-request throws an error. Some examples: * - The range is out of bounds * - The range is invalid * - The range is not supported for the given type */ export function badRangeResponse(url, body, init) { const response = new Response(body, { ...(init ?? {}), status: 416, statusText: 'Requested Range Not Satisfiable' }); setType(response, 'basic'); setUrl(response, url); return response; } //# sourceMappingURL=responses.js.map