@trpc/client
Version:
1 lines • 7.42 kB
Source Map (JSON)
{"version":3,"file":"httpLink-CWd1U86f.mjs","names":[],"sources":["../src/links/internals/contentTypes.ts","../src/links/httpLink.ts"],"sourcesContent":["/** Whether an input is binary: a `Uint8Array`, `Blob` or `File`. */\nexport function isOctetType(\n input: unknown,\n): input is Uint8Array<ArrayBuffer> | Blob {\n return (\n input instanceof Uint8Array ||\n // File extends from Blob but is only available in nodejs from v20\n input instanceof Blob\n );\n}\n\n/** Whether an input is `FormData`. */\nexport function isFormData(input: unknown) {\n return input instanceof FormData;\n}\n\n/**\n * Whether an input can't be sent as JSON: binary data or `FormData`. Use\n * it in a `splitLink` to send such inputs with `httpLink`.\n * @see https://trpc.io/docs/server/non-json-content-types#client-setup\n */\nexport function isNonJsonSerializable(input: unknown) {\n return isOctetType(input) || isFormData(input);\n}\n","import { observable } from '@trpc/server/observable';\nimport type {\n AnyClientTypes,\n AnyRouter,\n} from '@trpc/server/unstable-core-do-not-import';\nimport { transformResult } from '@trpc/server/unstable-core-do-not-import';\nimport { raceAbortSignalsWithCleanup } from '../internals/signals';\nimport { TRPCClientError } from '../TRPCClientError';\nimport type {\n HTTPLinkBaseOptions,\n HTTPResult,\n Requester,\n} from './internals/httpUtils';\nimport {\n getUrl,\n httpRequest,\n jsonHttpRequester,\n resolveHTTPLinkOptions,\n} from './internals/httpUtils';\nimport {\n isFormData,\n isOctetType,\n type HTTPHeaders,\n type Operation,\n type TRPCLink,\n} from './types';\n\n/**\n * The options of `httpLink`.\n * @see https://trpc.io/docs/client/links/httpLink#httplink-options\n */\nexport type HTTPLinkOptions<TRoot extends AnyClientTypes> =\n HTTPLinkBaseOptions<TRoot> & {\n /**\n * Headers for each request: an object, or a function of the operation\n * that returns them.\n * @see https://trpc.io/docs/client/headers\n */\n headers?:\n | HTTPHeaders\n | ((opts: { op: Operation }) => HTTPHeaders | Promise<HTTPHeaders>);\n };\n\nconst universalRequester: Requester = (opts) => {\n if ('input' in opts) {\n const { input } = opts;\n if (isFormData(input)) {\n if (opts.type !== 'mutation' && opts.methodOverride !== 'POST') {\n throw new Error('FormData is only supported for mutations');\n }\n\n return httpRequest({\n ...opts,\n // The browser will set this automatically and include the boundary= in it\n contentTypeHeader: undefined,\n getUrl,\n getBody: () => input,\n });\n }\n\n if (isOctetType(input)) {\n if (opts.type !== 'mutation' && opts.methodOverride !== 'POST') {\n throw new Error('Octet type input is only supported for mutations');\n }\n\n return httpRequest({\n ...opts,\n contentTypeHeader: 'application/octet-stream',\n getUrl,\n getBody: () => input,\n });\n }\n }\n\n return jsonHttpRequester(opts);\n};\n\n/**\n * A terminating link that sends each call in its own HTTP request. It can\n * send `FormData` and binary inputs.\n * @see https://trpc.io/docs/client/links/httpLink\n */\nexport function httpLink<TRouter extends AnyRouter = AnyRouter>(\n opts: HTTPLinkOptions<TRouter['_def']['_config']['$types']>,\n): TRPCLink<TRouter> {\n const resolvedOpts = resolveHTTPLinkOptions(opts);\n return () => {\n return (operationOpts) => {\n const { op } = operationOpts;\n return observable((observer) => {\n const { path, input, type } = op;\n /* istanbul ignore if -- @preserve */\n if (type === 'subscription') {\n throw new Error(\n 'Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`',\n );\n }\n\n const ac = new AbortController();\n const { signal, cleanup } = raceAbortSignalsWithCleanup(\n op.signal,\n ac.signal,\n );\n let request: Promise<HTTPResult>;\n try {\n request = universalRequester({\n ...resolvedOpts,\n type,\n path,\n input,\n signal,\n headers() {\n if (!opts.headers) {\n return {};\n }\n if (typeof opts.headers === 'function') {\n return opts.headers({\n op,\n });\n }\n return opts.headers;\n },\n });\n } catch (cause) {\n cleanup();\n throw cause;\n }\n let isDone = false;\n let meta: HTTPResult['meta'] | undefined = undefined;\n request\n .then((res) => {\n isDone = true;\n meta = res.meta;\n const transformed = transformResult(\n res.json,\n resolvedOpts.transformer.output,\n );\n\n if (!transformed.ok) {\n observer.error(\n TRPCClientError.from(transformed.error, {\n meta,\n }),\n );\n return;\n }\n observer.next({\n context: res.meta,\n result: transformed.result,\n });\n observer.complete();\n })\n .catch((cause) => {\n isDone = true;\n observer.error(TRPCClientError.from(cause, { meta }));\n });\n\n return () => {\n if (!isDone) {\n ac.abort();\n }\n cleanup();\n };\n });\n };\n };\n}\n"],"mappings":";;;;;;;AACA,SAAgB,YACd,OACyC;CACzC,OACE,iBAAiB,cAEjB,iBAAiB;AAErB;;AAGA,SAAgB,WAAW,OAAgB;CACzC,OAAO,iBAAiB;AAC1B;;;;;;AAOA,SAAgB,sBAAsB,OAAgB;CACpD,OAAO,YAAY,KAAK,KAAK,WAAW,KAAK;AAC/C;;;ACoBA,MAAM,sBAAiC,SAAS;CAC9C,IAAI,WAAW,MAAM;EACnB,MAAM,EAAE,UAAU;EAClB,IAAI,WAAW,KAAK,GAAG;GACrB,IAAI,KAAK,SAAS,cAAc,KAAK,mBAAmB,QACtD,MAAM,IAAI,MAAM,0CAA0C;GAG5D,OAAO,YAAA,eAAA,eAAA,CAAA,GACF,IAAA,GAAA,CAAA,GAAA;IAEH,mBAAmB,KAAA;IACnB;IACA,eAAe;GACjB,CAAA,CAAC;EACH;EAEA,IAAI,YAAY,KAAK,GAAG;GACtB,IAAI,KAAK,SAAS,cAAc,KAAK,mBAAmB,QACtD,MAAM,IAAI,MAAM,kDAAkD;GAGpE,OAAO,YAAA,eAAA,eAAA,CAAA,GACF,IAAA,GAAA,CAAA,GAAA;IACH,mBAAmB;IACnB;IACA,eAAe;GACjB,CAAA,CAAC;EACH;CACF;CAEA,OAAO,kBAAkB,IAAI;AAC/B;;;;;;AAOA,SAAgB,SACd,MACmB;CACnB,MAAM,eAAe,uBAAuB,IAAI;CAChD,aAAa;EACX,QAAQ,kBAAkB;GACxB,MAAM,EAAE,OAAO;GACf,OAAO,YAAY,aAAa;IAC9B,MAAM,EAAE,MAAM,OAAO,SAAS;;IAE9B,IAAI,SAAS,gBACX,MAAM,IAAI,MACR,sFACF;IAGF,MAAM,KAAK,IAAI,gBAAgB;IAC/B,MAAM,EAAE,QAAQ,YAAY,4BAC1B,GAAG,QACH,GAAG,MACL;IACA,IAAI;IACJ,IAAI;KACF,UAAU,mBAAA,eAAA,eAAA,CAAA,GACL,YAAA,GAAA,CAAA,GAAA;MACH;MACA;MACA;MACA;MACA,UAAU;OACR,IAAI,CAAC,KAAK,SACR,OAAO,CAAC;OAEV,IAAI,OAAO,KAAK,YAAY,YAC1B,OAAO,KAAK,QAAQ,EAClB,GACF,CAAC;OAEH,OAAO,KAAK;MACd;KACF,CAAA,CAAC;IACH,SAAS,OAAO;KACd,QAAQ;KACR,MAAM;IACR;IACA,IAAI,SAAS;IACb,IAAI,OAAuC,KAAA;IAC3C,QACG,MAAM,QAAQ;KACb,SAAS;KACT,OAAO,IAAI;KACX,MAAM,cAAc,gBAClB,IAAI,MACJ,aAAa,YAAY,MAC3B;KAEA,IAAI,CAAC,YAAY,IAAI;MACnB,SAAS,MACP,gBAAgB,KAAK,YAAY,OAAO,EACtC,KACF,CAAC,CACH;MACA;KACF;KACA,SAAS,KAAK;MACZ,SAAS,IAAI;MACb,QAAQ,YAAY;KACtB,CAAC;KACD,SAAS,SAAS;IACpB,CAAC,CAAC,CACD,OAAO,UAAU;KAChB,SAAS;KACT,SAAS,MAAM,gBAAgB,KAAK,OAAO,EAAE,KAAK,CAAC,CAAC;IACtD,CAAC;IAEH,aAAa;KACX,IAAI,CAAC,QACH,GAAG,MAAM;KAEX,QAAQ;IACV;GACF,CAAC;EACH;CACF;AACF"}