@orpc/client 0.0.0-next.32a6de9 → 0.0.0-next.32e1281
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 +17 -22
- package/dist/adapters/fetch/index.d.mts +13 -6
- package/dist/adapters/fetch/index.d.ts +13 -6
- package/dist/adapters/fetch/index.mjs +5 -8
- package/dist/adapters/message-port/index.d.mts +59 -0
- package/dist/adapters/message-port/index.d.ts +59 -0
- package/dist/adapters/message-port/index.mjs +71 -0
- package/dist/adapters/standard/index.d.mts +3 -3
- package/dist/adapters/standard/index.d.ts +3 -3
- package/dist/adapters/standard/index.mjs +2 -2
- package/dist/adapters/websocket/index.d.mts +29 -0
- package/dist/adapters/websocket/index.d.ts +29 -0
- package/dist/adapters/websocket/index.mjs +44 -0
- package/dist/index.d.mts +22 -8
- package/dist/index.d.ts +22 -8
- package/dist/index.mjs +4 -4
- package/dist/plugins/index.d.mts +103 -13
- package/dist/plugins/index.d.ts +103 -13
- package/dist/plugins/index.mjs +150 -17
- package/dist/shared/{client.CipPQkhk.d.ts → client.4TS_0JaO.d.mts} +1 -1
- package/dist/shared/{client.CipPQkhk.d.mts → client.4TS_0JaO.d.ts} +1 -1
- package/dist/shared/{client.cs2A0fEV.d.ts → client.7UM0t5o-.d.ts} +13 -9
- package/dist/shared/{client.p3ON_yzu.d.ts → client.BMoG_EdN.d.mts} +16 -10
- package/dist/shared/{client.jKEwIsRd.mjs → client.BX0_8bnM.mjs} +30 -33
- package/dist/shared/{client.Cev5VIeo.d.mts → client.BdD8cpjs.d.mts} +13 -9
- package/dist/shared/{client.C7z5zk4v.d.mts → client.C0KbSWlC.d.ts} +16 -10
- package/dist/shared/{client.BQuFq0Vi.mjs → client.CQCGVpTM.mjs} +33 -16
- package/package.json +16 -5
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { isAsyncIteratorObject, value, splitInHalf, toArray } from '@orpc/shared';
|
|
2
|
-
import { toBatchRequest, parseBatchResponse } from '@orpc/standard-server/batch';
|
|
3
|
-
import { getEventMeta } from '@orpc/standard-server';
|
|
1
|
+
import { isAsyncIteratorObject, defer, value, splitInHalf, toArray, stringifyJSON } from '@orpc/shared';
|
|
2
|
+
import { toBatchRequest, parseBatchResponse, toBatchAbortSignal } from '@orpc/standard-server/batch';
|
|
3
|
+
import { replicateStandardLazyResponse, getEventMeta } from '@orpc/standard-server';
|
|
4
4
|
|
|
5
5
|
class BatchLinkPlugin {
|
|
6
6
|
groups;
|
|
@@ -10,12 +10,15 @@ class BatchLinkPlugin {
|
|
|
10
10
|
batchHeaders;
|
|
11
11
|
mapRequestItem;
|
|
12
12
|
exclude;
|
|
13
|
+
mode;
|
|
13
14
|
pending;
|
|
15
|
+
order = 5e6;
|
|
14
16
|
constructor(options) {
|
|
15
17
|
this.groups = options.groups;
|
|
16
18
|
this.pending = /* @__PURE__ */ new Map();
|
|
17
19
|
this.maxSize = options.maxSize ?? 10;
|
|
18
20
|
this.maxUrlLength = options.maxUrlLength ?? 2083;
|
|
21
|
+
this.mode = options.mode ?? "streaming";
|
|
19
22
|
this.batchUrl = options.url ?? (([options2]) => `${options2.request.url.origin}${options2.request.url.pathname}/__batch__`);
|
|
20
23
|
this.batchHeaders = options.headers ?? (([options2, ...rest]) => {
|
|
21
24
|
const headers = {};
|
|
@@ -70,7 +73,7 @@ class BatchLinkPlugin {
|
|
|
70
73
|
}
|
|
71
74
|
return new Promise((resolve, reject) => {
|
|
72
75
|
this.#enqueueRequest(group, options2, resolve, reject);
|
|
73
|
-
|
|
76
|
+
defer(() => this.#processPendingBatches());
|
|
74
77
|
});
|
|
75
78
|
});
|
|
76
79
|
}
|
|
@@ -126,8 +129,9 @@ class BatchLinkPlugin {
|
|
|
126
129
|
this.#executeBatch(method, group, second);
|
|
127
130
|
return;
|
|
128
131
|
}
|
|
132
|
+
const mode = value(this.mode, options);
|
|
129
133
|
const lazyResponse = await options[0].next({
|
|
130
|
-
request: { ...batchRequest, headers: { ...batchRequest.headers, "x-orpc-batch":
|
|
134
|
+
request: { ...batchRequest, headers: { ...batchRequest.headers, "x-orpc-batch": mode } },
|
|
131
135
|
signal: batchRequest.signal,
|
|
132
136
|
context: group.context,
|
|
133
137
|
input: group.input,
|
|
@@ -146,6 +150,101 @@ class BatchLinkPlugin {
|
|
|
146
150
|
}
|
|
147
151
|
}
|
|
148
152
|
|
|
153
|
+
class DedupeRequestsPlugin {
|
|
154
|
+
#groups;
|
|
155
|
+
#filter;
|
|
156
|
+
order = 4e6;
|
|
157
|
+
// make sure execute before batch plugin
|
|
158
|
+
#queue = /* @__PURE__ */ new Map();
|
|
159
|
+
constructor(options) {
|
|
160
|
+
this.#groups = options.groups;
|
|
161
|
+
this.#filter = options.filter ?? (({ request }) => request.method === "GET");
|
|
162
|
+
}
|
|
163
|
+
init(options) {
|
|
164
|
+
options.clientInterceptors ??= [];
|
|
165
|
+
options.clientInterceptors.push((options2) => {
|
|
166
|
+
if (options2.request.body instanceof Blob || options2.request.body instanceof FormData || options2.request.body instanceof URLSearchParams || isAsyncIteratorObject(options2.request.body) || !this.#filter(options2)) {
|
|
167
|
+
return options2.next();
|
|
168
|
+
}
|
|
169
|
+
const group = this.#groups.find((group2) => group2.condition(options2));
|
|
170
|
+
if (!group) {
|
|
171
|
+
return options2.next();
|
|
172
|
+
}
|
|
173
|
+
return new Promise((resolve, reject) => {
|
|
174
|
+
this.#enqueue(group, options2, resolve, reject);
|
|
175
|
+
defer(() => this.#dequeue());
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
#enqueue(group, options, resolve, reject) {
|
|
180
|
+
let queue = this.#queue.get(group);
|
|
181
|
+
if (!queue) {
|
|
182
|
+
this.#queue.set(group, queue = []);
|
|
183
|
+
}
|
|
184
|
+
const matched = queue.find((item) => {
|
|
185
|
+
const requestString1 = stringifyJSON({
|
|
186
|
+
body: item.options.request.body,
|
|
187
|
+
headers: item.options.request.headers,
|
|
188
|
+
method: item.options.request.method,
|
|
189
|
+
url: item.options.request.url
|
|
190
|
+
});
|
|
191
|
+
const requestString2 = stringifyJSON({
|
|
192
|
+
body: options.request.body,
|
|
193
|
+
headers: options.request.headers,
|
|
194
|
+
method: options.request.method,
|
|
195
|
+
url: options.request.url
|
|
196
|
+
});
|
|
197
|
+
return requestString1 === requestString2;
|
|
198
|
+
});
|
|
199
|
+
if (matched) {
|
|
200
|
+
matched.signals.push(options.request.signal);
|
|
201
|
+
matched.resolves.push(resolve);
|
|
202
|
+
matched.rejects.push(reject);
|
|
203
|
+
} else {
|
|
204
|
+
queue.push({
|
|
205
|
+
options,
|
|
206
|
+
signals: [options.request.signal],
|
|
207
|
+
resolves: [resolve],
|
|
208
|
+
rejects: [reject]
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async #dequeue() {
|
|
213
|
+
const promises = [];
|
|
214
|
+
for (const [group, items] of this.#queue) {
|
|
215
|
+
for (const { options, signals, resolves, rejects } of items) {
|
|
216
|
+
promises.push(
|
|
217
|
+
this.#execute(group, options, signals, resolves, rejects)
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
this.#queue.clear();
|
|
222
|
+
await Promise.all(promises);
|
|
223
|
+
}
|
|
224
|
+
async #execute(group, options, signals, resolves, rejects) {
|
|
225
|
+
try {
|
|
226
|
+
const dedupedRequest = {
|
|
227
|
+
...options.request,
|
|
228
|
+
signal: toBatchAbortSignal(signals)
|
|
229
|
+
};
|
|
230
|
+
const response = await options.next({
|
|
231
|
+
...options,
|
|
232
|
+
request: dedupedRequest,
|
|
233
|
+
signal: dedupedRequest.signal,
|
|
234
|
+
context: group.context
|
|
235
|
+
});
|
|
236
|
+
const replicatedResponses = replicateStandardLazyResponse(response, resolves.length);
|
|
237
|
+
for (const resolve of resolves) {
|
|
238
|
+
resolve(replicatedResponses.shift());
|
|
239
|
+
}
|
|
240
|
+
} catch (error) {
|
|
241
|
+
for (const reject of rejects) {
|
|
242
|
+
reject(error);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
149
248
|
class ClientRetryPluginInvalidEventIteratorRetryResponse extends Error {
|
|
150
249
|
}
|
|
151
250
|
class ClientRetryPlugin {
|
|
@@ -174,20 +273,20 @@ class ClientRetryPlugin {
|
|
|
174
273
|
}
|
|
175
274
|
let lastEventId = interceptorOptions.lastEventId;
|
|
176
275
|
let lastEventRetry;
|
|
177
|
-
let
|
|
276
|
+
let callback;
|
|
178
277
|
let attemptIndex = 0;
|
|
179
|
-
const next = async (
|
|
180
|
-
let
|
|
278
|
+
const next = async (initialError) => {
|
|
279
|
+
let currentError = initialError;
|
|
181
280
|
while (true) {
|
|
182
281
|
const updatedInterceptorOptions = { ...interceptorOptions, lastEventId };
|
|
183
|
-
if (
|
|
282
|
+
if (currentError) {
|
|
184
283
|
if (attemptIndex >= maxAttempts) {
|
|
185
|
-
throw
|
|
284
|
+
throw currentError.error;
|
|
186
285
|
}
|
|
187
286
|
const attemptOptions = {
|
|
188
287
|
...updatedInterceptorOptions,
|
|
189
288
|
attemptIndex,
|
|
190
|
-
error:
|
|
289
|
+
error: currentError.error,
|
|
191
290
|
lastEventRetry
|
|
192
291
|
};
|
|
193
292
|
const shouldRetryBool = await value(
|
|
@@ -195,23 +294,24 @@ class ClientRetryPlugin {
|
|
|
195
294
|
attemptOptions
|
|
196
295
|
);
|
|
197
296
|
if (!shouldRetryBool) {
|
|
198
|
-
throw
|
|
297
|
+
throw currentError.error;
|
|
199
298
|
}
|
|
200
|
-
|
|
299
|
+
callback = onRetry?.(attemptOptions);
|
|
201
300
|
const retryDelayMs = await value(retryDelay, attemptOptions);
|
|
202
301
|
await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
|
|
203
302
|
attemptIndex++;
|
|
204
303
|
}
|
|
205
304
|
try {
|
|
305
|
+
currentError = void 0;
|
|
206
306
|
return await interceptorOptions.next(updatedInterceptorOptions);
|
|
207
307
|
} catch (error) {
|
|
308
|
+
currentError = { error };
|
|
208
309
|
if (updatedInterceptorOptions.signal?.aborted === true) {
|
|
209
310
|
throw error;
|
|
210
311
|
}
|
|
211
|
-
current = { error };
|
|
212
312
|
} finally {
|
|
213
|
-
|
|
214
|
-
|
|
313
|
+
callback?.(!currentError);
|
|
314
|
+
callback = void 0;
|
|
215
315
|
}
|
|
216
316
|
}
|
|
217
317
|
};
|
|
@@ -253,4 +353,37 @@ class ClientRetryPlugin {
|
|
|
253
353
|
}
|
|
254
354
|
}
|
|
255
355
|
|
|
256
|
-
|
|
356
|
+
class SimpleCsrfProtectionLinkPlugin {
|
|
357
|
+
headerName;
|
|
358
|
+
headerValue;
|
|
359
|
+
exclude;
|
|
360
|
+
constructor(options = {}) {
|
|
361
|
+
this.headerName = options.headerName ?? "x-csrf-token";
|
|
362
|
+
this.headerValue = options.headerValue ?? "orpc";
|
|
363
|
+
this.exclude = options.exclude ?? false;
|
|
364
|
+
}
|
|
365
|
+
order = 8e6;
|
|
366
|
+
init(options) {
|
|
367
|
+
options.clientInterceptors ??= [];
|
|
368
|
+
options.clientInterceptors.push(async (options2) => {
|
|
369
|
+
const excluded = await value(this.exclude, options2);
|
|
370
|
+
if (excluded) {
|
|
371
|
+
return options2.next();
|
|
372
|
+
}
|
|
373
|
+
const headerName = await value(this.headerName, options2);
|
|
374
|
+
const headerValue = await value(this.headerValue, options2);
|
|
375
|
+
return options2.next({
|
|
376
|
+
...options2,
|
|
377
|
+
request: {
|
|
378
|
+
...options2.request,
|
|
379
|
+
headers: {
|
|
380
|
+
...options2.request.headers,
|
|
381
|
+
[headerName]: headerValue
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export { BatchLinkPlugin, ClientRetryPlugin, ClientRetryPluginInvalidEventIteratorRetryResponse, DedupeRequestsPlugin, SimpleCsrfProtectionLinkPlugin };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PromiseWithError } from '@orpc/shared';
|
|
2
2
|
|
|
3
3
|
type HTTPPath = `/${string}`;
|
|
4
|
-
type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
4
|
+
type HTTPMethod = 'HEAD' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
5
5
|
type ClientContext = Record<PropertyKey, any>;
|
|
6
6
|
interface ClientOptions<T extends ClientContext> {
|
|
7
7
|
signal?: AbortSignal;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PromiseWithError } from '@orpc/shared';
|
|
2
2
|
|
|
3
3
|
type HTTPPath = `/${string}`;
|
|
4
|
-
type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
4
|
+
type HTTPMethod = 'HEAD' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
5
5
|
type ClientContext = Record<PropertyKey, any>;
|
|
6
6
|
interface ClientOptions<T extends ClientContext> {
|
|
7
7
|
signal?: AbortSignal;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as ClientContext,
|
|
2
|
-
import {
|
|
3
|
-
import { Segment, Value } from '@orpc/shared';
|
|
1
|
+
import { a as ClientContext, b as ClientOptions, d as HTTPMethod } from './client.4TS_0JaO.js';
|
|
2
|
+
import { e as StandardLinkCodec, b as StandardLinkOptions, d as StandardLink, f as StandardLinkClient } from './client.C0KbSWlC.js';
|
|
3
|
+
import { Segment, Value, Promisable } from '@orpc/shared';
|
|
4
4
|
import { StandardHeaders, StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
|
|
5
5
|
|
|
6
6
|
declare const STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES: {
|
|
@@ -44,30 +44,30 @@ interface StandardRPCLinkCodecOptions<T extends ClientContext> {
|
|
|
44
44
|
/**
|
|
45
45
|
* Base url for all requests.
|
|
46
46
|
*/
|
|
47
|
-
url: Value<string | URL
|
|
47
|
+
url: Value<Promisable<string | URL>, [options: ClientOptions<T>, path: readonly string[], input: unknown]>;
|
|
48
48
|
/**
|
|
49
49
|
* The maximum length of the URL.
|
|
50
50
|
*
|
|
51
51
|
* @default 2083
|
|
52
52
|
*/
|
|
53
|
-
maxUrlLength?: Value<number
|
|
53
|
+
maxUrlLength?: Value<Promisable<number>, [options: ClientOptions<T>, path: readonly string[], input: unknown]>;
|
|
54
54
|
/**
|
|
55
55
|
* The method used to make the request.
|
|
56
56
|
*
|
|
57
57
|
* @default 'POST'
|
|
58
58
|
*/
|
|
59
|
-
method?: Value<HTTPMethod, [
|
|
59
|
+
method?: Value<Promisable<Exclude<HTTPMethod, 'HEAD'>>, [options: ClientOptions<T>, path: readonly string[], input: unknown]>;
|
|
60
60
|
/**
|
|
61
61
|
* The method to use when the payload cannot safely pass to the server with method return from method function.
|
|
62
62
|
* GET is not allowed, it's very dangerous.
|
|
63
63
|
*
|
|
64
64
|
* @default 'POST'
|
|
65
65
|
*/
|
|
66
|
-
fallbackMethod?: Exclude<HTTPMethod, 'GET'>;
|
|
66
|
+
fallbackMethod?: Exclude<HTTPMethod, 'HEAD' | 'GET'>;
|
|
67
67
|
/**
|
|
68
68
|
* Inject headers to the request.
|
|
69
69
|
*/
|
|
70
|
-
headers?: Value<StandardHeaders
|
|
70
|
+
headers?: Value<Promisable<StandardHeaders>, [options: ClientOptions<T>, path: readonly string[], input: unknown]>;
|
|
71
71
|
}
|
|
72
72
|
declare class StandardRPCLinkCodec<T extends ClientContext> implements StandardLinkCodec<T> {
|
|
73
73
|
private readonly serializer;
|
|
@@ -83,5 +83,9 @@ declare class StandardRPCLinkCodec<T extends ClientContext> implements StandardL
|
|
|
83
83
|
|
|
84
84
|
interface StandardRPCLinkOptions<T extends ClientContext> extends StandardLinkOptions<T>, StandardRPCLinkCodecOptions<T>, StandardRPCJsonSerializerOptions {
|
|
85
85
|
}
|
|
86
|
+
declare class StandardRPCLink<T extends ClientContext> extends StandardLink<T> {
|
|
87
|
+
constructor(linkClient: StandardLinkClient<T>, options: StandardRPCLinkOptions<T>);
|
|
88
|
+
}
|
|
86
89
|
|
|
87
|
-
export { STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES as S,
|
|
90
|
+
export { STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES as S, StandardRPCJsonSerializer as e, StandardRPCLink as g, StandardRPCLinkCodec as i, StandardRPCSerializer as j };
|
|
91
|
+
export type { StandardRPCJsonSerializedMetaItem as a, StandardRPCJsonSerialized as b, StandardRPCCustomJsonSerializer as c, StandardRPCJsonSerializerOptions as d, StandardRPCLinkOptions as f, StandardRPCLinkCodecOptions as h };
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import { Interceptor
|
|
1
|
+
import { Interceptor } from '@orpc/shared';
|
|
2
2
|
import { StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
|
|
3
|
-
import { a as ClientContext, b as ClientOptions, C as ClientLink } from './client.
|
|
3
|
+
import { a as ClientContext, b as ClientOptions, C as ClientLink } from './client.4TS_0JaO.mjs';
|
|
4
|
+
|
|
5
|
+
interface StandardLinkPlugin<T extends ClientContext> {
|
|
6
|
+
order?: number;
|
|
7
|
+
init?(options: StandardLinkOptions<T>): void;
|
|
8
|
+
}
|
|
9
|
+
declare class CompositeStandardLinkPlugin<T extends ClientContext, TPlugin extends StandardLinkPlugin<T>> implements StandardLinkPlugin<T> {
|
|
10
|
+
protected readonly plugins: TPlugin[];
|
|
11
|
+
constructor(plugins?: readonly TPlugin[]);
|
|
12
|
+
init(options: StandardLinkOptions<T>): void;
|
|
13
|
+
}
|
|
4
14
|
|
|
5
15
|
interface StandardLinkCodec<T extends ClientContext> {
|
|
6
16
|
encode(path: readonly string[], input: unknown, options: ClientOptions<T>): Promise<StandardRequest>;
|
|
@@ -10,11 +20,6 @@ interface StandardLinkClient<T extends ClientContext> {
|
|
|
10
20
|
call(request: StandardRequest, options: ClientOptions<T>, path: readonly string[], input: unknown): Promise<StandardLazyResponse>;
|
|
11
21
|
}
|
|
12
22
|
|
|
13
|
-
declare class InvalidEventIteratorRetryResponse extends Error {
|
|
14
|
-
}
|
|
15
|
-
interface StandardLinkPlugin<T extends ClientContext> {
|
|
16
|
-
init?(options: StandardLinkOptions<T>): void;
|
|
17
|
-
}
|
|
18
23
|
interface StandardLinkInterceptorOptions<T extends ClientContext> extends ClientOptions<T> {
|
|
19
24
|
path: readonly string[];
|
|
20
25
|
input: unknown;
|
|
@@ -23,8 +28,8 @@ interface StandardLinkClientInterceptorOptions<T extends ClientContext> extends
|
|
|
23
28
|
request: StandardRequest;
|
|
24
29
|
}
|
|
25
30
|
interface StandardLinkOptions<T extends ClientContext> {
|
|
26
|
-
interceptors?: Interceptor<StandardLinkInterceptorOptions<T>, unknown
|
|
27
|
-
clientInterceptors?: Interceptor<StandardLinkClientInterceptorOptions<T>, StandardLazyResponse
|
|
31
|
+
interceptors?: Interceptor<StandardLinkInterceptorOptions<T>, Promise<unknown>>[];
|
|
32
|
+
clientInterceptors?: Interceptor<StandardLinkClientInterceptorOptions<T>, Promise<StandardLazyResponse>>[];
|
|
28
33
|
plugins?: StandardLinkPlugin<T>[];
|
|
29
34
|
}
|
|
30
35
|
declare class StandardLink<T extends ClientContext> implements ClientLink<T> {
|
|
@@ -37,4 +42,5 @@ declare class StandardLink<T extends ClientContext> implements ClientLink<T> {
|
|
|
37
42
|
call(path: readonly string[], input: unknown, options: ClientOptions<T>): Promise<unknown>;
|
|
38
43
|
}
|
|
39
44
|
|
|
40
|
-
export {
|
|
45
|
+
export { CompositeStandardLinkPlugin as C, StandardLink as d };
|
|
46
|
+
export type { StandardLinkClientInterceptorOptions as S, StandardLinkPlugin as a, StandardLinkOptions as b, StandardLinkInterceptorOptions as c, StandardLinkCodec as e, StandardLinkClient as f };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isObject, isTypescriptObject } from '@orpc/shared';
|
|
1
|
+
import { isObject, AsyncIteratorClass, isTypescriptObject } from '@orpc/shared';
|
|
2
2
|
import { getEventMeta, withEventMeta } from '@orpc/standard-server';
|
|
3
3
|
|
|
4
4
|
const COMMON_ORPC_ERROR_DEFS = {
|
|
@@ -110,22 +110,6 @@ class ORPCError extends Error {
|
|
|
110
110
|
data: this.data
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
|
-
static fromJSON(json, options) {
|
|
114
|
-
return new ORPCError(json.code, {
|
|
115
|
-
...options,
|
|
116
|
-
...json
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
static isValidJSON(json) {
|
|
120
|
-
if (!isObject(json)) {
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
const validKeys = ["defined", "code", "status", "message", "data"];
|
|
124
|
-
if (Object.keys(json).some((k) => !validKeys.includes(k))) {
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
return "defined" in json && typeof json.defined === "boolean" && "code" in json && typeof json.code === "string" && "status" in json && typeof json.status === "number" && "message" in json && typeof json.message === "string";
|
|
128
|
-
}
|
|
129
113
|
}
|
|
130
114
|
function isDefinedError(error) {
|
|
131
115
|
return error instanceof ORPCError && error.defined;
|
|
@@ -139,24 +123,35 @@ function toORPCError(error) {
|
|
|
139
123
|
function isORPCErrorStatus(status) {
|
|
140
124
|
return status < 200 || status >= 400;
|
|
141
125
|
}
|
|
126
|
+
function isORPCErrorJson(json) {
|
|
127
|
+
if (!isObject(json)) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
const validKeys = ["defined", "code", "status", "message", "data"];
|
|
131
|
+
if (Object.keys(json).some((k) => !validKeys.includes(k))) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
return "defined" in json && typeof json.defined === "boolean" && "code" in json && typeof json.code === "string" && "status" in json && typeof json.status === "number" && isORPCErrorStatus(json.status) && "message" in json && typeof json.message === "string";
|
|
135
|
+
}
|
|
136
|
+
function createORPCErrorFromJson(json, options = {}) {
|
|
137
|
+
return new ORPCError(json.code, {
|
|
138
|
+
...options,
|
|
139
|
+
...json
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
142
|
|
|
143
143
|
function mapEventIterator(iterator, maps) {
|
|
144
|
-
return async
|
|
144
|
+
return new AsyncIteratorClass(async () => {
|
|
145
145
|
try {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
mappedValue = withEventMeta(mappedValue, meta);
|
|
153
|
-
}
|
|
146
|
+
const { done, value } = await iterator.next();
|
|
147
|
+
let mappedValue = await maps.value(value, done);
|
|
148
|
+
if (mappedValue !== value) {
|
|
149
|
+
const meta = getEventMeta(value);
|
|
150
|
+
if (meta && isTypescriptObject(mappedValue)) {
|
|
151
|
+
mappedValue = withEventMeta(mappedValue, meta);
|
|
154
152
|
}
|
|
155
|
-
if (done) {
|
|
156
|
-
return mappedValue;
|
|
157
|
-
}
|
|
158
|
-
yield mappedValue;
|
|
159
153
|
}
|
|
154
|
+
return { done, value: mappedValue };
|
|
160
155
|
} catch (error) {
|
|
161
156
|
let mappedError = await maps.error(error);
|
|
162
157
|
if (mappedError !== error) {
|
|
@@ -166,10 +161,12 @@ function mapEventIterator(iterator, maps) {
|
|
|
166
161
|
}
|
|
167
162
|
}
|
|
168
163
|
throw mappedError;
|
|
169
|
-
}
|
|
164
|
+
}
|
|
165
|
+
}, async (reason) => {
|
|
166
|
+
if (reason !== "next") {
|
|
170
167
|
await iterator.return?.();
|
|
171
168
|
}
|
|
172
|
-
}
|
|
169
|
+
});
|
|
173
170
|
}
|
|
174
171
|
|
|
175
|
-
export { COMMON_ORPC_ERROR_DEFS as C, ORPCError as O, fallbackORPCErrorMessage as a, isORPCErrorStatus as b, fallbackORPCErrorStatus as f, isDefinedError as i, mapEventIterator as m, toORPCError as t };
|
|
172
|
+
export { COMMON_ORPC_ERROR_DEFS as C, ORPCError as O, fallbackORPCErrorMessage as a, isORPCErrorStatus as b, isORPCErrorJson as c, createORPCErrorFromJson as d, fallbackORPCErrorStatus as f, isDefinedError as i, mapEventIterator as m, toORPCError as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as ClientContext,
|
|
2
|
-
import {
|
|
3
|
-
import { Segment, Value } from '@orpc/shared';
|
|
1
|
+
import { a as ClientContext, b as ClientOptions, d as HTTPMethod } from './client.4TS_0JaO.mjs';
|
|
2
|
+
import { e as StandardLinkCodec, b as StandardLinkOptions, d as StandardLink, f as StandardLinkClient } from './client.BMoG_EdN.mjs';
|
|
3
|
+
import { Segment, Value, Promisable } from '@orpc/shared';
|
|
4
4
|
import { StandardHeaders, StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
|
|
5
5
|
|
|
6
6
|
declare const STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES: {
|
|
@@ -44,30 +44,30 @@ interface StandardRPCLinkCodecOptions<T extends ClientContext> {
|
|
|
44
44
|
/**
|
|
45
45
|
* Base url for all requests.
|
|
46
46
|
*/
|
|
47
|
-
url: Value<string | URL
|
|
47
|
+
url: Value<Promisable<string | URL>, [options: ClientOptions<T>, path: readonly string[], input: unknown]>;
|
|
48
48
|
/**
|
|
49
49
|
* The maximum length of the URL.
|
|
50
50
|
*
|
|
51
51
|
* @default 2083
|
|
52
52
|
*/
|
|
53
|
-
maxUrlLength?: Value<number
|
|
53
|
+
maxUrlLength?: Value<Promisable<number>, [options: ClientOptions<T>, path: readonly string[], input: unknown]>;
|
|
54
54
|
/**
|
|
55
55
|
* The method used to make the request.
|
|
56
56
|
*
|
|
57
57
|
* @default 'POST'
|
|
58
58
|
*/
|
|
59
|
-
method?: Value<HTTPMethod, [
|
|
59
|
+
method?: Value<Promisable<Exclude<HTTPMethod, 'HEAD'>>, [options: ClientOptions<T>, path: readonly string[], input: unknown]>;
|
|
60
60
|
/**
|
|
61
61
|
* The method to use when the payload cannot safely pass to the server with method return from method function.
|
|
62
62
|
* GET is not allowed, it's very dangerous.
|
|
63
63
|
*
|
|
64
64
|
* @default 'POST'
|
|
65
65
|
*/
|
|
66
|
-
fallbackMethod?: Exclude<HTTPMethod, 'GET'>;
|
|
66
|
+
fallbackMethod?: Exclude<HTTPMethod, 'HEAD' | 'GET'>;
|
|
67
67
|
/**
|
|
68
68
|
* Inject headers to the request.
|
|
69
69
|
*/
|
|
70
|
-
headers?: Value<StandardHeaders
|
|
70
|
+
headers?: Value<Promisable<StandardHeaders>, [options: ClientOptions<T>, path: readonly string[], input: unknown]>;
|
|
71
71
|
}
|
|
72
72
|
declare class StandardRPCLinkCodec<T extends ClientContext> implements StandardLinkCodec<T> {
|
|
73
73
|
private readonly serializer;
|
|
@@ -83,5 +83,9 @@ declare class StandardRPCLinkCodec<T extends ClientContext> implements StandardL
|
|
|
83
83
|
|
|
84
84
|
interface StandardRPCLinkOptions<T extends ClientContext> extends StandardLinkOptions<T>, StandardRPCLinkCodecOptions<T>, StandardRPCJsonSerializerOptions {
|
|
85
85
|
}
|
|
86
|
+
declare class StandardRPCLink<T extends ClientContext> extends StandardLink<T> {
|
|
87
|
+
constructor(linkClient: StandardLinkClient<T>, options: StandardRPCLinkOptions<T>);
|
|
88
|
+
}
|
|
86
89
|
|
|
87
|
-
export { STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES as S,
|
|
90
|
+
export { STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES as S, StandardRPCJsonSerializer as e, StandardRPCLink as g, StandardRPCLinkCodec as i, StandardRPCSerializer as j };
|
|
91
|
+
export type { StandardRPCJsonSerializedMetaItem as a, StandardRPCJsonSerialized as b, StandardRPCCustomJsonSerializer as c, StandardRPCJsonSerializerOptions as d, StandardRPCLinkOptions as f, StandardRPCLinkCodecOptions as h };
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import { Interceptor
|
|
1
|
+
import { Interceptor } from '@orpc/shared';
|
|
2
2
|
import { StandardRequest, StandardLazyResponse } from '@orpc/standard-server';
|
|
3
|
-
import { a as ClientContext, b as ClientOptions, C as ClientLink } from './client.
|
|
3
|
+
import { a as ClientContext, b as ClientOptions, C as ClientLink } from './client.4TS_0JaO.js';
|
|
4
|
+
|
|
5
|
+
interface StandardLinkPlugin<T extends ClientContext> {
|
|
6
|
+
order?: number;
|
|
7
|
+
init?(options: StandardLinkOptions<T>): void;
|
|
8
|
+
}
|
|
9
|
+
declare class CompositeStandardLinkPlugin<T extends ClientContext, TPlugin extends StandardLinkPlugin<T>> implements StandardLinkPlugin<T> {
|
|
10
|
+
protected readonly plugins: TPlugin[];
|
|
11
|
+
constructor(plugins?: readonly TPlugin[]);
|
|
12
|
+
init(options: StandardLinkOptions<T>): void;
|
|
13
|
+
}
|
|
4
14
|
|
|
5
15
|
interface StandardLinkCodec<T extends ClientContext> {
|
|
6
16
|
encode(path: readonly string[], input: unknown, options: ClientOptions<T>): Promise<StandardRequest>;
|
|
@@ -10,11 +20,6 @@ interface StandardLinkClient<T extends ClientContext> {
|
|
|
10
20
|
call(request: StandardRequest, options: ClientOptions<T>, path: readonly string[], input: unknown): Promise<StandardLazyResponse>;
|
|
11
21
|
}
|
|
12
22
|
|
|
13
|
-
declare class InvalidEventIteratorRetryResponse extends Error {
|
|
14
|
-
}
|
|
15
|
-
interface StandardLinkPlugin<T extends ClientContext> {
|
|
16
|
-
init?(options: StandardLinkOptions<T>): void;
|
|
17
|
-
}
|
|
18
23
|
interface StandardLinkInterceptorOptions<T extends ClientContext> extends ClientOptions<T> {
|
|
19
24
|
path: readonly string[];
|
|
20
25
|
input: unknown;
|
|
@@ -23,8 +28,8 @@ interface StandardLinkClientInterceptorOptions<T extends ClientContext> extends
|
|
|
23
28
|
request: StandardRequest;
|
|
24
29
|
}
|
|
25
30
|
interface StandardLinkOptions<T extends ClientContext> {
|
|
26
|
-
interceptors?: Interceptor<StandardLinkInterceptorOptions<T>, unknown
|
|
27
|
-
clientInterceptors?: Interceptor<StandardLinkClientInterceptorOptions<T>, StandardLazyResponse
|
|
31
|
+
interceptors?: Interceptor<StandardLinkInterceptorOptions<T>, Promise<unknown>>[];
|
|
32
|
+
clientInterceptors?: Interceptor<StandardLinkClientInterceptorOptions<T>, Promise<StandardLazyResponse>>[];
|
|
28
33
|
plugins?: StandardLinkPlugin<T>[];
|
|
29
34
|
}
|
|
30
35
|
declare class StandardLink<T extends ClientContext> implements ClientLink<T> {
|
|
@@ -37,4 +42,5 @@ declare class StandardLink<T extends ClientContext> implements ClientLink<T> {
|
|
|
37
42
|
call(path: readonly string[], input: unknown, options: ClientOptions<T>): Promise<unknown>;
|
|
38
43
|
}
|
|
39
44
|
|
|
40
|
-
export {
|
|
45
|
+
export { CompositeStandardLinkPlugin as C, StandardLink as d };
|
|
46
|
+
export type { StandardLinkClientInterceptorOptions as S, StandardLinkPlugin as a, StandardLinkOptions as b, StandardLinkInterceptorOptions as c, StandardLinkCodec as e, StandardLinkClient as f };
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import { toArray, intercept, isObject, value, isAsyncIteratorObject, stringifyJSON } from '@orpc/shared';
|
|
2
2
|
import { mergeStandardHeaders, ErrorEvent } from '@orpc/standard-server';
|
|
3
|
-
import { C as COMMON_ORPC_ERROR_DEFS, b as isORPCErrorStatus, O as ORPCError, m as mapEventIterator, t as toORPCError } from './client.
|
|
3
|
+
import { C as COMMON_ORPC_ERROR_DEFS, b as isORPCErrorStatus, c as isORPCErrorJson, d as createORPCErrorFromJson, O as ORPCError, m as mapEventIterator, t as toORPCError } from './client.BX0_8bnM.mjs';
|
|
4
4
|
|
|
5
|
-
class
|
|
5
|
+
class CompositeStandardLinkPlugin {
|
|
6
|
+
plugins;
|
|
7
|
+
constructor(plugins = []) {
|
|
8
|
+
this.plugins = [...plugins].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
9
|
+
}
|
|
10
|
+
init(options) {
|
|
11
|
+
for (const plugin of this.plugins) {
|
|
12
|
+
plugin.init?.(options);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
6
15
|
}
|
|
16
|
+
|
|
7
17
|
class StandardLink {
|
|
8
18
|
constructor(codec, sender, options = {}) {
|
|
9
19
|
this.codec = codec;
|
|
10
20
|
this.sender = sender;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
21
|
+
const plugin = new CompositeStandardLinkPlugin(options.plugins);
|
|
22
|
+
plugin.init(options);
|
|
14
23
|
this.interceptors = toArray(options.interceptors);
|
|
15
24
|
this.clientInterceptors = toArray(options.clientInterceptors);
|
|
16
25
|
}
|
|
@@ -202,10 +211,9 @@ class StandardRPCLinkCodec {
|
|
|
202
211
|
expectedMethod;
|
|
203
212
|
headers;
|
|
204
213
|
async encode(path, input, options) {
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const baseUrl = await value(this.baseUrl, generalOptions);
|
|
214
|
+
const expectedMethod = await value(this.expectedMethod, options, path, input);
|
|
215
|
+
let headers = await value(this.headers, options, path, input);
|
|
216
|
+
const baseUrl = await value(this.baseUrl, options, path, input);
|
|
209
217
|
const url = new URL(baseUrl);
|
|
210
218
|
url.pathname = `${url.pathname.replace(/\/$/, "")}${toHttpPath(path)}`;
|
|
211
219
|
if (options.lastEventId !== void 0) {
|
|
@@ -213,7 +221,7 @@ class StandardRPCLinkCodec {
|
|
|
213
221
|
}
|
|
214
222
|
const serialized = this.serializer.serialize(input);
|
|
215
223
|
if (expectedMethod === "GET" && !(serialized instanceof FormData) && !isAsyncIteratorObject(serialized)) {
|
|
216
|
-
const maxUrlLength = await value(this.maxUrlLength,
|
|
224
|
+
const maxUrlLength = await value(this.maxUrlLength, options, path, input);
|
|
217
225
|
const getUrl = new URL(url);
|
|
218
226
|
getUrl.searchParams.append("data", stringifyJSON(serialized));
|
|
219
227
|
if (getUrl.toString().length <= maxUrlLength) {
|
|
@@ -254,12 +262,12 @@ class StandardRPCLinkCodec {
|
|
|
254
262
|
}
|
|
255
263
|
})();
|
|
256
264
|
if (!isOk) {
|
|
257
|
-
if (
|
|
258
|
-
throw
|
|
265
|
+
if (isORPCErrorJson(deserialized)) {
|
|
266
|
+
throw createORPCErrorFromJson(deserialized);
|
|
259
267
|
}
|
|
260
268
|
throw new ORPCError(getMalformedResponseErrorCode(response.status), {
|
|
261
269
|
status: response.status,
|
|
262
|
-
data: deserialized
|
|
270
|
+
data: { ...response, body: deserialized }
|
|
263
271
|
});
|
|
264
272
|
}
|
|
265
273
|
return deserialized;
|
|
@@ -309,8 +317,8 @@ class StandardRPCSerializer {
|
|
|
309
317
|
return e;
|
|
310
318
|
}
|
|
311
319
|
const deserialized = this.#deserialize(e.data);
|
|
312
|
-
if (
|
|
313
|
-
return
|
|
320
|
+
if (isORPCErrorJson(deserialized)) {
|
|
321
|
+
return createORPCErrorFromJson(deserialized, { cause: e });
|
|
314
322
|
}
|
|
315
323
|
return new ErrorEvent({
|
|
316
324
|
data: deserialized,
|
|
@@ -335,4 +343,13 @@ class StandardRPCSerializer {
|
|
|
335
343
|
}
|
|
336
344
|
}
|
|
337
345
|
|
|
338
|
-
|
|
346
|
+
class StandardRPCLink extends StandardLink {
|
|
347
|
+
constructor(linkClient, options) {
|
|
348
|
+
const jsonSerializer = new StandardRPCJsonSerializer(options);
|
|
349
|
+
const serializer = new StandardRPCSerializer(jsonSerializer);
|
|
350
|
+
const linkCodec = new StandardRPCLinkCodec(serializer, options);
|
|
351
|
+
super(linkCodec, linkClient, options);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export { CompositeStandardLinkPlugin as C, StandardLink as S, STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES as a, StandardRPCJsonSerializer as b, StandardRPCLink as c, StandardRPCLinkCodec as d, StandardRPCSerializer as e, getMalformedResponseErrorCode as g, toHttpPath as t };
|