@orpc/client
Advanced tools
| import { Promisable, OrderablePlugin, Interceptor } from '@orpc/shared'; | ||
| import { StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.CFVTHyN6.mjs'; | ||
| type StandardLinkCodecDecodedResponse = { | ||
| kind: 'output'; | ||
| output: unknown; | ||
| } | { | ||
| kind: 'error'; | ||
| error: AnyORPCError; | ||
| }; | ||
| interface StandardLinkCodec<T extends ClientContext> { | ||
| encodeInput(input: unknown, path: string[], options: ClientOptions<T>): Promisable<StandardRequest>; | ||
| decodeResponse(response: StandardLazyResponse, path: string[], options: ClientOptions<T>): Promisable<StandardLinkCodecDecodedResponse>; | ||
| } | ||
| interface StandardLinkPlugin<T extends ClientContext> extends OrderablePlugin { | ||
| /** | ||
| * Initializes the plugin and returns new link options. | ||
| * Called once per plugin instance during composition. | ||
| * | ||
| * This method allows plugins to wrap, extend, or transform link options | ||
| * such as interceptors, or configuration. | ||
| * | ||
| * @param options - The current link options from previous plugins or base configuration | ||
| * @returns Transformed link options with plugin's modifications applied | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * init(options) { | ||
| * return { | ||
| * ...options, | ||
| * interceptors: [...(options.interceptors || []), myInterceptor] | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| init?(options: StandardLinkOptions<T>): StandardLinkOptions<T>; | ||
| } | ||
| declare class CompositeStandardLinkPlugin<T extends ClientContext> implements StandardLinkPlugin<T> { | ||
| name: string; | ||
| protected readonly plugins: StandardLinkPlugin<T>[]; | ||
| constructor(plugins?: StandardLinkPlugin<T>[]); | ||
| init(options: StandardLinkOptions<T>): StandardLinkOptions<T>; | ||
| } | ||
| /** | ||
| * Handles the transport layer for sending requests and receiving responses. | ||
| * | ||
| * Implementations are responsible for the actual network communication, | ||
| * such as HTTP fetch, WebSocket, or other transport mechanisms. | ||
| */ | ||
| interface StandardLinkTransport<T extends ClientContext> { | ||
| /** | ||
| * @throws Transport-level errors (network failures, timeouts, etc.) | ||
| */ | ||
| send(request: StandardRequest, path: string[], options: ClientOptions<T>): Promise<StandardLazyResponse>; | ||
| } | ||
| interface StandardLinkInterceptorOptions<T extends ClientContext> extends ClientOptions<T> { | ||
| path: string[]; | ||
| input: unknown; | ||
| } | ||
| type StandardLinkInterceptor<T extends ClientContext> = Interceptor<StandardLinkInterceptorOptions<T>, Promise<unknown>>; | ||
| interface StandardLinkTransportInterceptorOptions<T extends ClientContext> extends ClientOptions<T> { | ||
| path: string[]; | ||
| request: StandardRequest; | ||
| } | ||
| type StandardLinkTransportInterceptor<T extends ClientContext> = Interceptor<StandardLinkTransportInterceptorOptions<T>, Promise<StandardLazyResponse>>; | ||
| interface StandardLinkOptions<T extends ClientContext> { | ||
| /** | ||
| * Interceptors that execute around the entire call, including transport and codec. | ||
| * Useful for error handling, logging, metrics, ... | ||
| */ | ||
| interceptors?: StandardLinkInterceptor<T>[]; | ||
| /** | ||
| * Interceptors that execute around the transport layer, after encoding and before decoding. | ||
| * Useful for modifying the request or response, adding transport-level logging, ... | ||
| */ | ||
| transportInterceptors?: StandardLinkTransportInterceptor<T>[]; | ||
| plugins?: StandardLinkPlugin<T>[]; | ||
| } | ||
| declare class StandardLink<T extends ClientContext> implements ClientLink<T> { | ||
| private readonly codec; | ||
| private readonly transport; | ||
| private readonly interceptors; | ||
| private readonly transportInterceptors; | ||
| constructor(codec: StandardLinkCodec<T>, transport: StandardLinkTransport<T>, options?: StandardLinkOptions<T>); | ||
| /** | ||
| * @throws ORPCError, transport-level errors (network failures, timeouts, etc.) | ||
| */ | ||
| call(path: string[], input: unknown, options: ClientOptions<T>): Promise<unknown>; | ||
| } | ||
| export { CompositeStandardLinkPlugin as C, StandardLink as a }; | ||
| export type { StandardLinkTransport as S, StandardLinkOptions as b, StandardLinkPlugin as c, StandardLinkTransportInterceptorOptions as d, StandardLinkInterceptorOptions as e, StandardLinkCodec as f, StandardLinkCodecDecodedResponse as g, StandardLinkInterceptor as h, StandardLinkTransportInterceptor as i }; |
| import { Promisable, OrderablePlugin, Interceptor } from '@orpc/shared'; | ||
| import { StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.CFVTHyN6.js'; | ||
| type StandardLinkCodecDecodedResponse = { | ||
| kind: 'output'; | ||
| output: unknown; | ||
| } | { | ||
| kind: 'error'; | ||
| error: AnyORPCError; | ||
| }; | ||
| interface StandardLinkCodec<T extends ClientContext> { | ||
| encodeInput(input: unknown, path: string[], options: ClientOptions<T>): Promisable<StandardRequest>; | ||
| decodeResponse(response: StandardLazyResponse, path: string[], options: ClientOptions<T>): Promisable<StandardLinkCodecDecodedResponse>; | ||
| } | ||
| interface StandardLinkPlugin<T extends ClientContext> extends OrderablePlugin { | ||
| /** | ||
| * Initializes the plugin and returns new link options. | ||
| * Called once per plugin instance during composition. | ||
| * | ||
| * This method allows plugins to wrap, extend, or transform link options | ||
| * such as interceptors, or configuration. | ||
| * | ||
| * @param options - The current link options from previous plugins or base configuration | ||
| * @returns Transformed link options with plugin's modifications applied | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * init(options) { | ||
| * return { | ||
| * ...options, | ||
| * interceptors: [...(options.interceptors || []), myInterceptor] | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| init?(options: StandardLinkOptions<T>): StandardLinkOptions<T>; | ||
| } | ||
| declare class CompositeStandardLinkPlugin<T extends ClientContext> implements StandardLinkPlugin<T> { | ||
| name: string; | ||
| protected readonly plugins: StandardLinkPlugin<T>[]; | ||
| constructor(plugins?: StandardLinkPlugin<T>[]); | ||
| init(options: StandardLinkOptions<T>): StandardLinkOptions<T>; | ||
| } | ||
| /** | ||
| * Handles the transport layer for sending requests and receiving responses. | ||
| * | ||
| * Implementations are responsible for the actual network communication, | ||
| * such as HTTP fetch, WebSocket, or other transport mechanisms. | ||
| */ | ||
| interface StandardLinkTransport<T extends ClientContext> { | ||
| /** | ||
| * @throws Transport-level errors (network failures, timeouts, etc.) | ||
| */ | ||
| send(request: StandardRequest, path: string[], options: ClientOptions<T>): Promise<StandardLazyResponse>; | ||
| } | ||
| interface StandardLinkInterceptorOptions<T extends ClientContext> extends ClientOptions<T> { | ||
| path: string[]; | ||
| input: unknown; | ||
| } | ||
| type StandardLinkInterceptor<T extends ClientContext> = Interceptor<StandardLinkInterceptorOptions<T>, Promise<unknown>>; | ||
| interface StandardLinkTransportInterceptorOptions<T extends ClientContext> extends ClientOptions<T> { | ||
| path: string[]; | ||
| request: StandardRequest; | ||
| } | ||
| type StandardLinkTransportInterceptor<T extends ClientContext> = Interceptor<StandardLinkTransportInterceptorOptions<T>, Promise<StandardLazyResponse>>; | ||
| interface StandardLinkOptions<T extends ClientContext> { | ||
| /** | ||
| * Interceptors that execute around the entire call, including transport and codec. | ||
| * Useful for error handling, logging, metrics, ... | ||
| */ | ||
| interceptors?: StandardLinkInterceptor<T>[]; | ||
| /** | ||
| * Interceptors that execute around the transport layer, after encoding and before decoding. | ||
| * Useful for modifying the request or response, adding transport-level logging, ... | ||
| */ | ||
| transportInterceptors?: StandardLinkTransportInterceptor<T>[]; | ||
| plugins?: StandardLinkPlugin<T>[]; | ||
| } | ||
| declare class StandardLink<T extends ClientContext> implements ClientLink<T> { | ||
| private readonly codec; | ||
| private readonly transport; | ||
| private readonly interceptors; | ||
| private readonly transportInterceptors; | ||
| constructor(codec: StandardLinkCodec<T>, transport: StandardLinkTransport<T>, options?: StandardLinkOptions<T>); | ||
| /** | ||
| * @throws ORPCError, transport-level errors (network failures, timeouts, etc.) | ||
| */ | ||
| call(path: string[], input: unknown, options: ClientOptions<T>): Promise<unknown>; | ||
| } | ||
| export { CompositeStandardLinkPlugin as C, StandardLink as a }; | ||
| export type { StandardLinkTransport as S, StandardLinkOptions as b, StandardLinkPlugin as c, StandardLinkTransportInterceptorOptions as d, StandardLinkInterceptorOptions as e, StandardLinkCodec as f, StandardLinkCodecDecodedResponse as g, StandardLinkInterceptor as h, StandardLinkTransportInterceptor as i }; |
| import { isPlainObject, wrapAsyncIterator, isTypescriptObject, NullProtoObj, isAsyncIteratorObject, stringifyJSON } from '@orpc/shared'; | ||
| import { getEventMeta, withEventMeta, ErrorEvent } from '@standardserver/core'; | ||
| import { O as ORPCError, M as MalformedResponseError, C as COMMON_ERROR_STATUS_MAP } from './client.DcoDDrD4.mjs'; | ||
| function isInferableError(error) { | ||
| return error instanceof ORPCError && error.inferable; | ||
| } | ||
| function toORPCError(error) { | ||
| return error instanceof ORPCError ? error : new ORPCError("INTERNAL_SERVER_ERROR", { cause: error }); | ||
| } | ||
| function isORPCErrorJson(json) { | ||
| if (!isPlainObject(json)) { | ||
| return false; | ||
| } | ||
| const validKeys = ["defined", "inferable", "code", "message", "data"]; | ||
| if (Object.keys(json).some((k) => !validKeys.includes(k))) { | ||
| return false; | ||
| } | ||
| return "defined" in json && typeof json.defined === "boolean" && "inferable" in json && typeof json.inferable === "boolean" && "code" in json && typeof json.code === "string" && "message" in json && typeof json.message === "string"; | ||
| } | ||
| function createORPCErrorFromJson(json, options = {}) { | ||
| const error = new ORPCError(json.code, { | ||
| ...json, | ||
| ...options | ||
| }); | ||
| error.defined = json.defined; | ||
| error.inferable = json.inferable; | ||
| return error; | ||
| } | ||
| function createORPCErrorFromMalformedResponse(options) { | ||
| const error = new ORPCError("MALFORMED_ORPC_RESPONSE", { | ||
| message: options.message ?? inferMalformedResponseMessage(options.response), | ||
| data: options.response | ||
| }); | ||
| error.cause = new MalformedResponseError({ ...options, message: error.message }); | ||
| return error; | ||
| } | ||
| const INFERRED_MESSAGE_MIN_LENGTH = 1; | ||
| const INFERRED_MESSAGE_MAX_LENGTH = 256; | ||
| function isInferableMessage(text) { | ||
| return text.length >= INFERRED_MESSAGE_MIN_LENGTH && text.length <= INFERRED_MESSAGE_MAX_LENGTH; | ||
| } | ||
| function inferMalformedResponseMessage(response) { | ||
| if (typeof response.body === "string" && isInferableMessage(response.body)) { | ||
| return response.body; | ||
| } | ||
| if (isPlainObject(response.body) && typeof response.body.message === "string" && isInferableMessage(response.body.message)) { | ||
| return response.body.message; | ||
| } | ||
| const commonCode = Object.entries(COMMON_ERROR_STATUS_MAP).find(([, status]) => status === response.status)?.[0]; | ||
| return commonCode?.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" "); | ||
| } | ||
| function cloneORPCError(error) { | ||
| const cloned = new ORPCError(error.code, { | ||
| message: error.message, | ||
| data: error.data, | ||
| cause: error.cause | ||
| }); | ||
| Object.setPrototypeOf(cloned, Object.getPrototypeOf(error)); | ||
| Object.defineProperties(cloned, Object.getOwnPropertyDescriptors(error)); | ||
| cloned.stack = error.stack; | ||
| return cloned; | ||
| } | ||
| function wrapAsyncIteratorPreservingEventMeta(iterator, { mapResult, mapError, ...rest }) { | ||
| return wrapAsyncIterator(iterator, { | ||
| ...rest, | ||
| mapResult: mapResult && (async (result) => { | ||
| const mapped = await mapResult(result); | ||
| if (mapped.value !== result.value) { | ||
| const meta = getEventMeta(result.value); | ||
| if (meta && isTypescriptObject(mapped.value)) { | ||
| return { done: mapped.done, value: withEventMeta(mapped.value, meta) }; | ||
| } | ||
| } | ||
| return mapped; | ||
| }), | ||
| mapError: mapError && (async (error) => { | ||
| const mapped = await mapError(error); | ||
| if (mapped !== error) { | ||
| const meta = getEventMeta(error); | ||
| if (meta && isTypescriptObject(mapped)) { | ||
| return withEventMeta(mapped, meta); | ||
| } | ||
| } | ||
| return mapped; | ||
| }) | ||
| }); | ||
| } | ||
| const REGEX_STRING_PATTERN = /^\/([\s\S]*)\/([a-z]*)$/; | ||
| const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = { | ||
| undefined: { | ||
| condition(data) { | ||
| return data === void 0; | ||
| }, | ||
| serialize() { | ||
| return null; | ||
| }, | ||
| deserialize() { | ||
| return void 0; | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| bigint: { | ||
| condition(data) { | ||
| return typeof data === "bigint"; | ||
| }, | ||
| serialize(data) { | ||
| return data.toString(); | ||
| }, | ||
| deserialize(serialized) { | ||
| return BigInt(serialized); | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| date: { | ||
| condition(data) { | ||
| return data instanceof Date; | ||
| }, | ||
| serialize(data) { | ||
| if (Number.isNaN(data.getTime())) { | ||
| return null; | ||
| } | ||
| return data.toISOString(); | ||
| }, | ||
| deserialize(serialized) { | ||
| return new Date(serialized ?? "Invalid Date"); | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| nan: { | ||
| condition(data) { | ||
| return typeof data === "number" && Number.isNaN(data); | ||
| }, | ||
| serialize() { | ||
| return null; | ||
| }, | ||
| deserialize() { | ||
| return Number.NaN; | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| url: { | ||
| condition(data) { | ||
| return data instanceof URL; | ||
| }, | ||
| serialize(data) { | ||
| return data.toString(); | ||
| }, | ||
| deserialize(serialized) { | ||
| return new URL(serialized); | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| regexp: { | ||
| condition(data) { | ||
| return data instanceof RegExp; | ||
| }, | ||
| serialize(data) { | ||
| return data.toString(); | ||
| }, | ||
| deserialize(serialized) { | ||
| const [, pattern, flags] = serialized.match(REGEX_STRING_PATTERN); | ||
| return new RegExp(pattern, flags); | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| set: { | ||
| condition(data) { | ||
| return data instanceof Set; | ||
| }, | ||
| serialize(data) { | ||
| return Array.from(data); | ||
| }, | ||
| deserialize(serialized) { | ||
| return new Set(serialized); | ||
| } | ||
| }, | ||
| map: { | ||
| condition(data) { | ||
| return data instanceof Map; | ||
| }, | ||
| serialize(data) { | ||
| return Array.from(data.entries()); | ||
| }, | ||
| deserialize(serialized) { | ||
| return new Map(serialized); | ||
| } | ||
| } | ||
| }; | ||
| class RPCJsonSerializer { | ||
| handlers; | ||
| inlineBuiltInHandlers; | ||
| handlerEntries; | ||
| omitUndefinedProperties; | ||
| constructor(options = {}) { | ||
| this.omitUndefinedProperties = options.omitUndefinedProperties !== false; | ||
| this.handlers = Object.assign(new NullProtoObj(), DEFAULT_RPC_JSON_SERIALIZER_HANDLERS); | ||
| const customHandlers = options.handlers; | ||
| if (customHandlers === void 0) { | ||
| this.inlineBuiltInHandlers = true; | ||
| return; | ||
| } | ||
| let inlineBuiltInHandlers = true; | ||
| let handlerEntries = []; | ||
| for (const key in customHandlers) { | ||
| const handler = customHandlers[key]; | ||
| this.handlers[key] = handler; | ||
| if (inlineBuiltInHandlers && key in DEFAULT_RPC_JSON_SERIALIZER_HANDLERS) { | ||
| inlineBuiltInHandlers = false; | ||
| } | ||
| if (inlineBuiltInHandlers && handler !== void 0) { | ||
| handlerEntries.push([key, handler]); | ||
| } | ||
| } | ||
| if (!inlineBuiltInHandlers) { | ||
| handlerEntries = []; | ||
| for (const key in this.handlers) { | ||
| const handler = this.handlers[key]; | ||
| if (handler !== void 0) { | ||
| handlerEntries.push([key, handler]); | ||
| } | ||
| } | ||
| } | ||
| this.inlineBuiltInHandlers = inlineBuiltInHandlers; | ||
| this.handlerEntries = handlerEntries; | ||
| } | ||
| serialize(data) { | ||
| let meta = []; | ||
| const maps = []; | ||
| const blobs = []; | ||
| const json = this.serializeValue(data, [], meta, maps, blobs); | ||
| meta = meta.length === 0 ? void 0 : meta; | ||
| if (maps.length === 0) { | ||
| return { json, meta }; | ||
| } | ||
| return { json, meta, maps, blobs }; | ||
| } | ||
| /** | ||
| * `segments` is a shared mutable stack (push/pop while walking), | ||
| * so it must be copied before being stored in `meta` or `maps`. | ||
| */ | ||
| serializeValue(data, segments, meta, maps, blobs) { | ||
| if (this.inlineBuiltInHandlers) { | ||
| switch (typeof data) { | ||
| case "string": | ||
| case "boolean": | ||
| return data; | ||
| case "number": | ||
| if (Number.isNaN(data)) { | ||
| meta.push(["nan", ...segments]); | ||
| return null; | ||
| } | ||
| return data; | ||
| case "undefined": | ||
| meta.push(["undefined", ...segments]); | ||
| return null; | ||
| case "bigint": | ||
| meta.push(["bigint", ...segments]); | ||
| return data.toString(); | ||
| case "object": { | ||
| if (data === null) { | ||
| return data; | ||
| } | ||
| if (data instanceof Date) { | ||
| meta.push(["date", ...segments]); | ||
| return Number.isNaN(data.getTime()) ? null : data.toISOString(); | ||
| } | ||
| if (data instanceof URL) { | ||
| meta.push(["url", ...segments]); | ||
| return data.toString(); | ||
| } | ||
| if (data instanceof RegExp) { | ||
| meta.push(["regexp", ...segments]); | ||
| return data.toString(); | ||
| } | ||
| if (data instanceof Set) { | ||
| const result = this.serializeValue(Array.from(data), segments, meta, maps, blobs); | ||
| meta.push(["set", ...segments]); | ||
| return result; | ||
| } | ||
| if (data instanceof Map) { | ||
| const result = this.serializeValue(Array.from(data.entries()), segments, meta, maps, blobs); | ||
| meta.push(["map", ...segments]); | ||
| return result; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| const handlerEntries = this.handlerEntries; | ||
| if (handlerEntries) { | ||
| for (let i = 0; i < handlerEntries.length; i++) { | ||
| const entry = handlerEntries[i]; | ||
| const handler = entry[1]; | ||
| if (handler.condition(data)) { | ||
| const serialized = handler.serialize(data); | ||
| if (handler.isTerminal) { | ||
| meta.push([entry[0], ...segments]); | ||
| if (serialized instanceof Blob) { | ||
| maps.push(segments.slice()); | ||
| blobs.push(serialized); | ||
| } | ||
| return serialized; | ||
| } | ||
| const result = this.serializeValue(serialized, segments, meta, maps, blobs); | ||
| meta.push([entry[0], ...segments]); | ||
| return result; | ||
| } | ||
| } | ||
| } | ||
| if (data instanceof Blob) { | ||
| maps.push(segments.slice()); | ||
| blobs.push(data); | ||
| return data; | ||
| } | ||
| if (Array.isArray(data)) { | ||
| const json = []; | ||
| for (let i = 0; i < data.length; i++) { | ||
| segments.push(i); | ||
| json.push(this.serializeValue(data[i], segments, meta, maps, blobs)); | ||
| segments.pop(); | ||
| } | ||
| return json; | ||
| } | ||
| if (isPlainObject(data)) { | ||
| const json = new NullProtoObj(); | ||
| for (const k in data) { | ||
| const v = data[k]; | ||
| if (k === "toJSON" && typeof v === "function") { | ||
| continue; | ||
| } | ||
| if (v === void 0 && this.omitUndefinedProperties) { | ||
| continue; | ||
| } | ||
| segments.push(k); | ||
| json[k] = this.serializeValue(v, segments, meta, maps, blobs); | ||
| segments.pop(); | ||
| } | ||
| return json; | ||
| } | ||
| return data; | ||
| } | ||
| deserialize(serialized) { | ||
| const ref = { data: serialized.json }; | ||
| if (serialized.blobs?.length) { | ||
| for (let i = 0; i < serialized.maps.length; i++) { | ||
| const segments = serialized.maps[i]; | ||
| let currentRef = ref; | ||
| let preSegment = "data"; | ||
| for (let j = 0; j < segments.length; j++) { | ||
| currentRef = currentRef[preSegment]; | ||
| preSegment = segments[j]; | ||
| if (!Object.hasOwn(currentRef, preSegment)) { | ||
| throw new Error(`Security error: Invalid serialized data. Segment "${preSegment}" does not exist.`); | ||
| } | ||
| } | ||
| currentRef[preSegment] = serialized.blobs[i]; | ||
| } | ||
| } | ||
| if (serialized.meta) { | ||
| for (const item of serialized.meta) { | ||
| const type = item[0]; | ||
| let currentRef = ref; | ||
| let preSegment = "data"; | ||
| for (let i = 1; i < item.length; i++) { | ||
| currentRef = currentRef[preSegment]; | ||
| preSegment = item[i]; | ||
| if (!Object.hasOwn(currentRef, preSegment)) { | ||
| throw new Error(`Security error: Invalid serialized data. Segment "${preSegment}" does not exist.`); | ||
| } | ||
| } | ||
| currentRef[preSegment] = this.handlers[type].deserialize(currentRef[preSegment]); | ||
| } | ||
| } | ||
| return ref.data; | ||
| } | ||
| } | ||
| class RPCSerializer { | ||
| jsonSerializer; | ||
| defaultSerializeOptions; | ||
| constructor(options = {}) { | ||
| this.jsonSerializer = new RPCJsonSerializer(options); | ||
| this.defaultSerializeOptions = options.serialize; | ||
| } | ||
| serialize(data, options = {}) { | ||
| if (data === void 0 || data instanceof ReadableStream || data instanceof Blob) { | ||
| return data; | ||
| } | ||
| if (isAsyncIteratorObject(data)) { | ||
| return wrapAsyncIteratorPreservingEventMeta(data, { | ||
| mapResult: (result) => { | ||
| if (result.value === void 0) { | ||
| return result; | ||
| } | ||
| return { done: result.done, value: this.serializeValue(result.value, false) }; | ||
| }, | ||
| mapError: (e) => new ErrorEvent( | ||
| this.serializeValue(toORPCError(e).toJSON(), false), | ||
| { cause: e } | ||
| ) | ||
| }); | ||
| } | ||
| const useFormDataForBlobs = options.useFormDataForBlobFields ?? this.defaultSerializeOptions?.useFormDataForBlobFields ?? true; | ||
| return this.serializeValue(data, useFormDataForBlobs); | ||
| } | ||
| serializeValue(data, useFormDataForBlobs) { | ||
| const { json, meta, maps, blobs } = this.jsonSerializer.serialize(data); | ||
| if (!useFormDataForBlobs || !blobs?.length) { | ||
| return { json, meta }; | ||
| } | ||
| const form = new FormData(); | ||
| form.set("data", stringifyJSON({ json, meta, maps })); | ||
| blobs.forEach((blob, i) => { | ||
| form.set(i.toString(), blob); | ||
| }); | ||
| return form; | ||
| } | ||
| deserialize(data) { | ||
| if (data === void 0 || data instanceof ReadableStream || data instanceof Blob) { | ||
| return data; | ||
| } | ||
| if (isAsyncIteratorObject(data)) { | ||
| return wrapAsyncIteratorPreservingEventMeta(data, { | ||
| mapResult: (result) => { | ||
| if (result.value === void 0) { | ||
| return result; | ||
| } | ||
| return { done: result.done, value: this.deserializeValue(result.value) }; | ||
| }, | ||
| mapError: (e) => { | ||
| if (!(e instanceof ErrorEvent)) { | ||
| return e; | ||
| } | ||
| const deserialized = this.deserializeValue(e.data); | ||
| if (isORPCErrorJson(deserialized)) { | ||
| return createORPCErrorFromJson(deserialized, { cause: e }); | ||
| } | ||
| return new ErrorEvent(deserialized, { cause: e }); | ||
| } | ||
| }); | ||
| } | ||
| return this.deserializeValue(data); | ||
| } | ||
| deserializeValue(data) { | ||
| if (!(data instanceof FormData)) { | ||
| return this.jsonSerializer.deserialize(data); | ||
| } | ||
| const serialized = JSON.parse(data.get("data")); | ||
| const blobs = []; | ||
| for (const [key, value] of data) { | ||
| if (value instanceof Blob) { | ||
| blobs[Number(key)] = value; | ||
| } | ||
| } | ||
| return this.jsonSerializer.deserialize({ ...serialized, blobs }); | ||
| } | ||
| } | ||
| export { RPCSerializer as R, createORPCErrorFromJson as a, isInferableError as b, createORPCErrorFromMalformedResponse as c, RPCJsonSerializer as d, cloneORPCError as e, isORPCErrorJson as i, toORPCError as t, wrapAsyncIteratorPreservingEventMeta as w }; |
| import { PromiseWithError, Registry, MaybeOptionalOptions } from '@orpc/shared'; | ||
| import { StandardResponse } from '@standardserver/core'; | ||
| interface ClientContext { | ||
| [key: PropertyKey]: any; | ||
| } | ||
| interface ClientOptions<T extends ClientContext> { | ||
| signal?: AbortSignal | undefined; | ||
| lastEventId?: string | undefined; | ||
| context: T; | ||
| } | ||
| type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (object extends T ? { | ||
| context?: T; | ||
| } : { | ||
| context: T; | ||
| }); | ||
| type ClientRest<TClientContext extends ClientContext, TInput> = object extends TClientContext ? undefined extends TInput ? [input?: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options: FriendlyClientOptions<TClientContext>]; | ||
| interface Client<TClientContext extends ClientContext, TInput, TOutput, TError> { | ||
| (...rest: ClientRest<TClientContext, TInput>): PromiseWithError<TOutput, TError>; | ||
| } | ||
| type NestedClient<TClientContext extends ClientContext> = Client<TClientContext, any, any, any> | { | ||
| [k: string]: NestedClient<TClientContext>; | ||
| }; | ||
| type AnyNestedClient = NestedClient<any>; | ||
| /** | ||
| * Infers the **client context type** required by a client. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-context | Client-Side Clients - Infer Client Context} | ||
| */ | ||
| type InferClientContext<T extends AnyNestedClient> = T extends NestedClient<infer U> ? U : never; | ||
| interface ClientLink<TClientContext extends ClientContext> { | ||
| call: (path: string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>; | ||
| } | ||
| /** | ||
| * Recursively infers the **input types** from a client. | ||
| * | ||
| * Produces a nested map where each endpoint's input type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-inputs | Client-Side Clients - Infer Client Inputs} | ||
| */ | ||
| type InferClientInputs<T extends AnyNestedClient> = T extends Client<any, infer U, any, any> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientInputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **body input types** from a client. | ||
| * | ||
| * If an endpoint's input includes `{ body: ... }`, only the `body` portion is extracted. | ||
| * Produces a nested map of body input types. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-body-inputs | Client-Side Clients - Infer Client Body Inputs} | ||
| */ | ||
| type InferClientBodyInputs<T extends AnyNestedClient> = T extends Client<any, infer U, any, any> ? U extends { | ||
| body: infer UBody; | ||
| } ? UBody : U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientBodyInputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **output types** from a client. | ||
| * | ||
| * Produces a nested map where each endpoint's output type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-outputs | Client-Side Clients - Infer Client Outputs} | ||
| */ | ||
| type InferClientOutputs<T extends AnyNestedClient> = T extends Client<any, any, infer U, any> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientOutputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **body output types** from a client. | ||
| * | ||
| * If an endpoint's output includes `{ body: ... }`, only the `body` portion is extracted. | ||
| * Produces a nested map of body output types. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-body-outputs | Client-Side Clients - Infer Client Body Outputs} | ||
| */ | ||
| type InferClientBodyOutputs<T extends AnyNestedClient> = T extends Client<any, any, infer U, any> ? U extends { | ||
| body: infer UBody; | ||
| } ? UBody : U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientBodyOutputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#typesafe-errors). | ||
| * | ||
| * Produces a nested map where each endpoint's error type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-errors | Client-Side Clients - Infer Client Errors} | ||
| */ | ||
| type InferClientErrors<T extends AnyNestedClient> = T extends Client<any, any, any, infer U> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientErrors<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers a **union of all error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#typesafe-errors). | ||
| * | ||
| * Useful when you want to handle all possible errors from any endpoint at once. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-error | Client-Side Clients - Infer Client Error} | ||
| */ | ||
| type InferClientError<T extends AnyNestedClient> = T extends Client<any, any, any, infer U> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientError<T[K]> : never; | ||
| }[keyof T]; | ||
| /** | ||
| * Default mapping between common oRPC error codes and HTTP status codes. | ||
| * Handlers use it to determine response status codes; spread it to build a custom `errorStatusMap`. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/rpc/handler#custom-error-response | RPC Handler - Custom Error Response} | ||
| * @see {@link https://orpc.dev/docs/openapi/handler#custom-error-response | OpenAPI Handler - Custom Error Response} | ||
| */ | ||
| declare const COMMON_ERROR_STATUS_MAP: { | ||
| BAD_REQUEST: number; | ||
| UNAUTHORIZED: number; | ||
| PAYMENT_REQUIRED: number; | ||
| FORBIDDEN: number; | ||
| NOT_FOUND: number; | ||
| METHOD_NOT_SUPPORTED: number; | ||
| NOT_ACCEPTABLE: number; | ||
| TIMEOUT: number; | ||
| CONFLICT: number; | ||
| GONE: number; | ||
| PRECONDITION_FAILED: number; | ||
| PAYLOAD_TOO_LARGE: number; | ||
| UNSUPPORTED_MEDIA_TYPE: number; | ||
| UNPROCESSABLE_CONTENT: number; | ||
| PRECONDITION_REQUIRED: number; | ||
| TOO_MANY_REQUESTS: number; | ||
| CLIENT_CLOSED_REQUEST: number; | ||
| INTERNAL_SERVER_ERROR: number; | ||
| NOT_IMPLEMENTED: number; | ||
| BAD_GATEWAY: number; | ||
| SERVICE_UNAVAILABLE: number; | ||
| GATEWAY_TIMEOUT: number; | ||
| }; | ||
| type ORPCErrorCode = Registry extends { | ||
| ORPCErrorCode: infer T extends string; | ||
| } ? T : (keyof typeof COMMON_ERROR_STATUS_MAP) | (string & {}); | ||
| type ORPCErrorOptions<TData> = ErrorOptions & { | ||
| message?: string; | ||
| } & (undefined extends TData ? { | ||
| data?: TData; | ||
| } : { | ||
| data: TData; | ||
| }); | ||
| /** | ||
| * Typed error carrying a `code`, a `message`, and optional `data`. | ||
| * Throw it from handlers or middleware to produce typed error responses on the client. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/error-handling#orpcerror-class | Error Handling - ORPCError Class} | ||
| */ | ||
| declare class ORPCError<TCode extends ORPCErrorCode, TData> extends Error { | ||
| /** | ||
| * @remarks | ||
| * **Note**: The `__branch` property is used for type branding, helping TypeScript distinguish | ||
| * an `ORPCError` instance from plain objects with a similar structure. | ||
| */ | ||
| readonly name: "ORPCError" & { | ||
| __branch: "ORPCError"; | ||
| }; | ||
| /** | ||
| * Indicates whether the error matches a definition in the procedure's `.errors` map. | ||
| */ | ||
| readonly defined: boolean; | ||
| /** | ||
| * Indicates whether the error's type is inferable at the TypeScript level. | ||
| * This is typically true when the error is explicitly defined or returned within a handler. | ||
| */ | ||
| readonly inferable: boolean; | ||
| code: TCode; | ||
| data: TData; | ||
| constructor(code: TCode, ...rest: MaybeOptionalOptions<ORPCErrorOptions<TData>>); | ||
| toJSON(): ORPCErrorJSON<TCode, TData>; | ||
| /** | ||
| * Workaround for Next.js where different contexts use separate | ||
| * dependency graphs, causing multiple ORPCError constructors existing and breaking | ||
| * `instanceof` checks across contexts. | ||
| * | ||
| * This is particularly problematic with "Optimized SSR", where orpc-client | ||
| * executes in one context but is invoked from another. When an error is thrown | ||
| * in the execution context, `instanceof ORPCError` checks fail in the | ||
| * invocation context due to separate class constructors. | ||
| * | ||
| * @todo Remove this and related code if Next.js resolves the multiple dependency graph issue. | ||
| */ | ||
| static [Symbol.hasInstance](instance: unknown): boolean; | ||
| } | ||
| interface ORPCErrorJSON<TCode extends string, TData> extends Pick<ORPCError<TCode, TData>, 'code' | 'message' | 'data'> { | ||
| /** | ||
| * remove readonly | ||
| */ | ||
| defined: boolean; | ||
| /** | ||
| * remove readonly | ||
| */ | ||
| inferable: boolean; | ||
| } | ||
| type AnyORPCError = ORPCError<any, any>; | ||
| type AnyORPCErrorJSON = ORPCErrorJSON<any, any>; | ||
| interface MalformedResponseErrorOptions extends ErrorOptions { | ||
| message?: string; | ||
| response: StandardResponse; | ||
| } | ||
| /** | ||
| * Error indicating a response does not follow the expected oRPC format, carrying | ||
| * the resolved response. Found as the `cause` of a `MALFORMED_ORPC_RESPONSE` | ||
| * `ORPCError`. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/rpc/link#malformed-responses | RPC Link - Malformed Responses} | ||
| * @see {@link https://orpc.dev/docs/openapi/link#malformed-responses | OpenAPI Link - Malformed Responses} | ||
| */ | ||
| declare class MalformedResponseError extends Error { | ||
| readonly name = "MalformedResponseError"; | ||
| response: StandardResponse; | ||
| constructor(options: MalformedResponseErrorOptions); | ||
| } | ||
| export { ORPCError as h, COMMON_ERROR_STATUS_MAP as j, MalformedResponseError as p }; | ||
| export type { AnyORPCError as A, ClientContext as C, FriendlyClientOptions as F, InferClientContext as I, MalformedResponseErrorOptions as M, NestedClient as N, ORPCErrorCode as O, ClientOptions as a, ClientLink as b, AnyNestedClient as c, InferClientError as d, Client as e, ClientRest as f, ORPCErrorJSON as g, AnyORPCErrorJSON as i, InferClientBodyInputs as k, InferClientBodyOutputs as l, InferClientErrors as m, InferClientInputs as n, InferClientOutputs as o, ORPCErrorOptions as q }; |
| import { PromiseWithError, Registry, MaybeOptionalOptions } from '@orpc/shared'; | ||
| import { StandardResponse } from '@standardserver/core'; | ||
| interface ClientContext { | ||
| [key: PropertyKey]: any; | ||
| } | ||
| interface ClientOptions<T extends ClientContext> { | ||
| signal?: AbortSignal | undefined; | ||
| lastEventId?: string | undefined; | ||
| context: T; | ||
| } | ||
| type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (object extends T ? { | ||
| context?: T; | ||
| } : { | ||
| context: T; | ||
| }); | ||
| type ClientRest<TClientContext extends ClientContext, TInput> = object extends TClientContext ? undefined extends TInput ? [input?: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options: FriendlyClientOptions<TClientContext>]; | ||
| interface Client<TClientContext extends ClientContext, TInput, TOutput, TError> { | ||
| (...rest: ClientRest<TClientContext, TInput>): PromiseWithError<TOutput, TError>; | ||
| } | ||
| type NestedClient<TClientContext extends ClientContext> = Client<TClientContext, any, any, any> | { | ||
| [k: string]: NestedClient<TClientContext>; | ||
| }; | ||
| type AnyNestedClient = NestedClient<any>; | ||
| /** | ||
| * Infers the **client context type** required by a client. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-context | Client-Side Clients - Infer Client Context} | ||
| */ | ||
| type InferClientContext<T extends AnyNestedClient> = T extends NestedClient<infer U> ? U : never; | ||
| interface ClientLink<TClientContext extends ClientContext> { | ||
| call: (path: string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>; | ||
| } | ||
| /** | ||
| * Recursively infers the **input types** from a client. | ||
| * | ||
| * Produces a nested map where each endpoint's input type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-inputs | Client-Side Clients - Infer Client Inputs} | ||
| */ | ||
| type InferClientInputs<T extends AnyNestedClient> = T extends Client<any, infer U, any, any> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientInputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **body input types** from a client. | ||
| * | ||
| * If an endpoint's input includes `{ body: ... }`, only the `body` portion is extracted. | ||
| * Produces a nested map of body input types. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-body-inputs | Client-Side Clients - Infer Client Body Inputs} | ||
| */ | ||
| type InferClientBodyInputs<T extends AnyNestedClient> = T extends Client<any, infer U, any, any> ? U extends { | ||
| body: infer UBody; | ||
| } ? UBody : U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientBodyInputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **output types** from a client. | ||
| * | ||
| * Produces a nested map where each endpoint's output type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-outputs | Client-Side Clients - Infer Client Outputs} | ||
| */ | ||
| type InferClientOutputs<T extends AnyNestedClient> = T extends Client<any, any, infer U, any> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientOutputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **body output types** from a client. | ||
| * | ||
| * If an endpoint's output includes `{ body: ... }`, only the `body` portion is extracted. | ||
| * Produces a nested map of body output types. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-body-outputs | Client-Side Clients - Infer Client Body Outputs} | ||
| */ | ||
| type InferClientBodyOutputs<T extends AnyNestedClient> = T extends Client<any, any, infer U, any> ? U extends { | ||
| body: infer UBody; | ||
| } ? UBody : U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientBodyOutputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#typesafe-errors). | ||
| * | ||
| * Produces a nested map where each endpoint's error type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-errors | Client-Side Clients - Infer Client Errors} | ||
| */ | ||
| type InferClientErrors<T extends AnyNestedClient> = T extends Client<any, any, any, infer U> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientErrors<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers a **union of all error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#typesafe-errors). | ||
| * | ||
| * Useful when you want to handle all possible errors from any endpoint at once. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-error | Client-Side Clients - Infer Client Error} | ||
| */ | ||
| type InferClientError<T extends AnyNestedClient> = T extends Client<any, any, any, infer U> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientError<T[K]> : never; | ||
| }[keyof T]; | ||
| /** | ||
| * Default mapping between common oRPC error codes and HTTP status codes. | ||
| * Handlers use it to determine response status codes; spread it to build a custom `errorStatusMap`. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/rpc/handler#custom-error-response | RPC Handler - Custom Error Response} | ||
| * @see {@link https://orpc.dev/docs/openapi/handler#custom-error-response | OpenAPI Handler - Custom Error Response} | ||
| */ | ||
| declare const COMMON_ERROR_STATUS_MAP: { | ||
| BAD_REQUEST: number; | ||
| UNAUTHORIZED: number; | ||
| PAYMENT_REQUIRED: number; | ||
| FORBIDDEN: number; | ||
| NOT_FOUND: number; | ||
| METHOD_NOT_SUPPORTED: number; | ||
| NOT_ACCEPTABLE: number; | ||
| TIMEOUT: number; | ||
| CONFLICT: number; | ||
| GONE: number; | ||
| PRECONDITION_FAILED: number; | ||
| PAYLOAD_TOO_LARGE: number; | ||
| UNSUPPORTED_MEDIA_TYPE: number; | ||
| UNPROCESSABLE_CONTENT: number; | ||
| PRECONDITION_REQUIRED: number; | ||
| TOO_MANY_REQUESTS: number; | ||
| CLIENT_CLOSED_REQUEST: number; | ||
| INTERNAL_SERVER_ERROR: number; | ||
| NOT_IMPLEMENTED: number; | ||
| BAD_GATEWAY: number; | ||
| SERVICE_UNAVAILABLE: number; | ||
| GATEWAY_TIMEOUT: number; | ||
| }; | ||
| type ORPCErrorCode = Registry extends { | ||
| ORPCErrorCode: infer T extends string; | ||
| } ? T : (keyof typeof COMMON_ERROR_STATUS_MAP) | (string & {}); | ||
| type ORPCErrorOptions<TData> = ErrorOptions & { | ||
| message?: string; | ||
| } & (undefined extends TData ? { | ||
| data?: TData; | ||
| } : { | ||
| data: TData; | ||
| }); | ||
| /** | ||
| * Typed error carrying a `code`, a `message`, and optional `data`. | ||
| * Throw it from handlers or middleware to produce typed error responses on the client. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/error-handling#orpcerror-class | Error Handling - ORPCError Class} | ||
| */ | ||
| declare class ORPCError<TCode extends ORPCErrorCode, TData> extends Error { | ||
| /** | ||
| * @remarks | ||
| * **Note**: The `__branch` property is used for type branding, helping TypeScript distinguish | ||
| * an `ORPCError` instance from plain objects with a similar structure. | ||
| */ | ||
| readonly name: "ORPCError" & { | ||
| __branch: "ORPCError"; | ||
| }; | ||
| /** | ||
| * Indicates whether the error matches a definition in the procedure's `.errors` map. | ||
| */ | ||
| readonly defined: boolean; | ||
| /** | ||
| * Indicates whether the error's type is inferable at the TypeScript level. | ||
| * This is typically true when the error is explicitly defined or returned within a handler. | ||
| */ | ||
| readonly inferable: boolean; | ||
| code: TCode; | ||
| data: TData; | ||
| constructor(code: TCode, ...rest: MaybeOptionalOptions<ORPCErrorOptions<TData>>); | ||
| toJSON(): ORPCErrorJSON<TCode, TData>; | ||
| /** | ||
| * Workaround for Next.js where different contexts use separate | ||
| * dependency graphs, causing multiple ORPCError constructors existing and breaking | ||
| * `instanceof` checks across contexts. | ||
| * | ||
| * This is particularly problematic with "Optimized SSR", where orpc-client | ||
| * executes in one context but is invoked from another. When an error is thrown | ||
| * in the execution context, `instanceof ORPCError` checks fail in the | ||
| * invocation context due to separate class constructors. | ||
| * | ||
| * @todo Remove this and related code if Next.js resolves the multiple dependency graph issue. | ||
| */ | ||
| static [Symbol.hasInstance](instance: unknown): boolean; | ||
| } | ||
| interface ORPCErrorJSON<TCode extends string, TData> extends Pick<ORPCError<TCode, TData>, 'code' | 'message' | 'data'> { | ||
| /** | ||
| * remove readonly | ||
| */ | ||
| defined: boolean; | ||
| /** | ||
| * remove readonly | ||
| */ | ||
| inferable: boolean; | ||
| } | ||
| type AnyORPCError = ORPCError<any, any>; | ||
| type AnyORPCErrorJSON = ORPCErrorJSON<any, any>; | ||
| interface MalformedResponseErrorOptions extends ErrorOptions { | ||
| message?: string; | ||
| response: StandardResponse; | ||
| } | ||
| /** | ||
| * Error indicating a response does not follow the expected oRPC format, carrying | ||
| * the resolved response. Found as the `cause` of a `MALFORMED_ORPC_RESPONSE` | ||
| * `ORPCError`. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/rpc/link#malformed-responses | RPC Link - Malformed Responses} | ||
| * @see {@link https://orpc.dev/docs/openapi/link#malformed-responses | OpenAPI Link - Malformed Responses} | ||
| */ | ||
| declare class MalformedResponseError extends Error { | ||
| readonly name = "MalformedResponseError"; | ||
| response: StandardResponse; | ||
| constructor(options: MalformedResponseErrorOptions); | ||
| } | ||
| export { ORPCError as h, COMMON_ERROR_STATUS_MAP as j, MalformedResponseError as p }; | ||
| export type { AnyORPCError as A, ClientContext as C, FriendlyClientOptions as F, InferClientContext as I, MalformedResponseErrorOptions as M, NestedClient as N, ORPCErrorCode as O, ClientOptions as a, ClientLink as b, AnyNestedClient as c, InferClientError as d, Client as e, ClientRest as f, ORPCErrorJSON as g, AnyORPCErrorJSON as i, InferClientBodyInputs as k, InferClientBodyOutputs as l, InferClientErrors as m, InferClientInputs as n, InferClientOutputs as o, ORPCErrorOptions as q }; |
| import { resolveMaybeOptionalOptions, getConstructors } from '@orpc/shared'; | ||
| const COMMON_ERROR_STATUS_MAP = { | ||
| BAD_REQUEST: 400, | ||
| UNAUTHORIZED: 401, | ||
| PAYMENT_REQUIRED: 402, | ||
| FORBIDDEN: 403, | ||
| NOT_FOUND: 404, | ||
| METHOD_NOT_SUPPORTED: 405, | ||
| NOT_ACCEPTABLE: 406, | ||
| TIMEOUT: 408, | ||
| CONFLICT: 409, | ||
| GONE: 410, | ||
| PRECONDITION_FAILED: 412, | ||
| PAYLOAD_TOO_LARGE: 413, | ||
| UNSUPPORTED_MEDIA_TYPE: 415, | ||
| UNPROCESSABLE_CONTENT: 422, | ||
| PRECONDITION_REQUIRED: 428, | ||
| TOO_MANY_REQUESTS: 429, | ||
| CLIENT_CLOSED_REQUEST: 499, | ||
| INTERNAL_SERVER_ERROR: 500, | ||
| NOT_IMPLEMENTED: 501, | ||
| BAD_GATEWAY: 502, | ||
| SERVICE_UNAVAILABLE: 503, | ||
| GATEWAY_TIMEOUT: 504 | ||
| }; | ||
| let ORPCErrorConstructors; | ||
| class ORPCError extends Error { | ||
| static { | ||
| const ORPC_ERROR_CONSTRUCTORS_SYMBOL = Symbol.for("ORPC_ERROR_CONSTRUCTORS"); | ||
| void (globalThis[ORPC_ERROR_CONSTRUCTORS_SYMBOL] ??= /* @__PURE__ */ new WeakSet()); | ||
| ORPCErrorConstructors = globalThis[ORPC_ERROR_CONSTRUCTORS_SYMBOL]; | ||
| ORPCErrorConstructors.add(ORPCError); | ||
| } | ||
| /** | ||
| * @remarks | ||
| * **Note**: The `__branch` property is used for type branding, helping TypeScript distinguish | ||
| * an `ORPCError` instance from plain objects with a similar structure. | ||
| */ | ||
| name = "ORPCError"; | ||
| /** | ||
| * Indicates whether the error matches a definition in the procedure's `.errors` map. | ||
| */ | ||
| defined = false; | ||
| /** | ||
| * Indicates whether the error's type is inferable at the TypeScript level. | ||
| * This is typically true when the error is explicitly defined or returned within a handler. | ||
| */ | ||
| inferable = false; | ||
| code; | ||
| data; | ||
| constructor(code, ...rest) { | ||
| const options = resolveMaybeOptionalOptions(rest); | ||
| const message = options.message ?? code.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" "); | ||
| super(message, options); | ||
| this.code = code; | ||
| this.data = options.data; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| defined: this.defined, | ||
| inferable: this.inferable, | ||
| code: this.code, | ||
| message: this.message, | ||
| data: this.data | ||
| }; | ||
| } | ||
| /** | ||
| * Workaround for Next.js where different contexts use separate | ||
| * dependency graphs, causing multiple ORPCError constructors existing and breaking | ||
| * `instanceof` checks across contexts. | ||
| * | ||
| * This is particularly problematic with "Optimized SSR", where orpc-client | ||
| * executes in one context but is invoked from another. When an error is thrown | ||
| * in the execution context, `instanceof ORPCError` checks fail in the | ||
| * invocation context due to separate class constructors. | ||
| * | ||
| * @todo Remove this and related code if Next.js resolves the multiple dependency graph issue. | ||
| */ | ||
| static [Symbol.hasInstance](instance) { | ||
| if (!ORPCErrorConstructors.has(this)) { | ||
| return super[Symbol.hasInstance](instance); | ||
| } | ||
| for (const constructor of getConstructors(instance)) { | ||
| if (ORPCErrorConstructors.has(constructor)) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
| class MalformedResponseError extends Error { | ||
| name = "MalformedResponseError"; | ||
| response; | ||
| constructor(options) { | ||
| super(options.message, options); | ||
| this.response = options.response; | ||
| } | ||
| } | ||
| export { COMMON_ERROR_STATUS_MAP as C, MalformedResponseError as M, ORPCError as O }; |
| import { sortPlugins, runWithSpan, ORPC_NAME, isAsyncIteratorObject, override, traceAsyncIterator, intercept, getOpenTelemetryConfig, value, pathToHttpPath, stringifyJSON } from '@orpc/shared'; | ||
| import { mergeStandardHeaders, parseStandardUrl } from '@standardserver/core'; | ||
| import { toStandardHeaders } from '@standardserver/fetch'; | ||
| import { R as RPCSerializer, c as createORPCErrorFromMalformedResponse, i as isORPCErrorJson, a as createORPCErrorFromJson } from './client.BnATe4Ob.mjs'; | ||
| class CompositeStandardLinkPlugin { | ||
| name = "~composite"; | ||
| plugins; | ||
| constructor(plugins = []) { | ||
| this.plugins = sortPlugins(plugins); | ||
| } | ||
| init(options) { | ||
| for (const plugin of this.plugins) { | ||
| if (plugin.init) { | ||
| options = plugin.init(options); | ||
| } | ||
| } | ||
| return options; | ||
| } | ||
| } | ||
| class StandardLink { | ||
| constructor(codec, transport, options = {}) { | ||
| this.codec = codec; | ||
| this.transport = transport; | ||
| options = new CompositeStandardLinkPlugin(options.plugins).init(options); | ||
| this.interceptors = options.interceptors; | ||
| this.transportInterceptors = options.transportInterceptors; | ||
| } | ||
| interceptors; | ||
| transportInterceptors; | ||
| /** | ||
| * @throws ORPCError, transport-level errors (network failures, timeouts, etc.) | ||
| */ | ||
| call(path, input, options) { | ||
| return runWithSpan(`${ORPC_NAME}.${path.join("/")}`, (span) => { | ||
| span?.setAttribute("rpc.system", ORPC_NAME); | ||
| span?.setAttribute("rpc.method", path.join(".")); | ||
| if (isAsyncIteratorObject(input)) { | ||
| input = override(input, traceAsyncIterator("consume_async_iterator_object_input", input)); | ||
| } | ||
| return intercept(this.interceptors, { ...options, path, input }, async ({ path: path2, input: input2, ...options2 }) => { | ||
| const otel = getOpenTelemetryConfig(); | ||
| let activeContext; | ||
| const activeSpan = otel?.trace.getActiveSpan() ?? span; | ||
| if (activeSpan && otel) { | ||
| activeContext = otel.trace.setSpan(otel.context.active(), activeSpan); | ||
| } | ||
| let request = await runWithSpan( | ||
| { name: "encode_input", context: activeContext }, | ||
| () => this.codec.encodeInput(input2, path2, options2) | ||
| ); | ||
| if (activeContext && otel?.propagation) { | ||
| const headers = { ...request.headers }; | ||
| otel.propagation.inject(activeContext, headers); | ||
| request = { ...request, headers }; | ||
| } | ||
| const response = await intercept( | ||
| this.transportInterceptors, | ||
| { ...options2, path: path2, request }, | ||
| ({ path: path3, request: request2, ...options3 }) => { | ||
| let activeTransportContext; | ||
| const activeTransportSpan = otel?.trace.getActiveSpan() ?? activeSpan; | ||
| if (activeTransportSpan && otel) { | ||
| activeTransportContext = otel.trace.setSpan(otel.context.active(), activeTransportSpan); | ||
| } | ||
| return runWithSpan( | ||
| { name: "send_request", context: activeTransportContext }, | ||
| () => this.transport.send(request2, path3, options3) | ||
| ); | ||
| } | ||
| ); | ||
| const decodedResult = await runWithSpan( | ||
| { name: "decode_response", context: activeContext }, | ||
| () => this.codec.decodeResponse(response, path2, options2) | ||
| ); | ||
| if (decodedResult.kind === "error") { | ||
| throw decodedResult.error; | ||
| } | ||
| const output = decodedResult.output; | ||
| if (isAsyncIteratorObject(output)) { | ||
| return override(output, traceAsyncIterator("consume_async_iterator_object_output", output)); | ||
| } | ||
| return output; | ||
| }); | ||
| }); | ||
| } | ||
| } | ||
| const END_SLASH_REGEX = /\/$/; | ||
| class RPCLinkCodec { | ||
| baseUrl; | ||
| maxUrlLength; | ||
| fallbackMethod; | ||
| expectedMethod; | ||
| headers; | ||
| serializer; | ||
| constructor(options) { | ||
| this.baseUrl = options.url ?? "/"; | ||
| this.maxUrlLength = options.maxUrlLength ?? 2083; | ||
| this.fallbackMethod = options.fallbackMethod ?? "POST"; | ||
| this.expectedMethod = options.method ?? this.fallbackMethod; | ||
| this.headers = options.headers ?? {}; | ||
| this.serializer = options.serializer ?? new RPCSerializer(); | ||
| } | ||
| async encodeInput(input, path, options) { | ||
| let headers = toResolvedStandardHeaders(await value(this.headers, options, path, input)); | ||
| if (options.lastEventId !== void 0) { | ||
| headers = mergeStandardHeaders(headers, { "last-event-id": options.lastEventId }); | ||
| } | ||
| const expectedMethod = await value(this.expectedMethod, options, path, input); | ||
| const baseUrl = await value(this.baseUrl, options, path, input); | ||
| const [pathname, search, hash] = parseStandardUrl(baseUrl); | ||
| const newPathname = `${pathname.replace(END_SLASH_REGEX, "")}${pathToHttpPath(path)}`; | ||
| const serialized = this.serializer.serialize(input); | ||
| if (expectedMethod === "GET" && !(serialized instanceof Blob) && !(serialized instanceof ReadableStream) && !(serialized instanceof FormData) && !isAsyncIteratorObject(serialized)) { | ||
| const maxUrlLength = await value(this.maxUrlLength, options, path, input); | ||
| const mergedSearch = new URLSearchParams(search); | ||
| mergedSearch.append("data", stringifyJSON(serialized) ?? ""); | ||
| const url2 = `${newPathname}?${mergedSearch}${hash ?? ""}`; | ||
| if (url2.length <= maxUrlLength) { | ||
| return { | ||
| body: void 0, | ||
| method: expectedMethod, | ||
| headers, | ||
| url: url2, | ||
| signal: options.signal | ||
| }; | ||
| } | ||
| } | ||
| const url = `${newPathname}${search ?? ""}${hash ?? ""}`; | ||
| return { | ||
| url, | ||
| method: expectedMethod === "GET" ? this.fallbackMethod : expectedMethod, | ||
| headers, | ||
| body: serialized, | ||
| signal: options.signal | ||
| }; | ||
| } | ||
| async decodeResponse(response) { | ||
| const isOk = response.status < 400; | ||
| const body = await response.resolveBody(); | ||
| const deserialized = await (async () => { | ||
| try { | ||
| return this.serializer.deserialize(body); | ||
| } catch (cause) { | ||
| throw createORPCErrorFromMalformedResponse({ | ||
| message: "Invalid RPC response format.", | ||
| response: { status: response.status, headers: response.headers, body }, | ||
| cause | ||
| }); | ||
| } | ||
| })(); | ||
| if (!isOk) { | ||
| if (isORPCErrorJson(deserialized)) { | ||
| return { kind: "error", error: createORPCErrorFromJson(deserialized) }; | ||
| } | ||
| return { | ||
| kind: "error", | ||
| error: createORPCErrorFromMalformedResponse({ response: { headers: response.headers, status: response.status, body } }) | ||
| }; | ||
| } | ||
| return { kind: "output", output: deserialized }; | ||
| } | ||
| } | ||
| function toResolvedStandardHeaders(headers) { | ||
| if (typeof headers.forEach === "function") { | ||
| return toStandardHeaders(headers); | ||
| } | ||
| return headers; | ||
| } | ||
| export { CompositeStandardLinkPlugin as C, RPCLinkCodec as R, StandardLink as S }; |
@@ -1,6 +0,6 @@ | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.l_EYklFG.mjs'; | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.CFVTHyN6.mjs'; | ||
| import { Value, Promisable, Interceptor } from '@orpc/shared'; | ||
| import { StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { ToFetchBodyOptions } from '@standardserver/fetch'; | ||
| import { S as StandardLinkTransport, c as StandardLinkPlugin, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.BkoxWb8f.mjs'; | ||
| import { S as StandardLinkTransport, c as StandardLinkPlugin, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.B0-4UDVl.mjs'; | ||
| import { RPCLinkCodecOptions } from '../standard/index.mjs'; | ||
@@ -7,0 +7,0 @@ import '../../shared/client.B8tCfDzm.mjs'; |
@@ -1,6 +0,6 @@ | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.l_EYklFG.js'; | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.CFVTHyN6.js'; | ||
| import { Value, Promisable, Interceptor } from '@orpc/shared'; | ||
| import { StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { ToFetchBodyOptions } from '@standardserver/fetch'; | ||
| import { S as StandardLinkTransport, c as StandardLinkPlugin, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.ByTd6BR5.js'; | ||
| import { S as StandardLinkTransport, c as StandardLinkPlugin, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.BhTyskpV.js'; | ||
| import { RPCLinkCodecOptions } from '../standard/index.js'; | ||
@@ -7,0 +7,0 @@ import '../../shared/client.B8tCfDzm.js'; |
| import { sortPlugins, value, intercept, once } from '@orpc/shared'; | ||
| import { toFetchBody, toFetchHeaders, toStandardLazyResponse } from '@standardserver/fetch'; | ||
| import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.uztMy1KD.mjs'; | ||
| import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.vEM0O_Eg.mjs'; | ||
| import '@standardserver/core'; | ||
| import '../../shared/client.CPcOxSex.mjs'; | ||
| import '../../shared/client.COv0qq2C.mjs'; | ||
| import '../../shared/client.BnATe4Ob.mjs'; | ||
| import '../../shared/client.DcoDDrD4.mjs'; | ||
@@ -8,0 +8,0 @@ class CompositeFetchLinkTransportPlugin { |
@@ -1,6 +0,6 @@ | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.l_EYklFG.mjs'; | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.CFVTHyN6.mjs'; | ||
| import { Value, Promisable } from '@orpc/shared'; | ||
| import { StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { ClientPeer, EncodePeerMessageOptions, DecodePeerMessageOptions } from '@standardserver/peer'; | ||
| import { S as StandardLinkTransport, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.BkoxWb8f.mjs'; | ||
| import { S as StandardLinkTransport, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.B0-4UDVl.mjs'; | ||
| import { RPCLinkCodecOptions } from '../standard/index.mjs'; | ||
@@ -7,0 +7,0 @@ import '../../shared/client.B8tCfDzm.mjs'; |
@@ -1,6 +0,6 @@ | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.l_EYklFG.js'; | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.CFVTHyN6.js'; | ||
| import { Value, Promisable } from '@orpc/shared'; | ||
| import { StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { ClientPeer, EncodePeerMessageOptions, DecodePeerMessageOptions } from '@standardserver/peer'; | ||
| import { S as StandardLinkTransport, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.ByTd6BR5.js'; | ||
| import { S as StandardLinkTransport, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.BhTyskpV.js'; | ||
| import { RPCLinkCodecOptions } from '../standard/index.js'; | ||
@@ -7,0 +7,0 @@ import '../../shared/client.B8tCfDzm.js'; |
| import { value } from '@orpc/shared'; | ||
| import { ClientPeer, encodePeerMessage, decodePeerMessage, isServerPeerSendMessage, isPeerMessage } from '@standardserver/peer'; | ||
| import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.uztMy1KD.mjs'; | ||
| import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.vEM0O_Eg.mjs'; | ||
| import '@standardserver/core'; | ||
| import '@standardserver/fetch'; | ||
| import '../../shared/client.CPcOxSex.mjs'; | ||
| import '../../shared/client.COv0qq2C.mjs'; | ||
| import '../../shared/client.BnATe4Ob.mjs'; | ||
| import '../../shared/client.DcoDDrD4.mjs'; | ||
@@ -9,0 +9,0 @@ function postMessagePortMessage(port, data, transfer) { |
@@ -1,7 +0,6 @@ | ||
| import { f as StandardLinkCodec, g as StandardLinkCodecDecodedResponse } from '../../shared/client.BkoxWb8f.mjs'; | ||
| export { C as CompositeStandardLinkPlugin, a as StandardLink, h as StandardLinkInterceptor, e as StandardLinkInterceptorOptions, b as StandardLinkOptions, c as StandardLinkPlugin, S as StandardLinkTransport, i as StandardLinkTransportInterceptor, d as StandardLinkTransportInterceptorOptions } from '../../shared/client.BkoxWb8f.mjs'; | ||
| import { f as StandardLinkCodec, g as StandardLinkCodecDecodedResponse } from '../../shared/client.B0-4UDVl.mjs'; | ||
| export { C as CompositeStandardLinkPlugin, a as StandardLink, h as StandardLinkInterceptor, e as StandardLinkInterceptorOptions, b as StandardLinkOptions, c as StandardLinkPlugin, S as StandardLinkTransport, i as StandardLinkTransportInterceptor, d as StandardLinkTransportInterceptorOptions } from '../../shared/client.B0-4UDVl.mjs'; | ||
| import { Value, Promisable } from '@orpc/shared'; | ||
| import { StandardUrl, StandardHeaders, StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| export { StandardBody, StandardBodyHint, StandardHeaders, StandardLazyRequest, StandardLazyResponse, StandardMethod, StandardRequest, StandardResponse, StandardUrl } from '@standardserver/core'; | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.l_EYklFG.mjs'; | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.CFVTHyN6.mjs'; | ||
| import { e as RPCSerializer } from '../../shared/client.B8tCfDzm.mjs'; | ||
@@ -31,3 +30,3 @@ | ||
| */ | ||
| method?: Value<Promisable<'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'>, [options: ClientOptions<T>, path: string[], input: unknown]>; | ||
| method?: Value<Promisable<'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'QUERY'>, [options: ClientOptions<T>, path: string[], input: unknown]>; | ||
| /** | ||
@@ -39,3 +38,3 @@ * The method to use when the payload cannot safely pass to the server with method return from method function. | ||
| */ | ||
| fallbackMethod?: 'POST' | 'PUT' | 'PATCH' | 'DELETE'; | ||
| fallbackMethod?: 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'QUERY'; | ||
| /** | ||
@@ -42,0 +41,0 @@ * Inject headers to the request. |
@@ -1,7 +0,6 @@ | ||
| import { f as StandardLinkCodec, g as StandardLinkCodecDecodedResponse } from '../../shared/client.ByTd6BR5.js'; | ||
| export { C as CompositeStandardLinkPlugin, a as StandardLink, h as StandardLinkInterceptor, e as StandardLinkInterceptorOptions, b as StandardLinkOptions, c as StandardLinkPlugin, S as StandardLinkTransport, i as StandardLinkTransportInterceptor, d as StandardLinkTransportInterceptorOptions } from '../../shared/client.ByTd6BR5.js'; | ||
| import { f as StandardLinkCodec, g as StandardLinkCodecDecodedResponse } from '../../shared/client.BhTyskpV.js'; | ||
| export { C as CompositeStandardLinkPlugin, a as StandardLink, h as StandardLinkInterceptor, e as StandardLinkInterceptorOptions, b as StandardLinkOptions, c as StandardLinkPlugin, S as StandardLinkTransport, i as StandardLinkTransportInterceptor, d as StandardLinkTransportInterceptorOptions } from '../../shared/client.BhTyskpV.js'; | ||
| import { Value, Promisable } from '@orpc/shared'; | ||
| import { StandardUrl, StandardHeaders, StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| export { StandardBody, StandardBodyHint, StandardHeaders, StandardLazyRequest, StandardLazyResponse, StandardMethod, StandardRequest, StandardResponse, StandardUrl } from '@standardserver/core'; | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.l_EYklFG.js'; | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.CFVTHyN6.js'; | ||
| import { e as RPCSerializer } from '../../shared/client.B8tCfDzm.js'; | ||
@@ -31,3 +30,3 @@ | ||
| */ | ||
| method?: Value<Promisable<'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'>, [options: ClientOptions<T>, path: string[], input: unknown]>; | ||
| method?: Value<Promisable<'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'QUERY'>, [options: ClientOptions<T>, path: string[], input: unknown]>; | ||
| /** | ||
@@ -39,3 +38,3 @@ * The method to use when the payload cannot safely pass to the server with method return from method function. | ||
| */ | ||
| fallbackMethod?: 'POST' | 'PUT' | 'PATCH' | 'DELETE'; | ||
| fallbackMethod?: 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'QUERY'; | ||
| /** | ||
@@ -42,0 +41,0 @@ * Inject headers to the request. |
@@ -1,6 +0,6 @@ | ||
| export { C as CompositeStandardLinkPlugin, R as RPCLinkCodec, S as StandardLink } from '../../shared/client.uztMy1KD.mjs'; | ||
| export { C as CompositeStandardLinkPlugin, R as RPCLinkCodec, S as StandardLink } from '../../shared/client.vEM0O_Eg.mjs'; | ||
| import '@orpc/shared'; | ||
| import '@standardserver/core'; | ||
| import '@standardserver/fetch'; | ||
| import '../../shared/client.CPcOxSex.mjs'; | ||
| import '../../shared/client.COv0qq2C.mjs'; | ||
| import '../../shared/client.BnATe4Ob.mjs'; | ||
| import '../../shared/client.DcoDDrD4.mjs'; |
@@ -1,6 +0,6 @@ | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.l_EYklFG.mjs'; | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.CFVTHyN6.mjs'; | ||
| import { Promisable } from '@orpc/shared'; | ||
| import { StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { EncodePeerMessageOptions, DecodePeerMessageOptions } from '@standardserver/peer'; | ||
| import { S as StandardLinkTransport, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.BkoxWb8f.mjs'; | ||
| import { S as StandardLinkTransport, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.B0-4UDVl.mjs'; | ||
| import { RPCLinkCodecOptions } from '../standard/index.mjs'; | ||
@@ -7,0 +7,0 @@ import '../../shared/client.B8tCfDzm.mjs'; |
@@ -1,6 +0,6 @@ | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.l_EYklFG.js'; | ||
| import { C as ClientContext, a as ClientOptions } from '../../shared/client.CFVTHyN6.js'; | ||
| import { Promisable } from '@orpc/shared'; | ||
| import { StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { EncodePeerMessageOptions, DecodePeerMessageOptions } from '@standardserver/peer'; | ||
| import { S as StandardLinkTransport, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.ByTd6BR5.js'; | ||
| import { S as StandardLinkTransport, a as StandardLink, b as StandardLinkOptions } from '../../shared/client.BhTyskpV.js'; | ||
| import { RPCLinkCodecOptions } from '../standard/index.js'; | ||
@@ -7,0 +7,0 @@ import '../../shared/client.B8tCfDzm.js'; |
| import { runWithSignal, AbortError, sleep, promiseWithResolvers, sequential, loadBytes, toStringOrBytes } from '@orpc/shared'; | ||
| import { ClientPeer, encodePeerMessage, decodePeerMessage, isServerPeerSendMessage } from '@standardserver/peer'; | ||
| import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.uztMy1KD.mjs'; | ||
| import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.vEM0O_Eg.mjs'; | ||
| import '@standardserver/core'; | ||
| import '@standardserver/fetch'; | ||
| import '../../shared/client.CPcOxSex.mjs'; | ||
| import '../../shared/client.COv0qq2C.mjs'; | ||
| import '../../shared/client.BnATe4Ob.mjs'; | ||
| import '../../shared/client.DcoDDrD4.mjs'; | ||
@@ -9,0 +9,0 @@ const WEBSOCKET_CONNECTING = 0; |
+15
-4
| import { WrapAsyncIteratorOptions, AsyncIteratorClass, Interceptor, PromiseWithError, ThrowableError, Promisable } from '@orpc/shared'; | ||
| export { AsyncCleanupFn, AsyncIteratorClass, AsyncIteratorClassNextFn, PromiseWithError as ClientPromiseResult, MaybeOptionalOptions, PromiseWithError, Registry, ThrowableError, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, consumeAsyncIterator, consumeAsyncIterator as consumeEventIterator, asyncIteratorToStream as eventIteratorToStream, asyncIteratorToUnproxiedDataStream as eventIteratorToUnproxiedDataStream, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, streamToAsyncIteratorObject, streamToAsyncIteratorObject as streamToEventIterator } from '@orpc/shared'; | ||
| import { C as ClientContext, a as ClientOptions, c as AnyNestedClient, I as InferClientContext, d as InferClientError, e as Client, b as ClientLink, A as AnyORPCError, f as ClientRest, F as FriendlyClientOptions, O as ORPCErrorCode, g as ORPCErrorJSON, h as ORPCError } from './shared/client.l_EYklFG.mjs'; | ||
| export { i as AnyORPCErrorJSON, j as COMMON_ERROR_STATUS_MAP, k as InferClientBodyInputs, l as InferClientBodyOutputs, m as InferClientErrors, n as InferClientInputs, o as InferClientOutputs, N as NestedClient, p as ORPCErrorOptions } from './shared/client.l_EYklFG.mjs'; | ||
| import { C as ClientContext, a as ClientOptions, c as AnyNestedClient, I as InferClientContext, d as InferClientError, e as Client, b as ClientLink, A as AnyORPCError, f as ClientRest, F as FriendlyClientOptions, O as ORPCErrorCode, g as ORPCErrorJSON, h as ORPCError, M as MalformedResponseErrorOptions } from './shared/client.CFVTHyN6.mjs'; | ||
| export { i as AnyORPCErrorJSON, j as COMMON_ERROR_STATUS_MAP, k as InferClientBodyInputs, l as InferClientBodyOutputs, m as InferClientErrors, n as InferClientInputs, o as InferClientOutputs, p as MalformedResponseError, N as NestedClient, q as ORPCErrorOptions } from './shared/client.CFVTHyN6.mjs'; | ||
| import { StandardResponse } from '@standardserver/core'; | ||
| export { ErrorEvent, EventMeta, StandardBody, StandardBodyHint, StandardHeaders, StandardLazyRequest, StandardLazyResponse, StandardMethod, StandardRequest, StandardResponse, StandardUrl, getEventMeta, unwrapEvent, withEventMeta } from '@standardserver/core'; | ||
| export { R as RPCJsonSerialization, a as RPCJsonSerializationMeta, b as RPCJsonSerializer, c as RPCJsonSerializerHandler, d as RPCJsonSerializerOptions, e as RPCSerializer, f as RPCSerializerOptions, g as RPCSerializerSerializeOptions } from './shared/client.B8tCfDzm.mjs'; | ||
| export { ErrorEvent, EventMeta, getEventMeta, unwrapEvent, withEventMeta } from '@standardserver/core'; | ||
@@ -135,2 +136,12 @@ declare function wrapAsyncIteratorPreservingEventMeta<TYield, TReturn, TMappedYield = TYield, TMappedReturn = TReturn>(iterator: AsyncIterator<TYield, TReturn>, { mapResult, mapError, ...rest }: WrapAsyncIteratorOptions<TYield, TReturn, TMappedYield, TMappedReturn>): AsyncIteratorClass<TMappedYield, TMappedReturn>; | ||
| /** | ||
| * Creates the `MALFORMED_ORPC_RESPONSE` `ORPCError` used when a response | ||
| * does not follow the expected oRPC format. Unless overridden via `options.message`, | ||
| * the message is inferred from the response body or status. The `cause` is a | ||
| * `MalformedResponseError` carrying the resolved response. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/rpc/link#malformed-responses | RPC Link - Malformed Responses} | ||
| * @see {@link https://orpc.dev/docs/openapi/link#malformed-responses | OpenAPI Link - Malformed Responses} | ||
| */ | ||
| declare function createORPCErrorFromMalformedResponse(options: MalformedResponseErrorOptions): ORPCError<'MALFORMED_ORPC_RESPONSE', StandardResponse>; | ||
| /** | ||
| * Clones an `ORPCError` while preserving its prototype chain, so instances of | ||
@@ -145,3 +156,3 @@ * `ORPCError` subclasses remain `instanceof` their class. | ||
| export { AnyNestedClient, AnyORPCError, Client, ClientContext, ClientLink, ClientOptions, ClientRest, DynamicLink, FriendlyClientOptions, InferClientContext, InferClientError, InferClientError as InferClientErrorUnion, ORPCError, ORPCErrorCode, ORPCErrorJSON, RECURSIVE_CLIENT_UNWRAP_KEYS, cloneORPCError, createORPCClient, createORPCErrorFromJson, createSafeClient, isInferableError as isDefinedError, isInferableError, isORPCErrorJson, resolveClientRest, resolveFriendlyClientOptions, safe, toORPCError, wrapAsyncIteratorPreservingEventMeta }; | ||
| export { AnyNestedClient, AnyORPCError, Client, ClientContext, ClientLink, ClientOptions, ClientRest, DynamicLink, FriendlyClientOptions, InferClientContext, InferClientError, InferClientError as InferClientErrorUnion, MalformedResponseErrorOptions, ORPCError, ORPCErrorCode, ORPCErrorJSON, RECURSIVE_CLIENT_UNWRAP_KEYS, cloneORPCError, createORPCClient, createORPCErrorFromJson, createORPCErrorFromMalformedResponse, createSafeClient, isInferableError as isDefinedError, isInferableError, isORPCErrorJson, resolveClientRest, resolveFriendlyClientOptions, safe, toORPCError, wrapAsyncIteratorPreservingEventMeta }; | ||
| export type { ORPCClientInterceptor, ORPCClientInterceptorOptions, ORPCClientOptions, ORPCClientScoped, ORPCClientScopedOptions, SafeClient, SafeResult }; |
+15
-4
| import { WrapAsyncIteratorOptions, AsyncIteratorClass, Interceptor, PromiseWithError, ThrowableError, Promisable } from '@orpc/shared'; | ||
| export { AsyncCleanupFn, AsyncIteratorClass, AsyncIteratorClassNextFn, PromiseWithError as ClientPromiseResult, MaybeOptionalOptions, PromiseWithError, Registry, ThrowableError, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, consumeAsyncIterator, consumeAsyncIterator as consumeEventIterator, asyncIteratorToStream as eventIteratorToStream, asyncIteratorToUnproxiedDataStream as eventIteratorToUnproxiedDataStream, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, streamToAsyncIteratorObject, streamToAsyncIteratorObject as streamToEventIterator } from '@orpc/shared'; | ||
| import { C as ClientContext, a as ClientOptions, c as AnyNestedClient, I as InferClientContext, d as InferClientError, e as Client, b as ClientLink, A as AnyORPCError, f as ClientRest, F as FriendlyClientOptions, O as ORPCErrorCode, g as ORPCErrorJSON, h as ORPCError } from './shared/client.l_EYklFG.js'; | ||
| export { i as AnyORPCErrorJSON, j as COMMON_ERROR_STATUS_MAP, k as InferClientBodyInputs, l as InferClientBodyOutputs, m as InferClientErrors, n as InferClientInputs, o as InferClientOutputs, N as NestedClient, p as ORPCErrorOptions } from './shared/client.l_EYklFG.js'; | ||
| import { C as ClientContext, a as ClientOptions, c as AnyNestedClient, I as InferClientContext, d as InferClientError, e as Client, b as ClientLink, A as AnyORPCError, f as ClientRest, F as FriendlyClientOptions, O as ORPCErrorCode, g as ORPCErrorJSON, h as ORPCError, M as MalformedResponseErrorOptions } from './shared/client.CFVTHyN6.js'; | ||
| export { i as AnyORPCErrorJSON, j as COMMON_ERROR_STATUS_MAP, k as InferClientBodyInputs, l as InferClientBodyOutputs, m as InferClientErrors, n as InferClientInputs, o as InferClientOutputs, p as MalformedResponseError, N as NestedClient, q as ORPCErrorOptions } from './shared/client.CFVTHyN6.js'; | ||
| import { StandardResponse } from '@standardserver/core'; | ||
| export { ErrorEvent, EventMeta, StandardBody, StandardBodyHint, StandardHeaders, StandardLazyRequest, StandardLazyResponse, StandardMethod, StandardRequest, StandardResponse, StandardUrl, getEventMeta, unwrapEvent, withEventMeta } from '@standardserver/core'; | ||
| export { R as RPCJsonSerialization, a as RPCJsonSerializationMeta, b as RPCJsonSerializer, c as RPCJsonSerializerHandler, d as RPCJsonSerializerOptions, e as RPCSerializer, f as RPCSerializerOptions, g as RPCSerializerSerializeOptions } from './shared/client.B8tCfDzm.js'; | ||
| export { ErrorEvent, EventMeta, getEventMeta, unwrapEvent, withEventMeta } from '@standardserver/core'; | ||
@@ -135,2 +136,12 @@ declare function wrapAsyncIteratorPreservingEventMeta<TYield, TReturn, TMappedYield = TYield, TMappedReturn = TReturn>(iterator: AsyncIterator<TYield, TReturn>, { mapResult, mapError, ...rest }: WrapAsyncIteratorOptions<TYield, TReturn, TMappedYield, TMappedReturn>): AsyncIteratorClass<TMappedYield, TMappedReturn>; | ||
| /** | ||
| * Creates the `MALFORMED_ORPC_RESPONSE` `ORPCError` used when a response | ||
| * does not follow the expected oRPC format. Unless overridden via `options.message`, | ||
| * the message is inferred from the response body or status. The `cause` is a | ||
| * `MalformedResponseError` carrying the resolved response. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/rpc/link#malformed-responses | RPC Link - Malformed Responses} | ||
| * @see {@link https://orpc.dev/docs/openapi/link#malformed-responses | OpenAPI Link - Malformed Responses} | ||
| */ | ||
| declare function createORPCErrorFromMalformedResponse(options: MalformedResponseErrorOptions): ORPCError<'MALFORMED_ORPC_RESPONSE', StandardResponse>; | ||
| /** | ||
| * Clones an `ORPCError` while preserving its prototype chain, so instances of | ||
@@ -145,3 +156,3 @@ * `ORPCError` subclasses remain `instanceof` their class. | ||
| export { AnyNestedClient, AnyORPCError, Client, ClientContext, ClientLink, ClientOptions, ClientRest, DynamicLink, FriendlyClientOptions, InferClientContext, InferClientError, InferClientError as InferClientErrorUnion, ORPCError, ORPCErrorCode, ORPCErrorJSON, RECURSIVE_CLIENT_UNWRAP_KEYS, cloneORPCError, createORPCClient, createORPCErrorFromJson, createSafeClient, isInferableError as isDefinedError, isInferableError, isORPCErrorJson, resolveClientRest, resolveFriendlyClientOptions, safe, toORPCError, wrapAsyncIteratorPreservingEventMeta }; | ||
| export { AnyNestedClient, AnyORPCError, Client, ClientContext, ClientLink, ClientOptions, ClientRest, DynamicLink, FriendlyClientOptions, InferClientContext, InferClientError, InferClientError as InferClientErrorUnion, MalformedResponseErrorOptions, ORPCError, ORPCErrorCode, ORPCErrorJSON, RECURSIVE_CLIENT_UNWRAP_KEYS, cloneORPCError, createORPCClient, createORPCErrorFromJson, createORPCErrorFromMalformedResponse, createSafeClient, isInferableError as isDefinedError, isInferableError, isORPCErrorJson, resolveClientRest, resolveFriendlyClientOptions, safe, toORPCError, wrapAsyncIteratorPreservingEventMeta }; | ||
| export type { ORPCClientInterceptor, ORPCClientInterceptorOptions, ORPCClientOptions, ORPCClientScoped, ORPCClientScopedOptions, SafeClient, SafeResult }; |
+3
-3
@@ -1,6 +0,6 @@ | ||
| import { a as isInferableError } from './shared/client.COv0qq2C.mjs'; | ||
| export { b as RPCJsonSerializer, R as RPCSerializer, d as cloneORPCError, c as createORPCErrorFromJson, i as isORPCErrorJson, t as toORPCError, w as wrapAsyncIteratorPreservingEventMeta } from './shared/client.COv0qq2C.mjs'; | ||
| import { b as isInferableError } from './shared/client.BnATe4Ob.mjs'; | ||
| export { d as RPCJsonSerializer, R as RPCSerializer, e as cloneORPCError, a as createORPCErrorFromJson, c as createORPCErrorFromMalformedResponse, i as isORPCErrorJson, t as toORPCError, w as wrapAsyncIteratorPreservingEventMeta } from './shared/client.BnATe4Ob.mjs'; | ||
| import { toArray, intercept, isTypescriptObject } from '@orpc/shared'; | ||
| export { AsyncIteratorClass, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, consumeAsyncIterator, consumeAsyncIterator as consumeEventIterator, asyncIteratorToStream as eventIteratorToStream, asyncIteratorToUnproxiedDataStream as eventIteratorToUnproxiedDataStream, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, streamToAsyncIteratorObject, streamToAsyncIteratorObject as streamToEventIterator } from '@orpc/shared'; | ||
| export { C as COMMON_ERROR_STATUS_MAP, O as ORPCError } from './shared/client.CPcOxSex.mjs'; | ||
| export { C as COMMON_ERROR_STATUS_MAP, M as MalformedResponseError, O as ORPCError } from './shared/client.DcoDDrD4.mjs'; | ||
| export { ErrorEvent, getEventMeta, unwrapEvent, withEventMeta } from '@standardserver/core'; | ||
@@ -7,0 +7,0 @@ |
| import { Value, Promisable } from '@orpc/shared'; | ||
| import { StandardUrl, StandardHeaders, StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { C as ClientContext } from '../shared/client.l_EYklFG.mjs'; | ||
| import { c as StandardLinkPlugin, d as StandardLinkTransportInterceptorOptions, b as StandardLinkOptions, e as StandardLinkInterceptorOptions } from '../shared/client.BkoxWb8f.mjs'; | ||
| import { C as ClientContext } from '../shared/client.CFVTHyN6.mjs'; | ||
| import { c as StandardLinkPlugin, d as StandardLinkTransportInterceptorOptions, b as StandardLinkOptions, e as StandardLinkInterceptorOptions } from '../shared/client.B0-4UDVl.mjs'; | ||
@@ -26,4 +26,2 @@ type BatchLinkPluginMode = 'streaming' | 'buffered'; | ||
| } | ||
| declare class BatchLinkPluginError extends TypeError { | ||
| } | ||
| interface BatchLinkPluginOptions<T extends ClientContext> { | ||
@@ -132,3 +130,3 @@ groups: [BatchLinkPluginGroup<T>, ...BatchLinkPluginGroup<T>[]]; | ||
| * | ||
| * @default ({ request }) => request.method === 'GET' | ||
| * @default ({ request }) => request.method === 'GET' || request.method === 'QUERY' | ||
| */ | ||
@@ -357,3 +355,3 @@ filter?: Value<boolean, [options: StandardLinkTransportInterceptorOptions<T>]>; | ||
| export { BatchLinkPlugin, BatchLinkPluginError, RetryLinkPlugin as ClientRetryPlugin, DedupeLinkPlugin, DedupeLinkPlugin as DedupeRequestsPlugin, RequestCompressionLinkPlugin, ResponseCompressionLinkPlugin, RetryAfterLinkPlugin, RetryAfterLinkPlugin as RetryAfterPlugin, RetryLinkPlugin, TimeoutLinkPlugin }; | ||
| export { BatchLinkPlugin, RetryLinkPlugin as ClientRetryPlugin, DedupeLinkPlugin, DedupeLinkPlugin as DedupeRequestsPlugin, RequestCompressionLinkPlugin, ResponseCompressionLinkPlugin, RetryAfterLinkPlugin, RetryAfterLinkPlugin as RetryAfterPlugin, RetryLinkPlugin, TimeoutLinkPlugin }; | ||
| export type { BatchLinkPluginGroup, BatchLinkPluginMode, BatchLinkPluginOptions, RetryLinkPluginContext as ClientRetryPluginContext, DedupeLinkPluginGroup, DedupeLinkPluginOptions, RequestCompressionLinkPluginOptions, ResponseCompressionLinkPluginOptions, RetryAfterLinkPluginOptions, RetryLinkPluginAttemptOptions, RetryLinkPluginContext, RetryLinkPluginOptions, TimeoutLinkPluginOptions }; |
| import { Value, Promisable } from '@orpc/shared'; | ||
| import { StandardUrl, StandardHeaders, StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { C as ClientContext } from '../shared/client.l_EYklFG.js'; | ||
| import { c as StandardLinkPlugin, d as StandardLinkTransportInterceptorOptions, b as StandardLinkOptions, e as StandardLinkInterceptorOptions } from '../shared/client.ByTd6BR5.js'; | ||
| import { C as ClientContext } from '../shared/client.CFVTHyN6.js'; | ||
| import { c as StandardLinkPlugin, d as StandardLinkTransportInterceptorOptions, b as StandardLinkOptions, e as StandardLinkInterceptorOptions } from '../shared/client.BhTyskpV.js'; | ||
@@ -26,4 +26,2 @@ type BatchLinkPluginMode = 'streaming' | 'buffered'; | ||
| } | ||
| declare class BatchLinkPluginError extends TypeError { | ||
| } | ||
| interface BatchLinkPluginOptions<T extends ClientContext> { | ||
@@ -132,3 +130,3 @@ groups: [BatchLinkPluginGroup<T>, ...BatchLinkPluginGroup<T>[]]; | ||
| * | ||
| * @default ({ request }) => request.method === 'GET' | ||
| * @default ({ request }) => request.method === 'GET' || request.method === 'QUERY' | ||
| */ | ||
@@ -357,3 +355,3 @@ filter?: Value<boolean, [options: StandardLinkTransportInterceptorOptions<T>]>; | ||
| export { BatchLinkPlugin, BatchLinkPluginError, RetryLinkPlugin as ClientRetryPlugin, DedupeLinkPlugin, DedupeLinkPlugin as DedupeRequestsPlugin, RequestCompressionLinkPlugin, ResponseCompressionLinkPlugin, RetryAfterLinkPlugin, RetryAfterLinkPlugin as RetryAfterPlugin, RetryLinkPlugin, TimeoutLinkPlugin }; | ||
| export { BatchLinkPlugin, RetryLinkPlugin as ClientRetryPlugin, DedupeLinkPlugin, DedupeLinkPlugin as DedupeRequestsPlugin, RequestCompressionLinkPlugin, ResponseCompressionLinkPlugin, RetryAfterLinkPlugin, RetryAfterLinkPlugin as RetryAfterPlugin, RetryLinkPlugin, TimeoutLinkPlugin }; | ||
| export type { BatchLinkPluginGroup, BatchLinkPluginMode, BatchLinkPluginOptions, RetryLinkPluginContext as ClientRetryPluginContext, DedupeLinkPluginGroup, DedupeLinkPluginOptions, RequestCompressionLinkPluginOptions, ResponseCompressionLinkPluginOptions, RetryAfterLinkPluginOptions, RetryLinkPluginAttemptOptions, RetryLinkPluginContext, RetryLinkPluginOptions, TimeoutLinkPluginOptions }; |
+26
-16
@@ -1,9 +0,7 @@ | ||
| import { toArray, value, splitInHalf, stringifyJSON, isAsyncIteratorObject, defer, loadBytes, allAbortSignal, replicateAsyncIterator, replicateReadableStream, isCompressibleContentType, override, AsyncIteratorClass, sleep, AbortError, anyAbortSignal } from '@orpc/shared'; | ||
| import { toArray, value, splitInHalf, stringifyJSON, once, isAsyncIteratorObject, defer, loadBytes, allAbortSignal, replicateAsyncIterator, replicateReadableStream, isCompressibleContentType, override, AsyncIteratorClass, sleep, AbortError, anyAbortSignal } from '@orpc/shared'; | ||
| import { parseStandardUrl, flattenStandardHeader, generateContentDisposition, getEventMeta } from '@standardserver/core'; | ||
| import { ClientPeer, isServerPeerSendMessage, decodePeerMessage } from '@standardserver/peer'; | ||
| import { toFetchHeaders, toStandardBody } from '@standardserver/fetch'; | ||
| import { C as COMMON_ERROR_STATUS_MAP } from '../shared/client.CPcOxSex.mjs'; | ||
| import { C as COMMON_ERROR_STATUS_MAP } from '../shared/client.DcoDDrD4.mjs'; | ||
| class BatchLinkPluginError extends TypeError { | ||
| } | ||
| class BatchLinkPlugin { | ||
@@ -55,3 +53,3 @@ name = "~batch"; | ||
| }); | ||
| this.mapSubresponse = (subResponse, batchResponse) => { | ||
| this.mapSubresponse = options.mapSubresponse ?? ((subResponse, batchResponse) => { | ||
| return { | ||
@@ -65,3 +63,3 @@ ...subResponse, | ||
| }; | ||
| }; | ||
| }); | ||
| } | ||
@@ -96,5 +94,7 @@ init(options) { | ||
| const getItems = items.filter(([options]) => options.request.method === "GET"); | ||
| const restItems = items.filter(([options]) => options.request.method !== "GET"); | ||
| const queryItems = items.filter(([options]) => options.request.method === "QUERY"); | ||
| const unsafeItems = items.filter(([options]) => options.request.method !== "GET" && options.request.method !== "QUERY"); | ||
| this.executeBatch("GET", group, getItems); | ||
| this.executeBatch("POST", group, restItems); | ||
| this.executeBatch("QUERY", group, queryItems); | ||
| this.executeBatch("POST", group, unsafeItems); | ||
| } | ||
@@ -168,2 +168,12 @@ } | ||
| }); | ||
| if (batchResponse.status >= 400) { | ||
| suppressErrorFromCurrentBatch = true; | ||
| const resolveBody = once(() => batchResponse.resolveBody()); | ||
| const errorResponse = { ...batchResponse, resolveBody }; | ||
| groupItems.forEach(([subOptions, resolve]) => { | ||
| resolve(this.mapSubresponse(errorResponse, batchResponse, subOptions)); | ||
| }); | ||
| await peer.close(); | ||
| return; | ||
| } | ||
| const body = await batchResponse.resolveBody(); | ||
@@ -179,5 +189,5 @@ if (Array.isArray(body) && body.every((v) => isServerPeerSendMessage(v))) { | ||
| } else { | ||
| throw new BatchLinkPluginError("Invalid batch response format."); | ||
| throw new TypeError("Invalid batch response format."); | ||
| } | ||
| await peer.close(new BatchLinkPluginError("Batch response is incomplete.")); | ||
| await peer.close(new TypeError("Batch response is incomplete.")); | ||
| } catch (error) { | ||
@@ -203,3 +213,3 @@ await peer.close(error); | ||
| if (offset + 4 > buffer.length) { | ||
| throw new BatchLinkPluginError("Invalid batch response: incomplete length header."); | ||
| throw new TypeError("Invalid batch response: incomplete length header."); | ||
| } | ||
@@ -210,3 +220,3 @@ const view = new DataView(buffer.buffer, buffer.byteOffset + offset, 4); | ||
| if (offset + length > buffer.length) { | ||
| throw new BatchLinkPluginError("Invalid batch response: incomplete message."); | ||
| throw new TypeError("Invalid batch response: incomplete message."); | ||
| } | ||
@@ -217,3 +227,3 @@ const messageBytes = buffer.subarray(offset, offset + length); | ||
| if (!result.matched || !isServerPeerSendMessage(result.message)) { | ||
| throw new BatchLinkPluginError("Invalid batch response: invalid message."); | ||
| throw new TypeError("Invalid batch response: invalid message."); | ||
| } | ||
@@ -249,3 +259,3 @@ await peer.message(result.message); | ||
| if (!result.matched || !isServerPeerSendMessage(result.message)) { | ||
| throw new BatchLinkPluginError("Invalid batch response: invalid message."); | ||
| throw new TypeError("Invalid batch response: invalid message."); | ||
| } | ||
@@ -271,3 +281,3 @@ await peer.message(result.message); | ||
| this.groups = options.groups; | ||
| this.filter = options.filter ?? (({ request }) => request.method === "GET"); | ||
| this.filter = options.filter ?? (({ request }) => request.method === "GET" || request.method === "QUERY"); | ||
| } | ||
@@ -841,2 +851,2 @@ init(options) { | ||
| export { BatchLinkPlugin, BatchLinkPluginError, RetryLinkPlugin as ClientRetryPlugin, DedupeLinkPlugin, DedupeLinkPlugin as DedupeRequestsPlugin, RequestCompressionLinkPlugin, ResponseCompressionLinkPlugin, RetryAfterLinkPlugin, RetryAfterLinkPlugin as RetryAfterPlugin, RetryLinkPlugin, TimeoutLinkPlugin }; | ||
| export { BatchLinkPlugin, RetryLinkPlugin as ClientRetryPlugin, DedupeLinkPlugin, DedupeLinkPlugin as DedupeRequestsPlugin, RequestCompressionLinkPlugin, ResponseCompressionLinkPlugin, RetryAfterLinkPlugin, RetryAfterLinkPlugin as RetryAfterPlugin, RetryLinkPlugin, TimeoutLinkPlugin }; |
+2
-2
| { | ||
| "name": "@orpc/client", | ||
| "type": "module", | ||
| "version": "2.0.0-beta.26", | ||
| "version": "2.0.0-beta.27", | ||
| "license": "MIT", | ||
@@ -57,3 +57,3 @@ "funding": "https://github.com/sponsors/dinwwwh", | ||
| "@standardserver/peer": "^0.7.1", | ||
| "@orpc/shared": "2.0.0-beta.26" | ||
| "@orpc/shared": "2.0.0-beta.27" | ||
| }, | ||
@@ -60,0 +60,0 @@ "devDependencies": { |
+37
-76
@@ -59,2 +59,3 @@ <h1 align="center">oRPC - Typesafe APIs Made Simple 🪄</h1> | ||
| - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/). | ||
| - [@orpc/node](https://www.npmjs.com/package/@orpc/node): [Node.js](https://nodejs.org/) plugins, helpers, like serving static files. | ||
| - [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/). | ||
@@ -78,3 +79,3 @@ - [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare): Adapters for [Cloudflare's RateLimit and Durable Objects](https://developers.cloudflare.com/workers/). | ||
| <tr> | ||
| <td align="center"><a href="https://screenshotone.com/?ref=orpc" target="_blank" rel="noopener" title="ScreenshotOne.com"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="279" alt="ScreenshotOne.com"/><br />ScreenshotOne.com</a></td> | ||
| <td align="center"><a href="https://screenshotone.com/?ref=orpc" target="_blank" rel="sponsored noopener" title="ScreenshotOne.com"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="279" alt="ScreenshotOne.com"/><br />ScreenshotOne.com</a></td> | ||
| </tr> | ||
@@ -87,3 +88,3 @@ </table> | ||
| <tr> | ||
| <td align="center"><a href="https://misskey.io/?ref=orpc" target="_blank" rel="noopener" title="村上さん"><img src="https://avatars.githubusercontent.com/u/37681609?u=0dd4c7e4ba937cbb52b068c55914b1d8164dc0c7&v=4" width="209" alt="村上さん"/><br />村上さん</a></td> | ||
| <td align="center"><a href="https://misskey.io/?ref=orpc" target="_blank" rel="sponsored noopener" title="村上さん"><img src="https://avatars.githubusercontent.com/u/37681609?u=0dd4c7e4ba937cbb52b068c55914b1d8164dc0c7&v=4" width="209" alt="村上さん"/><br />村上さん</a></td> | ||
| </tr> | ||
@@ -96,3 +97,3 @@ </table> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/ln-markets?ref=orpc" target="_blank" rel="noopener" title="LN Markets"><img src="https://avatars.githubusercontent.com/u/70597625?v=4" width="167" alt="LN Markets"/><br />LN Markets</a></td> | ||
| <td align="center"><a href="https://github.com/ln-markets?ref=orpc" target="_blank" rel="sponsored noopener" title="LN Markets"><img src="https://avatars.githubusercontent.com/u/70597625?v=4" width="167" alt="LN Markets"/><br />LN Markets</a></td> | ||
| </tr> | ||
@@ -105,20 +106,21 @@ </table> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/hrmcdonald?ref=orpc" target="_blank" rel="noopener" title="Reece McDonald"><img src="https://avatars.githubusercontent.com/u/39349270?v=4" width="139" alt="Reece McDonald"/><br />Reece McDonald</a></td> | ||
| <td align="center"><a href="https://github.com/nicognaW?ref=orpc" target="_blank" rel="noopener" title="nk"><img src="https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&v=4" width="139" alt="nk"/><br />nk</a></td> | ||
| <td align="center"><a href="https://github.com/supastarter?ref=orpc" target="_blank" rel="noopener" title="supastarter"><img src="https://avatars.githubusercontent.com/u/110960143?v=4" width="139" alt="supastarter"/><br />supastarter</a></td> | ||
| <td align="center"><a href="https://github.com/divmgl?ref=orpc" target="_blank" rel="noopener" title="Dexter Miguel"><img src="https://avatars.githubusercontent.com/u/5452298?u=645993204be8696c085ecf0d228c3062efe2ed65&v=4" width="139" alt="Dexter Miguel"/><br />Dexter Miguel</a></td> | ||
| <td align="center"><a href="https://github.com/herrfugbaum?ref=orpc" target="_blank" rel="noopener" title="herrfugbaum"><img src="https://avatars.githubusercontent.com/u/12859776?u=644dc1666d0220bc0468eb0de3c56b919f635b16&v=4" width="139" alt="herrfugbaum"/><br />herrfugbaum</a></td> | ||
| <td align="center"><a href="https://github.com/ryota-murakami?ref=orpc" target="_blank" rel="noopener" title="Ryota Murakami"><img src="https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&v=4" width="139" alt="Ryota Murakami"/><br />Ryota Murakami</a></td> | ||
| <td align="center"><a href="https://github.com/hrmcdonald?ref=orpc" target="_blank" rel="sponsored noopener" title="Reece McDonald"><img src="https://avatars.githubusercontent.com/u/39349270?v=4" width="139" alt="Reece McDonald"/><br />Reece McDonald</a></td> | ||
| <td align="center"><a href="https://github.com/u1-liquid?ref=orpc" target="_blank" rel="sponsored noopener" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&v=4" width="139" alt="あわわわとーにゅ"/><br />あわわわとーにゅ</a></td> | ||
| <td align="center"><a href="https://github.com/nicognaW?ref=orpc" target="_blank" rel="sponsored noopener" title="nk"><img src="https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&v=4" width="139" alt="nk"/><br />nk</a></td> | ||
| <td align="center"><a href="https://github.com/supastarter?ref=orpc" target="_blank" rel="sponsored noopener" title="supastarter"><img src="https://avatars.githubusercontent.com/u/110960143?v=4" width="139" alt="supastarter"/><br />supastarter</a></td> | ||
| <td align="center"><a href="https://github.com/divmgl?ref=orpc" target="_blank" rel="sponsored noopener" title="Dexter Miguel"><img src="https://avatars.githubusercontent.com/u/5452298?u=645993204be8696c085ecf0d228c3062efe2ed65&v=4" width="139" alt="Dexter Miguel"/><br />Dexter Miguel</a></td> | ||
| <td align="center"><a href="https://github.com/herrfugbaum?ref=orpc" target="_blank" rel="sponsored noopener" title="herrfugbaum"><img src="https://avatars.githubusercontent.com/u/12859776?u=644dc1666d0220bc0468eb0de3c56b919f635b16&v=4" width="139" alt="herrfugbaum"/><br />herrfugbaum</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/dcramer?ref=orpc" target="_blank" rel="noopener" title="David Cramer"><img src="https://avatars.githubusercontent.com/u/23610?v=4" width="139" alt="David Cramer"/><br />David Cramer</a></td> | ||
| <td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td> | ||
| <td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td> | ||
| <td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td> | ||
| <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td> | ||
| <td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td> | ||
| <td align="center"><a href="https://github.com/ryota-murakami?ref=orpc" target="_blank" rel="sponsored noopener" title="Ryota Murakami"><img src="https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&v=4" width="139" alt="Ryota Murakami"/><br />Ryota Murakami</a></td> | ||
| <td align="center"><a href="https://github.com/dcramer?ref=orpc" target="_blank" rel="sponsored noopener" title="David Cramer"><img src="https://avatars.githubusercontent.com/u/23610?v=4" width="139" alt="David Cramer"/><br />David Cramer</a></td> | ||
| <td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="sponsored noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td> | ||
| <td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="sponsored noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td> | ||
| <td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="sponsored noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td> | ||
| <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="sponsored noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&v=4" width="139" alt="shota"/><br />shota</a></td> | ||
| <td align="center"><a href="https://github.com/ellis-driscoll?ref=orpc" target="_blank" rel="noopener" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td> | ||
| <td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="sponsored noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td> | ||
| <td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="sponsored noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&v=4" width="139" alt="shota"/><br />shota</a></td> | ||
| <td align="center"><a href="https://github.com/ellis-driscoll?ref=orpc" target="_blank" rel="sponsored noopener" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td> | ||
| </tr> | ||
@@ -131,69 +133,28 @@ </table> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td> | ||
| <td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td> | ||
| <td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td> | ||
| <td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&v=4" width="119" alt="soonoo"/><br />soonoo</a></td> | ||
| <td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td> | ||
| <td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&v=4" width="119" alt="Denis"/><br />Denis</a></td> | ||
| <td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td> | ||
| <td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="sponsored noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td> | ||
| <td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="sponsored noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td> | ||
| <td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="sponsored noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td> | ||
| <td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="sponsored noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&v=4" width="119" alt="soonoo"/><br />soonoo</a></td> | ||
| <td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="sponsored noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td> | ||
| <td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="sponsored noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&v=4" width="119" alt="Denis"/><br />Denis</a></td> | ||
| <td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="sponsored noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td> | ||
| <td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&v=4" width="119" alt="Sam"/><br />Sam</a></td> | ||
| <td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&v=4" width="119" alt="Titoine"/><br />Titoine</a></td> | ||
| <td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td> | ||
| <td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td> | ||
| <td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td> | ||
| <td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td> | ||
| <td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="sponsored noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td> | ||
| <td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="sponsored noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&v=4" width="119" alt="Sam"/><br />Sam</a></td> | ||
| <td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="sponsored noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&v=4" width="119" alt="Titoine"/><br />Titoine</a></td> | ||
| <td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="sponsored noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td> | ||
| <td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="sponsored noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td> | ||
| <td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="sponsored noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td> | ||
| <td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="sponsored noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/guyariely?ref=orpc" target="_blank" rel="noopener" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td> | ||
| <td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&v=4" width="119" alt="Alex"/><br />Alex</a></td> | ||
| <td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td> | ||
| <td align="center"><a href="https://github.com/guyariely?ref=orpc" target="_blank" rel="sponsored noopener" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td> | ||
| <td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="sponsored noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&v=4" width="119" alt="Alex"/><br />Alex</a></td> | ||
| <td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="sponsored noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td> | ||
| </tr> | ||
| </table> | ||
| ### Past Sponsors | ||
| With thanks to 37 past sponsors who helped get oRPC here. | ||
| <p> | ||
| <a href="https://github.com/MrMaxie?ref=orpc" target="_blank" rel="noopener" title="Maxie"><img src="https://avatars.githubusercontent.com/u/3857836?u=5e6b57973d4385d655663ffdd836e487856f2984&v=4" width="32" height="32" alt="Maxie" /></a> | ||
| <a href="https://github.com/Stijn-Timmer?ref=orpc" target="_blank" rel="noopener" title="Stijn Timmer"><img src="https://avatars.githubusercontent.com/u/100147665?u=106b2c18e9c98a61861b4ee7fc100f5b9906a6c9&v=4" width="32" height="32" alt="Stijn Timmer" /></a> | ||
| <a href="https://github.com/u1-liquid?ref=orpc" target="_blank" rel="noopener" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&v=4" width="32" height="32" alt="あわわわとーにゅ" /></a> | ||
| <a href="https://github.com/zuplo?ref=orpc" target="_blank" rel="noopener" title="Zuplo"><img src="https://avatars.githubusercontent.com/u/85497839?v=4" width="32" height="32" alt="Zuplo" /></a> | ||
| <a href="https://github.com/motopods?ref=orpc" target="_blank" rel="noopener" title="motopods"><img src="https://avatars.githubusercontent.com/u/58200641?v=4" width="32" height="32" alt="motopods" /></a> | ||
| <a href="https://github.com/franciscohermida?ref=orpc" target="_blank" rel="noopener" title="Francisco Hermida"><img src="https://avatars.githubusercontent.com/u/483242?u=bbcbc80eb9d8781ff401f7dafc3b59cd7bea0561&v=4" width="32" height="32" alt="Francisco Hermida" /></a> | ||
| <a href="https://github.com/theoludwig?ref=orpc" target="_blank" rel="noopener" title="Théo LUDWIG"><img src="https://avatars.githubusercontent.com/u/25207499?u=a6a9653725a2f574c07893748806668e0598cdbe&v=4" width="32" height="32" alt="Théo LUDWIG" /></a> | ||
| <a href="https://github.com/abhay-ramesh?ref=orpc" target="_blank" rel="noopener" title="Abhay Ramesh"><img src="https://avatars.githubusercontent.com/u/66196314?u=c5c2b0327b26606c2efcfaf17046ab18c3d25c57&v=4" width="32" height="32" alt="Abhay Ramesh" /></a> | ||
| <a href="https://github.com/shr-ink?ref=orpc" target="_blank" rel="noopener" title="shr.ink oü"><img src="https://avatars.githubusercontent.com/u/139700438?v=4" width="32" height="32" alt="shr.ink oü" /></a> | ||
| <a href="https://github.com/johngerome?ref=orpc" target="_blank" rel="noopener" title="0x4e32"><img src="https://avatars.githubusercontent.com/u/2002000?u=505e54608466ab53754f702973687b04c6424c1f&v=4" width="32" height="32" alt="0x4e32" /></a> | ||
| <a href="https://github.com/yzuyr?ref=orpc" target="_blank" rel="noopener" title="Ryuz"><img src="https://avatars.githubusercontent.com/u/196539378?u=d38374588d219b6748b16406982f6559411466d4&v=4" width="32" height="32" alt="Ryuz" /></a> | ||
| <a href="https://github.com/happyboy2022?ref=orpc" target="_blank" rel="noopener" title="happyboy"><img src="https://avatars.githubusercontent.com/u/103669586?u=65b49c4b893ed3703909fbb3a7a22313f3f9c121&v=4" width="32" height="32" alt="happyboy" /></a> | ||
| <a href="https://github.com/YiCChi?ref=orpc" target="_blank" rel="noopener" title="yicchi"><img src="https://avatars.githubusercontent.com/u/86967274?u=6c2756f09fe15dd94d572f560e979cd157982852&v=4" width="32" height="32" alt="yicchi" /></a> | ||
| <a href="https://github.com/cloudycotton?ref=orpc" target="_blank" rel="noopener" title="Saksham"><img src="https://avatars.githubusercontent.com/u/168998965?u=9b9634a5aed66a51c1b880663272725b00b92b14&v=4" width="32" height="32" alt="Saksham" /></a> | ||
| <a href="https://github.com/hrynevychroman?ref=orpc" target="_blank" rel="noopener" title="Roman Hrynevych"><img src="https://avatars.githubusercontent.com/u/82209198?u=1a1d111ab3d589855b9cc8a7fefb1b5c6a4fbbaf&v=4" width="32" height="32" alt="Roman Hrynevych" /></a> | ||
| <a href="https://github.com/rokitgg?ref=orpc" target="_blank" rel="noopener" title="rokitg"><img src="https://avatars.githubusercontent.com/u/125133357?u=06c74aefaa2236b06a2e5fba5a5c612339f45912&v=4" width="32" height="32" alt="rokitg" /></a> | ||
| <a href="https://github.com/omarkhatibgg?ref=orpc" target="_blank" rel="noopener" title="Omar Khatib"><img src="https://avatars.githubusercontent.com/u/9054278?u=afbba7331b85c51b8eee4130f5fd31b1017dc919&v=4" width="32" height="32" alt="Omar Khatib" /></a> | ||
| <a href="https://github.com/YuSabo90002?ref=orpc" target="_blank" rel="noopener" title="Yu-Sabo"><img src="https://avatars.githubusercontent.com/u/13120582?v=4" width="32" height="32" alt="Yu-Sabo" /></a> | ||
| <a href="https://github.com/bapspatil?ref=orpc" target="_blank" rel="noopener" title="Bapusaheb Patil"><img src="https://avatars.githubusercontent.com/u/16699418?u=6d9d8e0a64a6f91ca1c4d559c72d931172bdcbbd&v=4" width="32" height="32" alt="Bapusaheb Patil" /></a> | ||
| <a href="https://github.com/ripgrim?ref=orpc" target="_blank" rel="noopener" title="grim"><img src="https://avatars.githubusercontent.com/u/75869731?u=b17c42ec2309552fdb822a86b25a2f99146a4d72&v=4" width="32" height="32" alt="grim" /></a> | ||
| <a href="https://github.com/nelsonlaidev?ref=orpc" target="_blank" rel="noopener" title="Nelson Lai"><img src="https://avatars.githubusercontent.com/u/75498339?u=2fc0e0b95dd184c5ffb744df977cb15a18b60672&v=4" width="32" height="32" alt="Nelson Lai" /></a> | ||
| <a href="https://github.com/nguyenlc1993?ref=orpc" target="_blank" rel="noopener" title="Lê Cao Nguyên"><img src="https://avatars.githubusercontent.com/u/13871971?u=83c8b69d9e35b589c4e1f066cc113b1d9461386f&v=4" width="32" height="32" alt="Lê Cao Nguyên" /></a> | ||
| <a href="https://github.com/wobsoriano?ref=orpc" target="_blank" rel="noopener" title="Robert Soriano"><img src="https://avatars.githubusercontent.com/u/13049130?u=6d72104182e7c9ed25934815313fb69107332111&v=4" width="32" height="32" alt="Robert Soriano" /></a> | ||
| <a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="32" height="32" alt="Andrew Peters" /></a> | ||
| <a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&v=4" width="32" height="32" alt="Ryan Vogel" /></a> | ||
| <a href="https://github.com/SKostyukovich?ref=orpc" target="_blank" rel="noopener" title="SKostyukovich"><img src="https://avatars.githubusercontent.com/u/10700067?v=4" width="32" height="32" alt="SKostyukovich" /></a> | ||
| <a href="https://github.com/peter-adam-dy?ref=orpc" target="_blank" rel="noopener" title="Peter Adam"><img src="https://avatars.githubusercontent.com/u/132129459?u=4f3dbbb3b443990b56acb7d6a5d11ed2c555f6db&v=4" width="32" height="32" alt="Peter Adam" /></a> | ||
| <a href="https://github.com/FabworksHQ?ref=orpc" target="_blank" rel="noopener" title="Fabworks"><img src="https://avatars.githubusercontent.com/u/160179500?v=4" width="32" height="32" alt="Fabworks" /></a> | ||
| <a href="https://github.com/NovakAnton?ref=orpc" target="_blank" rel="noopener" title="Novak Antonijevic"><img src="https://avatars.githubusercontent.com/u/157126729?u=ae49fa22292d55c0434ff0ca008206155b18663b&v=4" width="32" height="32" alt="Novak Antonijevic" /></a> | ||
| <a href="https://github.com/laduniestu?ref=orpc" target="_blank" rel="noopener" title="Laduni Estu Syalwa"><img src="https://avatars.githubusercontent.com/u/44757637?u=a2fc1ea8f7d827a96721176f79d30592d1c48059&v=4" width="32" height="32" alt="Laduni Estu Syalwa" /></a> | ||
| <a href="https://github.com/yukimotochern?ref=orpc" target="_blank" rel="noopener" title="Chen, Zhi-Yuan"><img src="https://avatars.githubusercontent.com/u/20896173?u=945c33fc21725e4d566a0d02afc54b136ca1d67a&v=4" width="32" height="32" alt="Chen, Zhi-Yuan" /></a> | ||
| <a href="https://github.com/illarionvk?ref=orpc" target="_blank" rel="noopener" title="Illarion Koperski"><img src="https://avatars.githubusercontent.com/u/5012724?u=7cfa13652f7ac5fb3c56d880e3eb3fbe40c3ea34&v=4" width="32" height="32" alt="Illarion Koperski" /></a> | ||
| <a href="https://github.com/steelbrain?ref=orpc" target="_blank" rel="noopener" title="Anees Iqbal"><img src="https://avatars.githubusercontent.com/u/4278113?u=22b80b5399eed68ac76cd58b02961b0481f1db11&v=4" width="32" height="32" alt="Anees Iqbal" /></a> | ||
| <a href="https://github.com/Scrumplex?ref=orpc" target="_blank" rel="noopener" title="Sefa Eyeoglu"><img src="https://avatars.githubusercontent.com/u/11587657?u=ab503582165c0bbff0cca47ce31c9450bb1553c9&v=4" width="32" height="32" alt="Sefa Eyeoglu" /></a> | ||
| <a href="https://github.com/nattstack?ref=orpc" target="_blank" rel="noopener" title="natt"><img src="https://avatars.githubusercontent.com/u/31426677?u=fa9dbb8b3e66eb0ea3c88db5dc07f31c8c5418fe&v=4" width="32" height="32" alt="natt" /></a> | ||
| <a href="https://github.com/ChromeGG?ref=orpc" target="_blank" rel="noopener" title="Adam Tkaczyk"><img src="https://avatars.githubusercontent.com/u/39050595?u=a58ca6042a6950e94e6e92442db76ef584279bc0&v=4" width="32" height="32" alt="Adam Tkaczyk" /></a> | ||
| <a href="https://github.com/plancraft?ref=orpc" target="_blank" rel="noopener" title="plancraft"><img src="https://avatars.githubusercontent.com/u/46482287?v=4" width="32" height="32" alt="plancraft" /></a> | ||
| <a href="https://github.com/Nic13Gamer?ref=orpc" target="_blank" rel="noopener" title="Nicholas"><img src="https://avatars.githubusercontent.com/u/54724556?u=56a7ab430ce7a80d648ab6eba051d454a818ed0b&v=4" width="32" height="32" alt="Nicholas" /></a> | ||
| </p> | ||
| ## References | ||
@@ -200,0 +161,0 @@ |
| import { Promisable, OrderablePlugin, Interceptor } from '@orpc/shared'; | ||
| import { StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.l_EYklFG.mjs'; | ||
| type StandardLinkCodecDecodedResponse = { | ||
| kind: 'output'; | ||
| output: unknown; | ||
| } | { | ||
| kind: 'error'; | ||
| error: AnyORPCError; | ||
| }; | ||
| interface StandardLinkCodec<T extends ClientContext> { | ||
| encodeInput(input: unknown, path: string[], options: ClientOptions<T>): Promisable<StandardRequest>; | ||
| decodeResponse(response: StandardLazyResponse, path: string[], options: ClientOptions<T>): Promisable<StandardLinkCodecDecodedResponse>; | ||
| } | ||
| interface StandardLinkPlugin<T extends ClientContext> extends OrderablePlugin { | ||
| /** | ||
| * Initializes the plugin and returns new link options. | ||
| * Called once per plugin instance during composition. | ||
| * | ||
| * This method allows plugins to wrap, extend, or transform link options | ||
| * such as interceptors, or configuration. | ||
| * | ||
| * @param options - The current link options from previous plugins or base configuration | ||
| * @returns Transformed link options with plugin's modifications applied | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * init(options) { | ||
| * return { | ||
| * ...options, | ||
| * interceptors: [...(options.interceptors || []), myInterceptor] | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| init?(options: StandardLinkOptions<T>): StandardLinkOptions<T>; | ||
| } | ||
| declare class CompositeStandardLinkPlugin<T extends ClientContext> implements StandardLinkPlugin<T> { | ||
| name: string; | ||
| protected readonly plugins: StandardLinkPlugin<T>[]; | ||
| constructor(plugins?: StandardLinkPlugin<T>[]); | ||
| init(options: StandardLinkOptions<T>): StandardLinkOptions<T>; | ||
| } | ||
| /** | ||
| * Handles the transport layer for sending requests and receiving responses. | ||
| * | ||
| * Implementations are responsible for the actual network communication, | ||
| * such as HTTP fetch, WebSocket, or other transport mechanisms. | ||
| */ | ||
| interface StandardLinkTransport<T extends ClientContext> { | ||
| /** | ||
| * @throws Transport-level errors (network failures, timeouts, etc.) | ||
| */ | ||
| send(request: StandardRequest, path: string[], options: ClientOptions<T>): Promise<StandardLazyResponse>; | ||
| } | ||
| interface StandardLinkInterceptorOptions<T extends ClientContext> extends ClientOptions<T> { | ||
| path: string[]; | ||
| input: unknown; | ||
| } | ||
| type StandardLinkInterceptor<T extends ClientContext> = Interceptor<StandardLinkInterceptorOptions<T>, Promise<unknown>>; | ||
| interface StandardLinkTransportInterceptorOptions<T extends ClientContext> extends ClientOptions<T> { | ||
| path: string[]; | ||
| request: StandardRequest; | ||
| } | ||
| type StandardLinkTransportInterceptor<T extends ClientContext> = Interceptor<StandardLinkTransportInterceptorOptions<T>, Promise<StandardLazyResponse>>; | ||
| interface StandardLinkOptions<T extends ClientContext> { | ||
| /** | ||
| * Interceptors that execute around the entire call, including transport and codec. | ||
| * Useful for error handling, logging, metrics, ... | ||
| */ | ||
| interceptors?: StandardLinkInterceptor<T>[]; | ||
| /** | ||
| * Interceptors that execute around the transport layer, after encoding and before decoding. | ||
| * Useful for modifying the request or response, adding transport-level logging, ... | ||
| */ | ||
| transportInterceptors?: StandardLinkTransportInterceptor<T>[]; | ||
| plugins?: StandardLinkPlugin<T>[]; | ||
| } | ||
| declare class StandardLink<T extends ClientContext> implements ClientLink<T> { | ||
| private readonly codec; | ||
| private readonly transport; | ||
| private readonly interceptors; | ||
| private readonly transportInterceptors; | ||
| constructor(codec: StandardLinkCodec<T>, transport: StandardLinkTransport<T>, options?: StandardLinkOptions<T>); | ||
| /** | ||
| * @throws ORPCError, transport-level errors (network failures, timeouts, etc.) | ||
| */ | ||
| call(path: string[], input: unknown, options: ClientOptions<T>): Promise<unknown>; | ||
| } | ||
| export { CompositeStandardLinkPlugin as C, StandardLink as a }; | ||
| export type { StandardLinkTransport as S, StandardLinkOptions as b, StandardLinkPlugin as c, StandardLinkTransportInterceptorOptions as d, StandardLinkInterceptorOptions as e, StandardLinkCodec as f, StandardLinkCodecDecodedResponse as g, StandardLinkInterceptor as h, StandardLinkTransportInterceptor as i }; |
| import { Promisable, OrderablePlugin, Interceptor } from '@orpc/shared'; | ||
| import { StandardRequest, StandardLazyResponse } from '@standardserver/core'; | ||
| import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.l_EYklFG.js'; | ||
| type StandardLinkCodecDecodedResponse = { | ||
| kind: 'output'; | ||
| output: unknown; | ||
| } | { | ||
| kind: 'error'; | ||
| error: AnyORPCError; | ||
| }; | ||
| interface StandardLinkCodec<T extends ClientContext> { | ||
| encodeInput(input: unknown, path: string[], options: ClientOptions<T>): Promisable<StandardRequest>; | ||
| decodeResponse(response: StandardLazyResponse, path: string[], options: ClientOptions<T>): Promisable<StandardLinkCodecDecodedResponse>; | ||
| } | ||
| interface StandardLinkPlugin<T extends ClientContext> extends OrderablePlugin { | ||
| /** | ||
| * Initializes the plugin and returns new link options. | ||
| * Called once per plugin instance during composition. | ||
| * | ||
| * This method allows plugins to wrap, extend, or transform link options | ||
| * such as interceptors, or configuration. | ||
| * | ||
| * @param options - The current link options from previous plugins or base configuration | ||
| * @returns Transformed link options with plugin's modifications applied | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * init(options) { | ||
| * return { | ||
| * ...options, | ||
| * interceptors: [...(options.interceptors || []), myInterceptor] | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| init?(options: StandardLinkOptions<T>): StandardLinkOptions<T>; | ||
| } | ||
| declare class CompositeStandardLinkPlugin<T extends ClientContext> implements StandardLinkPlugin<T> { | ||
| name: string; | ||
| protected readonly plugins: StandardLinkPlugin<T>[]; | ||
| constructor(plugins?: StandardLinkPlugin<T>[]); | ||
| init(options: StandardLinkOptions<T>): StandardLinkOptions<T>; | ||
| } | ||
| /** | ||
| * Handles the transport layer for sending requests and receiving responses. | ||
| * | ||
| * Implementations are responsible for the actual network communication, | ||
| * such as HTTP fetch, WebSocket, or other transport mechanisms. | ||
| */ | ||
| interface StandardLinkTransport<T extends ClientContext> { | ||
| /** | ||
| * @throws Transport-level errors (network failures, timeouts, etc.) | ||
| */ | ||
| send(request: StandardRequest, path: string[], options: ClientOptions<T>): Promise<StandardLazyResponse>; | ||
| } | ||
| interface StandardLinkInterceptorOptions<T extends ClientContext> extends ClientOptions<T> { | ||
| path: string[]; | ||
| input: unknown; | ||
| } | ||
| type StandardLinkInterceptor<T extends ClientContext> = Interceptor<StandardLinkInterceptorOptions<T>, Promise<unknown>>; | ||
| interface StandardLinkTransportInterceptorOptions<T extends ClientContext> extends ClientOptions<T> { | ||
| path: string[]; | ||
| request: StandardRequest; | ||
| } | ||
| type StandardLinkTransportInterceptor<T extends ClientContext> = Interceptor<StandardLinkTransportInterceptorOptions<T>, Promise<StandardLazyResponse>>; | ||
| interface StandardLinkOptions<T extends ClientContext> { | ||
| /** | ||
| * Interceptors that execute around the entire call, including transport and codec. | ||
| * Useful for error handling, logging, metrics, ... | ||
| */ | ||
| interceptors?: StandardLinkInterceptor<T>[]; | ||
| /** | ||
| * Interceptors that execute around the transport layer, after encoding and before decoding. | ||
| * Useful for modifying the request or response, adding transport-level logging, ... | ||
| */ | ||
| transportInterceptors?: StandardLinkTransportInterceptor<T>[]; | ||
| plugins?: StandardLinkPlugin<T>[]; | ||
| } | ||
| declare class StandardLink<T extends ClientContext> implements ClientLink<T> { | ||
| private readonly codec; | ||
| private readonly transport; | ||
| private readonly interceptors; | ||
| private readonly transportInterceptors; | ||
| constructor(codec: StandardLinkCodec<T>, transport: StandardLinkTransport<T>, options?: StandardLinkOptions<T>); | ||
| /** | ||
| * @throws ORPCError, transport-level errors (network failures, timeouts, etc.) | ||
| */ | ||
| call(path: string[], input: unknown, options: ClientOptions<T>): Promise<unknown>; | ||
| } | ||
| export { CompositeStandardLinkPlugin as C, StandardLink as a }; | ||
| export type { StandardLinkTransport as S, StandardLinkOptions as b, StandardLinkPlugin as c, StandardLinkTransportInterceptorOptions as d, StandardLinkInterceptorOptions as e, StandardLinkCodec as f, StandardLinkCodecDecodedResponse as g, StandardLinkInterceptor as h, StandardLinkTransportInterceptor as i }; |
| import { isPlainObject, wrapAsyncIterator, isTypescriptObject, NullProtoObj, isAsyncIteratorObject, stringifyJSON } from '@orpc/shared'; | ||
| import { getEventMeta, withEventMeta, ErrorEvent } from '@standardserver/core'; | ||
| import { O as ORPCError } from './client.CPcOxSex.mjs'; | ||
| function isInferableError(error) { | ||
| return error instanceof ORPCError && error.inferable; | ||
| } | ||
| function toORPCError(error) { | ||
| return error instanceof ORPCError ? error : new ORPCError("INTERNAL_SERVER_ERROR", { cause: error }); | ||
| } | ||
| function isORPCErrorJson(json) { | ||
| if (!isPlainObject(json)) { | ||
| return false; | ||
| } | ||
| const validKeys = ["defined", "inferable", "code", "message", "data"]; | ||
| if (Object.keys(json).some((k) => !validKeys.includes(k))) { | ||
| return false; | ||
| } | ||
| return "defined" in json && typeof json.defined === "boolean" && "inferable" in json && typeof json.inferable === "boolean" && "code" in json && typeof json.code === "string" && "message" in json && typeof json.message === "string"; | ||
| } | ||
| function createORPCErrorFromJson(json, options = {}) { | ||
| const error = new ORPCError(json.code, { | ||
| ...json, | ||
| ...options | ||
| }); | ||
| error.defined = json.defined; | ||
| error.inferable = json.inferable; | ||
| return error; | ||
| } | ||
| function cloneORPCError(error) { | ||
| const cloned = new ORPCError(error.code, { | ||
| message: error.message, | ||
| data: error.data, | ||
| cause: error.cause | ||
| }); | ||
| Object.setPrototypeOf(cloned, Object.getPrototypeOf(error)); | ||
| Object.defineProperties(cloned, Object.getOwnPropertyDescriptors(error)); | ||
| cloned.stack = error.stack; | ||
| return cloned; | ||
| } | ||
| function wrapAsyncIteratorPreservingEventMeta(iterator, { mapResult, mapError, ...rest }) { | ||
| return wrapAsyncIterator(iterator, { | ||
| ...rest, | ||
| mapResult: mapResult && (async (result) => { | ||
| const mapped = await mapResult(result); | ||
| if (mapped.value !== result.value) { | ||
| const meta = getEventMeta(result.value); | ||
| if (meta && isTypescriptObject(mapped.value)) { | ||
| return { done: mapped.done, value: withEventMeta(mapped.value, meta) }; | ||
| } | ||
| } | ||
| return mapped; | ||
| }), | ||
| mapError: mapError && (async (error) => { | ||
| const mapped = await mapError(error); | ||
| if (mapped !== error) { | ||
| const meta = getEventMeta(error); | ||
| if (meta && isTypescriptObject(mapped)) { | ||
| return withEventMeta(mapped, meta); | ||
| } | ||
| } | ||
| return mapped; | ||
| }) | ||
| }); | ||
| } | ||
| const REGEX_STRING_PATTERN = /^\/([\s\S]*)\/([a-z]*)$/; | ||
| const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = { | ||
| undefined: { | ||
| condition(data) { | ||
| return data === void 0; | ||
| }, | ||
| serialize() { | ||
| return null; | ||
| }, | ||
| deserialize() { | ||
| return void 0; | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| bigint: { | ||
| condition(data) { | ||
| return typeof data === "bigint"; | ||
| }, | ||
| serialize(data) { | ||
| return data.toString(); | ||
| }, | ||
| deserialize(serialized) { | ||
| return BigInt(serialized); | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| date: { | ||
| condition(data) { | ||
| return data instanceof Date; | ||
| }, | ||
| serialize(data) { | ||
| if (Number.isNaN(data.getTime())) { | ||
| return null; | ||
| } | ||
| return data.toISOString(); | ||
| }, | ||
| deserialize(serialized) { | ||
| return new Date(serialized ?? "Invalid Date"); | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| nan: { | ||
| condition(data) { | ||
| return typeof data === "number" && Number.isNaN(data); | ||
| }, | ||
| serialize() { | ||
| return null; | ||
| }, | ||
| deserialize() { | ||
| return Number.NaN; | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| url: { | ||
| condition(data) { | ||
| return data instanceof URL; | ||
| }, | ||
| serialize(data) { | ||
| return data.toString(); | ||
| }, | ||
| deserialize(serialized) { | ||
| return new URL(serialized); | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| regexp: { | ||
| condition(data) { | ||
| return data instanceof RegExp; | ||
| }, | ||
| serialize(data) { | ||
| return data.toString(); | ||
| }, | ||
| deserialize(serialized) { | ||
| const [, pattern, flags] = serialized.match(REGEX_STRING_PATTERN); | ||
| return new RegExp(pattern, flags); | ||
| }, | ||
| isTerminal: true | ||
| }, | ||
| set: { | ||
| condition(data) { | ||
| return data instanceof Set; | ||
| }, | ||
| serialize(data) { | ||
| return Array.from(data); | ||
| }, | ||
| deserialize(serialized) { | ||
| return new Set(serialized); | ||
| } | ||
| }, | ||
| map: { | ||
| condition(data) { | ||
| return data instanceof Map; | ||
| }, | ||
| serialize(data) { | ||
| return Array.from(data.entries()); | ||
| }, | ||
| deserialize(serialized) { | ||
| return new Map(serialized); | ||
| } | ||
| } | ||
| }; | ||
| class RPCJsonSerializer { | ||
| handlers; | ||
| inlineBuiltInHandlers; | ||
| handlerEntries; | ||
| omitUndefinedProperties; | ||
| constructor(options = {}) { | ||
| this.omitUndefinedProperties = options.omitUndefinedProperties !== false; | ||
| this.handlers = Object.assign(new NullProtoObj(), DEFAULT_RPC_JSON_SERIALIZER_HANDLERS); | ||
| const customHandlers = options.handlers; | ||
| if (customHandlers === void 0) { | ||
| this.inlineBuiltInHandlers = true; | ||
| return; | ||
| } | ||
| let inlineBuiltInHandlers = true; | ||
| let handlerEntries = []; | ||
| for (const key in customHandlers) { | ||
| const handler = customHandlers[key]; | ||
| this.handlers[key] = handler; | ||
| if (inlineBuiltInHandlers && key in DEFAULT_RPC_JSON_SERIALIZER_HANDLERS) { | ||
| inlineBuiltInHandlers = false; | ||
| } | ||
| if (inlineBuiltInHandlers && handler !== void 0) { | ||
| handlerEntries.push([key, handler]); | ||
| } | ||
| } | ||
| if (!inlineBuiltInHandlers) { | ||
| handlerEntries = []; | ||
| for (const key in this.handlers) { | ||
| const handler = this.handlers[key]; | ||
| if (handler !== void 0) { | ||
| handlerEntries.push([key, handler]); | ||
| } | ||
| } | ||
| } | ||
| this.inlineBuiltInHandlers = inlineBuiltInHandlers; | ||
| this.handlerEntries = handlerEntries; | ||
| } | ||
| serialize(data) { | ||
| let meta = []; | ||
| const maps = []; | ||
| const blobs = []; | ||
| const json = this.serializeValue(data, [], meta, maps, blobs); | ||
| meta = meta.length === 0 ? void 0 : meta; | ||
| if (maps.length === 0) { | ||
| return { json, meta }; | ||
| } | ||
| return { json, meta, maps, blobs }; | ||
| } | ||
| /** | ||
| * `segments` is a shared mutable stack (push/pop while walking), | ||
| * so it must be copied before being stored in `meta` or `maps`. | ||
| */ | ||
| serializeValue(data, segments, meta, maps, blobs) { | ||
| if (this.inlineBuiltInHandlers) { | ||
| switch (typeof data) { | ||
| case "string": | ||
| case "boolean": | ||
| return data; | ||
| case "number": | ||
| if (Number.isNaN(data)) { | ||
| meta.push(["nan", ...segments]); | ||
| return null; | ||
| } | ||
| return data; | ||
| case "undefined": | ||
| meta.push(["undefined", ...segments]); | ||
| return null; | ||
| case "bigint": | ||
| meta.push(["bigint", ...segments]); | ||
| return data.toString(); | ||
| case "object": { | ||
| if (data === null) { | ||
| return data; | ||
| } | ||
| if (data instanceof Date) { | ||
| meta.push(["date", ...segments]); | ||
| return Number.isNaN(data.getTime()) ? null : data.toISOString(); | ||
| } | ||
| if (data instanceof URL) { | ||
| meta.push(["url", ...segments]); | ||
| return data.toString(); | ||
| } | ||
| if (data instanceof RegExp) { | ||
| meta.push(["regexp", ...segments]); | ||
| return data.toString(); | ||
| } | ||
| if (data instanceof Set) { | ||
| const result = this.serializeValue(Array.from(data), segments, meta, maps, blobs); | ||
| meta.push(["set", ...segments]); | ||
| return result; | ||
| } | ||
| if (data instanceof Map) { | ||
| const result = this.serializeValue(Array.from(data.entries()), segments, meta, maps, blobs); | ||
| meta.push(["map", ...segments]); | ||
| return result; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| const handlerEntries = this.handlerEntries; | ||
| if (handlerEntries) { | ||
| for (let i = 0; i < handlerEntries.length; i++) { | ||
| const entry = handlerEntries[i]; | ||
| const handler = entry[1]; | ||
| if (handler.condition(data)) { | ||
| const serialized = handler.serialize(data); | ||
| if (handler.isTerminal) { | ||
| meta.push([entry[0], ...segments]); | ||
| if (serialized instanceof Blob) { | ||
| maps.push(segments.slice()); | ||
| blobs.push(serialized); | ||
| } | ||
| return serialized; | ||
| } | ||
| const result = this.serializeValue(serialized, segments, meta, maps, blobs); | ||
| meta.push([entry[0], ...segments]); | ||
| return result; | ||
| } | ||
| } | ||
| } | ||
| if (data instanceof Blob) { | ||
| maps.push(segments.slice()); | ||
| blobs.push(data); | ||
| return data; | ||
| } | ||
| if (Array.isArray(data)) { | ||
| const json = []; | ||
| for (let i = 0; i < data.length; i++) { | ||
| segments.push(i); | ||
| json.push(this.serializeValue(data[i], segments, meta, maps, blobs)); | ||
| segments.pop(); | ||
| } | ||
| return json; | ||
| } | ||
| if (isPlainObject(data)) { | ||
| const json = new NullProtoObj(); | ||
| for (const k in data) { | ||
| const v = data[k]; | ||
| if (k === "toJSON" && typeof v === "function") { | ||
| continue; | ||
| } | ||
| if (v === void 0 && this.omitUndefinedProperties) { | ||
| continue; | ||
| } | ||
| segments.push(k); | ||
| json[k] = this.serializeValue(v, segments, meta, maps, blobs); | ||
| segments.pop(); | ||
| } | ||
| return json; | ||
| } | ||
| return data; | ||
| } | ||
| deserialize(serialized) { | ||
| const ref = { data: serialized.json }; | ||
| if (serialized.blobs?.length) { | ||
| for (let i = 0; i < serialized.maps.length; i++) { | ||
| const segments = serialized.maps[i]; | ||
| let currentRef = ref; | ||
| let preSegment = "data"; | ||
| for (let j = 0; j < segments.length; j++) { | ||
| currentRef = currentRef[preSegment]; | ||
| preSegment = segments[j]; | ||
| if (!Object.hasOwn(currentRef, preSegment)) { | ||
| throw new Error(`Security error: Invalid serialized data. Segment "${preSegment}" does not exist.`); | ||
| } | ||
| } | ||
| currentRef[preSegment] = serialized.blobs[i]; | ||
| } | ||
| } | ||
| if (serialized.meta) { | ||
| for (const item of serialized.meta) { | ||
| const type = item[0]; | ||
| let currentRef = ref; | ||
| let preSegment = "data"; | ||
| for (let i = 1; i < item.length; i++) { | ||
| currentRef = currentRef[preSegment]; | ||
| preSegment = item[i]; | ||
| if (!Object.hasOwn(currentRef, preSegment)) { | ||
| throw new Error(`Security error: Invalid serialized data. Segment "${preSegment}" does not exist.`); | ||
| } | ||
| } | ||
| currentRef[preSegment] = this.handlers[type].deserialize(currentRef[preSegment]); | ||
| } | ||
| } | ||
| return ref.data; | ||
| } | ||
| } | ||
| class RPCSerializer { | ||
| jsonSerializer; | ||
| defaultSerializeOptions; | ||
| constructor(options = {}) { | ||
| this.jsonSerializer = new RPCJsonSerializer(options); | ||
| this.defaultSerializeOptions = options.serialize; | ||
| } | ||
| serialize(data, options = {}) { | ||
| if (data === void 0 || data instanceof ReadableStream || data instanceof Blob) { | ||
| return data; | ||
| } | ||
| if (isAsyncIteratorObject(data)) { | ||
| return wrapAsyncIteratorPreservingEventMeta(data, { | ||
| mapResult: (result) => { | ||
| if (result.value === void 0) { | ||
| return result; | ||
| } | ||
| return { done: result.done, value: this.serializeValue(result.value, false) }; | ||
| }, | ||
| mapError: (e) => new ErrorEvent( | ||
| this.serializeValue(toORPCError(e).toJSON(), false), | ||
| { cause: e } | ||
| ) | ||
| }); | ||
| } | ||
| const useFormDataForBlobs = options.useFormDataForBlobFields ?? this.defaultSerializeOptions?.useFormDataForBlobFields ?? true; | ||
| return this.serializeValue(data, useFormDataForBlobs); | ||
| } | ||
| serializeValue(data, useFormDataForBlobs) { | ||
| const { json, meta, maps, blobs } = this.jsonSerializer.serialize(data); | ||
| if (!useFormDataForBlobs || !blobs?.length) { | ||
| return { json, meta }; | ||
| } | ||
| const form = new FormData(); | ||
| form.set("data", stringifyJSON({ json, meta, maps })); | ||
| blobs.forEach((blob, i) => { | ||
| form.set(i.toString(), blob); | ||
| }); | ||
| return form; | ||
| } | ||
| deserialize(data) { | ||
| if (data === void 0 || data instanceof ReadableStream || data instanceof Blob) { | ||
| return data; | ||
| } | ||
| if (isAsyncIteratorObject(data)) { | ||
| return wrapAsyncIteratorPreservingEventMeta(data, { | ||
| mapResult: (result) => { | ||
| if (result.value === void 0) { | ||
| return result; | ||
| } | ||
| return { done: result.done, value: this.deserializeValue(result.value) }; | ||
| }, | ||
| mapError: (e) => { | ||
| if (!(e instanceof ErrorEvent)) { | ||
| return e; | ||
| } | ||
| const deserialized = this.deserializeValue(e.data); | ||
| if (isORPCErrorJson(deserialized)) { | ||
| return createORPCErrorFromJson(deserialized, { cause: e }); | ||
| } | ||
| return new ErrorEvent(deserialized, { cause: e }); | ||
| } | ||
| }); | ||
| } | ||
| return this.deserializeValue(data); | ||
| } | ||
| deserializeValue(data) { | ||
| if (!(data instanceof FormData)) { | ||
| return this.jsonSerializer.deserialize(data); | ||
| } | ||
| const serialized = JSON.parse(data.get("data")); | ||
| const blobs = []; | ||
| for (const [key, value] of data) { | ||
| if (value instanceof Blob) { | ||
| blobs[Number(key)] = value; | ||
| } | ||
| } | ||
| return this.jsonSerializer.deserialize({ ...serialized, blobs }); | ||
| } | ||
| } | ||
| export { RPCSerializer as R, isInferableError as a, RPCJsonSerializer as b, createORPCErrorFromJson as c, cloneORPCError as d, isORPCErrorJson as i, toORPCError as t, wrapAsyncIteratorPreservingEventMeta as w }; |
| import { resolveMaybeOptionalOptions, getConstructors } from '@orpc/shared'; | ||
| const COMMON_ERROR_STATUS_MAP = { | ||
| BAD_REQUEST: 400, | ||
| UNAUTHORIZED: 401, | ||
| PAYMENT_REQUIRED: 402, | ||
| FORBIDDEN: 403, | ||
| NOT_FOUND: 404, | ||
| METHOD_NOT_SUPPORTED: 405, | ||
| NOT_ACCEPTABLE: 406, | ||
| TIMEOUT: 408, | ||
| CONFLICT: 409, | ||
| GONE: 410, | ||
| PRECONDITION_FAILED: 412, | ||
| PAYLOAD_TOO_LARGE: 413, | ||
| UNSUPPORTED_MEDIA_TYPE: 415, | ||
| UNPROCESSABLE_CONTENT: 422, | ||
| PRECONDITION_REQUIRED: 428, | ||
| TOO_MANY_REQUESTS: 429, | ||
| CLIENT_CLOSED_REQUEST: 499, | ||
| INTERNAL_SERVER_ERROR: 500, | ||
| NOT_IMPLEMENTED: 501, | ||
| BAD_GATEWAY: 502, | ||
| SERVICE_UNAVAILABLE: 503, | ||
| GATEWAY_TIMEOUT: 504 | ||
| }; | ||
| let ORPCErrorConstructors; | ||
| class ORPCError extends Error { | ||
| static { | ||
| const ORPC_ERROR_CONSTRUCTORS_SYMBOL = Symbol.for("ORPC_ERROR_CONSTRUCTORS"); | ||
| void (globalThis[ORPC_ERROR_CONSTRUCTORS_SYMBOL] ??= /* @__PURE__ */ new WeakSet()); | ||
| ORPCErrorConstructors = globalThis[ORPC_ERROR_CONSTRUCTORS_SYMBOL]; | ||
| ORPCErrorConstructors.add(ORPCError); | ||
| } | ||
| /** | ||
| * @remarks | ||
| * **Note**: The `__branch` property is used for type branding, helping TypeScript distinguish | ||
| * an `ORPCError` instance from plain objects with a similar structure. | ||
| */ | ||
| name = "ORPCError"; | ||
| /** | ||
| * Indicates whether the error matches a definition in the procedure's `.errors` map. | ||
| */ | ||
| defined = false; | ||
| /** | ||
| * Indicates whether the error's type is inferable at the TypeScript level. | ||
| * This is typically true when the error is explicitly defined or returned within a handler. | ||
| */ | ||
| inferable = false; | ||
| code; | ||
| data; | ||
| constructor(code, ...rest) { | ||
| const options = resolveMaybeOptionalOptions(rest); | ||
| const message = options.message ?? code.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" "); | ||
| super(message, options); | ||
| this.code = code; | ||
| this.data = options.data; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| defined: this.defined, | ||
| inferable: this.inferable, | ||
| code: this.code, | ||
| message: this.message, | ||
| data: this.data | ||
| }; | ||
| } | ||
| /** | ||
| * Workaround for Next.js where different contexts use separate | ||
| * dependency graphs, causing multiple ORPCError constructors existing and breaking | ||
| * `instanceof` checks across contexts. | ||
| * | ||
| * This is particularly problematic with "Optimized SSR", where orpc-client | ||
| * executes in one context but is invoked from another. When an error is thrown | ||
| * in the execution context, `instanceof ORPCError` checks fail in the | ||
| * invocation context due to separate class constructors. | ||
| * | ||
| * @todo Remove this and related code if Next.js resolves the multiple dependency graph issue. | ||
| */ | ||
| static [Symbol.hasInstance](instance) { | ||
| if (!ORPCErrorConstructors.has(this)) { | ||
| return super[Symbol.hasInstance](instance); | ||
| } | ||
| for (const constructor of getConstructors(instance)) { | ||
| if (ORPCErrorConstructors.has(constructor)) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
| export { COMMON_ERROR_STATUS_MAP as C, ORPCError as O }; |
| import { PromiseWithError, Registry, MaybeOptionalOptions } from '@orpc/shared'; | ||
| interface ClientContext { | ||
| [key: PropertyKey]: any; | ||
| } | ||
| interface ClientOptions<T extends ClientContext> { | ||
| signal?: AbortSignal | undefined; | ||
| lastEventId?: string | undefined; | ||
| context: T; | ||
| } | ||
| type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (object extends T ? { | ||
| context?: T; | ||
| } : { | ||
| context: T; | ||
| }); | ||
| type ClientRest<TClientContext extends ClientContext, TInput> = object extends TClientContext ? undefined extends TInput ? [input?: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options: FriendlyClientOptions<TClientContext>]; | ||
| interface Client<TClientContext extends ClientContext, TInput, TOutput, TError> { | ||
| (...rest: ClientRest<TClientContext, TInput>): PromiseWithError<TOutput, TError>; | ||
| } | ||
| type NestedClient<TClientContext extends ClientContext> = Client<TClientContext, any, any, any> | { | ||
| [k: string]: NestedClient<TClientContext>; | ||
| }; | ||
| type AnyNestedClient = NestedClient<any>; | ||
| /** | ||
| * Infers the **client context type** required by a client. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-context | Client-Side Clients - Infer Client Context} | ||
| */ | ||
| type InferClientContext<T extends AnyNestedClient> = T extends NestedClient<infer U> ? U : never; | ||
| interface ClientLink<TClientContext extends ClientContext> { | ||
| call: (path: string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>; | ||
| } | ||
| /** | ||
| * Recursively infers the **input types** from a client. | ||
| * | ||
| * Produces a nested map where each endpoint's input type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-inputs | Client-Side Clients - Infer Client Inputs} | ||
| */ | ||
| type InferClientInputs<T extends AnyNestedClient> = T extends Client<any, infer U, any, any> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientInputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **body input types** from a client. | ||
| * | ||
| * If an endpoint's input includes `{ body: ... }`, only the `body` portion is extracted. | ||
| * Produces a nested map of body input types. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-body-inputs | Client-Side Clients - Infer Client Body Inputs} | ||
| */ | ||
| type InferClientBodyInputs<T extends AnyNestedClient> = T extends Client<any, infer U, any, any> ? U extends { | ||
| body: infer UBody; | ||
| } ? UBody : U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientBodyInputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **output types** from a client. | ||
| * | ||
| * Produces a nested map where each endpoint's output type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-outputs | Client-Side Clients - Infer Client Outputs} | ||
| */ | ||
| type InferClientOutputs<T extends AnyNestedClient> = T extends Client<any, any, infer U, any> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientOutputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **body output types** from a client. | ||
| * | ||
| * If an endpoint's output includes `{ body: ... }`, only the `body` portion is extracted. | ||
| * Produces a nested map of body output types. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-body-outputs | Client-Side Clients - Infer Client Body Outputs} | ||
| */ | ||
| type InferClientBodyOutputs<T extends AnyNestedClient> = T extends Client<any, any, infer U, any> ? U extends { | ||
| body: infer UBody; | ||
| } ? UBody : U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientBodyOutputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#typesafe-errors). | ||
| * | ||
| * Produces a nested map where each endpoint's error type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-errors | Client-Side Clients - Infer Client Errors} | ||
| */ | ||
| type InferClientErrors<T extends AnyNestedClient> = T extends Client<any, any, any, infer U> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientErrors<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers a **union of all error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#typesafe-errors). | ||
| * | ||
| * Useful when you want to handle all possible errors from any endpoint at once. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-error | Client-Side Clients - Infer Client Error} | ||
| */ | ||
| type InferClientError<T extends AnyNestedClient> = T extends Client<any, any, any, infer U> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientError<T[K]> : never; | ||
| }[keyof T]; | ||
| /** | ||
| * Default mapping between common oRPC error codes and HTTP status codes. | ||
| * Handlers use it to determine response status codes; spread it to build a custom `errorStatusMap`. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/rpc/handler#custom-error-response | RPC Handler - Custom Error Response} | ||
| * @see {@link https://orpc.dev/docs/openapi/handler#custom-error-response | OpenAPI Handler - Custom Error Response} | ||
| */ | ||
| declare const COMMON_ERROR_STATUS_MAP: { | ||
| BAD_REQUEST: number; | ||
| UNAUTHORIZED: number; | ||
| PAYMENT_REQUIRED: number; | ||
| FORBIDDEN: number; | ||
| NOT_FOUND: number; | ||
| METHOD_NOT_SUPPORTED: number; | ||
| NOT_ACCEPTABLE: number; | ||
| TIMEOUT: number; | ||
| CONFLICT: number; | ||
| GONE: number; | ||
| PRECONDITION_FAILED: number; | ||
| PAYLOAD_TOO_LARGE: number; | ||
| UNSUPPORTED_MEDIA_TYPE: number; | ||
| UNPROCESSABLE_CONTENT: number; | ||
| PRECONDITION_REQUIRED: number; | ||
| TOO_MANY_REQUESTS: number; | ||
| CLIENT_CLOSED_REQUEST: number; | ||
| INTERNAL_SERVER_ERROR: number; | ||
| NOT_IMPLEMENTED: number; | ||
| BAD_GATEWAY: number; | ||
| SERVICE_UNAVAILABLE: number; | ||
| GATEWAY_TIMEOUT: number; | ||
| }; | ||
| type ORPCErrorCode = Registry extends { | ||
| ORPCErrorCode: infer T extends string; | ||
| } ? T : (keyof typeof COMMON_ERROR_STATUS_MAP) | (string & {}); | ||
| type ORPCErrorOptions<TData> = ErrorOptions & { | ||
| message?: string; | ||
| } & (undefined extends TData ? { | ||
| data?: TData; | ||
| } : { | ||
| data: TData; | ||
| }); | ||
| /** | ||
| * Typed error carrying a `code`, a `message`, and optional `data`. | ||
| * Throw it from handlers or middleware to produce typed error responses on the client. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/error-handling#orpcerror-class | Error Handling - ORPCError Class} | ||
| */ | ||
| declare class ORPCError<TCode extends ORPCErrorCode, TData> extends Error { | ||
| /** | ||
| * @remarks | ||
| * **Note**: The `__branch` property is used for type branding, helping TypeScript distinguish | ||
| * an `ORPCError` instance from plain objects with a similar structure. | ||
| */ | ||
| readonly name: "ORPCError" & { | ||
| __branch: "ORPCError"; | ||
| }; | ||
| /** | ||
| * Indicates whether the error matches a definition in the procedure's `.errors` map. | ||
| */ | ||
| readonly defined: boolean; | ||
| /** | ||
| * Indicates whether the error's type is inferable at the TypeScript level. | ||
| * This is typically true when the error is explicitly defined or returned within a handler. | ||
| */ | ||
| readonly inferable: boolean; | ||
| code: TCode; | ||
| data: TData; | ||
| constructor(code: TCode, ...rest: MaybeOptionalOptions<ORPCErrorOptions<TData>>); | ||
| toJSON(): ORPCErrorJSON<TCode, TData>; | ||
| /** | ||
| * Workaround for Next.js where different contexts use separate | ||
| * dependency graphs, causing multiple ORPCError constructors existing and breaking | ||
| * `instanceof` checks across contexts. | ||
| * | ||
| * This is particularly problematic with "Optimized SSR", where orpc-client | ||
| * executes in one context but is invoked from another. When an error is thrown | ||
| * in the execution context, `instanceof ORPCError` checks fail in the | ||
| * invocation context due to separate class constructors. | ||
| * | ||
| * @todo Remove this and related code if Next.js resolves the multiple dependency graph issue. | ||
| */ | ||
| static [Symbol.hasInstance](instance: unknown): boolean; | ||
| } | ||
| interface ORPCErrorJSON<TCode extends string, TData> extends Pick<ORPCError<TCode, TData>, 'code' | 'message' | 'data'> { | ||
| /** | ||
| * remove readonly | ||
| */ | ||
| defined: boolean; | ||
| /** | ||
| * remove readonly | ||
| */ | ||
| inferable: boolean; | ||
| } | ||
| type AnyORPCError = ORPCError<any, any>; | ||
| type AnyORPCErrorJSON = ORPCErrorJSON<any, any>; | ||
| export { ORPCError as h, COMMON_ERROR_STATUS_MAP as j }; | ||
| export type { AnyORPCError as A, ClientContext as C, FriendlyClientOptions as F, InferClientContext as I, NestedClient as N, ORPCErrorCode as O, ClientOptions as a, ClientLink as b, AnyNestedClient as c, InferClientError as d, Client as e, ClientRest as f, ORPCErrorJSON as g, AnyORPCErrorJSON as i, InferClientBodyInputs as k, InferClientBodyOutputs as l, InferClientErrors as m, InferClientInputs as n, InferClientOutputs as o, ORPCErrorOptions as p }; |
| import { PromiseWithError, Registry, MaybeOptionalOptions } from '@orpc/shared'; | ||
| interface ClientContext { | ||
| [key: PropertyKey]: any; | ||
| } | ||
| interface ClientOptions<T extends ClientContext> { | ||
| signal?: AbortSignal | undefined; | ||
| lastEventId?: string | undefined; | ||
| context: T; | ||
| } | ||
| type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (object extends T ? { | ||
| context?: T; | ||
| } : { | ||
| context: T; | ||
| }); | ||
| type ClientRest<TClientContext extends ClientContext, TInput> = object extends TClientContext ? undefined extends TInput ? [input?: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options: FriendlyClientOptions<TClientContext>]; | ||
| interface Client<TClientContext extends ClientContext, TInput, TOutput, TError> { | ||
| (...rest: ClientRest<TClientContext, TInput>): PromiseWithError<TOutput, TError>; | ||
| } | ||
| type NestedClient<TClientContext extends ClientContext> = Client<TClientContext, any, any, any> | { | ||
| [k: string]: NestedClient<TClientContext>; | ||
| }; | ||
| type AnyNestedClient = NestedClient<any>; | ||
| /** | ||
| * Infers the **client context type** required by a client. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-context | Client-Side Clients - Infer Client Context} | ||
| */ | ||
| type InferClientContext<T extends AnyNestedClient> = T extends NestedClient<infer U> ? U : never; | ||
| interface ClientLink<TClientContext extends ClientContext> { | ||
| call: (path: string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>; | ||
| } | ||
| /** | ||
| * Recursively infers the **input types** from a client. | ||
| * | ||
| * Produces a nested map where each endpoint's input type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-inputs | Client-Side Clients - Infer Client Inputs} | ||
| */ | ||
| type InferClientInputs<T extends AnyNestedClient> = T extends Client<any, infer U, any, any> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientInputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **body input types** from a client. | ||
| * | ||
| * If an endpoint's input includes `{ body: ... }`, only the `body` portion is extracted. | ||
| * Produces a nested map of body input types. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-body-inputs | Client-Side Clients - Infer Client Body Inputs} | ||
| */ | ||
| type InferClientBodyInputs<T extends AnyNestedClient> = T extends Client<any, infer U, any, any> ? U extends { | ||
| body: infer UBody; | ||
| } ? UBody : U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientBodyInputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **output types** from a client. | ||
| * | ||
| * Produces a nested map where each endpoint's output type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-outputs | Client-Side Clients - Infer Client Outputs} | ||
| */ | ||
| type InferClientOutputs<T extends AnyNestedClient> = T extends Client<any, any, infer U, any> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientOutputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **body output types** from a client. | ||
| * | ||
| * If an endpoint's output includes `{ body: ... }`, only the `body` portion is extracted. | ||
| * Produces a nested map of body output types. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-body-outputs | Client-Side Clients - Infer Client Body Outputs} | ||
| */ | ||
| type InferClientBodyOutputs<T extends AnyNestedClient> = T extends Client<any, any, infer U, any> ? U extends { | ||
| body: infer UBody; | ||
| } ? UBody : U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientBodyOutputs<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers the **error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#typesafe-errors). | ||
| * | ||
| * Produces a nested map where each endpoint's error type is preserved. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-errors | Client-Side Clients - Infer Client Errors} | ||
| */ | ||
| type InferClientErrors<T extends AnyNestedClient> = T extends Client<any, any, any, infer U> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientErrors<T[K]> : never; | ||
| }; | ||
| /** | ||
| * Recursively infers a **union of all error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#typesafe-errors). | ||
| * | ||
| * Useful when you want to handle all possible errors from any endpoint at once. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/client/client-side#infer-client-error | Client-Side Clients - Infer Client Error} | ||
| */ | ||
| type InferClientError<T extends AnyNestedClient> = T extends Client<any, any, any, infer U> ? U : { | ||
| [K in keyof T]: T[K] extends AnyNestedClient ? InferClientError<T[K]> : never; | ||
| }[keyof T]; | ||
| /** | ||
| * Default mapping between common oRPC error codes and HTTP status codes. | ||
| * Handlers use it to determine response status codes; spread it to build a custom `errorStatusMap`. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/rpc/handler#custom-error-response | RPC Handler - Custom Error Response} | ||
| * @see {@link https://orpc.dev/docs/openapi/handler#custom-error-response | OpenAPI Handler - Custom Error Response} | ||
| */ | ||
| declare const COMMON_ERROR_STATUS_MAP: { | ||
| BAD_REQUEST: number; | ||
| UNAUTHORIZED: number; | ||
| PAYMENT_REQUIRED: number; | ||
| FORBIDDEN: number; | ||
| NOT_FOUND: number; | ||
| METHOD_NOT_SUPPORTED: number; | ||
| NOT_ACCEPTABLE: number; | ||
| TIMEOUT: number; | ||
| CONFLICT: number; | ||
| GONE: number; | ||
| PRECONDITION_FAILED: number; | ||
| PAYLOAD_TOO_LARGE: number; | ||
| UNSUPPORTED_MEDIA_TYPE: number; | ||
| UNPROCESSABLE_CONTENT: number; | ||
| PRECONDITION_REQUIRED: number; | ||
| TOO_MANY_REQUESTS: number; | ||
| CLIENT_CLOSED_REQUEST: number; | ||
| INTERNAL_SERVER_ERROR: number; | ||
| NOT_IMPLEMENTED: number; | ||
| BAD_GATEWAY: number; | ||
| SERVICE_UNAVAILABLE: number; | ||
| GATEWAY_TIMEOUT: number; | ||
| }; | ||
| type ORPCErrorCode = Registry extends { | ||
| ORPCErrorCode: infer T extends string; | ||
| } ? T : (keyof typeof COMMON_ERROR_STATUS_MAP) | (string & {}); | ||
| type ORPCErrorOptions<TData> = ErrorOptions & { | ||
| message?: string; | ||
| } & (undefined extends TData ? { | ||
| data?: TData; | ||
| } : { | ||
| data: TData; | ||
| }); | ||
| /** | ||
| * Typed error carrying a `code`, a `message`, and optional `data`. | ||
| * Throw it from handlers or middleware to produce typed error responses on the client. | ||
| * | ||
| * @see {@link https://orpc.dev/docs/error-handling#orpcerror-class | Error Handling - ORPCError Class} | ||
| */ | ||
| declare class ORPCError<TCode extends ORPCErrorCode, TData> extends Error { | ||
| /** | ||
| * @remarks | ||
| * **Note**: The `__branch` property is used for type branding, helping TypeScript distinguish | ||
| * an `ORPCError` instance from plain objects with a similar structure. | ||
| */ | ||
| readonly name: "ORPCError" & { | ||
| __branch: "ORPCError"; | ||
| }; | ||
| /** | ||
| * Indicates whether the error matches a definition in the procedure's `.errors` map. | ||
| */ | ||
| readonly defined: boolean; | ||
| /** | ||
| * Indicates whether the error's type is inferable at the TypeScript level. | ||
| * This is typically true when the error is explicitly defined or returned within a handler. | ||
| */ | ||
| readonly inferable: boolean; | ||
| code: TCode; | ||
| data: TData; | ||
| constructor(code: TCode, ...rest: MaybeOptionalOptions<ORPCErrorOptions<TData>>); | ||
| toJSON(): ORPCErrorJSON<TCode, TData>; | ||
| /** | ||
| * Workaround for Next.js where different contexts use separate | ||
| * dependency graphs, causing multiple ORPCError constructors existing and breaking | ||
| * `instanceof` checks across contexts. | ||
| * | ||
| * This is particularly problematic with "Optimized SSR", where orpc-client | ||
| * executes in one context but is invoked from another. When an error is thrown | ||
| * in the execution context, `instanceof ORPCError` checks fail in the | ||
| * invocation context due to separate class constructors. | ||
| * | ||
| * @todo Remove this and related code if Next.js resolves the multiple dependency graph issue. | ||
| */ | ||
| static [Symbol.hasInstance](instance: unknown): boolean; | ||
| } | ||
| interface ORPCErrorJSON<TCode extends string, TData> extends Pick<ORPCError<TCode, TData>, 'code' | 'message' | 'data'> { | ||
| /** | ||
| * remove readonly | ||
| */ | ||
| defined: boolean; | ||
| /** | ||
| * remove readonly | ||
| */ | ||
| inferable: boolean; | ||
| } | ||
| type AnyORPCError = ORPCError<any, any>; | ||
| type AnyORPCErrorJSON = ORPCErrorJSON<any, any>; | ||
| export { ORPCError as h, COMMON_ERROR_STATUS_MAP as j }; | ||
| export type { AnyORPCError as A, ClientContext as C, FriendlyClientOptions as F, InferClientContext as I, NestedClient as N, ORPCErrorCode as O, ClientOptions as a, ClientLink as b, AnyNestedClient as c, InferClientError as d, Client as e, ClientRest as f, ORPCErrorJSON as g, AnyORPCErrorJSON as i, InferClientBodyInputs as k, InferClientBodyOutputs as l, InferClientErrors as m, InferClientInputs as n, InferClientOutputs as o, ORPCErrorOptions as p }; |
| import { sortPlugins, runWithSpan, ORPC_NAME, isAsyncIteratorObject, override, traceAsyncIterator, intercept, getOpenTelemetryConfig, value, pathToHttpPath, stringifyJSON } from '@orpc/shared'; | ||
| import { mergeStandardHeaders, parseStandardUrl } from '@standardserver/core'; | ||
| import { toStandardHeaders } from '@standardserver/fetch'; | ||
| import { O as ORPCError } from './client.CPcOxSex.mjs'; | ||
| import { R as RPCSerializer, i as isORPCErrorJson, c as createORPCErrorFromJson } from './client.COv0qq2C.mjs'; | ||
| class CompositeStandardLinkPlugin { | ||
| name = "~composite"; | ||
| plugins; | ||
| constructor(plugins = []) { | ||
| this.plugins = sortPlugins(plugins); | ||
| } | ||
| init(options) { | ||
| for (const plugin of this.plugins) { | ||
| if (plugin.init) { | ||
| options = plugin.init(options); | ||
| } | ||
| } | ||
| return options; | ||
| } | ||
| } | ||
| class StandardLink { | ||
| constructor(codec, transport, options = {}) { | ||
| this.codec = codec; | ||
| this.transport = transport; | ||
| options = new CompositeStandardLinkPlugin(options.plugins).init(options); | ||
| this.interceptors = options.interceptors; | ||
| this.transportInterceptors = options.transportInterceptors; | ||
| } | ||
| interceptors; | ||
| transportInterceptors; | ||
| /** | ||
| * @throws ORPCError, transport-level errors (network failures, timeouts, etc.) | ||
| */ | ||
| call(path, input, options) { | ||
| return runWithSpan(`${ORPC_NAME}.${path.join("/")}`, (span) => { | ||
| span?.setAttribute("rpc.system", ORPC_NAME); | ||
| span?.setAttribute("rpc.method", path.join(".")); | ||
| if (isAsyncIteratorObject(input)) { | ||
| input = override(input, traceAsyncIterator("consume_async_iterator_object_input", input)); | ||
| } | ||
| return intercept(this.interceptors, { ...options, path, input }, async ({ path: path2, input: input2, ...options2 }) => { | ||
| const otel = getOpenTelemetryConfig(); | ||
| let activeContext; | ||
| const activeSpan = otel?.trace.getActiveSpan() ?? span; | ||
| if (activeSpan && otel) { | ||
| activeContext = otel.trace.setSpan(otel.context.active(), activeSpan); | ||
| } | ||
| let request = await runWithSpan( | ||
| { name: "encode_input", context: activeContext }, | ||
| () => this.codec.encodeInput(input2, path2, options2) | ||
| ); | ||
| if (activeContext && otel?.propagation) { | ||
| const headers = { ...request.headers }; | ||
| otel.propagation.inject(activeContext, headers); | ||
| request = { ...request, headers }; | ||
| } | ||
| const response = await intercept( | ||
| this.transportInterceptors, | ||
| { ...options2, path: path2, request }, | ||
| ({ path: path3, request: request2, ...options3 }) => { | ||
| let activeTransportContext; | ||
| const activeTransportSpan = otel?.trace.getActiveSpan() ?? activeSpan; | ||
| if (activeTransportSpan && otel) { | ||
| activeTransportContext = otel.trace.setSpan(otel.context.active(), activeTransportSpan); | ||
| } | ||
| return runWithSpan( | ||
| { name: "send_request", context: activeTransportContext }, | ||
| () => this.transport.send(request2, path3, options3) | ||
| ); | ||
| } | ||
| ); | ||
| const decodedResult = await runWithSpan( | ||
| { name: "decode_response", context: activeContext }, | ||
| () => this.codec.decodeResponse(response, path2, options2) | ||
| ); | ||
| if (decodedResult.kind === "error") { | ||
| throw decodedResult.error; | ||
| } | ||
| const output = decodedResult.output; | ||
| if (isAsyncIteratorObject(output)) { | ||
| return override(output, traceAsyncIterator("consume_async_iterator_object_output", output)); | ||
| } | ||
| return output; | ||
| }); | ||
| }); | ||
| } | ||
| } | ||
| const END_SLASH_REGEX = /\/$/; | ||
| class RPCLinkCodec { | ||
| baseUrl; | ||
| maxUrlLength; | ||
| fallbackMethod; | ||
| expectedMethod; | ||
| headers; | ||
| serializer; | ||
| constructor(options) { | ||
| this.baseUrl = options.url ?? "/"; | ||
| this.maxUrlLength = options.maxUrlLength ?? 2083; | ||
| this.fallbackMethod = options.fallbackMethod ?? "POST"; | ||
| this.expectedMethod = options.method ?? this.fallbackMethod; | ||
| this.headers = options.headers ?? {}; | ||
| this.serializer = options.serializer ?? new RPCSerializer(); | ||
| } | ||
| async encodeInput(input, path, options) { | ||
| let headers = toResolvedStandardHeaders(await value(this.headers, options, path, input)); | ||
| if (options.lastEventId !== void 0) { | ||
| headers = mergeStandardHeaders(headers, { "last-event-id": options.lastEventId }); | ||
| } | ||
| const expectedMethod = await value(this.expectedMethod, options, path, input); | ||
| const baseUrl = await value(this.baseUrl, options, path, input); | ||
| const [pathname, search, hash] = parseStandardUrl(baseUrl); | ||
| const newPathname = `${pathname.replace(END_SLASH_REGEX, "")}${pathToHttpPath(path)}`; | ||
| const serialized = this.serializer.serialize(input); | ||
| if (expectedMethod === "GET" && !(serialized instanceof Blob) && !(serialized instanceof ReadableStream) && !(serialized instanceof FormData) && !isAsyncIteratorObject(serialized)) { | ||
| const maxUrlLength = await value(this.maxUrlLength, options, path, input); | ||
| const mergedSearch = new URLSearchParams(search); | ||
| mergedSearch.append("data", stringifyJSON(serialized) ?? ""); | ||
| const url2 = `${newPathname}?${mergedSearch}${hash ?? ""}`; | ||
| if (url2.length <= maxUrlLength) { | ||
| return { | ||
| body: void 0, | ||
| method: expectedMethod, | ||
| headers, | ||
| url: url2, | ||
| signal: options.signal | ||
| }; | ||
| } | ||
| } | ||
| const url = `${newPathname}${search ?? ""}${hash ?? ""}`; | ||
| return { | ||
| url, | ||
| method: expectedMethod === "GET" ? this.fallbackMethod : expectedMethod, | ||
| headers, | ||
| body: serialized, | ||
| signal: options.signal | ||
| }; | ||
| } | ||
| async decodeResponse(response) { | ||
| const isOk = response.status < 400; | ||
| const body = await response.resolveBody(); | ||
| const deserialized = await (async () => { | ||
| try { | ||
| return this.serializer.deserialize(body); | ||
| } catch (cause) { | ||
| throw new Error("Invalid RPC response format.", { | ||
| cause | ||
| }); | ||
| } | ||
| })(); | ||
| if (!isOk) { | ||
| if (isORPCErrorJson(deserialized)) { | ||
| return { kind: "error", error: createORPCErrorFromJson(deserialized) }; | ||
| } | ||
| return { | ||
| kind: "error", | ||
| error: new ORPCError("MALFORMED_ORPC_ERROR_RESPONSE", { | ||
| data: { headers: response.headers, status: response.status, body: deserialized } | ||
| }) | ||
| }; | ||
| } | ||
| return { kind: "output", output: deserialized }; | ||
| } | ||
| } | ||
| function toResolvedStandardHeaders(headers) { | ||
| if (typeof headers.forEach === "function") { | ||
| return toStandardHeaders(headers); | ||
| } | ||
| return headers; | ||
| } | ||
| export { CompositeStandardLinkPlugin as C, RPCLinkCodec as R, StandardLink as S }; |
3238
2.18%207403
-1.55%164
-19.21%+ Added
- Removed
Updated