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 lex 85 lines 2.1 kB view raw
1import type { DidString } from "@atp/lex"; 2 3export type FetchHandler = ( 4 path: `/${string}`, 5 init: RequestInit, 6) => Promise<Response>; 7 8export interface Agent { 9 readonly did?: DidString; 10 fetchHandler: FetchHandler; 11} 12 13export function isAgent(value: unknown): value is Agent { 14 return ( 15 typeof value === "object" && 16 value !== null && 17 "fetchHandler" in value && 18 typeof value.fetchHandler === "function" && 19 (!("did" in value) || 20 value.did === undefined || 21 typeof value.did === "string") 22 ); 23} 24 25export type AgentConfig = { 26 did?: DidString; 27 service: string | URL; 28 headers?: HeadersInit; 29 fetch?: typeof globalThis.fetch; 30}; 31 32export type AgentOptions = AgentConfig | FetchHandler | string | URL; 33 34export function buildAgent<O extends Agent | AgentOptions>( 35 options: O, 36): O extends Agent ? O : Agent; 37export function buildAgent(options: Agent | AgentOptions): Agent { 38 const config: Agent | AgentConfig = typeof options === "function" 39 ? { did: undefined, fetchHandler: options } 40 : typeof options === "string" || options instanceof URL 41 ? { did: undefined, service: options } 42 : options; 43 44 if (isAgent(config)) { 45 return config; 46 } 47 48 const { service, fetch = globalThis.fetch } = config; 49 50 if (typeof fetch !== "function") { 51 throw new TypeError("fetch() is not available in this environment"); 52 } 53 54 return { 55 get did() { 56 return config.did; 57 }, 58 fetchHandler(path, init) { 59 const headers = config.headers != null && init.headers != null 60 ? mergeHeaders(config.headers, init.headers) 61 : config.headers || init.headers; 62 63 return fetch( 64 new URL(path, service), 65 headers !== init.headers ? { ...init, headers } : init, 66 ); 67 }, 68 }; 69} 70 71function mergeHeaders( 72 defaultHeaders: HeadersInit, 73 requestHeaders: HeadersInit, 74): Headers { 75 const result = new Headers(defaultHeaders); 76 const overrides = requestHeaders instanceof Headers 77 ? requestHeaders 78 : new Headers(requestHeaders); 79 80 for (const [key, value] of overrides.entries()) { 81 result.set(key, value); 82 } 83 84 return result; 85}