@orpc/server 2.0.0-beta.44 → 2.0.0-beta.45
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 +55 -48
- package/dist/adapters/aws-lambda/index.mjs +2 -2
- package/dist/adapters/crossws/index.mjs +2 -2
- package/dist/adapters/fastify/index.mjs +2 -2
- package/dist/adapters/fetch/index.d.mts +2 -2
- package/dist/adapters/fetch/index.d.ts +2 -2
- package/dist/adapters/fetch/index.mjs +2 -2
- 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 +2 -2
- package/dist/adapters/node/index.d.mts +1 -1
- package/dist/adapters/node/index.d.ts +1 -1
- package/dist/adapters/node/index.mjs +2 -2
- package/dist/adapters/standard/index.d.mts +8 -7
- package/dist/adapters/standard/index.d.ts +8 -7
- package/dist/adapters/standard/index.mjs +2 -2
- package/dist/adapters/websocket/index.mjs +2 -2
- package/dist/helpers/index.mjs +2 -8
- package/dist/index.d.mts +14 -7
- package/dist/index.d.ts +14 -7
- package/dist/index.mjs +2 -2
- package/dist/plugins/index.d.mts +57 -32
- package/dist/plugins/index.d.ts +57 -32
- package/dist/plugins/index.mjs +183 -45
- package/dist/shared/{server.BllfVJLm.d.mts → server.B4hFgqPr.d.mts} +2 -2
- package/dist/shared/{server.BEdOJs6S.d.mts → server.BWhT-63L.d.mts} +5 -5
- package/dist/shared/{server.BEdOJs6S.d.ts → server.BWhT-63L.d.ts} +5 -5
- package/dist/shared/{server.CVO0hWyj.d.mts → server.BYNQ06wN.d.ts} +5 -5
- package/dist/shared/{server.BgvqVW_v.mjs → server.BcxD3fmU.mjs} +15 -3
- package/dist/shared/{server.COfbQ0D8.d.ts → server.CI0qiBzm.d.ts} +2 -2
- package/dist/shared/{server.DFEuNUt4.d.ts → server.CO_upro1.d.ts} +3 -3
- package/dist/shared/{server.DZeVx8K9.d.ts → server.DcDZdSrg.d.ts} +1 -1
- package/dist/shared/{server.UG_xdTub.d.mts → server.DgcwQ-Wr.d.mts} +3 -3
- package/dist/shared/{server.B34dZrzY.mjs → server.Kbq-C85k.mjs} +2 -8
- package/dist/shared/{server.DJNkZPfD.d.ts → server.TVSii8T9.d.mts} +5 -5
- package/dist/shared/{server.DD1roZl9.d.mts → server.TjEHK8V3.d.mts} +1 -1
- package/package.json +12 -12
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
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
6
|
import { isClientPeerSendMessage, ServerPeer, encodePeerMessage } from '@standard-server/peer';
|
|
5
7
|
import { toFetchHeaders, toStandardBody, toStandardHeaders } from '@standard-server/fetch';
|
|
@@ -17,6 +19,45 @@ 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 internalError(err) {
|
|
26
|
+
Promise.reject(err);
|
|
27
|
+
return { status: 500, headers: {}, body: "Internal server error" };
|
|
28
|
+
}
|
|
29
|
+
function liftSubresponseHeaders(batchHeaders, subresponseHeaders) {
|
|
30
|
+
const [first = {}, ...rest] = subresponseHeaders;
|
|
31
|
+
const shared = {};
|
|
32
|
+
for (const [name, value2] of Object.entries(first)) {
|
|
33
|
+
if (value2 === void 0 || isBodyHeader(name)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const flattened = flattenStandardHeader(value2);
|
|
37
|
+
if (rest.every((other) => flattenStandardHeader(other[name]) === flattened)) {
|
|
38
|
+
shared[name] = value2;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const headers = { ...shared, ...batchHeaders };
|
|
42
|
+
const cookies = new Set([batchHeaders, ...subresponseHeaders].flatMap((other) => toArray(other["set-cookie"])));
|
|
43
|
+
if (cookies.size > 0) {
|
|
44
|
+
headers["set-cookie"] = [...cookies];
|
|
45
|
+
}
|
|
46
|
+
const varies = /* @__PURE__ */ new Map();
|
|
47
|
+
for (const value2 of [batchHeaders, ...subresponseHeaders].flatMap((other) => toArray(other.vary))) {
|
|
48
|
+
for (const field of value2.split(",")) {
|
|
49
|
+
const name = field.trim();
|
|
50
|
+
const key = name.toLowerCase();
|
|
51
|
+
if (name && !varies.has(key)) {
|
|
52
|
+
varies.set(key, name);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (varies.size > 0) {
|
|
57
|
+
headers.vary = varies.has("*") ? "*" : [...varies.values()].join(", ");
|
|
58
|
+
}
|
|
59
|
+
return headers;
|
|
60
|
+
}
|
|
20
61
|
class BatchHandlerPlugin {
|
|
21
62
|
name = "~batch";
|
|
22
63
|
/**
|
|
@@ -26,12 +67,13 @@ class BatchHandlerPlugin {
|
|
|
26
67
|
after = ["~tracing"];
|
|
27
68
|
maxSize;
|
|
28
69
|
mapSubrequest;
|
|
70
|
+
mapSubresponse;
|
|
29
71
|
successStatus;
|
|
30
72
|
headers;
|
|
31
73
|
keepAliveEnabled;
|
|
32
74
|
keepAliveInterval;
|
|
33
75
|
constructor(options = {}) {
|
|
34
|
-
this.maxSize = options.maxSize ??
|
|
76
|
+
this.maxSize = options.maxSize ?? DEFAULT_BATCH_MAX_SIZE;
|
|
35
77
|
this.mapSubrequest = options.mapSubrequest ?? ((subRequest, { request: batchRequest }) => ({
|
|
36
78
|
...subRequest,
|
|
37
79
|
headers: {
|
|
@@ -42,10 +84,19 @@ class BatchHandlerPlugin {
|
|
|
42
84
|
* or `origin`, cannot be overridden by a subrequest, which is just request payload.
|
|
43
85
|
*/
|
|
44
86
|
...batchRequest.headers,
|
|
45
|
-
|
|
87
|
+
[BATCH_HEADER]: void 0
|
|
46
88
|
// useful in case batch plugin is used multiple times
|
|
47
89
|
}
|
|
48
90
|
}));
|
|
91
|
+
this.mapSubresponse = options.mapSubresponse ?? ((subresponse, { headers: batchHeaders }) => {
|
|
92
|
+
const headers = {};
|
|
93
|
+
for (const [name, value2] of Object.entries(subresponse.headers)) {
|
|
94
|
+
if (name !== "set-cookie" && flattenStandardHeader(value2) !== flattenStandardHeader(batchHeaders[name])) {
|
|
95
|
+
headers[name] = value2;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return { ...subresponse, headers };
|
|
99
|
+
});
|
|
49
100
|
this.successStatus = options.successStatus ?? 207;
|
|
50
101
|
this.headers = options.headers ?? {};
|
|
51
102
|
this.keepAliveEnabled = options.keepAlive?.enabled ?? true;
|
|
@@ -53,11 +104,9 @@ class BatchHandlerPlugin {
|
|
|
53
104
|
}
|
|
54
105
|
init(options) {
|
|
55
106
|
const routingInterceptor = async (interceptorOptions) => {
|
|
56
|
-
|
|
57
|
-
if (batchHeader === void 0) {
|
|
107
|
+
if (flattenStandardHeader(interceptorOptions.request.headers[BATCH_HEADER]) === void 0) {
|
|
58
108
|
return interceptorOptions.next();
|
|
59
109
|
}
|
|
60
|
-
const mode = batchHeader === "buffered" ? "buffered" : "streaming";
|
|
61
110
|
let messages;
|
|
62
111
|
try {
|
|
63
112
|
if (interceptorOptions.request.method === "GET") {
|
|
@@ -117,6 +166,14 @@ class BatchHandlerPlugin {
|
|
|
117
166
|
const bufferedMessages = [];
|
|
118
167
|
let streamController;
|
|
119
168
|
let keepAliveTimer;
|
|
169
|
+
const ready = messages.map(() => promiseWithResolvers());
|
|
170
|
+
const lifting = Promise.all(ready.map(({ promise }) => promise)).then((all) => {
|
|
171
|
+
const heads = all.filter((head) => head !== void 0);
|
|
172
|
+
return {
|
|
173
|
+
batchHeaders: liftSubresponseHeaders(headers, heads.map((head) => head.headers)),
|
|
174
|
+
streams: heads.some((head) => head.stream)
|
|
175
|
+
};
|
|
176
|
+
});
|
|
120
177
|
const clearKeepAlive = () => {
|
|
121
178
|
if (keepAliveTimer !== void 0) {
|
|
122
179
|
clearInterval(keepAliveTimer);
|
|
@@ -143,50 +200,37 @@ class BatchHandlerPlugin {
|
|
|
143
200
|
scheduleKeepAlive();
|
|
144
201
|
};
|
|
145
202
|
const peer = new ServerPeer(async (message) => {
|
|
146
|
-
if (mode === "streaming") {
|
|
147
|
-
startStreaming();
|
|
148
|
-
}
|
|
149
203
|
if (streamController === void 0) {
|
|
150
204
|
bufferedMessages.push(message);
|
|
151
205
|
} else {
|
|
152
206
|
await enqueueMessage(message);
|
|
153
207
|
}
|
|
154
208
|
});
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
209
|
+
const handleIndividualRequest = async (request, markReady) => {
|
|
210
|
+
let response;
|
|
211
|
+
try {
|
|
212
|
+
request = this.mapSubrequest(request, interceptorOptions);
|
|
213
|
+
const result = await interceptorOptions.next({ ...interceptorOptions, request });
|
|
214
|
+
response = result.matched ? result.response : { status: 404, headers: {}, body: "No procedure matched" };
|
|
215
|
+
} catch (err) {
|
|
216
|
+
response = internalError(err);
|
|
159
217
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
scheduleKeepAlive();
|
|
164
|
-
},
|
|
165
|
-
async cancel(reason) {
|
|
166
|
-
clearKeepAlive();
|
|
167
|
-
await peer.close(reason);
|
|
168
|
-
}
|
|
218
|
+
markReady({
|
|
219
|
+
headers: response.headers,
|
|
220
|
+
stream: response.body instanceof ReadableStream || isAsyncIteratorObject(response.body)
|
|
169
221
|
});
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
const handleIndividualRequest = async (request) => {
|
|
222
|
+
const { batchHeaders: batchHeaders2 } = await lifting;
|
|
173
223
|
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;
|
|
224
|
+
return this.mapSubresponse(response, { status, headers: batchHeaders2 }, interceptorOptions);
|
|
183
225
|
} catch (err) {
|
|
184
|
-
|
|
185
|
-
return { status: 500, headers: {}, body: "Internal server error" };
|
|
226
|
+
return internalError(err);
|
|
186
227
|
}
|
|
187
228
|
};
|
|
188
229
|
const runSubrequests = async () => {
|
|
189
|
-
const promise = Promise.all(messages.map((msg) =>
|
|
230
|
+
const promise = Promise.all(messages.map((msg, i) => {
|
|
231
|
+
const { resolve } = ready[i];
|
|
232
|
+
return peer.message(msg, (request) => handleIndividualRequest(request, resolve)).finally(() => resolve(void 0));
|
|
233
|
+
}));
|
|
190
234
|
const signal = interceptorOptions.request.signal;
|
|
191
235
|
const closePeer = () => peer.close(signal?.reason);
|
|
192
236
|
if (signal?.aborted) {
|
|
@@ -200,8 +244,9 @@ class BatchHandlerPlugin {
|
|
|
200
244
|
}
|
|
201
245
|
};
|
|
202
246
|
const subrequests = runSubrequests();
|
|
203
|
-
const
|
|
204
|
-
if (
|
|
247
|
+
const { batchHeaders, streams } = await lifting;
|
|
248
|
+
if (!streams) {
|
|
249
|
+
await subrequests;
|
|
205
250
|
await peer.close();
|
|
206
251
|
if (bufferedMessages.some((msg) => msg.binary !== void 0)) {
|
|
207
252
|
const chunks = (await Promise.all(bufferedMessages.map(encodeFrame))).flat();
|
|
@@ -209,17 +254,28 @@ class BatchHandlerPlugin {
|
|
|
209
254
|
matched: true,
|
|
210
255
|
response: {
|
|
211
256
|
status,
|
|
212
|
-
headers,
|
|
257
|
+
headers: batchHeaders,
|
|
213
258
|
body: new Blob(chunks, { type: BATCH_CONTENT_TYPE })
|
|
214
259
|
}
|
|
215
260
|
};
|
|
216
261
|
}
|
|
217
262
|
return {
|
|
218
263
|
matched: true,
|
|
219
|
-
response: { status, headers, body: bufferedMessages }
|
|
264
|
+
response: { status, headers: batchHeaders, body: bufferedMessages }
|
|
220
265
|
};
|
|
221
266
|
}
|
|
222
|
-
|
|
267
|
+
const body = new ReadableStream({
|
|
268
|
+
start(controller) {
|
|
269
|
+
streamController = controller;
|
|
270
|
+
scheduleKeepAlive();
|
|
271
|
+
},
|
|
272
|
+
async cancel(reason) {
|
|
273
|
+
clearKeepAlive();
|
|
274
|
+
await peer.close(reason);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
const flushed = Promise.all(bufferedMessages.splice(0).map(enqueueMessage));
|
|
278
|
+
Promise.all([flushed, subrequests]).then(async () => {
|
|
223
279
|
clearKeepAlive();
|
|
224
280
|
streamController.close();
|
|
225
281
|
await peer.close();
|
|
@@ -232,8 +288,8 @@ class BatchHandlerPlugin {
|
|
|
232
288
|
matched: true,
|
|
233
289
|
response: {
|
|
234
290
|
status,
|
|
235
|
-
headers: { ...
|
|
236
|
-
body
|
|
291
|
+
headers: { ...batchHeaders, "content-type": BATCH_CONTENT_TYPE },
|
|
292
|
+
body
|
|
237
293
|
}
|
|
238
294
|
};
|
|
239
295
|
};
|
|
@@ -774,6 +830,88 @@ class RethrowHandlerPlugin {
|
|
|
774
830
|
}
|
|
775
831
|
}
|
|
776
832
|
|
|
833
|
+
class SignalSyncHandlerPlugin {
|
|
834
|
+
name = "~signal-sync";
|
|
835
|
+
init(options) {
|
|
836
|
+
const clientInterceptor = async (interceptorOptions) => {
|
|
837
|
+
const controller = new AbortController();
|
|
838
|
+
const signal = anyAbortSignal([interceptorOptions.signal, controller.signal]);
|
|
839
|
+
const cancel = () => controller.abort(new AbortError("The response body was cancelled"));
|
|
840
|
+
const output = await interceptorOptions.next({ ...interceptorOptions, signal });
|
|
841
|
+
if (isAsyncIteratorObject(output)) {
|
|
842
|
+
return override(output, syncAsyncIterator(output, signal, cancel));
|
|
843
|
+
}
|
|
844
|
+
if (output instanceof ReadableStream) {
|
|
845
|
+
return override(output, syncReadableStream(output, signal, cancel));
|
|
846
|
+
}
|
|
847
|
+
return output;
|
|
848
|
+
};
|
|
849
|
+
return { ...options, clientInterceptors: [clientInterceptor, ...toArray(options.clientInterceptors)] };
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
function listenAbort(signal, onAbort) {
|
|
853
|
+
if (signal.aborted) {
|
|
854
|
+
onAbort();
|
|
855
|
+
} else {
|
|
856
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
857
|
+
}
|
|
858
|
+
return () => signal.removeEventListener("abort", onAbort);
|
|
859
|
+
}
|
|
860
|
+
function syncAsyncIterator(iterator, signal, cancel) {
|
|
861
|
+
let cancelling;
|
|
862
|
+
const unlisten = listenAbort(signal, () => {
|
|
863
|
+
cancelling = (async () => iterator.return?.())();
|
|
864
|
+
cancelling.catch(() => {
|
|
865
|
+
});
|
|
866
|
+
});
|
|
867
|
+
return new AsyncIteratorClass(
|
|
868
|
+
() => runWithSignal(signal, () => iterator.next()),
|
|
869
|
+
async ({ kind }) => {
|
|
870
|
+
if (kind === "cancelled") {
|
|
871
|
+
cancel();
|
|
872
|
+
await cancelling;
|
|
873
|
+
}
|
|
874
|
+
unlisten();
|
|
875
|
+
}
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
function syncReadableStream(stream, signal, cancel) {
|
|
879
|
+
const reader = stream.getReader();
|
|
880
|
+
let cancelling;
|
|
881
|
+
let unlisten;
|
|
882
|
+
return new ReadableStream({
|
|
883
|
+
start(controller) {
|
|
884
|
+
unlisten = listenAbort(signal, () => {
|
|
885
|
+
controller.error(signal.reason);
|
|
886
|
+
cancelling = reader.cancel(signal.reason);
|
|
887
|
+
cancelling.catch(() => {
|
|
888
|
+
});
|
|
889
|
+
});
|
|
890
|
+
},
|
|
891
|
+
async pull(controller) {
|
|
892
|
+
try {
|
|
893
|
+
const { done, value } = await reader.read();
|
|
894
|
+
if (signal.aborted) {
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
if (done) {
|
|
898
|
+
unlisten();
|
|
899
|
+
controller.close();
|
|
900
|
+
} else {
|
|
901
|
+
controller.enqueue(value);
|
|
902
|
+
}
|
|
903
|
+
} catch (error) {
|
|
904
|
+
unlisten();
|
|
905
|
+
throw error;
|
|
906
|
+
}
|
|
907
|
+
},
|
|
908
|
+
async cancel() {
|
|
909
|
+
cancel();
|
|
910
|
+
await cancelling;
|
|
911
|
+
}
|
|
912
|
+
}, { highWaterMark: 0 });
|
|
913
|
+
}
|
|
914
|
+
|
|
777
915
|
class TimeoutHandlerPlugin {
|
|
778
916
|
timeout;
|
|
779
917
|
streamingTimeout;
|
|
@@ -823,4 +961,4 @@ class TimeoutHandlerPlugin {
|
|
|
823
961
|
}
|
|
824
962
|
}
|
|
825
963
|
|
|
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 };
|
|
964
|
+
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,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.BWhT-63L.mjs';
|
|
2
|
+
import { b as StandardHandlerPlugin, c as StandardHandlerOptions } from './server.TVSii8T9.mjs';
|
|
3
3
|
|
|
4
4
|
interface RequestLimitHandlerPluginOptions {
|
|
5
5
|
/**
|
|
@@ -13,7 +13,7 @@ type MiddlewareResult<TOutContext extends Context, TOutput> = Promisable<{
|
|
|
13
13
|
context: TOutContext;
|
|
14
14
|
}>;
|
|
15
15
|
type MiddlewareNextOptions<TOutContext extends Context> = object extends TOutContext ? {
|
|
16
|
-
context?: TOutContext;
|
|
16
|
+
context?: TOutContext | undefined;
|
|
17
17
|
} : {
|
|
18
18
|
context: TOutContext;
|
|
19
19
|
};
|
|
@@ -21,7 +21,7 @@ interface MiddlewareNext<TOutput> {
|
|
|
21
21
|
<T extends Context = object>(...rest: MaybeOptionalOptions<MiddlewareNextOptions<T>>): MiddlewareResult<T, TOutput>;
|
|
22
22
|
}
|
|
23
23
|
type MiddlewareDoneOptions<TOutContext, TOutput> = (object extends TOutContext ? {
|
|
24
|
-
context?: TOutContext;
|
|
24
|
+
context?: TOutContext | undefined;
|
|
25
25
|
} : {
|
|
26
26
|
context: TOutContext;
|
|
27
27
|
}) & {
|
|
@@ -150,10 +150,10 @@ interface ProcedureClientInterceptorOptions<TInitialContext extends Context, TEr
|
|
|
150
150
|
}
|
|
151
151
|
type ProcedureClientInterceptor<TInitialContext extends Context, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap> = Interceptor<ProcedureClientInterceptorOptions<TInitialContext, TErrorMap>, PromiseWithError<InferSchemaOutput<TOutputSchema>, ORPCErrorFromErrorMap<TErrorMap> | ThrowableError>>;
|
|
152
152
|
type ProcedureClientOptions<TInitialContext extends Context, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TClientContext extends ClientContext> = {
|
|
153
|
-
path?: string[];
|
|
154
|
-
interceptors?: ProcedureClientInterceptor<TInitialContext, TOutputSchema, TErrorMap>[];
|
|
153
|
+
path?: string[] | undefined;
|
|
154
|
+
interceptors?: ProcedureClientInterceptor<TInitialContext, TOutputSchema, TErrorMap>[] | undefined;
|
|
155
155
|
} & (object extends TInitialContext ? {
|
|
156
|
-
context?: Value<Promisable<TInitialContext>, [clientContext: TClientContext]
|
|
156
|
+
context?: Value<Promisable<TInitialContext>, [clientContext: TClientContext]> | undefined;
|
|
157
157
|
} : {
|
|
158
158
|
context: Value<Promisable<TInitialContext>, [clientContext: TClientContext]>;
|
|
159
159
|
});
|
|
@@ -13,7 +13,7 @@ type MiddlewareResult<TOutContext extends Context, TOutput> = Promisable<{
|
|
|
13
13
|
context: TOutContext;
|
|
14
14
|
}>;
|
|
15
15
|
type MiddlewareNextOptions<TOutContext extends Context> = object extends TOutContext ? {
|
|
16
|
-
context?: TOutContext;
|
|
16
|
+
context?: TOutContext | undefined;
|
|
17
17
|
} : {
|
|
18
18
|
context: TOutContext;
|
|
19
19
|
};
|
|
@@ -21,7 +21,7 @@ interface MiddlewareNext<TOutput> {
|
|
|
21
21
|
<T extends Context = object>(...rest: MaybeOptionalOptions<MiddlewareNextOptions<T>>): MiddlewareResult<T, TOutput>;
|
|
22
22
|
}
|
|
23
23
|
type MiddlewareDoneOptions<TOutContext, TOutput> = (object extends TOutContext ? {
|
|
24
|
-
context?: TOutContext;
|
|
24
|
+
context?: TOutContext | undefined;
|
|
25
25
|
} : {
|
|
26
26
|
context: TOutContext;
|
|
27
27
|
}) & {
|
|
@@ -150,10 +150,10 @@ interface ProcedureClientInterceptorOptions<TInitialContext extends Context, TEr
|
|
|
150
150
|
}
|
|
151
151
|
type ProcedureClientInterceptor<TInitialContext extends Context, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap> = Interceptor<ProcedureClientInterceptorOptions<TInitialContext, TErrorMap>, PromiseWithError<InferSchemaOutput<TOutputSchema>, ORPCErrorFromErrorMap<TErrorMap> | ThrowableError>>;
|
|
152
152
|
type ProcedureClientOptions<TInitialContext extends Context, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TClientContext extends ClientContext> = {
|
|
153
|
-
path?: string[];
|
|
154
|
-
interceptors?: ProcedureClientInterceptor<TInitialContext, TOutputSchema, TErrorMap>[];
|
|
153
|
+
path?: string[] | undefined;
|
|
154
|
+
interceptors?: ProcedureClientInterceptor<TInitialContext, TOutputSchema, TErrorMap>[] | undefined;
|
|
155
155
|
} & (object extends TInitialContext ? {
|
|
156
|
-
context?: Value<Promisable<TInitialContext>, [clientContext: TClientContext]
|
|
156
|
+
context?: Value<Promisable<TInitialContext>, [clientContext: TClientContext]> | undefined;
|
|
157
157
|
} : {
|
|
158
158
|
context: Value<Promisable<TInitialContext>, [clientContext: TClientContext]>;
|
|
159
159
|
});
|
|
@@ -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.BWhT-63L.js';
|
|
5
5
|
import { Schema, ErrorMap } from '@orpc/contract';
|
|
6
6
|
|
|
7
7
|
interface StandardHandlerPlugin<T extends Context> extends OrderablePlugin {
|
|
@@ -73,19 +73,19 @@ interface StandardHandlerOptions<TContext extends Context> {
|
|
|
73
73
|
* - batch plugins - separate one request into multiple and call multiple next
|
|
74
74
|
* - openapi spec plugin - to intercept a request and early response
|
|
75
75
|
*/
|
|
76
|
-
routingInterceptors?: StandardHandlerRoutingInterceptor<TContext>[];
|
|
76
|
+
routingInterceptors?: StandardHandlerRoutingInterceptor<TContext>[] | undefined;
|
|
77
77
|
/**
|
|
78
78
|
* interceptor run after routing and before error handler,
|
|
79
79
|
* useful for error handling, logging, metrics, etc.
|
|
80
80
|
*/
|
|
81
|
-
interceptors?: StandardHandlerInterceptor<TContext>[];
|
|
81
|
+
interceptors?: StandardHandlerInterceptor<TContext>[] | undefined;
|
|
82
82
|
/**
|
|
83
83
|
*
|
|
84
84
|
* ClientInterceptor equivalent with createRouterClient.interceptors / createProcedure.interceptors
|
|
85
85
|
* useful for error handling, logging, metrics, etc. (not counting encoding/decoding)
|
|
86
86
|
*/
|
|
87
|
-
clientInterceptors?: ProcedureClientInterceptor<TContext, Schema<unknown>, ErrorMap>[];
|
|
88
|
-
plugins?: StandardHandlerPlugin<TContext>[];
|
|
87
|
+
clientInterceptors?: ProcedureClientInterceptor<TContext, Schema<unknown>, ErrorMap>[] | undefined;
|
|
88
|
+
plugins?: StandardHandlerPlugin<TContext>[] | undefined;
|
|
89
89
|
}
|
|
90
90
|
declare class StandardHandler<T extends Context> {
|
|
91
91
|
private readonly codec;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { c as createProcedureClient, P as Procedure, L as Lazy, u as unlazy } from './server.FEqy7Hrj.mjs';
|
|
2
1
|
import { resolveMetaPlugins, mergeErrorMap, ProcedureContract } from '@orpc/contract';
|
|
3
2
|
import { omit, isTypescriptObject, getOwn } from '@orpc/shared';
|
|
3
|
+
import { c as createProcedureClient, P as Procedure, L as Lazy, u as unlazy } from './server.FEqy7Hrj.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, createContractProcedure as h, getHiddenRouterContract as i, walkProcedureContractsAsync as j, 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.BWhT-63L.js';
|
|
2
|
+
import { b as StandardHandlerPlugin, c as StandardHandlerOptions } from './server.BYNQ06wN.js';
|
|
3
3
|
|
|
4
4
|
interface RequestLimitHandlerPluginOptions {
|
|
5
5
|
/**
|
|
@@ -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.BWhT-63L.js';
|
|
4
|
+
import { a as StandardHandlerHandleOptions } from './server.BYNQ06wN.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,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.BWhT-63L.js';
|
|
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.BWhT-63L.mjs';
|
|
4
|
+
import { a as StandardHandlerHandleOptions } from './server.TVSii8T9.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
|
});
|
|
@@ -2,7 +2,7 @@ import { ORPCError, toORPCError, RPCSerializer, COMMON_ERROR_STATUS_MAP } from '
|
|
|
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
4
|
import { c as createProcedureClient, u as unlazy, P as Procedure } from './server.FEqy7Hrj.mjs';
|
|
5
|
-
import { w as walkProcedureContractsSync,
|
|
5
|
+
import { w as walkProcedureContractsSync, r as resolveContractProcedure, D as DEFAULT_SUCCESS_STATUS, a as DEFAULT_ERROR_STATUS } from './server.BcxD3fmU.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
|
}
|
|
@@ -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.BWhT-63L.mjs';
|
|
5
5
|
import { Schema, ErrorMap } from '@orpc/contract';
|
|
6
6
|
|
|
7
7
|
interface StandardHandlerPlugin<T extends Context> extends OrderablePlugin {
|
|
@@ -73,19 +73,19 @@ interface StandardHandlerOptions<TContext extends Context> {
|
|
|
73
73
|
* - batch plugins - separate one request into multiple and call multiple next
|
|
74
74
|
* - openapi spec plugin - to intercept a request and early response
|
|
75
75
|
*/
|
|
76
|
-
routingInterceptors?: StandardHandlerRoutingInterceptor<TContext>[];
|
|
76
|
+
routingInterceptors?: StandardHandlerRoutingInterceptor<TContext>[] | undefined;
|
|
77
77
|
/**
|
|
78
78
|
* interceptor run after routing and before error handler,
|
|
79
79
|
* useful for error handling, logging, metrics, etc.
|
|
80
80
|
*/
|
|
81
|
-
interceptors?: StandardHandlerInterceptor<TContext>[];
|
|
81
|
+
interceptors?: StandardHandlerInterceptor<TContext>[] | undefined;
|
|
82
82
|
/**
|
|
83
83
|
*
|
|
84
84
|
* ClientInterceptor equivalent with createRouterClient.interceptors / createProcedure.interceptors
|
|
85
85
|
* useful for error handling, logging, metrics, etc. (not counting encoding/decoding)
|
|
86
86
|
*/
|
|
87
|
-
clientInterceptors?: ProcedureClientInterceptor<TContext, Schema<unknown>, ErrorMap>[];
|
|
88
|
-
plugins?: StandardHandlerPlugin<TContext>[];
|
|
87
|
+
clientInterceptors?: ProcedureClientInterceptor<TContext, Schema<unknown>, ErrorMap>[] | undefined;
|
|
88
|
+
plugins?: StandardHandlerPlugin<TContext>[] | undefined;
|
|
89
89
|
}
|
|
90
90
|
declare class StandardHandler<T extends Context> {
|
|
91
91
|
private readonly codec;
|
|
@@ -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.BWhT-63L.mjs';
|
|
3
3
|
|
|
4
4
|
type Router<TInitialContext extends Context> = Procedure<TInitialContext, any, any, any, any> | {
|
|
5
5
|
[k: string]: Lazyable<Router<TInitialContext>>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orpc/server",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.45",
|
|
5
5
|
"description": "Build typesafe APIs with oRPC: RPC and OpenAPI support, middleware, and adapters for Node.js, Bun, Deno, Fetch, Fastify, WebSocket, AWS Lambda, and more",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": [
|
|
@@ -117,23 +117,23 @@
|
|
|
117
117
|
}
|
|
118
118
|
},
|
|
119
119
|
"dependencies": {
|
|
120
|
-
"@orpc/client": "2.0.0-beta.
|
|
121
|
-
"@orpc/contract": "2.0.0-beta.
|
|
122
|
-
"@orpc/shared": "2.0.0-beta.
|
|
123
|
-
"@standard-server/aws-lambda": "~0.
|
|
124
|
-
"@standard-server/core": "~0.
|
|
125
|
-
"@standard-server/fastify": "~0.
|
|
126
|
-
"@standard-server/fetch": "~0.
|
|
127
|
-
"@standard-server/node": "~0.
|
|
128
|
-
"@standard-server/peer": "~0.
|
|
120
|
+
"@orpc/client": "2.0.0-beta.45",
|
|
121
|
+
"@orpc/contract": "2.0.0-beta.45",
|
|
122
|
+
"@orpc/shared": "2.0.0-beta.45",
|
|
123
|
+
"@standard-server/aws-lambda": "~0.11.0",
|
|
124
|
+
"@standard-server/core": "~0.11.0",
|
|
125
|
+
"@standard-server/fastify": "~0.11.0",
|
|
126
|
+
"@standard-server/fetch": "~0.11.0",
|
|
127
|
+
"@standard-server/node": "~0.11.0",
|
|
128
|
+
"@standard-server/peer": "~0.11.0",
|
|
129
129
|
"cookie": "^2.0.1"
|
|
130
130
|
},
|
|
131
131
|
"devDependencies": {
|
|
132
132
|
"crossws": "^0.4.15",
|
|
133
|
-
"fastify": "^5.12.
|
|
133
|
+
"fastify": "^5.12.7",
|
|
134
134
|
"supertest": "^7.3.1",
|
|
135
135
|
"ws": "^8.22.0",
|
|
136
|
-
"zod": "^4.6.
|
|
136
|
+
"zod": "^4.6.7"
|
|
137
137
|
},
|
|
138
138
|
"scripts": {
|
|
139
139
|
"type:check": "tsc -b"
|