UNPKG

ketting

Version:

Opinionated HATEOAS / Rest client.

74 lines 2.51 kB
import problemFactory from './error.js'; import packageJson from 'ketting/package.json' with { type: 'json' }; /** * The fetcher object is responsible for calling fetch() * * This is wrapped in an object because we want to support * 'fetch middlewares'. These middlewares are similar to server-side * middlewares and can intercept requests and alter requests/responses. */ export class Fetcher { middlewares = []; advertiseKetting = true; /** * A wrapper for MDN fetch() * * This wrapper supports 'fetch middlewares'. It will call them * in sequence. */ fetch(resource, init) { const request = new Request(resource, init); const origin = new URL(request.url).origin; const mws = this.getMiddlewaresByOrigin(origin); mws.push((innerRequest) => { if (!innerRequest.headers.has('User-Agent') && this.advertiseKetting) { // eslint-disable-next-line @typescript-eslint/no-require-imports innerRequest.headers.set('User-Agent', `Ketting/${packageJson.version}`); } return fetch(innerRequest); }); return invokeMiddlewares(mws, request); } /** * Returns the list of middlewares that are applicable to * a specific origin */ getMiddlewaresByOrigin(origin) { return this.middlewares.filter(([regex]) => { return regex.test(origin); }).map(([, middleware]) => { return middleware; }); } /** * Add a middleware */ use(mw, origin = '*') { const matchSplit = origin.split('*'); const matchRegex = matchSplit.map(part => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('(.*)'); const regex = new RegExp('^' + matchRegex + '$'); this.middlewares.push([regex, mw]); } /** * Does a HTTP request and throws an exception if the server emitted * a HTTP error. * * @see https://developer.mozilla.org/en-US/docs/Web/API/Request/Request */ async fetchOrThrow(resource, init) { const response = await this.fetch(resource, init); if (response.ok) { return response; } else { throw await problemFactory(response); } } } export default Fetcher; function invokeMiddlewares(mws, request) { return mws[0](request, (nextRequest) => { return invokeMiddlewares(mws.slice(1), nextRequest); }); } //# sourceMappingURL=fetcher.js.map