@orpc/server 2.0.0-beta.44 → 2.0.0-beta.46
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 +100 -62
- package/dist/adapters/aws-lambda/index.d.mts +1 -0
- package/dist/adapters/aws-lambda/index.d.ts +1 -0
- package/dist/adapters/aws-lambda/index.mjs +3 -3
- package/dist/adapters/crossws/index.mjs +3 -3
- package/dist/adapters/fastify/index.mjs +3 -3
- package/dist/adapters/fetch/index.d.mts +2 -2
- package/dist/adapters/fetch/index.d.ts +2 -2
- package/dist/adapters/fetch/index.mjs +3 -3
- package/dist/adapters/message-port/index.d.mts +1 -1
- package/dist/adapters/message-port/index.d.ts +1 -1
- package/dist/adapters/message-port/index.mjs +3 -3
- package/dist/adapters/node/index.d.mts +1 -1
- package/dist/adapters/node/index.d.ts +1 -1
- package/dist/adapters/node/index.mjs +3 -3
- package/dist/adapters/standard/index.d.mts +8 -7
- package/dist/adapters/standard/index.d.ts +8 -7
- package/dist/adapters/standard/index.mjs +3 -3
- package/dist/adapters/websocket/index.mjs +3 -3
- package/dist/extensions/callable.mjs +2 -2
- package/dist/helpers/index.mjs +2 -8
- package/dist/index.d.mts +18 -33
- package/dist/index.d.ts +18 -33
- package/dist/index.mjs +12 -10
- package/dist/plugins/index.d.mts +57 -32
- package/dist/plugins/index.d.ts +57 -32
- package/dist/plugins/index.mjs +189 -48
- package/dist/shared/{server.DJNkZPfD.d.ts → server.9B1jEm5a.d.mts} +6 -16
- package/dist/shared/{server.FEqy7Hrj.mjs → server.BB464y-6.mjs} +6 -4
- package/dist/shared/{server.DD1roZl9.d.mts → server.BC5BIu02.d.mts} +1 -1
- package/dist/shared/{server.UG_xdTub.d.mts → server.BSYGskId.d.ts} +3 -3
- package/dist/shared/{server.DFEuNUt4.d.ts → server.BvG3boBj.d.mts} +3 -3
- package/dist/shared/{server.BllfVJLm.d.mts → server.CTV_mC2P.d.mts} +2 -2
- package/dist/shared/{server.BgvqVW_v.mjs → server.CYbIpHbH.mjs} +17 -5
- package/dist/shared/{server.COfbQ0D8.d.ts → server.CgBF3Vj1.d.ts} +2 -2
- package/dist/shared/{server.B34dZrzY.mjs → server.Chq5FpXf.mjs} +4 -10
- package/dist/shared/{server.BEdOJs6S.d.mts → server.DFPxP2v3.d.mts} +11 -8
- package/dist/shared/{server.BEdOJs6S.d.ts → server.DFPxP2v3.d.ts} +11 -8
- package/dist/shared/{server.CVO0hWyj.d.mts → server.DOg7ke6y.d.ts} +6 -16
- package/dist/shared/{server.DZeVx8K9.d.ts → server.Dz7j9BEh.d.ts} +1 -1
- package/dist/shared/{server.AVQWL-DI.mjs → server.sBQSgqK3.mjs} +1 -1
- package/package.json +12 -12
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ORPCError } from '@orpc/client';
|
|
2
|
-
import {
|
|
2
|
+
import { DEFAULT_BATCH_MAX_SIZE, BATCH_HEADER } from '@orpc/client/plugins';
|
|
3
|
+
export { BATCH_HEADER, DEFAULT_BATCH_MAX_SIZE } from '@orpc/client/plugins';
|
|
4
|
+
import { toArray, value, promiseWithResolvers, isAsyncIteratorObject, isCompressibleContentType, isNoTransformCacheControl, parseAcceptEncodingQualities, isAcceptableEncoding, varyByAcceptEncoding, stringifyJSON, anyAbortSignal, override, AsyncIteratorClass, runWithSignal, AbortError, wrapAsyncIterator, wrapReadableStream } from '@orpc/shared';
|
|
3
5
|
import { flattenStandardHeader, parseStandardUrl, generateContentDisposition, mergeStandardHeaders } from '@standard-server/core';
|
|
4
|
-
import {
|
|
6
|
+
import { ServerPeer, isPeerMessage, isClientPeerSendMessage, encodePeerMessage } from '@standard-server/peer';
|
|
5
7
|
import { toFetchHeaders, toStandardBody, toStandardHeaders } from '@standard-server/fetch';
|
|
6
8
|
export { R as RequestLimitHandlerPlugin } from '../shared/server.1ExWFMze.mjs';
|
|
7
9
|
|
|
@@ -17,6 +19,48 @@ async function encodeFrame(message) {
|
|
|
17
19
|
const bytes = typeof encoded === "string" ? textEncoder.encode(encoded) : encoded;
|
|
18
20
|
return [encodeLengthPrefix(bytes.byteLength), bytes];
|
|
19
21
|
}
|
|
22
|
+
function isBodyHeader(name) {
|
|
23
|
+
return name.startsWith("content-") || name === "standard-server";
|
|
24
|
+
}
|
|
25
|
+
function isClientPeerSendMessages(maybe) {
|
|
26
|
+
return Array.isArray(maybe) && maybe.every((m) => isPeerMessage(m) && isClientPeerSendMessage(m));
|
|
27
|
+
}
|
|
28
|
+
function internalError(err) {
|
|
29
|
+
Promise.reject(err);
|
|
30
|
+
return { status: 500, headers: {}, body: "Internal server error" };
|
|
31
|
+
}
|
|
32
|
+
function liftSubresponseHeaders(batchHeaders, subresponseHeaders) {
|
|
33
|
+
const [first = {}, ...rest] = subresponseHeaders;
|
|
34
|
+
const shared = {};
|
|
35
|
+
for (const [name, value2] of Object.entries(first)) {
|
|
36
|
+
if (value2 === void 0 || isBodyHeader(name)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const flattened = flattenStandardHeader(value2);
|
|
40
|
+
if (rest.every((other) => flattenStandardHeader(other[name]) === flattened)) {
|
|
41
|
+
shared[name] = value2;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const headers = { ...shared, ...batchHeaders };
|
|
45
|
+
const cookies = new Set([batchHeaders, ...subresponseHeaders].flatMap((other) => toArray(other["set-cookie"])));
|
|
46
|
+
if (cookies.size > 0) {
|
|
47
|
+
headers["set-cookie"] = [...cookies];
|
|
48
|
+
}
|
|
49
|
+
const varies = /* @__PURE__ */ new Map();
|
|
50
|
+
for (const value2 of [batchHeaders, ...subresponseHeaders].flatMap((other) => toArray(other.vary))) {
|
|
51
|
+
for (const field of value2.split(",")) {
|
|
52
|
+
const name = field.trim();
|
|
53
|
+
const key = name.toLowerCase();
|
|
54
|
+
if (name && !varies.has(key)) {
|
|
55
|
+
varies.set(key, name);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (varies.size > 0) {
|
|
60
|
+
headers.vary = varies.has("*") ? "*" : [...varies.values()].join(", ");
|
|
61
|
+
}
|
|
62
|
+
return headers;
|
|
63
|
+
}
|
|
20
64
|
class BatchHandlerPlugin {
|
|
21
65
|
name = "~batch";
|
|
22
66
|
/**
|
|
@@ -26,12 +70,13 @@ class BatchHandlerPlugin {
|
|
|
26
70
|
after = ["~tracing"];
|
|
27
71
|
maxSize;
|
|
28
72
|
mapSubrequest;
|
|
73
|
+
mapSubresponse;
|
|
29
74
|
successStatus;
|
|
30
75
|
headers;
|
|
31
76
|
keepAliveEnabled;
|
|
32
77
|
keepAliveInterval;
|
|
33
78
|
constructor(options = {}) {
|
|
34
|
-
this.maxSize = options.maxSize ??
|
|
79
|
+
this.maxSize = options.maxSize ?? DEFAULT_BATCH_MAX_SIZE;
|
|
35
80
|
this.mapSubrequest = options.mapSubrequest ?? ((subRequest, { request: batchRequest }) => ({
|
|
36
81
|
...subRequest,
|
|
37
82
|
headers: {
|
|
@@ -42,10 +87,19 @@ class BatchHandlerPlugin {
|
|
|
42
87
|
* or `origin`, cannot be overridden by a subrequest, which is just request payload.
|
|
43
88
|
*/
|
|
44
89
|
...batchRequest.headers,
|
|
45
|
-
|
|
90
|
+
[BATCH_HEADER]: void 0
|
|
46
91
|
// useful in case batch plugin is used multiple times
|
|
47
92
|
}
|
|
48
93
|
}));
|
|
94
|
+
this.mapSubresponse = options.mapSubresponse ?? ((subresponse, { headers: batchHeaders }) => {
|
|
95
|
+
const headers = {};
|
|
96
|
+
for (const [name, value2] of Object.entries(subresponse.headers)) {
|
|
97
|
+
if (name !== "set-cookie" && flattenStandardHeader(value2) !== flattenStandardHeader(batchHeaders[name])) {
|
|
98
|
+
headers[name] = value2;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return { ...subresponse, headers };
|
|
102
|
+
});
|
|
49
103
|
this.successStatus = options.successStatus ?? 207;
|
|
50
104
|
this.headers = options.headers ?? {};
|
|
51
105
|
this.keepAliveEnabled = options.keepAlive?.enabled ?? true;
|
|
@@ -53,11 +107,9 @@ class BatchHandlerPlugin {
|
|
|
53
107
|
}
|
|
54
108
|
init(options) {
|
|
55
109
|
const routingInterceptor = async (interceptorOptions) => {
|
|
56
|
-
|
|
57
|
-
if (batchHeader === void 0) {
|
|
110
|
+
if (flattenStandardHeader(interceptorOptions.request.headers[BATCH_HEADER]) === void 0) {
|
|
58
111
|
return interceptorOptions.next();
|
|
59
112
|
}
|
|
60
|
-
const mode = batchHeader === "buffered" ? "buffered" : "streaming";
|
|
61
113
|
let messages;
|
|
62
114
|
try {
|
|
63
115
|
if (interceptorOptions.request.method === "GET") {
|
|
@@ -71,7 +123,7 @@ class BatchHandlerPlugin {
|
|
|
71
123
|
};
|
|
72
124
|
}
|
|
73
125
|
const mightBeMessages = JSON.parse(data);
|
|
74
|
-
if (!
|
|
126
|
+
if (!isClientPeerSendMessages(mightBeMessages)) {
|
|
75
127
|
return {
|
|
76
128
|
matched: true,
|
|
77
129
|
response: { status: 400, headers: {}, body: "Invalid batch request data parameter" }
|
|
@@ -80,7 +132,7 @@ class BatchHandlerPlugin {
|
|
|
80
132
|
messages = mightBeMessages;
|
|
81
133
|
} else {
|
|
82
134
|
const mightBeMessages = await interceptorOptions.request.resolveBody();
|
|
83
|
-
if (!
|
|
135
|
+
if (!isClientPeerSendMessages(mightBeMessages)) {
|
|
84
136
|
return {
|
|
85
137
|
matched: true,
|
|
86
138
|
response: { status: 400, headers: {}, body: "Invalid batch request body" }
|
|
@@ -117,6 +169,14 @@ class BatchHandlerPlugin {
|
|
|
117
169
|
const bufferedMessages = [];
|
|
118
170
|
let streamController;
|
|
119
171
|
let keepAliveTimer;
|
|
172
|
+
const ready = messages.map(() => promiseWithResolvers());
|
|
173
|
+
const lifting = Promise.all(ready.map(({ promise }) => promise)).then((all) => {
|
|
174
|
+
const heads = all.filter((head) => head !== void 0);
|
|
175
|
+
return {
|
|
176
|
+
batchHeaders: liftSubresponseHeaders(headers, heads.map((head) => head.headers)),
|
|
177
|
+
streams: heads.some((head) => head.stream)
|
|
178
|
+
};
|
|
179
|
+
});
|
|
120
180
|
const clearKeepAlive = () => {
|
|
121
181
|
if (keepAliveTimer !== void 0) {
|
|
122
182
|
clearInterval(keepAliveTimer);
|
|
@@ -143,50 +203,37 @@ class BatchHandlerPlugin {
|
|
|
143
203
|
scheduleKeepAlive();
|
|
144
204
|
};
|
|
145
205
|
const peer = new ServerPeer(async (message) => {
|
|
146
|
-
if (mode === "streaming") {
|
|
147
|
-
startStreaming();
|
|
148
|
-
}
|
|
149
206
|
if (streamController === void 0) {
|
|
150
207
|
bufferedMessages.push(message);
|
|
151
208
|
} else {
|
|
152
209
|
await enqueueMessage(message);
|
|
153
210
|
}
|
|
154
211
|
});
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
212
|
+
const handleIndividualRequest = async (request, markReady) => {
|
|
213
|
+
let response;
|
|
214
|
+
try {
|
|
215
|
+
request = this.mapSubrequest(request, interceptorOptions);
|
|
216
|
+
const result = await interceptorOptions.next({ ...interceptorOptions, request });
|
|
217
|
+
response = result.matched ? result.response : { status: 404, headers: {}, body: "No procedure matched" };
|
|
218
|
+
} catch (err) {
|
|
219
|
+
response = internalError(err);
|
|
159
220
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
scheduleKeepAlive();
|
|
164
|
-
},
|
|
165
|
-
async cancel(reason) {
|
|
166
|
-
clearKeepAlive();
|
|
167
|
-
await peer.close(reason);
|
|
168
|
-
}
|
|
221
|
+
markReady({
|
|
222
|
+
headers: response.headers,
|
|
223
|
+
stream: response.body instanceof ReadableStream || isAsyncIteratorObject(response.body)
|
|
169
224
|
});
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
const handleIndividualRequest = async (request) => {
|
|
225
|
+
const { batchHeaders: batchHeaders2 } = await lifting;
|
|
173
226
|
try {
|
|
174
|
-
|
|
175
|
-
const { matched, response } = await interceptorOptions.next({ ...interceptorOptions, request });
|
|
176
|
-
if (!matched) {
|
|
177
|
-
return { status: 404, headers: {}, body: "No procedure matched" };
|
|
178
|
-
}
|
|
179
|
-
if (response.body instanceof ReadableStream || isAsyncIteratorObject(response.body)) {
|
|
180
|
-
startStreaming();
|
|
181
|
-
}
|
|
182
|
-
return response;
|
|
227
|
+
return this.mapSubresponse(response, { status, headers: batchHeaders2 }, interceptorOptions);
|
|
183
228
|
} catch (err) {
|
|
184
|
-
|
|
185
|
-
return { status: 500, headers: {}, body: "Internal server error" };
|
|
229
|
+
return internalError(err);
|
|
186
230
|
}
|
|
187
231
|
};
|
|
188
232
|
const runSubrequests = async () => {
|
|
189
|
-
const promise = Promise.all(messages.map((msg) =>
|
|
233
|
+
const promise = Promise.all(messages.map((msg, i) => {
|
|
234
|
+
const { resolve } = ready[i];
|
|
235
|
+
return peer.message(msg, (request) => handleIndividualRequest(request, resolve)).finally(() => resolve(void 0));
|
|
236
|
+
}));
|
|
190
237
|
const signal = interceptorOptions.request.signal;
|
|
191
238
|
const closePeer = () => peer.close(signal?.reason);
|
|
192
239
|
if (signal?.aborted) {
|
|
@@ -200,8 +247,9 @@ class BatchHandlerPlugin {
|
|
|
200
247
|
}
|
|
201
248
|
};
|
|
202
249
|
const subrequests = runSubrequests();
|
|
203
|
-
const
|
|
204
|
-
if (
|
|
250
|
+
const { batchHeaders, streams } = await lifting;
|
|
251
|
+
if (!streams) {
|
|
252
|
+
await subrequests;
|
|
205
253
|
await peer.close();
|
|
206
254
|
if (bufferedMessages.some((msg) => msg.binary !== void 0)) {
|
|
207
255
|
const chunks = (await Promise.all(bufferedMessages.map(encodeFrame))).flat();
|
|
@@ -209,17 +257,28 @@ class BatchHandlerPlugin {
|
|
|
209
257
|
matched: true,
|
|
210
258
|
response: {
|
|
211
259
|
status,
|
|
212
|
-
headers,
|
|
260
|
+
headers: batchHeaders,
|
|
213
261
|
body: new Blob(chunks, { type: BATCH_CONTENT_TYPE })
|
|
214
262
|
}
|
|
215
263
|
};
|
|
216
264
|
}
|
|
217
265
|
return {
|
|
218
266
|
matched: true,
|
|
219
|
-
response: { status, headers, body: bufferedMessages }
|
|
267
|
+
response: { status, headers: batchHeaders, body: bufferedMessages }
|
|
220
268
|
};
|
|
221
269
|
}
|
|
222
|
-
|
|
270
|
+
const body = new ReadableStream({
|
|
271
|
+
start(controller) {
|
|
272
|
+
streamController = controller;
|
|
273
|
+
scheduleKeepAlive();
|
|
274
|
+
},
|
|
275
|
+
async cancel(reason) {
|
|
276
|
+
clearKeepAlive();
|
|
277
|
+
await peer.close(reason);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
const flushed = Promise.all(bufferedMessages.splice(0).map(enqueueMessage));
|
|
281
|
+
Promise.all([flushed, subrequests]).then(async () => {
|
|
223
282
|
clearKeepAlive();
|
|
224
283
|
streamController.close();
|
|
225
284
|
await peer.close();
|
|
@@ -232,8 +291,8 @@ class BatchHandlerPlugin {
|
|
|
232
291
|
matched: true,
|
|
233
292
|
response: {
|
|
234
293
|
status,
|
|
235
|
-
headers: { ...
|
|
236
|
-
body
|
|
294
|
+
headers: { ...batchHeaders, "content-type": BATCH_CONTENT_TYPE },
|
|
295
|
+
body
|
|
237
296
|
}
|
|
238
297
|
};
|
|
239
298
|
};
|
|
@@ -774,6 +833,88 @@ class RethrowHandlerPlugin {
|
|
|
774
833
|
}
|
|
775
834
|
}
|
|
776
835
|
|
|
836
|
+
class SignalSyncHandlerPlugin {
|
|
837
|
+
name = "~signal-sync";
|
|
838
|
+
init(options) {
|
|
839
|
+
const clientInterceptor = async (interceptorOptions) => {
|
|
840
|
+
const controller = new AbortController();
|
|
841
|
+
const signal = anyAbortSignal([interceptorOptions.signal, controller.signal]);
|
|
842
|
+
const cancel = () => controller.abort(new AbortError("The response body was cancelled"));
|
|
843
|
+
const output = await interceptorOptions.next({ ...interceptorOptions, signal });
|
|
844
|
+
if (isAsyncIteratorObject(output)) {
|
|
845
|
+
return override(output, syncAsyncIterator(output, signal, cancel));
|
|
846
|
+
}
|
|
847
|
+
if (output instanceof ReadableStream) {
|
|
848
|
+
return override(output, syncReadableStream(output, signal, cancel));
|
|
849
|
+
}
|
|
850
|
+
return output;
|
|
851
|
+
};
|
|
852
|
+
return { ...options, clientInterceptors: [clientInterceptor, ...toArray(options.clientInterceptors)] };
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
function listenAbort(signal, onAbort) {
|
|
856
|
+
if (signal.aborted) {
|
|
857
|
+
onAbort();
|
|
858
|
+
} else {
|
|
859
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
860
|
+
}
|
|
861
|
+
return () => signal.removeEventListener("abort", onAbort);
|
|
862
|
+
}
|
|
863
|
+
function syncAsyncIterator(iterator, signal, cancel) {
|
|
864
|
+
let cancelling;
|
|
865
|
+
const unlisten = listenAbort(signal, () => {
|
|
866
|
+
cancelling = (async () => iterator.return?.())();
|
|
867
|
+
cancelling.catch(() => {
|
|
868
|
+
});
|
|
869
|
+
});
|
|
870
|
+
return new AsyncIteratorClass(
|
|
871
|
+
() => runWithSignal(signal, () => iterator.next()),
|
|
872
|
+
async ({ kind }) => {
|
|
873
|
+
if (kind === "cancelled") {
|
|
874
|
+
cancel();
|
|
875
|
+
await cancelling;
|
|
876
|
+
}
|
|
877
|
+
unlisten();
|
|
878
|
+
}
|
|
879
|
+
);
|
|
880
|
+
}
|
|
881
|
+
function syncReadableStream(stream, signal, cancel) {
|
|
882
|
+
const reader = stream.getReader();
|
|
883
|
+
let cancelling;
|
|
884
|
+
let unlisten;
|
|
885
|
+
return new ReadableStream({
|
|
886
|
+
start(controller) {
|
|
887
|
+
unlisten = listenAbort(signal, () => {
|
|
888
|
+
controller.error(signal.reason);
|
|
889
|
+
cancelling = reader.cancel(signal.reason);
|
|
890
|
+
cancelling.catch(() => {
|
|
891
|
+
});
|
|
892
|
+
});
|
|
893
|
+
},
|
|
894
|
+
async pull(controller) {
|
|
895
|
+
try {
|
|
896
|
+
const { done, value } = await reader.read();
|
|
897
|
+
if (signal.aborted) {
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
if (done) {
|
|
901
|
+
unlisten();
|
|
902
|
+
controller.close();
|
|
903
|
+
} else {
|
|
904
|
+
controller.enqueue(value);
|
|
905
|
+
}
|
|
906
|
+
} catch (error) {
|
|
907
|
+
unlisten();
|
|
908
|
+
throw error;
|
|
909
|
+
}
|
|
910
|
+
},
|
|
911
|
+
async cancel() {
|
|
912
|
+
cancel();
|
|
913
|
+
await cancelling;
|
|
914
|
+
}
|
|
915
|
+
}, { highWaterMark: 0 });
|
|
916
|
+
}
|
|
917
|
+
|
|
777
918
|
class TimeoutHandlerPlugin {
|
|
778
919
|
timeout;
|
|
779
920
|
streamingTimeout;
|
|
@@ -823,4 +964,4 @@ class TimeoutHandlerPlugin {
|
|
|
823
964
|
}
|
|
824
965
|
}
|
|
825
966
|
|
|
826
|
-
export { BATCH_CONTENT_TYPE, BatchHandlerPlugin, CORSHandlerPlugin, CORSHandlerPlugin as CORSPlugin, GetMethodCsrfProtectionHandlerPlugin, MethodOverrideHandlerPlugin, RequestCompressionHandlerPlugin, RequestHeadersHandlerPlugin, RequestHeadersHandlerPlugin as RequestHeadersPlugin, ResponseCompressionHandlerPlugin, ResponseHeadersHandlerPlugin, ResponseHeadersHandlerPlugin as ResponseHeadersPlugin, RethrowHandlerPlugin, TimeoutHandlerPlugin, negotiateResponseCompressionEncoding, toCompressedHeaders };
|
|
967
|
+
export { BATCH_CONTENT_TYPE, BatchHandlerPlugin, CORSHandlerPlugin, CORSHandlerPlugin as CORSPlugin, GetMethodCsrfProtectionHandlerPlugin, MethodOverrideHandlerPlugin, RequestCompressionHandlerPlugin, RequestHeadersHandlerPlugin, RequestHeadersHandlerPlugin as RequestHeadersPlugin, ResponseCompressionHandlerPlugin, ResponseHeadersHandlerPlugin, ResponseHeadersHandlerPlugin as ResponseHeadersPlugin, RethrowHandlerPlugin, SignalSyncHandlerPlugin, TimeoutHandlerPlugin, negotiateResponseCompressionEncoding, toCompressedHeaders };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AnyORPCError } from '@orpc/client';
|
|
2
2
|
import { OrderablePlugin, Value, Promisable, Interceptor } from '@orpc/shared';
|
|
3
3
|
import { StandardLazyRequest, StandardResponse } from '@standard-server/core';
|
|
4
|
-
import { C as Context, c as ProcedureClientInterceptor, A as AnyProcedure } from './server.
|
|
4
|
+
import { C as Context, c as ProcedureClientInterceptor, A as AnyProcedure } from './server.DFPxP2v3.mjs';
|
|
5
5
|
import { Schema, ErrorMap } from '@orpc/contract';
|
|
6
6
|
|
|
7
7
|
interface StandardHandlerPlugin<T extends Context> extends OrderablePlugin {
|
|
@@ -27,12 +27,6 @@ interface StandardHandlerPlugin<T extends Context> extends OrderablePlugin {
|
|
|
27
27
|
*/
|
|
28
28
|
init?(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
29
29
|
}
|
|
30
|
-
declare class CompositeStandardHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
31
|
-
readonly name = "~composite";
|
|
32
|
-
protected readonly plugins: StandardHandlerPlugin<T>[];
|
|
33
|
-
constructor(plugins?: StandardHandlerPlugin<T>[]);
|
|
34
|
-
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
35
|
-
}
|
|
36
30
|
|
|
37
31
|
interface StandardHandlerHandleOptions<T extends Context> {
|
|
38
32
|
prefix?: `/${string}` | undefined;
|
|
@@ -73,19 +67,19 @@ interface StandardHandlerOptions<TContext extends Context> {
|
|
|
73
67
|
* - batch plugins - separate one request into multiple and call multiple next
|
|
74
68
|
* - openapi spec plugin - to intercept a request and early response
|
|
75
69
|
*/
|
|
76
|
-
routingInterceptors?: StandardHandlerRoutingInterceptor<TContext>[];
|
|
70
|
+
routingInterceptors?: StandardHandlerRoutingInterceptor<TContext>[] | undefined;
|
|
77
71
|
/**
|
|
78
72
|
* interceptor run after routing and before error handler,
|
|
79
73
|
* useful for error handling, logging, metrics, etc.
|
|
80
74
|
*/
|
|
81
|
-
interceptors?: StandardHandlerInterceptor<TContext>[];
|
|
75
|
+
interceptors?: StandardHandlerInterceptor<TContext>[] | undefined;
|
|
82
76
|
/**
|
|
83
77
|
*
|
|
84
78
|
* ClientInterceptor equivalent with createRouterClient.interceptors / createProcedure.interceptors
|
|
85
79
|
* useful for error handling, logging, metrics, etc. (not counting encoding/decoding)
|
|
86
80
|
*/
|
|
87
|
-
clientInterceptors?: ProcedureClientInterceptor<TContext, Schema<unknown>, ErrorMap>[];
|
|
88
|
-
plugins?: StandardHandlerPlugin<TContext>[];
|
|
81
|
+
clientInterceptors?: ProcedureClientInterceptor<TContext, Schema<unknown>, ErrorMap>[] | undefined;
|
|
82
|
+
plugins?: StandardHandlerPlugin<TContext>[] | undefined;
|
|
89
83
|
}
|
|
90
84
|
declare class StandardHandler<T extends Context> {
|
|
91
85
|
private readonly codec;
|
|
@@ -95,10 +89,6 @@ declare class StandardHandler<T extends Context> {
|
|
|
95
89
|
constructor(codec: StandardHandlerCodec<T>, options: StandardHandlerOptions<T>);
|
|
96
90
|
handle(request: StandardLazyRequest, options: StandardHandlerHandleOptions<T>): Promise<StandardHandlerHandleResult>;
|
|
97
91
|
}
|
|
98
|
-
declare class TracingHandlerPlugin implements StandardHandlerPlugin<any> {
|
|
99
|
-
name: string;
|
|
100
|
-
init(options: StandardHandlerOptions<any>): StandardHandlerOptions<any>;
|
|
101
|
-
}
|
|
102
92
|
|
|
103
93
|
interface StandardHandlerCodecResolvedProcedure {
|
|
104
94
|
path: string[];
|
|
@@ -111,5 +101,5 @@ interface StandardHandlerCodec<T extends Context> {
|
|
|
111
101
|
encodeError(error: AnyORPCError, procedure: AnyProcedure, path: string[], options: ResolvedStandardHandlerHandleOptions<T>): Promisable<StandardResponse>;
|
|
112
102
|
}
|
|
113
103
|
|
|
114
|
-
export {
|
|
104
|
+
export { StandardHandler as S };
|
|
115
105
|
export type { ResolvedStandardHandlerHandleOptions as R, StandardHandlerHandleOptions as a, StandardHandlerPlugin as b, StandardHandlerOptions as c, StandardHandlerRoutingInterceptorOptions as d, StandardHandlerInterceptorOptions as e, StandardHandlerCodec as f, StandardHandlerCodecResolvedProcedure as g, StandardHandlerHandleResult as h, StandardHandlerInterceptor as i, StandardHandlerRoutingInterceptor as j };
|
|
@@ -120,7 +120,7 @@ async function executeProcedureInternal(procedure, options) {
|
|
|
120
120
|
const inputSchemas = toArray(procedure["~orpc"].inputSchemas);
|
|
121
121
|
const outputSchemas = toArray(procedure["~orpc"].outputSchemas);
|
|
122
122
|
const orderedMiddlewares = procedure["~orpc"].orderedMiddlewares;
|
|
123
|
-
const next = async (midIndex, context, input) => {
|
|
123
|
+
const next = async (midIndex, context, input, signal) => {
|
|
124
124
|
let currentInput = input;
|
|
125
125
|
let middlewareInput = input;
|
|
126
126
|
const startInputIndex = midIndex === 0 ? 0 : orderedMiddlewares[midIndex - 1].inputSchemasLengthAtUse ?? 0;
|
|
@@ -146,13 +146,15 @@ async function executeProcedureInternal(procedure, options) {
|
|
|
146
146
|
{
|
|
147
147
|
...options,
|
|
148
148
|
context,
|
|
149
|
+
signal,
|
|
149
150
|
next: (...rest) => {
|
|
150
151
|
const nextOptions = resolveMaybeOptionalOptions(rest);
|
|
151
152
|
const nextContext = nextOptions.context ?? {};
|
|
152
153
|
return next(
|
|
153
154
|
midIndex + 1,
|
|
154
155
|
{ ...context, ...nextContext },
|
|
155
|
-
currentInput
|
|
156
|
+
currentInput,
|
|
157
|
+
nextOptions.signal ?? signal
|
|
156
158
|
);
|
|
157
159
|
},
|
|
158
160
|
lastEventId: options.lastEventId
|
|
@@ -166,7 +168,7 @@ async function executeProcedureInternal(procedure, options) {
|
|
|
166
168
|
} else {
|
|
167
169
|
currentOutput = await runWithSpan(
|
|
168
170
|
"handler",
|
|
169
|
-
() => procedure["~orpc"].handler({ ...options, context, input: currentInput }, currentInput)
|
|
171
|
+
() => procedure["~orpc"].handler({ ...options, context, input: currentInput, signal }, currentInput)
|
|
170
172
|
);
|
|
171
173
|
}
|
|
172
174
|
const startOutputIndex = midIndex === 0 ? 0 : orderedMiddlewares[midIndex - 1].outputSchemasLengthAtUse ?? 0;
|
|
@@ -178,7 +180,7 @@ async function executeProcedureInternal(procedure, options) {
|
|
|
178
180
|
}
|
|
179
181
|
return { output: currentOutput, context: currentContext };
|
|
180
182
|
};
|
|
181
|
-
const { output } = await next(0, options.context, options.input);
|
|
183
|
+
const { output } = await next(0, options.context, options.input, options.signal);
|
|
182
184
|
return output;
|
|
183
185
|
}
|
|
184
186
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RouterContract, ProcedureContract, ORPCErrorFromErrorMap, ThrowableError, InferSchemaInput, InferSchemaOutput } from '@orpc/contract';
|
|
2
|
-
import { C as Context, a as Procedure, L as Lazyable, M as MergedContext } from './server.
|
|
2
|
+
import { C as Context, a as Procedure, L as Lazyable, M as MergedContext } from './server.DFPxP2v3.mjs';
|
|
3
3
|
|
|
4
4
|
type Router<TInitialContext extends Context> = Procedure<TInitialContext, any, any, any, any> | {
|
|
5
5
|
[k: string]: Lazyable<Router<TInitialContext>>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Value, Promisable } from '@orpc/shared';
|
|
2
2
|
import { StandardLazyRequest } from '@standard-server/core';
|
|
3
|
-
import { C as Context } from './server.
|
|
4
|
-
import { a as StandardHandlerHandleOptions } from './server.
|
|
3
|
+
import { C as Context } from './server.DFPxP2v3.js';
|
|
4
|
+
import { a as StandardHandlerHandleOptions } from './server.DOg7ke6y.js';
|
|
5
5
|
|
|
6
6
|
type FriendlyStandardHandlerHandleOptions<T extends Context> = Omit<StandardHandlerHandleOptions<T>, 'context'> & (object extends T ? {
|
|
7
|
-
context?: Value<Promisable<T>, [request: StandardLazyRequest]
|
|
7
|
+
context?: Value<Promisable<T>, [request: StandardLazyRequest]> | undefined;
|
|
8
8
|
} : {
|
|
9
9
|
context: Value<Promisable<T>, [request: StandardLazyRequest]>;
|
|
10
10
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Value, Promisable } from '@orpc/shared';
|
|
2
2
|
import { StandardLazyRequest } from '@standard-server/core';
|
|
3
|
-
import { C as Context } from './server.
|
|
4
|
-
import { a as StandardHandlerHandleOptions } from './server.
|
|
3
|
+
import { C as Context } from './server.DFPxP2v3.mjs';
|
|
4
|
+
import { a as StandardHandlerHandleOptions } from './server.9B1jEm5a.mjs';
|
|
5
5
|
|
|
6
6
|
type FriendlyStandardHandlerHandleOptions<T extends Context> = Omit<StandardHandlerHandleOptions<T>, 'context'> & (object extends T ? {
|
|
7
|
-
context?: Value<Promisable<T>, [request: StandardLazyRequest]
|
|
7
|
+
context?: Value<Promisable<T>, [request: StandardLazyRequest]> | undefined;
|
|
8
8
|
} : {
|
|
9
9
|
context: Value<Promisable<T>, [request: StandardLazyRequest]>;
|
|
10
10
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Context } from './server.
|
|
2
|
-
import { b as StandardHandlerPlugin, c as StandardHandlerOptions } from './server.
|
|
1
|
+
import { C as Context } from './server.DFPxP2v3.mjs';
|
|
2
|
+
import { b as StandardHandlerPlugin, c as StandardHandlerOptions } from './server.9B1jEm5a.mjs';
|
|
3
3
|
|
|
4
4
|
interface RequestLimitHandlerPluginOptions {
|
|
5
5
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { ProcedureContract, resolveMetaPlugins, mergeErrorMap } from '@orpc/contract';
|
|
2
|
+
import { isTypescriptObject, getOwn, omit } from '@orpc/shared';
|
|
3
|
+
import { c as createProcedureClient, L as Lazy, u as unlazy, P as Procedure } from './server.BB464y-6.mjs';
|
|
4
4
|
|
|
5
5
|
const DEFAULT_SUCCESS_STATUS = 200;
|
|
6
|
-
const DEFAULT_ERROR_STATUS =
|
|
6
|
+
const DEFAULT_ERROR_STATUS = 400;
|
|
7
7
|
|
|
8
8
|
function createGuardedProcedureLazy(lazy) {
|
|
9
9
|
const guarded = new Lazy({
|
|
@@ -130,6 +130,18 @@ function augmentImplementedRouter(router, options) {
|
|
|
130
130
|
}
|
|
131
131
|
return enhanced;
|
|
132
132
|
}
|
|
133
|
+
async function resolveContractProcedure(router, contract, path) {
|
|
134
|
+
if (contract instanceof Procedure) {
|
|
135
|
+
return contract;
|
|
136
|
+
}
|
|
137
|
+
const { default: maybeProcedure } = await unlazy(getRouter(router, path));
|
|
138
|
+
if (!(maybeProcedure instanceof Procedure)) {
|
|
139
|
+
throw new TypeError(
|
|
140
|
+
`[Contract-First] Missing or invalid implementation for procedure at path: "${path.join(".")}". Ensure the procedure is correctly implemented and matches its contract.`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
return createContractProcedure(maybeProcedure, contract);
|
|
144
|
+
}
|
|
133
145
|
function getRouter(router, path) {
|
|
134
146
|
let current = router;
|
|
135
147
|
for (let i = 0; i < path.length; i++) {
|
|
@@ -224,4 +236,4 @@ async function unlazyRouter(router) {
|
|
|
224
236
|
return unlazied;
|
|
225
237
|
}
|
|
226
238
|
|
|
227
|
-
export { DEFAULT_SUCCESS_STATUS as D, DEFAULT_ERROR_STATUS as a, augmentRouter as b,
|
|
239
|
+
export { DEFAULT_SUCCESS_STATUS as D, DEFAULT_ERROR_STATUS as a, augmentRouter as b, augmentImplementedRouter as c, withHiddenRouterContract as d, createGuardedProcedureLazy as e, call as f, getRouter as g, walkProcedureContractsAsync as h, resolveContractProcedure as r, unlazyRouter as u, walkProcedureContractsSync as w };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Context } from './server.
|
|
2
|
-
import { b as StandardHandlerPlugin, c as StandardHandlerOptions } from './server.
|
|
1
|
+
import { C as Context } from './server.DFPxP2v3.js';
|
|
2
|
+
import { b as StandardHandlerPlugin, c as StandardHandlerOptions } from './server.DOg7ke6y.js';
|
|
3
3
|
|
|
4
4
|
interface RequestLimitHandlerPluginOptions {
|
|
5
5
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ORPCError, toORPCError, RPCSerializer, COMMON_ERROR_STATUS_MAP } from '@orpc/client';
|
|
2
2
|
import { sortPlugins, toArray, matchesHttpPathPrefix, value, intercept, getTracer, runWithSpan, ORPC_NAME, isAsyncIteratorObject, override, traceAsyncIterator, traceReadableStream, recordSpanError, wrapAsyncIterator, toTracingException, wrapReadableStream, pathToHttpPath, normalizeHttpPath, parseEmptyableJSON, getOwn } from '@orpc/shared';
|
|
3
3
|
import { flattenStandardHeader, parseStandardUrl, ErrorEvent } from '@standard-server/core';
|
|
4
|
-
import { c as createProcedureClient, u as unlazy, P as Procedure } from './server.
|
|
5
|
-
import { w as walkProcedureContractsSync,
|
|
4
|
+
import { c as createProcedureClient, u as unlazy, P as Procedure } from './server.BB464y-6.mjs';
|
|
5
|
+
import { w as walkProcedureContractsSync, r as resolveContractProcedure, D as DEFAULT_SUCCESS_STATUS, a as DEFAULT_ERROR_STATUS } from './server.CYbIpHbH.mjs';
|
|
6
6
|
|
|
7
7
|
class CompositeStandardHandlerPlugin {
|
|
8
8
|
name = "~composite";
|
|
@@ -298,13 +298,7 @@ class RPCMatcher {
|
|
|
298
298
|
this.pendingLazyRouters.delete(httpPathPrefix);
|
|
299
299
|
}
|
|
300
300
|
async resolveProcedure(entry) {
|
|
301
|
-
|
|
302
|
-
if (!(maybeProcedure instanceof Procedure)) {
|
|
303
|
-
throw new TypeError(
|
|
304
|
-
`[Contract-First] Missing or invalid implementation for procedure at path: "${entry.path.join(".")}". Ensure the procedure is correctly implemented and matches its contract.`
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
entry.procedure = createContractProcedure(maybeProcedure, entry.contract);
|
|
301
|
+
entry.procedure = await resolveContractProcedure(this.rootRouter, entry.contract, entry.path);
|
|
308
302
|
return entry.procedure;
|
|
309
303
|
}
|
|
310
304
|
}
|
|
@@ -356,4 +350,4 @@ class RPCHandlerCodec {
|
|
|
356
350
|
}
|
|
357
351
|
}
|
|
358
352
|
|
|
359
|
-
export {
|
|
353
|
+
export { RPCHandlerCodec as R, StandardHandler as S, RPCMatcher as a, RPC_DEFAULT_ALLOW_METHODS as b };
|
|
@@ -12,16 +12,19 @@ type MiddlewareResult<TOutContext extends Context, TOutput> = Promisable<{
|
|
|
12
12
|
output: TOutput;
|
|
13
13
|
context: TOutContext;
|
|
14
14
|
}>;
|
|
15
|
-
type MiddlewareNextOptions<TOutContext extends Context> = object extends TOutContext ? {
|
|
16
|
-
context?: TOutContext;
|
|
15
|
+
type MiddlewareNextOptions<TOutContext extends Context> = (object extends TOutContext ? {
|
|
16
|
+
context?: TOutContext | undefined;
|
|
17
17
|
} : {
|
|
18
18
|
context: TOutContext;
|
|
19
|
+
}) & {
|
|
20
|
+
/** Overrides the signal for the rest of the chain. */
|
|
21
|
+
signal?: AbortSignal | undefined;
|
|
19
22
|
};
|
|
20
23
|
interface MiddlewareNext<TOutput> {
|
|
21
24
|
<T extends Context = object>(...rest: MaybeOptionalOptions<MiddlewareNextOptions<T>>): MiddlewareResult<T, TOutput>;
|
|
22
25
|
}
|
|
23
26
|
type MiddlewareDoneOptions<TOutContext, TOutput> = (object extends TOutContext ? {
|
|
24
|
-
context?: TOutContext;
|
|
27
|
+
context?: TOutContext | undefined;
|
|
25
28
|
} : {
|
|
26
29
|
context: TOutContext;
|
|
27
30
|
}) & {
|
|
@@ -150,14 +153,14 @@ interface ProcedureClientInterceptorOptions<TInitialContext extends Context, TEr
|
|
|
150
153
|
}
|
|
151
154
|
type ProcedureClientInterceptor<TInitialContext extends Context, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap> = Interceptor<ProcedureClientInterceptorOptions<TInitialContext, TErrorMap>, PromiseWithError<InferSchemaOutput<TOutputSchema>, ORPCErrorFromErrorMap<TErrorMap> | ThrowableError>>;
|
|
152
155
|
type ProcedureClientOptions<TInitialContext extends Context, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TClientContext extends ClientContext> = {
|
|
153
|
-
path?: string[];
|
|
154
|
-
interceptors?: ProcedureClientInterceptor<TInitialContext, TOutputSchema, TErrorMap>[];
|
|
156
|
+
path?: string[] | undefined;
|
|
157
|
+
interceptors?: ProcedureClientInterceptor<TInitialContext, TOutputSchema, TErrorMap>[] | undefined;
|
|
155
158
|
} & (object extends TInitialContext ? {
|
|
156
|
-
context?: Value<Promisable<TInitialContext>, [clientContext: TClientContext]
|
|
159
|
+
context?: Value<Promisable<TInitialContext>, [clientContext: TClientContext]> | undefined;
|
|
157
160
|
} : {
|
|
158
161
|
context: Value<Promisable<TInitialContext>, [clientContext: TClientContext]>;
|
|
159
162
|
});
|
|
160
163
|
declare function createProcedureClient<TInitialContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TClientContext extends ClientContext = object>(lazyableProcedure: Lazyable<Procedure<TInitialContext, any, TInputSchema, TOutputSchema, TErrorMap>>, ...rest: MaybeOptionalOptions<ProcedureClientOptions<TInitialContext, TOutputSchema, TErrorMap, TClientContext>>): ProcedureClient<TClientContext, TInputSchema, TOutputSchema, TErrorMap>;
|
|
161
164
|
|
|
162
|
-
export { Procedure as a, Lazy as
|
|
163
|
-
export type { AnyProcedure as A, Context as C, Lazyable as L, MergedContext as M, OrderedMiddleware as O, ProcedureClientOptions as P, ProcedureClient as b, ProcedureClientInterceptor as c, Middleware as d, MergedInitialContext as e,
|
|
165
|
+
export { Procedure as a, Lazy as f, createProcedureClient as u, unlazy as v };
|
|
166
|
+
export type { AnyProcedure as A, Context as C, Lazyable as L, MergedContext as M, OrderedMiddleware as O, ProcedureClientOptions as P, ProcedureClient as b, ProcedureClientInterceptor as c, Middleware as d, MergedInitialContext as e, ProcedureHandler as g, ProcedureConfig as h, AnyMiddleware as i, LazyDefinition as j, MiddlewareDefinition as k, MiddlewareDone as l, MiddlewareDoneOptions as m, MiddlewareNext as n, MiddlewareNextOptions as o, MiddlewareOptions as p, MiddlewareResult as q, ProcedureClientInterceptorOptions as r, ProcedureDefinition as s, ProcedureHandlerOptions as t };
|