import { AnyRouter } from '@trpc/server'; import { observable } from '@trpc/server/observable'; import { TRPCClientError } from '../TRPCClientError'; import { HTTPLinkBaseOptions, httpRequest, resolveHTTPLinkOptions, } from './internals/httpUtils'; import { transformResult } from './internals/transformResult'; import { HTTPHeaders, Operation, TRPCLink } from './types'; export interface HTTPLinkOptions extends HTTPLinkBaseOptions { /** * Headers to be set on outgoing requests or a callback that of said headers * @link http://trpc.io/docs/client/headers */ headers?: | HTTPHeaders | ((opts: { op: Operation }) => HTTPHeaders | Promise); } export function httpLink( opts: HTTPLinkOptions, ): TRPCLink { const resolvedOpts = resolveHTTPLinkOptions(opts); return (runtime) => ({ op }) => observable((observer) => { const { path, input, type } = op; const { promise, cancel } = httpRequest({ ...resolvedOpts, runtime, type, path, input, headers() { if (!opts.headers) { return {}; } if (typeof opts.headers === 'function') { return opts.headers({ op, }); } return opts.headers; }, ops: [op], }); promise .then((res) => { const transformed = transformResult(res.json, runtime); if (!transformed.ok) { observer.error( TRPCClientError.from(transformed.error, { meta: res.meta, }), ); return; } observer.next({ context: res.meta, result: transformed.result, }); observer.complete(); }) .catch((cause) => observer.error(TRPCClientError.from(cause))); return () => { cancel(); }; }); }