@orpc/client 2.0.0-beta.4 → 2.0.0-beta.40
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.
- package/README.md +97 -94
- package/dist/adapters/fetch/index.d.mts +16 -33
- package/dist/adapters/fetch/index.d.ts +16 -33
- package/dist/adapters/fetch/index.mjs +32 -30
- package/dist/adapters/message-port/index.d.mts +13 -8
- package/dist/adapters/message-port/index.d.ts +13 -8
- package/dist/adapters/message-port/index.mjs +22 -17
- package/dist/adapters/standard/index.d.mts +9 -10
- package/dist/adapters/standard/index.d.ts +9 -10
- package/dist/adapters/standard/index.mjs +5 -5
- package/dist/adapters/websocket/index.d.mts +21 -16
- package/dist/adapters/websocket/index.d.ts +21 -16
- package/dist/adapters/websocket/index.mjs +14 -14
- package/dist/index.d.mts +62 -61
- package/dist/index.d.ts +62 -61
- package/dist/index.mjs +47 -54
- package/dist/plugins/index.d.mts +134 -13
- package/dist/plugins/index.d.ts +134 -13
- package/dist/plugins/index.mjs +298 -27
- package/dist/shared/{client.Cby_-GGh.d.mts → client.BWkR2vPU.d.mts} +2 -2
- package/dist/shared/client.BYHnU_Z3.mjs +469 -0
- package/dist/shared/{client.CPF3hX6O.d.ts → client.BnpRXnLi.d.ts} +2 -2
- package/dist/shared/{client.8ug8I-zu.d.mts → client.BoXZCzuS.d.mts} +56 -16
- package/dist/shared/{client.8ug8I-zu.d.ts → client.BoXZCzuS.d.ts} +56 -16
- package/dist/shared/{client.Dnfj8jnT.mjs → client.Dtv1JPkU.mjs} +19 -15
- package/dist/shared/{client.DXhchJ84.mjs → client.VXsLhJtT.mjs} +25 -30
- package/dist/shared/{client.BdItY5DT.d.mts → client.n8K9dFhY.d.mts} +25 -4
- package/dist/shared/{client.BdItY5DT.d.ts → client.n8K9dFhY.d.ts} +25 -4
- package/package.json +20 -8
- package/dist/shared/client.DMXKFDyV.mjs +0 -343
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import { isPlainObject, wrapAsyncIterator, isTypescriptObject, NullProtoObj, copyOnWrite, isAsyncIteratorObject, stringifyJSON } from '@orpc/shared';
|
|
2
|
+
import { getEventMeta, withEventMeta, ErrorEvent } from '@standard-server/core';
|
|
3
|
+
import { O as ORPCError, M as MalformedResponseError, C as COMMON_ERROR_STATUS_MAP } from './client.Dtv1JPkU.mjs';
|
|
4
|
+
|
|
5
|
+
function isDefinedError(error) {
|
|
6
|
+
return error instanceof ORPCError && error.defined;
|
|
7
|
+
}
|
|
8
|
+
function toORPCError(error) {
|
|
9
|
+
return error instanceof ORPCError ? error : new ORPCError("INTERNAL_SERVER_ERROR", { cause: error });
|
|
10
|
+
}
|
|
11
|
+
function isORPCErrorJson(json) {
|
|
12
|
+
if (!isPlainObject(json)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const validKeys = ["defined", "code", "message", "data"];
|
|
16
|
+
if (Object.keys(json).some((k) => !validKeys.includes(k))) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return "defined" in json && typeof json.defined === "boolean" && "code" in json && typeof json.code === "string" && "message" in json && typeof json.message === "string";
|
|
20
|
+
}
|
|
21
|
+
function createORPCErrorFromJson(json, options = {}) {
|
|
22
|
+
const error = new ORPCError(json.code, {
|
|
23
|
+
...json,
|
|
24
|
+
...options
|
|
25
|
+
});
|
|
26
|
+
error.defined = json.defined;
|
|
27
|
+
return error;
|
|
28
|
+
}
|
|
29
|
+
function createORPCErrorFromMalformedResponse(options) {
|
|
30
|
+
const error = new ORPCError("MALFORMED_ORPC_RESPONSE", {
|
|
31
|
+
message: options.message ?? inferMalformedResponseMessage(options.response),
|
|
32
|
+
data: options.response
|
|
33
|
+
});
|
|
34
|
+
error.cause = new MalformedResponseError({ ...options, message: error.message });
|
|
35
|
+
return error;
|
|
36
|
+
}
|
|
37
|
+
const INFERRED_MESSAGE_MIN_LENGTH = 1;
|
|
38
|
+
const INFERRED_MESSAGE_MAX_LENGTH = 256;
|
|
39
|
+
function isInferableMessage(text) {
|
|
40
|
+
return text.length >= INFERRED_MESSAGE_MIN_LENGTH && text.length <= INFERRED_MESSAGE_MAX_LENGTH;
|
|
41
|
+
}
|
|
42
|
+
function inferMalformedResponseMessage(response) {
|
|
43
|
+
if (typeof response.body === "string" && isInferableMessage(response.body)) {
|
|
44
|
+
return response.body;
|
|
45
|
+
}
|
|
46
|
+
if (isPlainObject(response.body) && typeof response.body.message === "string" && isInferableMessage(response.body.message)) {
|
|
47
|
+
return response.body.message;
|
|
48
|
+
}
|
|
49
|
+
const commonCode = Object.entries(COMMON_ERROR_STATUS_MAP).find(([, status]) => status === response.status)?.[0];
|
|
50
|
+
return commonCode?.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
51
|
+
}
|
|
52
|
+
function cloneORPCError(error) {
|
|
53
|
+
const cloned = new ORPCError(error.code, {
|
|
54
|
+
message: error.message,
|
|
55
|
+
data: error.data,
|
|
56
|
+
cause: error.cause
|
|
57
|
+
});
|
|
58
|
+
Object.setPrototypeOf(cloned, Object.getPrototypeOf(error));
|
|
59
|
+
Object.defineProperties(cloned, Object.getOwnPropertyDescriptors(error));
|
|
60
|
+
cloned.stack = error.stack;
|
|
61
|
+
return cloned;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function wrapAsyncIteratorPreservingEventMeta(iterator, { mapResult, mapError, ...rest }) {
|
|
65
|
+
return wrapAsyncIterator(iterator, {
|
|
66
|
+
...rest,
|
|
67
|
+
mapResult: mapResult && (async (result) => {
|
|
68
|
+
const mapped = await mapResult(result);
|
|
69
|
+
if (mapped.value !== result.value) {
|
|
70
|
+
const meta = getEventMeta(result.value);
|
|
71
|
+
if (meta && isTypescriptObject(mapped.value)) {
|
|
72
|
+
return { done: mapped.done, value: withEventMeta(mapped.value, meta) };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return mapped;
|
|
76
|
+
}),
|
|
77
|
+
mapError: mapError && (async (error) => {
|
|
78
|
+
const mapped = await mapError(error);
|
|
79
|
+
if (mapped !== error) {
|
|
80
|
+
const meta = getEventMeta(error);
|
|
81
|
+
if (meta && isTypescriptObject(mapped)) {
|
|
82
|
+
return withEventMeta(mapped, meta);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return mapped;
|
|
86
|
+
})
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function invalidSerializedData(detail) {
|
|
91
|
+
return new TypeError(`Invalid RPC serialized data: ${detail}`);
|
|
92
|
+
}
|
|
93
|
+
function assertSerializedType(ok, type, expected) {
|
|
94
|
+
if (!ok) {
|
|
95
|
+
throw invalidSerializedData(`type "${type}" expects ${expected}.`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = {
|
|
99
|
+
undefined: {
|
|
100
|
+
condition(data) {
|
|
101
|
+
return data === void 0;
|
|
102
|
+
},
|
|
103
|
+
serialize() {
|
|
104
|
+
return null;
|
|
105
|
+
},
|
|
106
|
+
deserialize(serialized) {
|
|
107
|
+
assertSerializedType(serialized === null, "undefined", "null");
|
|
108
|
+
return void 0;
|
|
109
|
+
},
|
|
110
|
+
isTerminal: true
|
|
111
|
+
},
|
|
112
|
+
bigint: {
|
|
113
|
+
condition(data) {
|
|
114
|
+
return typeof data === "bigint";
|
|
115
|
+
},
|
|
116
|
+
serialize(data) {
|
|
117
|
+
return data.toString();
|
|
118
|
+
},
|
|
119
|
+
deserialize(serialized) {
|
|
120
|
+
assertSerializedType(typeof serialized === "string", "bigint", "a string");
|
|
121
|
+
return BigInt(serialized);
|
|
122
|
+
},
|
|
123
|
+
isTerminal: true
|
|
124
|
+
},
|
|
125
|
+
date: {
|
|
126
|
+
condition(data) {
|
|
127
|
+
return data instanceof Date;
|
|
128
|
+
},
|
|
129
|
+
serialize(data) {
|
|
130
|
+
if (Number.isNaN(data.getTime())) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
return data.toISOString();
|
|
134
|
+
},
|
|
135
|
+
deserialize(serialized) {
|
|
136
|
+
assertSerializedType(typeof serialized === "string" || serialized === null, "date", "a string or null");
|
|
137
|
+
return new Date(serialized ?? Number.NaN);
|
|
138
|
+
},
|
|
139
|
+
isTerminal: true
|
|
140
|
+
},
|
|
141
|
+
nan: {
|
|
142
|
+
condition(data) {
|
|
143
|
+
return typeof data === "number" && Number.isNaN(data);
|
|
144
|
+
},
|
|
145
|
+
serialize() {
|
|
146
|
+
return null;
|
|
147
|
+
},
|
|
148
|
+
deserialize(serialized) {
|
|
149
|
+
assertSerializedType(serialized === null, "nan", "null");
|
|
150
|
+
return Number.NaN;
|
|
151
|
+
},
|
|
152
|
+
isTerminal: true
|
|
153
|
+
},
|
|
154
|
+
url: {
|
|
155
|
+
condition(data) {
|
|
156
|
+
return data instanceof URL;
|
|
157
|
+
},
|
|
158
|
+
serialize(data) {
|
|
159
|
+
return data.toString();
|
|
160
|
+
},
|
|
161
|
+
deserialize(serialized) {
|
|
162
|
+
assertSerializedType(typeof serialized === "string", "url", "a string");
|
|
163
|
+
return new URL(serialized);
|
|
164
|
+
},
|
|
165
|
+
isTerminal: true
|
|
166
|
+
},
|
|
167
|
+
set: {
|
|
168
|
+
condition(data) {
|
|
169
|
+
return data instanceof Set;
|
|
170
|
+
},
|
|
171
|
+
serialize(data) {
|
|
172
|
+
return Array.from(data);
|
|
173
|
+
},
|
|
174
|
+
deserialize(serialized) {
|
|
175
|
+
assertSerializedType(Array.isArray(serialized), "set", "an array");
|
|
176
|
+
return new Set(serialized);
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
map: {
|
|
180
|
+
condition(data) {
|
|
181
|
+
return data instanceof Map;
|
|
182
|
+
},
|
|
183
|
+
serialize(data) {
|
|
184
|
+
return Array.from(data.entries());
|
|
185
|
+
},
|
|
186
|
+
deserialize(serialized) {
|
|
187
|
+
assertSerializedType(Array.isArray(serialized), "map", "an array");
|
|
188
|
+
return new Map(serialized);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
class RPCJsonSerializer {
|
|
193
|
+
handlers;
|
|
194
|
+
inlineBuiltInHandlers;
|
|
195
|
+
handlerEntries;
|
|
196
|
+
omitUndefinedProperties;
|
|
197
|
+
constructor(options = {}) {
|
|
198
|
+
this.omitUndefinedProperties = options.omitUndefinedProperties !== false;
|
|
199
|
+
this.handlers = Object.assign(new NullProtoObj(), DEFAULT_RPC_JSON_SERIALIZER_HANDLERS);
|
|
200
|
+
const customHandlers = options.handlers;
|
|
201
|
+
if (customHandlers === void 0) {
|
|
202
|
+
this.inlineBuiltInHandlers = true;
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
let inlineBuiltInHandlers = true;
|
|
206
|
+
let handlerEntries = [];
|
|
207
|
+
for (const key of Object.keys(customHandlers)) {
|
|
208
|
+
const handler = customHandlers[key];
|
|
209
|
+
this.handlers[key] = handler;
|
|
210
|
+
if (inlineBuiltInHandlers && key in DEFAULT_RPC_JSON_SERIALIZER_HANDLERS) {
|
|
211
|
+
inlineBuiltInHandlers = false;
|
|
212
|
+
}
|
|
213
|
+
if (inlineBuiltInHandlers && handler !== void 0) {
|
|
214
|
+
handlerEntries.push([key, handler]);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (!inlineBuiltInHandlers) {
|
|
218
|
+
handlerEntries = [];
|
|
219
|
+
for (const key of Object.keys(this.handlers)) {
|
|
220
|
+
const handler = this.handlers[key];
|
|
221
|
+
if (handler !== void 0) {
|
|
222
|
+
handlerEntries.push([key, handler]);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
this.inlineBuiltInHandlers = inlineBuiltInHandlers;
|
|
227
|
+
this.handlerEntries = handlerEntries;
|
|
228
|
+
}
|
|
229
|
+
serialize(data) {
|
|
230
|
+
let meta = [];
|
|
231
|
+
const maps = [];
|
|
232
|
+
const blobs = [];
|
|
233
|
+
const json = this.serializeValue(data, [], meta, maps, blobs);
|
|
234
|
+
meta = meta.length === 0 ? void 0 : meta;
|
|
235
|
+
if (maps.length === 0) {
|
|
236
|
+
return { json, meta };
|
|
237
|
+
}
|
|
238
|
+
return { json, meta, maps, blobs };
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* `segments` is a shared mutable stack (push/pop while walking),
|
|
242
|
+
* so it must be copied before being stored in `meta` or `maps`.
|
|
243
|
+
*/
|
|
244
|
+
serializeValue(data, segments, meta, maps, blobs) {
|
|
245
|
+
if (this.inlineBuiltInHandlers) {
|
|
246
|
+
switch (typeof data) {
|
|
247
|
+
case "string":
|
|
248
|
+
case "boolean":
|
|
249
|
+
return data;
|
|
250
|
+
case "number":
|
|
251
|
+
if (Number.isNaN(data)) {
|
|
252
|
+
meta.push(["nan", ...segments]);
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
return data;
|
|
256
|
+
case "undefined":
|
|
257
|
+
meta.push(["undefined", ...segments]);
|
|
258
|
+
return null;
|
|
259
|
+
case "bigint":
|
|
260
|
+
meta.push(["bigint", ...segments]);
|
|
261
|
+
return data.toString();
|
|
262
|
+
case "object": {
|
|
263
|
+
if (data === null) {
|
|
264
|
+
return data;
|
|
265
|
+
}
|
|
266
|
+
if (data instanceof Date) {
|
|
267
|
+
meta.push(["date", ...segments]);
|
|
268
|
+
return Number.isNaN(data.getTime()) ? null : data.toISOString();
|
|
269
|
+
}
|
|
270
|
+
if (data instanceof URL) {
|
|
271
|
+
meta.push(["url", ...segments]);
|
|
272
|
+
return data.toString();
|
|
273
|
+
}
|
|
274
|
+
if (data instanceof Set) {
|
|
275
|
+
const result = this.serializeValue(Array.from(data), segments, meta, maps, blobs);
|
|
276
|
+
meta.push(["set", ...segments]);
|
|
277
|
+
return result;
|
|
278
|
+
}
|
|
279
|
+
if (data instanceof Map) {
|
|
280
|
+
const result = this.serializeValue(Array.from(data.entries()), segments, meta, maps, blobs);
|
|
281
|
+
meta.push(["map", ...segments]);
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const handlerEntries = this.handlerEntries;
|
|
288
|
+
if (handlerEntries) {
|
|
289
|
+
for (let i = 0; i < handlerEntries.length; i++) {
|
|
290
|
+
const entry = handlerEntries[i];
|
|
291
|
+
const handler = entry[1];
|
|
292
|
+
if (handler.condition(data)) {
|
|
293
|
+
const serialized = handler.serialize(data);
|
|
294
|
+
if (handler.isTerminal) {
|
|
295
|
+
meta.push([entry[0], ...segments]);
|
|
296
|
+
if (serialized instanceof Blob) {
|
|
297
|
+
maps.push(segments.slice());
|
|
298
|
+
blobs.push(serialized);
|
|
299
|
+
}
|
|
300
|
+
return serialized;
|
|
301
|
+
}
|
|
302
|
+
const result = this.serializeValue(serialized, segments, meta, maps, blobs);
|
|
303
|
+
meta.push([entry[0], ...segments]);
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (data instanceof Blob) {
|
|
309
|
+
maps.push(segments.slice());
|
|
310
|
+
blobs.push(data);
|
|
311
|
+
return data;
|
|
312
|
+
}
|
|
313
|
+
if (Array.isArray(data)) {
|
|
314
|
+
const json = [];
|
|
315
|
+
for (let i = 0; i < data.length; i++) {
|
|
316
|
+
segments.push(i);
|
|
317
|
+
json.push(this.serializeValue(data[i], segments, meta, maps, blobs));
|
|
318
|
+
segments.pop();
|
|
319
|
+
}
|
|
320
|
+
return json;
|
|
321
|
+
}
|
|
322
|
+
if (isPlainObject(data)) {
|
|
323
|
+
const json = new NullProtoObj();
|
|
324
|
+
for (const k of Object.keys(data)) {
|
|
325
|
+
const v = data[k];
|
|
326
|
+
if (k === "toJSON" && typeof v === "function") {
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
if (v === void 0 && this.omitUndefinedProperties) {
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
segments.push(k);
|
|
333
|
+
json[k] = this.serializeValue(v, segments, meta, maps, blobs);
|
|
334
|
+
segments.pop();
|
|
335
|
+
}
|
|
336
|
+
return json;
|
|
337
|
+
}
|
|
338
|
+
return data;
|
|
339
|
+
}
|
|
340
|
+
deserialize(serialized) {
|
|
341
|
+
const ref = { json: serialized.json };
|
|
342
|
+
if (serialized.blobs?.length) {
|
|
343
|
+
for (let i = 0; i < serialized.maps.length; i++) {
|
|
344
|
+
const blob = serialized.blobs[i];
|
|
345
|
+
if (!(blob instanceof Blob)) {
|
|
346
|
+
throw invalidSerializedData(`blob ${i} is not a Blob.`);
|
|
347
|
+
}
|
|
348
|
+
const segments = serialized.maps[i];
|
|
349
|
+
let original = serialized;
|
|
350
|
+
let currentRef = ref;
|
|
351
|
+
let preSegment = "json";
|
|
352
|
+
for (let j = 0; j < segments.length; j++) {
|
|
353
|
+
original = original[preSegment];
|
|
354
|
+
currentRef = copyOnWrite(currentRef, preSegment, original);
|
|
355
|
+
preSegment = segments[j];
|
|
356
|
+
if (!Object.hasOwn(currentRef, preSegment)) {
|
|
357
|
+
throw invalidSerializedData(`segment "${preSegment}" does not exist.`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
currentRef[preSegment] = blob;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (serialized.meta) {
|
|
364
|
+
for (const item of serialized.meta) {
|
|
365
|
+
const type = item[0];
|
|
366
|
+
const handler = this.handlers[type];
|
|
367
|
+
if (handler === void 0) {
|
|
368
|
+
throw invalidSerializedData(`type "${type}" is not supported.`);
|
|
369
|
+
}
|
|
370
|
+
let original = serialized;
|
|
371
|
+
let currentRef = ref;
|
|
372
|
+
let preSegment = "json";
|
|
373
|
+
for (let i = 1; i < item.length; i++) {
|
|
374
|
+
original = original[preSegment];
|
|
375
|
+
currentRef = copyOnWrite(currentRef, preSegment, original);
|
|
376
|
+
preSegment = item[i];
|
|
377
|
+
if (!Object.hasOwn(currentRef, preSegment)) {
|
|
378
|
+
throw invalidSerializedData(`segment "${preSegment}" does not exist.`);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
currentRef[preSegment] = handler.deserialize(currentRef[preSegment]);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return ref.json;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
class RPCSerializer {
|
|
389
|
+
jsonSerializer;
|
|
390
|
+
defaultSerializeOptions;
|
|
391
|
+
constructor(options = {}) {
|
|
392
|
+
this.jsonSerializer = new RPCJsonSerializer(options);
|
|
393
|
+
this.defaultSerializeOptions = options.serialize;
|
|
394
|
+
}
|
|
395
|
+
serialize(data, options = {}) {
|
|
396
|
+
if (data === void 0 || data instanceof ReadableStream || data instanceof Blob) {
|
|
397
|
+
return data;
|
|
398
|
+
}
|
|
399
|
+
if (isAsyncIteratorObject(data)) {
|
|
400
|
+
return wrapAsyncIteratorPreservingEventMeta(data, {
|
|
401
|
+
mapResult: (result) => {
|
|
402
|
+
if (result.value === void 0) {
|
|
403
|
+
return result;
|
|
404
|
+
}
|
|
405
|
+
return { done: result.done, value: this.serializeValue(result.value, false) };
|
|
406
|
+
},
|
|
407
|
+
mapError: (e) => new ErrorEvent(
|
|
408
|
+
this.serializeValue(toORPCError(e).toJSON(), false),
|
|
409
|
+
{ cause: e }
|
|
410
|
+
)
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
const useFormDataForBlobs = options.useFormDataForBlobFields ?? this.defaultSerializeOptions?.useFormDataForBlobFields ?? true;
|
|
414
|
+
return this.serializeValue(data, useFormDataForBlobs);
|
|
415
|
+
}
|
|
416
|
+
serializeValue(data, useFormDataForBlobs) {
|
|
417
|
+
const { json, meta, maps, blobs } = this.jsonSerializer.serialize(data);
|
|
418
|
+
if (!useFormDataForBlobs || !blobs?.length) {
|
|
419
|
+
return { json, meta };
|
|
420
|
+
}
|
|
421
|
+
const form = new FormData();
|
|
422
|
+
form.set("data", stringifyJSON({ json, meta, maps }));
|
|
423
|
+
blobs.forEach((blob, i) => {
|
|
424
|
+
form.set(i.toString(), blob);
|
|
425
|
+
});
|
|
426
|
+
return form;
|
|
427
|
+
}
|
|
428
|
+
deserialize(data) {
|
|
429
|
+
if (data === void 0 || data instanceof ReadableStream || data instanceof Blob) {
|
|
430
|
+
return data;
|
|
431
|
+
}
|
|
432
|
+
if (isAsyncIteratorObject(data)) {
|
|
433
|
+
return wrapAsyncIteratorPreservingEventMeta(data, {
|
|
434
|
+
mapResult: (result) => {
|
|
435
|
+
if (result.value === void 0) {
|
|
436
|
+
return result;
|
|
437
|
+
}
|
|
438
|
+
return { done: result.done, value: this.deserializeValue(result.value) };
|
|
439
|
+
},
|
|
440
|
+
mapError: (e) => {
|
|
441
|
+
if (!(e instanceof ErrorEvent)) {
|
|
442
|
+
return e;
|
|
443
|
+
}
|
|
444
|
+
const deserialized = this.deserializeValue(e.data);
|
|
445
|
+
if (isORPCErrorJson(deserialized)) {
|
|
446
|
+
return createORPCErrorFromJson(deserialized, { cause: e });
|
|
447
|
+
}
|
|
448
|
+
return new ErrorEvent(deserialized, { cause: e });
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
return this.deserializeValue(data);
|
|
453
|
+
}
|
|
454
|
+
deserializeValue(data) {
|
|
455
|
+
if (!(data instanceof FormData)) {
|
|
456
|
+
return this.jsonSerializer.deserialize(data);
|
|
457
|
+
}
|
|
458
|
+
const serialized = JSON.parse(data.get("data"));
|
|
459
|
+
const blobs = [];
|
|
460
|
+
for (const [key, value] of data) {
|
|
461
|
+
if (value instanceof Blob) {
|
|
462
|
+
blobs[Number(key)] = value;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return this.jsonSerializer.deserialize({ ...serialized, blobs });
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export { RPCSerializer as R, createORPCErrorFromJson as a, isDefinedError as b, createORPCErrorFromMalformedResponse as c, RPCJsonSerializer as d, cloneORPCError as e, isORPCErrorJson as i, toORPCError as t, wrapAsyncIteratorPreservingEventMeta as w };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Promisable, OrderablePlugin, Interceptor } from '@orpc/shared';
|
|
2
|
-
import { StandardRequest, StandardLazyResponse } from '@
|
|
3
|
-
import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.
|
|
2
|
+
import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
|
|
3
|
+
import { C as ClientContext, a as ClientOptions, A as AnyORPCError, b as ClientLink } from './client.BoXZCzuS.js';
|
|
4
4
|
|
|
5
5
|
type StandardLinkCodecDecodedResponse = {
|
|
6
6
|
kind: 'output';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PromiseWithError, Registry, MaybeOptionalOptions } from '@orpc/shared';
|
|
2
|
+
import { StandardResponse } from '@standard-server/core';
|
|
2
3
|
|
|
3
4
|
interface ClientContext {
|
|
4
5
|
[key: PropertyKey]: any;
|
|
@@ -21,6 +22,11 @@ type NestedClient<TClientContext extends ClientContext> = Client<TClientContext,
|
|
|
21
22
|
[k: string]: NestedClient<TClientContext>;
|
|
22
23
|
};
|
|
23
24
|
type AnyNestedClient = NestedClient<any>;
|
|
25
|
+
/**
|
|
26
|
+
* Infers the **client context type** required by a client.
|
|
27
|
+
*
|
|
28
|
+
* @see {@link https://orpc.dev/docs/client/client-side#infer-client-context | Client-Side Clients - Infer Client Context}
|
|
29
|
+
*/
|
|
24
30
|
type InferClientContext<T extends AnyNestedClient> = T extends NestedClient<infer U> ? U : never;
|
|
25
31
|
interface ClientLink<TClientContext extends ClientContext> {
|
|
26
32
|
call: (path: string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>;
|
|
@@ -29,6 +35,8 @@ interface ClientLink<TClientContext extends ClientContext> {
|
|
|
29
35
|
* Recursively infers the **input types** from a client.
|
|
30
36
|
*
|
|
31
37
|
* Produces a nested map where each endpoint's input type is preserved.
|
|
38
|
+
*
|
|
39
|
+
* @see {@link https://orpc.dev/docs/client/client-side#infer-client-inputs | Client-Side Clients - Infer Client Inputs}
|
|
32
40
|
*/
|
|
33
41
|
type InferClientInputs<T extends AnyNestedClient> = T extends Client<any, infer U, any, any> ? U : {
|
|
34
42
|
[K in keyof T]: T[K] extends AnyNestedClient ? InferClientInputs<T[K]> : never;
|
|
@@ -38,6 +46,8 @@ type InferClientInputs<T extends AnyNestedClient> = T extends Client<any, infer
|
|
|
38
46
|
*
|
|
39
47
|
* If an endpoint's input includes `{ body: ... }`, only the `body` portion is extracted.
|
|
40
48
|
* Produces a nested map of body input types.
|
|
49
|
+
*
|
|
50
|
+
* @see {@link https://orpc.dev/docs/client/client-side#infer-client-body-inputs | Client-Side Clients - Infer Client Body Inputs}
|
|
41
51
|
*/
|
|
42
52
|
type InferClientBodyInputs<T extends AnyNestedClient> = T extends Client<any, infer U, any, any> ? U extends {
|
|
43
53
|
body: infer UBody;
|
|
@@ -48,6 +58,8 @@ type InferClientBodyInputs<T extends AnyNestedClient> = T extends Client<any, in
|
|
|
48
58
|
* Recursively infers the **output types** from a client.
|
|
49
59
|
*
|
|
50
60
|
* Produces a nested map where each endpoint's output type is preserved.
|
|
61
|
+
*
|
|
62
|
+
* @see {@link https://orpc.dev/docs/client/client-side#infer-client-outputs | Client-Side Clients - Infer Client Outputs}
|
|
51
63
|
*/
|
|
52
64
|
type InferClientOutputs<T extends AnyNestedClient> = T extends Client<any, any, infer U, any> ? U : {
|
|
53
65
|
[K in keyof T]: T[K] extends AnyNestedClient ? InferClientOutputs<T[K]> : never;
|
|
@@ -57,6 +69,8 @@ type InferClientOutputs<T extends AnyNestedClient> = T extends Client<any, any,
|
|
|
57
69
|
*
|
|
58
70
|
* If an endpoint's output includes `{ body: ... }`, only the `body` portion is extracted.
|
|
59
71
|
* Produces a nested map of body output types.
|
|
72
|
+
*
|
|
73
|
+
* @see {@link https://orpc.dev/docs/client/client-side#infer-client-body-outputs | Client-Side Clients - Infer Client Body Outputs}
|
|
60
74
|
*/
|
|
61
75
|
type InferClientBodyOutputs<T extends AnyNestedClient> = T extends Client<any, any, infer U, any> ? U extends {
|
|
62
76
|
body: infer UBody;
|
|
@@ -64,22 +78,33 @@ type InferClientBodyOutputs<T extends AnyNestedClient> = T extends Client<any, a
|
|
|
64
78
|
[K in keyof T]: T[K] extends AnyNestedClient ? InferClientBodyOutputs<T[K]> : never;
|
|
65
79
|
};
|
|
66
80
|
/**
|
|
67
|
-
* Recursively infers the **error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#
|
|
81
|
+
* Recursively infers the **error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#typesafe-errors).
|
|
68
82
|
*
|
|
69
83
|
* Produces a nested map where each endpoint's error type is preserved.
|
|
84
|
+
*
|
|
85
|
+
* @see {@link https://orpc.dev/docs/client/client-side#infer-client-errors | Client-Side Clients - Infer Client Errors}
|
|
70
86
|
*/
|
|
71
87
|
type InferClientErrors<T extends AnyNestedClient> = T extends Client<any, any, any, infer U> ? U : {
|
|
72
88
|
[K in keyof T]: T[K] extends AnyNestedClient ? InferClientErrors<T[K]> : never;
|
|
73
89
|
};
|
|
74
90
|
/**
|
|
75
|
-
* Recursively infers a **union of all error types** from a client when you use [type-safe errors](https://orpc.dev/docs/error-handling#
|
|
91
|
+
* 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).
|
|
76
92
|
*
|
|
77
93
|
* Useful when you want to handle all possible errors from any endpoint at once.
|
|
94
|
+
*
|
|
95
|
+
* @see {@link https://orpc.dev/docs/client/client-side#infer-client-error | Client-Side Clients - Infer Client Error}
|
|
78
96
|
*/
|
|
79
97
|
type InferClientError<T extends AnyNestedClient> = T extends Client<any, any, any, infer U> ? U : {
|
|
80
98
|
[K in keyof T]: T[K] extends AnyNestedClient ? InferClientError<T[K]> : never;
|
|
81
99
|
}[keyof T];
|
|
82
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Default mapping between common oRPC error codes and HTTP status codes.
|
|
103
|
+
* Handlers use it to determine response status codes; spread it to build a custom `errorStatusMap`.
|
|
104
|
+
*
|
|
105
|
+
* @see {@link https://orpc.dev/docs/rpc/handler#custom-error-response | RPC Handler - Custom Error Response}
|
|
106
|
+
* @see {@link https://orpc.dev/docs/openapi/handler#custom-error-response | OpenAPI Handler - Custom Error Response}
|
|
107
|
+
*/
|
|
83
108
|
declare const COMMON_ERROR_STATUS_MAP: {
|
|
84
109
|
BAD_REQUEST: number;
|
|
85
110
|
UNAUTHORIZED: number;
|
|
@@ -114,24 +139,26 @@ type ORPCErrorOptions<TData> = ErrorOptions & {
|
|
|
114
139
|
} : {
|
|
115
140
|
data: TData;
|
|
116
141
|
});
|
|
142
|
+
/**
|
|
143
|
+
* Typed error carrying a `code`, a `message`, and optional `data`.
|
|
144
|
+
* Throw it from handlers or middleware to produce typed error responses on the client.
|
|
145
|
+
*
|
|
146
|
+
* @see {@link https://orpc.dev/docs/error-handling#orpcerror-class | Error Handling - ORPCError Class}
|
|
147
|
+
*/
|
|
117
148
|
declare class ORPCError<TCode extends ORPCErrorCode, TData> extends Error {
|
|
118
149
|
/**
|
|
119
|
-
* @
|
|
120
|
-
* The `__branch` property is used for type branding, helping TypeScript distinguish
|
|
150
|
+
* @remarks
|
|
151
|
+
* **Note**: The `__branch` property is used for type branding, helping TypeScript distinguish
|
|
121
152
|
* an `ORPCError` instance from plain objects with a similar structure.
|
|
122
153
|
*/
|
|
123
154
|
readonly name: "ORPCError" & {
|
|
124
155
|
__branch: "ORPCError";
|
|
125
156
|
};
|
|
126
157
|
/**
|
|
127
|
-
* Indicates whether the error matches a definition in the procedure's `.errors` map
|
|
158
|
+
* Indicates whether the error matches a definition in the procedure's `.errors` map,
|
|
159
|
+
* which makes its type inferable on the client.
|
|
128
160
|
*/
|
|
129
161
|
readonly defined: boolean;
|
|
130
|
-
/**
|
|
131
|
-
* Indicates whether the error's type is inferable at the TypeScript level.
|
|
132
|
-
* This is typically true when the error is explicitly defined or returned within a handler.
|
|
133
|
-
*/
|
|
134
|
-
readonly inferable: boolean;
|
|
135
162
|
code: TCode;
|
|
136
163
|
data: TData;
|
|
137
164
|
constructor(code: TCode, ...rest: MaybeOptionalOptions<ORPCErrorOptions<TData>>);
|
|
@@ -155,13 +182,26 @@ interface ORPCErrorJSON<TCode extends string, TData> extends Pick<ORPCError<TCod
|
|
|
155
182
|
* remove readonly
|
|
156
183
|
*/
|
|
157
184
|
defined: boolean;
|
|
158
|
-
/**
|
|
159
|
-
* remove readonly
|
|
160
|
-
*/
|
|
161
|
-
inferable: boolean;
|
|
162
185
|
}
|
|
163
186
|
type AnyORPCError = ORPCError<any, any>;
|
|
164
187
|
type AnyORPCErrorJSON = ORPCErrorJSON<any, any>;
|
|
188
|
+
interface MalformedResponseErrorOptions extends ErrorOptions {
|
|
189
|
+
message?: string;
|
|
190
|
+
response: StandardResponse;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Error indicating a response does not follow the expected oRPC format, carrying
|
|
194
|
+
* the resolved response. Found as the `cause` of a `MALFORMED_ORPC_RESPONSE`
|
|
195
|
+
* `ORPCError`.
|
|
196
|
+
*
|
|
197
|
+
* @see {@link https://orpc.dev/docs/rpc/link#malformed-responses | RPC Link - Malformed Responses}
|
|
198
|
+
* @see {@link https://orpc.dev/docs/openapi/link#malformed-responses | OpenAPI Link - Malformed Responses}
|
|
199
|
+
*/
|
|
200
|
+
declare class MalformedResponseError extends Error {
|
|
201
|
+
readonly name = "MalformedResponseError";
|
|
202
|
+
response: StandardResponse;
|
|
203
|
+
constructor(options: MalformedResponseErrorOptions);
|
|
204
|
+
}
|
|
165
205
|
|
|
166
|
-
export { ORPCError as
|
|
167
|
-
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,
|
|
206
|
+
export { ORPCError as h, COMMON_ERROR_STATUS_MAP as j, MalformedResponseError as p };
|
|
207
|
+
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 };
|