@orpc/openapi-client 0.0.0-next.ea0903c → 0.0.0-next.ea1d4fd

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,302 @@
1
+ import { toStandardHeaders, toHttpPath, getMalformedResponseErrorCode, StandardLink } from '@orpc/client/standard';
2
+ import { S as StandardBracketNotationSerializer } from './openapi-client.t9fCAe3x.mjs';
3
+ import { isObject, value, get, isAsyncIteratorObject } from '@orpc/shared';
4
+ import { isORPCErrorStatus, isORPCErrorJson, createORPCErrorFromJson, mapEventIterator, toORPCError } from '@orpc/client';
5
+ import { isContractProcedure, fallbackContractConfig, ORPCError } from '@orpc/contract';
6
+ import { mergeStandardHeaders, ErrorEvent } from '@orpc/standard-server';
7
+
8
+ class StandardOpenAPIJsonSerializer {
9
+ customSerializers;
10
+ constructor(options = {}) {
11
+ this.customSerializers = options.customJsonSerializers ?? [];
12
+ }
13
+ serialize(data, hasBlobRef = { value: false }) {
14
+ for (const custom of this.customSerializers) {
15
+ if (custom.condition(data)) {
16
+ const result = this.serialize(custom.serialize(data), hasBlobRef);
17
+ return result;
18
+ }
19
+ }
20
+ if (data instanceof Blob) {
21
+ hasBlobRef.value = true;
22
+ return [data, hasBlobRef.value];
23
+ }
24
+ if (data instanceof Set) {
25
+ return this.serialize(Array.from(data), hasBlobRef);
26
+ }
27
+ if (data instanceof Map) {
28
+ return this.serialize(Array.from(data.entries()), hasBlobRef);
29
+ }
30
+ if (Array.isArray(data)) {
31
+ const json = data.map((v) => v === void 0 ? null : this.serialize(v, hasBlobRef)[0]);
32
+ return [json, hasBlobRef.value];
33
+ }
34
+ if (isObject(data)) {
35
+ const json = {};
36
+ for (const k in data) {
37
+ if (k === "toJSON" && typeof data[k] === "function") {
38
+ continue;
39
+ }
40
+ json[k] = this.serialize(data[k], hasBlobRef)[0];
41
+ }
42
+ return [json, hasBlobRef.value];
43
+ }
44
+ if (typeof data === "bigint" || data instanceof RegExp || data instanceof URL) {
45
+ return [data.toString(), hasBlobRef.value];
46
+ }
47
+ if (data instanceof Date) {
48
+ return [Number.isNaN(data.getTime()) ? null : data.toISOString(), hasBlobRef.value];
49
+ }
50
+ if (Number.isNaN(data)) {
51
+ return [null, hasBlobRef.value];
52
+ }
53
+ return [data, hasBlobRef.value];
54
+ }
55
+ }
56
+
57
+ function standardizeHTTPPath(path) {
58
+ return `/${path.replace(/\/{2,}/g, "/").replace(/^\/|\/$/g, "")}`;
59
+ }
60
+ function getDynamicParams(path) {
61
+ return path ? standardizeHTTPPath(path).match(/\/\{[^}]+\}/g)?.map((v) => ({
62
+ raw: v,
63
+ name: v.match(/\{\+?([^}]+)\}/)[1]
64
+ })) : void 0;
65
+ }
66
+
67
+ class StandardOpenapiLinkCodec {
68
+ constructor(contract, serializer, options) {
69
+ this.contract = contract;
70
+ this.serializer = serializer;
71
+ this.baseUrl = options.url;
72
+ this.headers = options.headers ?? {};
73
+ this.customErrorResponseBodyDecoder = options.customErrorResponseBodyDecoder;
74
+ }
75
+ baseUrl;
76
+ headers;
77
+ customErrorResponseBodyDecoder;
78
+ async encode(path, input, options) {
79
+ let headers = toStandardHeaders(await value(this.headers, options, path, input));
80
+ if (options.lastEventId !== void 0) {
81
+ headers = mergeStandardHeaders(headers, { "last-event-id": options.lastEventId });
82
+ }
83
+ const baseUrl = await value(this.baseUrl, options, path, input);
84
+ const procedure = get(this.contract, path);
85
+ if (!isContractProcedure(procedure)) {
86
+ throw new Error(`[StandardOpenapiLinkCodec] expect a contract procedure at ${path.join(".")}`);
87
+ }
88
+ const inputStructure = fallbackContractConfig("defaultInputStructure", procedure["~orpc"].route.inputStructure);
89
+ return inputStructure === "compact" ? this.#encodeCompact(procedure, path, input, options, baseUrl, headers) : this.#encodeDetailed(procedure, path, input, options, baseUrl, headers);
90
+ }
91
+ #encodeCompact(procedure, path, input, options, baseUrl, headers) {
92
+ let httpPath = standardizeHTTPPath(procedure["~orpc"].route.path ?? toHttpPath(path));
93
+ let httpBody = input;
94
+ const dynamicParams = getDynamicParams(httpPath);
95
+ if (dynamicParams?.length) {
96
+ if (!isObject(input)) {
97
+ throw new TypeError(`[StandardOpenapiLinkCodec] Invalid input shape for "compact" structure when has dynamic params at ${path.join(".")}.`);
98
+ }
99
+ const body = { ...input };
100
+ for (const param of dynamicParams) {
101
+ const value2 = input[param.name];
102
+ httpPath = httpPath.replace(param.raw, `/${encodeURIComponent(`${this.serializer.serialize(value2)}`)}`);
103
+ delete body[param.name];
104
+ }
105
+ httpBody = Object.keys(body).length ? body : void 0;
106
+ }
107
+ const method = fallbackContractConfig("defaultMethod", procedure["~orpc"].route.method);
108
+ const url = new URL(baseUrl);
109
+ url.pathname = `${url.pathname.replace(/\/$/, "")}${httpPath}`;
110
+ if (method === "GET") {
111
+ const serialized = this.serializer.serialize(httpBody, { outputFormat: "URLSearchParams" });
112
+ for (const [key, value2] of serialized) {
113
+ url.searchParams.append(key, value2);
114
+ }
115
+ return {
116
+ url,
117
+ method,
118
+ headers,
119
+ body: void 0,
120
+ signal: options.signal
121
+ };
122
+ }
123
+ return {
124
+ url,
125
+ method,
126
+ headers,
127
+ body: this.serializer.serialize(httpBody),
128
+ signal: options.signal
129
+ };
130
+ }
131
+ #encodeDetailed(procedure, path, input, options, baseUrl, headers) {
132
+ let httpPath = standardizeHTTPPath(procedure["~orpc"].route.path ?? toHttpPath(path));
133
+ const dynamicParams = getDynamicParams(httpPath);
134
+ if (!isObject(input) && input !== void 0) {
135
+ throw new TypeError(`[StandardOpenapiLinkCodec] Invalid input shape for "detailed" structure at ${path.join(".")}.`);
136
+ }
137
+ if (dynamicParams?.length) {
138
+ if (!isObject(input?.params)) {
139
+ throw new TypeError(`[StandardOpenapiLinkCodec] Invalid input.params shape for "detailed" structure when has dynamic params at ${path.join(".")}.`);
140
+ }
141
+ for (const param of dynamicParams) {
142
+ const value2 = input.params[param.name];
143
+ httpPath = httpPath.replace(param.raw, `/${encodeURIComponent(`${this.serializer.serialize(value2)}`)}`);
144
+ }
145
+ }
146
+ let mergedHeaders = headers;
147
+ if (input?.headers !== void 0) {
148
+ if (!isObject(input.headers)) {
149
+ throw new TypeError(`[StandardOpenapiLinkCodec] Invalid input.headers shape for "detailed" structure at ${path.join(".")}.`);
150
+ }
151
+ mergedHeaders = mergeStandardHeaders(input.headers, headers);
152
+ }
153
+ const method = fallbackContractConfig("defaultMethod", procedure["~orpc"].route.method);
154
+ const url = new URL(baseUrl);
155
+ url.pathname = `${url.pathname.replace(/\/$/, "")}${httpPath}`;
156
+ if (input?.query !== void 0) {
157
+ const query = this.serializer.serialize(input.query, { outputFormat: "URLSearchParams" });
158
+ for (const [key, value2] of query) {
159
+ url.searchParams.append(key, value2);
160
+ }
161
+ }
162
+ if (method === "GET") {
163
+ return {
164
+ url,
165
+ method,
166
+ headers: mergedHeaders,
167
+ body: void 0,
168
+ signal: options.signal
169
+ };
170
+ }
171
+ return {
172
+ url,
173
+ method,
174
+ headers: mergedHeaders,
175
+ body: this.serializer.serialize(input?.body),
176
+ signal: options.signal
177
+ };
178
+ }
179
+ async decode(response, _options, path) {
180
+ const isOk = !isORPCErrorStatus(response.status);
181
+ const deserialized = await (async () => {
182
+ let isBodyOk = false;
183
+ try {
184
+ const body = await response.body();
185
+ isBodyOk = true;
186
+ return this.serializer.deserialize(body);
187
+ } catch (error) {
188
+ if (!isBodyOk) {
189
+ throw new Error("Cannot parse response body, please check the response body and content-type.", {
190
+ cause: error
191
+ });
192
+ }
193
+ throw new Error("Invalid OpenAPI response format.", {
194
+ cause: error
195
+ });
196
+ }
197
+ })();
198
+ if (!isOk) {
199
+ const error = this.customErrorResponseBodyDecoder?.(deserialized, response);
200
+ if (error !== null && error !== void 0) {
201
+ throw error;
202
+ }
203
+ if (isORPCErrorJson(deserialized)) {
204
+ throw createORPCErrorFromJson(deserialized);
205
+ }
206
+ throw new ORPCError(getMalformedResponseErrorCode(response.status), {
207
+ status: response.status,
208
+ data: { ...response, body: deserialized }
209
+ });
210
+ }
211
+ const procedure = get(this.contract, path);
212
+ if (!isContractProcedure(procedure)) {
213
+ throw new Error(`[StandardOpenapiLinkCodec] expect a contract procedure at ${path.join(".")}`);
214
+ }
215
+ const outputStructure = fallbackContractConfig("defaultOutputStructure", procedure["~orpc"].route.outputStructure);
216
+ if (outputStructure === "compact") {
217
+ return deserialized;
218
+ }
219
+ return {
220
+ status: response.status,
221
+ headers: response.headers,
222
+ body: deserialized
223
+ };
224
+ }
225
+ }
226
+
227
+ class StandardOpenAPISerializer {
228
+ constructor(jsonSerializer, bracketNotation) {
229
+ this.jsonSerializer = jsonSerializer;
230
+ this.bracketNotation = bracketNotation;
231
+ }
232
+ serialize(data, options = {}) {
233
+ if (isAsyncIteratorObject(data) && !options.outputFormat) {
234
+ return mapEventIterator(data, {
235
+ value: async (value) => this.#serialize(value, { outputFormat: "plain" }),
236
+ error: async (e) => {
237
+ return new ErrorEvent({
238
+ data: this.#serialize(toORPCError(e).toJSON(), { outputFormat: "plain" }),
239
+ cause: e
240
+ });
241
+ }
242
+ });
243
+ }
244
+ return this.#serialize(data, options);
245
+ }
246
+ #serialize(data, options) {
247
+ const [json, hasBlob] = this.jsonSerializer.serialize(data);
248
+ if (options.outputFormat === "plain") {
249
+ return json;
250
+ }
251
+ if (options.outputFormat === "URLSearchParams") {
252
+ const params = new URLSearchParams();
253
+ for (const [path, value] of this.bracketNotation.serialize(json)) {
254
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
255
+ params.append(path, value.toString());
256
+ }
257
+ }
258
+ return params;
259
+ }
260
+ if (json instanceof Blob || json === void 0 || !hasBlob) {
261
+ return json;
262
+ }
263
+ const form = new FormData();
264
+ for (const [path, value] of this.bracketNotation.serialize(json)) {
265
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
266
+ form.append(path, value.toString());
267
+ } else if (value instanceof Blob) {
268
+ form.append(path, value);
269
+ }
270
+ }
271
+ return form;
272
+ }
273
+ deserialize(data) {
274
+ if (data instanceof URLSearchParams || data instanceof FormData) {
275
+ return this.bracketNotation.deserialize(Array.from(data.entries()));
276
+ }
277
+ if (isAsyncIteratorObject(data)) {
278
+ return mapEventIterator(data, {
279
+ value: async (value) => value,
280
+ error: async (e) => {
281
+ if (e instanceof ErrorEvent && isORPCErrorJson(e.data)) {
282
+ return createORPCErrorFromJson(e.data, { cause: e });
283
+ }
284
+ return e;
285
+ }
286
+ });
287
+ }
288
+ return data;
289
+ }
290
+ }
291
+
292
+ class StandardOpenAPILink extends StandardLink {
293
+ constructor(contract, linkClient, options) {
294
+ const jsonSerializer = new StandardOpenAPIJsonSerializer(options);
295
+ const bracketNotationSerializer = new StandardBracketNotationSerializer({ maxBracketNotationArrayIndex: 4294967294 });
296
+ const serializer = new StandardOpenAPISerializer(jsonSerializer, bracketNotationSerializer);
297
+ const linkCodec = new StandardOpenapiLinkCodec(contract, serializer, options);
298
+ super(linkCodec, linkClient, options);
299
+ }
300
+ }
301
+
302
+ export { StandardOpenAPIJsonSerializer as S, StandardOpenAPILink as a, StandardOpenapiLinkCodec as b, StandardOpenAPISerializer as c, getDynamicParams as g, standardizeHTTPPath as s };
@@ -0,0 +1,39 @@
1
+ import { isSchemaIssue } from '@orpc/contract';
2
+ import { isTypescriptObject } from '@orpc/shared';
3
+ import { S as StandardBracketNotationSerializer } from './openapi-client.t9fCAe3x.mjs';
4
+
5
+ function parseFormData(form) {
6
+ const serializer = new StandardBracketNotationSerializer();
7
+ return serializer.deserialize(Array.from(form.entries()));
8
+ }
9
+ function getIssueMessage(error, path) {
10
+ if (!isTypescriptObject(error) || !isTypescriptObject(error.data) || !Array.isArray(error.data.issues)) {
11
+ return void 0;
12
+ }
13
+ const serializer = new StandardBracketNotationSerializer();
14
+ for (const issue of error.data.issues) {
15
+ if (!isSchemaIssue(issue)) {
16
+ continue;
17
+ }
18
+ if (issue.path === void 0) {
19
+ if (path === "") {
20
+ return issue.message;
21
+ }
22
+ continue;
23
+ }
24
+ const issuePath = serializer.stringifyPath(
25
+ issue.path.map((segment) => typeof segment === "object" ? segment.key.toString() : segment.toString())
26
+ );
27
+ if (issuePath === path) {
28
+ return issue.message;
29
+ }
30
+ if (path.endsWith("[]") && issuePath.replace(/\[(?:0|[1-9]\d*)\]$/, "[]") === path) {
31
+ return issue.message;
32
+ }
33
+ if (path === "" && issuePath.match(/(?:0|[1-9]\d*)$/)) {
34
+ return issue.message;
35
+ }
36
+ }
37
+ }
38
+
39
+ export { getIssueMessage as g, parseFormData as p };
@@ -0,0 +1,107 @@
1
+ import { ClientContext, ClientOptions } from '@orpc/client';
2
+ import { StandardLinkCodec, StandardLinkOptions, StandardLink, StandardLinkClient } from '@orpc/client/standard';
3
+ import { ORPCError, AnyContractRouter } from '@orpc/contract';
4
+ import { Segment, Value, Promisable } from '@orpc/shared';
5
+ import { StandardHeaders, StandardLazyResponse, StandardRequest } from '@orpc/standard-server';
6
+
7
+ type StandardBracketNotationSerialized = [string, unknown][];
8
+ interface StandardBracketNotationSerializerOptions {
9
+ /**
10
+ * Maximum allowed array index for bracket notation deserialization.
11
+ *
12
+ * This helps protect against memory exhaustion attacks where malicious input
13
+ * uses extremely large array indices (e.g., `?arr[4294967296]=value`).
14
+ *
15
+ * While bracket notation creates sparse arrays that handle large indices efficiently,
16
+ * downstream code might inadvertently convert these sparse arrays to dense arrays,
17
+ * potentially creating millions of undefined elements and causing memory issues.
18
+ *
19
+ * @note Only applies to deserialization.
20
+ * @default 9_999 (array with 10,000 elements)
21
+ */
22
+ maxBracketNotationArrayIndex?: number;
23
+ }
24
+ declare class StandardBracketNotationSerializer {
25
+ private readonly maxArrayIndex;
26
+ constructor(options?: StandardBracketNotationSerializerOptions);
27
+ serialize(data: unknown, segments?: Segment[], result?: StandardBracketNotationSerialized): StandardBracketNotationSerialized;
28
+ deserialize(serialized: StandardBracketNotationSerialized): Record<string, unknown> | unknown[];
29
+ stringifyPath(segments: readonly Segment[]): string;
30
+ parsePath(path: string): string[];
31
+ }
32
+
33
+ type StandardOpenAPIJsonSerialized = [json: unknown, hasBlob: boolean];
34
+ interface StandardOpenAPICustomJsonSerializer {
35
+ condition(data: unknown): boolean;
36
+ serialize(data: any): unknown;
37
+ }
38
+ interface StandardOpenAPIJsonSerializerOptions {
39
+ customJsonSerializers?: readonly StandardOpenAPICustomJsonSerializer[];
40
+ }
41
+ declare class StandardOpenAPIJsonSerializer {
42
+ private readonly customSerializers;
43
+ constructor(options?: StandardOpenAPIJsonSerializerOptions);
44
+ serialize(data: unknown, hasBlobRef?: {
45
+ value: boolean;
46
+ }): StandardOpenAPIJsonSerialized;
47
+ }
48
+
49
+ interface StandardOpenAPISerializeOptions {
50
+ outputFormat?: 'plain' | 'URLSearchParams';
51
+ }
52
+ declare class StandardOpenAPISerializer {
53
+ #private;
54
+ private readonly jsonSerializer;
55
+ private readonly bracketNotation;
56
+ constructor(jsonSerializer: StandardOpenAPIJsonSerializer, bracketNotation: StandardBracketNotationSerializer);
57
+ serialize(data: unknown, options?: StandardOpenAPISerializeOptions): unknown;
58
+ deserialize(data: unknown): unknown;
59
+ }
60
+
61
+ interface StandardOpenapiLinkCodecOptions<T extends ClientContext> {
62
+ /**
63
+ * Base url for all requests.
64
+ */
65
+ url: Value<Promisable<string | URL>, [
66
+ options: ClientOptions<T>,
67
+ path: readonly string[],
68
+ input: unknown
69
+ ]>;
70
+ /**
71
+ * Inject headers to the request.
72
+ */
73
+ headers?: Value<Promisable<StandardHeaders | Headers>, [
74
+ options: ClientOptions<T>,
75
+ path: readonly string[],
76
+ input: unknown
77
+ ]>;
78
+ /**
79
+ * Customize how a response body is decoded into an ORPC error.
80
+ * Useful when the default decoder cannot fully interpret
81
+ * your server's error format.
82
+ *
83
+ * @remarks
84
+ * - Return `null | undefined` to fallback to default behavior.
85
+ */
86
+ customErrorResponseBodyDecoder?: (deserializedBody: unknown, response: StandardLazyResponse) => ORPCError<any, any> | null | undefined;
87
+ }
88
+ declare class StandardOpenapiLinkCodec<T extends ClientContext> implements StandardLinkCodec<T> {
89
+ #private;
90
+ private readonly contract;
91
+ private readonly serializer;
92
+ private readonly baseUrl;
93
+ private readonly headers;
94
+ private readonly customErrorResponseBodyDecoder;
95
+ constructor(contract: AnyContractRouter, serializer: StandardOpenAPISerializer, options: StandardOpenapiLinkCodecOptions<T>);
96
+ encode(path: readonly string[], input: unknown, options: ClientOptions<T>): Promise<StandardRequest>;
97
+ decode(response: StandardLazyResponse, _options: ClientOptions<T>, path: readonly string[]): Promise<unknown>;
98
+ }
99
+
100
+ interface StandardOpenAPILinkOptions<T extends ClientContext> extends StandardLinkOptions<T>, StandardOpenapiLinkCodecOptions<T>, StandardOpenAPIJsonSerializerOptions {
101
+ }
102
+ declare class StandardOpenAPILink<T extends ClientContext> extends StandardLink<T> {
103
+ constructor(contract: AnyContractRouter, linkClient: StandardLinkClient<T>, options: StandardOpenAPILinkOptions<T>);
104
+ }
105
+
106
+ export { StandardBracketNotationSerializer as b, StandardOpenAPIJsonSerializer as f, StandardOpenAPILink as h, StandardOpenapiLinkCodec as j, StandardOpenAPISerializer as l };
107
+ export type { StandardBracketNotationSerialized as S, StandardBracketNotationSerializerOptions as a, StandardOpenAPIJsonSerialized as c, StandardOpenAPICustomJsonSerializer as d, StandardOpenAPIJsonSerializerOptions as e, StandardOpenAPILinkOptions as g, StandardOpenapiLinkCodecOptions as i, StandardOpenAPISerializeOptions as k };
@@ -0,0 +1,107 @@
1
+ import { ClientContext, ClientOptions } from '@orpc/client';
2
+ import { StandardLinkCodec, StandardLinkOptions, StandardLink, StandardLinkClient } from '@orpc/client/standard';
3
+ import { ORPCError, AnyContractRouter } from '@orpc/contract';
4
+ import { Segment, Value, Promisable } from '@orpc/shared';
5
+ import { StandardHeaders, StandardLazyResponse, StandardRequest } from '@orpc/standard-server';
6
+
7
+ type StandardBracketNotationSerialized = [string, unknown][];
8
+ interface StandardBracketNotationSerializerOptions {
9
+ /**
10
+ * Maximum allowed array index for bracket notation deserialization.
11
+ *
12
+ * This helps protect against memory exhaustion attacks where malicious input
13
+ * uses extremely large array indices (e.g., `?arr[4294967296]=value`).
14
+ *
15
+ * While bracket notation creates sparse arrays that handle large indices efficiently,
16
+ * downstream code might inadvertently convert these sparse arrays to dense arrays,
17
+ * potentially creating millions of undefined elements and causing memory issues.
18
+ *
19
+ * @note Only applies to deserialization.
20
+ * @default 9_999 (array with 10,000 elements)
21
+ */
22
+ maxBracketNotationArrayIndex?: number;
23
+ }
24
+ declare class StandardBracketNotationSerializer {
25
+ private readonly maxArrayIndex;
26
+ constructor(options?: StandardBracketNotationSerializerOptions);
27
+ serialize(data: unknown, segments?: Segment[], result?: StandardBracketNotationSerialized): StandardBracketNotationSerialized;
28
+ deserialize(serialized: StandardBracketNotationSerialized): Record<string, unknown> | unknown[];
29
+ stringifyPath(segments: readonly Segment[]): string;
30
+ parsePath(path: string): string[];
31
+ }
32
+
33
+ type StandardOpenAPIJsonSerialized = [json: unknown, hasBlob: boolean];
34
+ interface StandardOpenAPICustomJsonSerializer {
35
+ condition(data: unknown): boolean;
36
+ serialize(data: any): unknown;
37
+ }
38
+ interface StandardOpenAPIJsonSerializerOptions {
39
+ customJsonSerializers?: readonly StandardOpenAPICustomJsonSerializer[];
40
+ }
41
+ declare class StandardOpenAPIJsonSerializer {
42
+ private readonly customSerializers;
43
+ constructor(options?: StandardOpenAPIJsonSerializerOptions);
44
+ serialize(data: unknown, hasBlobRef?: {
45
+ value: boolean;
46
+ }): StandardOpenAPIJsonSerialized;
47
+ }
48
+
49
+ interface StandardOpenAPISerializeOptions {
50
+ outputFormat?: 'plain' | 'URLSearchParams';
51
+ }
52
+ declare class StandardOpenAPISerializer {
53
+ #private;
54
+ private readonly jsonSerializer;
55
+ private readonly bracketNotation;
56
+ constructor(jsonSerializer: StandardOpenAPIJsonSerializer, bracketNotation: StandardBracketNotationSerializer);
57
+ serialize(data: unknown, options?: StandardOpenAPISerializeOptions): unknown;
58
+ deserialize(data: unknown): unknown;
59
+ }
60
+
61
+ interface StandardOpenapiLinkCodecOptions<T extends ClientContext> {
62
+ /**
63
+ * Base url for all requests.
64
+ */
65
+ url: Value<Promisable<string | URL>, [
66
+ options: ClientOptions<T>,
67
+ path: readonly string[],
68
+ input: unknown
69
+ ]>;
70
+ /**
71
+ * Inject headers to the request.
72
+ */
73
+ headers?: Value<Promisable<StandardHeaders | Headers>, [
74
+ options: ClientOptions<T>,
75
+ path: readonly string[],
76
+ input: unknown
77
+ ]>;
78
+ /**
79
+ * Customize how a response body is decoded into an ORPC error.
80
+ * Useful when the default decoder cannot fully interpret
81
+ * your server's error format.
82
+ *
83
+ * @remarks
84
+ * - Return `null | undefined` to fallback to default behavior.
85
+ */
86
+ customErrorResponseBodyDecoder?: (deserializedBody: unknown, response: StandardLazyResponse) => ORPCError<any, any> | null | undefined;
87
+ }
88
+ declare class StandardOpenapiLinkCodec<T extends ClientContext> implements StandardLinkCodec<T> {
89
+ #private;
90
+ private readonly contract;
91
+ private readonly serializer;
92
+ private readonly baseUrl;
93
+ private readonly headers;
94
+ private readonly customErrorResponseBodyDecoder;
95
+ constructor(contract: AnyContractRouter, serializer: StandardOpenAPISerializer, options: StandardOpenapiLinkCodecOptions<T>);
96
+ encode(path: readonly string[], input: unknown, options: ClientOptions<T>): Promise<StandardRequest>;
97
+ decode(response: StandardLazyResponse, _options: ClientOptions<T>, path: readonly string[]): Promise<unknown>;
98
+ }
99
+
100
+ interface StandardOpenAPILinkOptions<T extends ClientContext> extends StandardLinkOptions<T>, StandardOpenapiLinkCodecOptions<T>, StandardOpenAPIJsonSerializerOptions {
101
+ }
102
+ declare class StandardOpenAPILink<T extends ClientContext> extends StandardLink<T> {
103
+ constructor(contract: AnyContractRouter, linkClient: StandardLinkClient<T>, options: StandardOpenAPILinkOptions<T>);
104
+ }
105
+
106
+ export { StandardBracketNotationSerializer as b, StandardOpenAPIJsonSerializer as f, StandardOpenAPILink as h, StandardOpenapiLinkCodec as j, StandardOpenAPISerializer as l };
107
+ export type { StandardBracketNotationSerialized as S, StandardBracketNotationSerializerOptions as a, StandardOpenAPIJsonSerialized as c, StandardOpenAPICustomJsonSerializer as d, StandardOpenAPIJsonSerializerOptions as e, StandardOpenAPILinkOptions as g, StandardOpenapiLinkCodecOptions as i, StandardOpenAPISerializeOptions as k };