Suite of AT Protocol TypeScript libraries built on web standards
21
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 91 lines 2.9 kB view raw
1import type { Gettable } from "./types.ts"; 2import { combineHeaders } from "./util.ts"; 3 4export type FetchHandler = ( 5 this: void, 6 /** 7 * The URL (pathname + query parameters) to make the request to, without the 8 * origin. The origin (protocol, hostname, and port) must be added by this 9 * {@link FetchHandler}, typically based on authentication or other factors. 10 */ 11 url: string, 12 init: RequestInit, 13) => Promise<Response>; 14 15export type FetchHandlerOptions = BuildFetchHandlerOptions | string | URL; 16 17export type BuildFetchHandlerOptions = { 18 /** 19 * The service URL to make requests to. This can be a string, URL, or a 20 * function that returns a string or URL. This is useful for dynamic URLs, 21 * such as a service URL that changes based on authentication. 22 */ 23 service: Gettable<string | URL>; 24 25 /** 26 * Headers to be added to every request. If a function is provided, it will be 27 * called on each request to get the headers. This is useful for dynamic 28 * headers, such as authentication tokens that may expire. 29 */ 30 headers?: { 31 [_ in string]?: Gettable<null | string>; 32 }; 33 34 /** 35 * Bring your own fetch implementation. Typically useful for testing, logging, 36 * mocking, or adding retries, session management, signatures, proof of 37 * possession (DPoP), SSRF protection, etc. Defaults to the global `fetch` 38 * function. 39 */ 40 fetch?: typeof globalThis.fetch; 41}; 42 43export interface FetchHandlerObject { 44 fetchHandler: ( 45 this: FetchHandlerObject, 46 /** 47 * The URL (pathname + query parameters) to make the request to, without the 48 * origin. The origin (protocol, hostname, and port) must be added by this 49 * {@link FetchHandler}, typically based on authentication or other factors. 50 */ 51 url: string, 52 init: RequestInit, 53 ) => Promise<Response>; 54} 55 56export function buildFetchHandler( 57 options: FetchHandler | FetchHandlerObject | FetchHandlerOptions, 58): FetchHandler { 59 // Already a fetch handler (allowed for convenience) 60 if (typeof options === "function") return options; 61 if (typeof options === "object" && "fetchHandler" in options) { 62 return options.fetchHandler.bind(options); 63 } 64 65 const { 66 service, 67 headers: defaultHeaders = undefined, 68 fetch = globalThis.fetch, 69 } = typeof options === "string" || options instanceof URL 70 ? { service: options } 71 : options; 72 73 if (typeof fetch !== "function") { 74 throw new TypeError( 75 "XrpcDispatcher requires fetch() to be available in your environment.", 76 ); 77 } 78 79 const defaultHeadersEntries = defaultHeaders != null 80 ? Object.entries(defaultHeaders) 81 : undefined; 82 83 return function (url, init) { 84 const base = typeof service === "function" ? service() : service; 85 const fullUrl = new URL(url, base); 86 87 const headers = combineHeaders(init.headers, defaultHeadersEntries); 88 89 return fetch(fullUrl, { ...init, headers }); 90 }; 91}