@orpc/server 2.0.0-beta.5 → 2.0.0-beta.50
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 +137 -102
- package/dist/adapters/aws-lambda/handler.d.ts +27 -0
- package/dist/adapters/aws-lambda/handler.js +24 -0
- package/dist/adapters/aws-lambda/index.d.ts +4 -0
- package/dist/adapters/aws-lambda/index.js +2 -0
- package/dist/adapters/aws-lambda/rpc-handler.d.ts +19 -0
- package/dist/adapters/aws-lambda/rpc-handler.js +21 -0
- package/dist/adapters/crossws/handler.d.ts +47 -0
- package/dist/adapters/crossws/handler.js +53 -0
- package/dist/adapters/crossws/index.d.ts +3 -54
- package/dist/adapters/crossws/index.js +2 -0
- package/dist/adapters/crossws/rpc-handler.d.ts +16 -0
- package/dist/adapters/crossws/rpc-handler.js +18 -0
- package/dist/adapters/fastify/handler.d.ts +23 -0
- package/dist/adapters/fastify/handler.js +20 -0
- package/dist/adapters/fastify/index.d.ts +3 -0
- package/dist/adapters/fastify/index.js +2 -0
- package/dist/adapters/fastify/rpc-handler.d.ts +15 -0
- package/dist/adapters/fastify/rpc-handler.js +17 -0
- package/dist/adapters/fetch/handler.d.ts +25 -0
- package/dist/adapters/fetch/handler.js +22 -0
- package/dist/adapters/fetch/index.d.ts +4 -140
- package/dist/adapters/fetch/index.js +3 -0
- package/dist/adapters/fetch/rpc-handler.d.ts +17 -0
- package/dist/adapters/fetch/rpc-handler.js +19 -0
- package/dist/adapters/message-port/handler.d.ts +62 -0
- package/dist/adapters/message-port/handler.js +72 -0
- package/dist/adapters/message-port/index.d.ts +3 -74
- package/dist/adapters/message-port/index.js +2 -0
- package/dist/adapters/message-port/rpc-handler.d.ts +16 -0
- package/dist/adapters/message-port/rpc-handler.js +18 -0
- package/dist/adapters/node/handler.d.ts +23 -0
- package/dist/adapters/node/handler.js +20 -0
- package/dist/adapters/node/index.d.ts +4 -121
- package/dist/adapters/node/index.js +3 -0
- package/dist/adapters/node/rpc-handler.d.ts +16 -0
- package/dist/adapters/node/rpc-handler.js +18 -0
- package/dist/adapters/standard/codec.d.ts +16 -0
- package/dist/adapters/standard/handler.d.ts +68 -0
- package/dist/adapters/standard/handler.js +205 -0
- package/dist/adapters/standard/index.d.ts +7 -19
- package/dist/adapters/standard/index.js +4 -0
- package/dist/adapters/standard/plugin.d.ts +26 -0
- package/dist/adapters/standard/plugin.js +14 -0
- package/dist/adapters/standard/rpc-handler-codec.d.ts +42 -0
- package/dist/adapters/standard/rpc-handler-codec.js +50 -0
- package/dist/adapters/standard/rpc-matcher.d.ts +53 -0
- package/dist/adapters/standard/rpc-matcher.js +106 -0
- package/dist/adapters/standard/utils.d.ts +10 -0
- package/dist/adapters/standard/utils.js +8 -0
- package/dist/adapters/standard-peer/index.d.ts +2 -16
- package/dist/adapters/standard-peer/index.js +1 -0
- package/dist/adapters/standard-peer/utils.d.ts +6 -0
- package/dist/adapters/standard-peer/utils.js +13 -0
- package/dist/adapters/websocket/handler.d.ts +61 -0
- package/dist/adapters/websocket/handler.js +75 -0
- package/dist/adapters/websocket/index.d.ts +3 -61
- package/dist/adapters/websocket/index.js +2 -0
- package/dist/adapters/websocket/rpc-handler.d.ts +16 -0
- package/dist/adapters/websocket/rpc-handler.js +18 -0
- package/dist/builder-variants.d.ts +226 -0
- package/dist/builder.d.ts +126 -0
- package/dist/builder.js +200 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +4 -0
- package/dist/context.d.ts +6 -0
- package/dist/extensions/callable.d.ts +11 -10
- package/dist/extensions/callable.js +8 -0
- package/dist/helpers/base64url.d.ts +31 -0
- package/dist/helpers/base64url.js +48 -0
- package/dist/helpers/cookie.d.ts +50 -0
- package/dist/helpers/cookie.js +62 -0
- package/dist/helpers/encryption.d.ts +28 -0
- package/dist/helpers/encryption.js +90 -0
- package/dist/helpers/index.d.ts +5 -149
- package/dist/helpers/index.js +4 -0
- package/dist/helpers/signing.d.ts +50 -0
- package/dist/helpers/signing.js +78 -0
- package/dist/implementer-procedure.d.ts +15 -0
- package/dist/implementer-procedure.js +37 -0
- package/dist/implementer-router.d.ts +34 -0
- package/dist/implementer-router.js +98 -0
- package/dist/implementer.d.ts +16 -0
- package/dist/implementer.js +30 -0
- package/dist/index.d.ts +22 -196
- package/dist/index.js +16 -0
- package/dist/lazy.d.ts +20 -0
- package/dist/lazy.js +20 -0
- package/dist/middleware-decorated.d.ts +9 -0
- package/dist/middleware-decorated.js +67 -0
- package/dist/middleware.d.ts +54 -0
- package/dist/plugins/batch.d.ts +102 -0
- package/dist/plugins/batch.js +371 -0
- package/dist/plugins/cors.d.ts +69 -0
- package/dist/plugins/cors.js +119 -0
- package/dist/plugins/get-method-csrf-protection.d.ts +25 -0
- package/dist/plugins/get-method-csrf-protection.js +48 -0
- package/dist/plugins/head-method.d.ts +25 -0
- package/dist/plugins/head-method.js +107 -0
- package/dist/plugins/index.d.ts +15 -197
- package/dist/plugins/index.js +14 -0
- package/dist/plugins/method-override.d.ts +40 -0
- package/dist/plugins/method-override.js +54 -0
- package/dist/plugins/request-compression.d.ts +18 -0
- package/dist/plugins/request-compression.js +55 -0
- package/dist/plugins/request-headers.d.ts +24 -0
- package/dist/plugins/request-headers.js +28 -0
- package/dist/plugins/request-limit.d.ts +32 -0
- package/dist/plugins/request-limit.js +61 -0
- package/dist/plugins/response-compression.d.ts +62 -0
- package/dist/plugins/response-compression.js +157 -0
- package/dist/plugins/response-headers.d.ts +32 -0
- package/dist/plugins/response-headers.js +44 -0
- package/dist/plugins/rethrow.d.ts +35 -0
- package/dist/plugins/rethrow.js +47 -0
- package/dist/plugins/signal-sync.d.ts +15 -0
- package/dist/plugins/signal-sync.js +76 -0
- package/dist/plugins/timeout.d.ts +39 -0
- package/dist/plugins/timeout.js +62 -0
- package/dist/procedure-client.d.ts +18 -0
- package/dist/procedure-client.js +158 -0
- package/dist/procedure-decorated.d.ts +10 -0
- package/dist/procedure-decorated.js +36 -0
- package/dist/procedure-utils.d.ts +21 -0
- package/dist/procedure-utils.js +48 -0
- package/dist/procedure.d.ts +72 -0
- package/dist/procedure.js +18 -0
- package/dist/router-client.d.ts +21 -0
- package/dist/router-client.js +35 -0
- package/dist/router-hidden.js +12 -0
- package/dist/router-utils.d.ts +31 -0
- package/dist/router-utils.js +157 -0
- package/dist/router.d.ts +58 -0
- package/package.json +95 -63
- package/dist/adapters/crossws/index.d.mts +0 -54
- package/dist/adapters/crossws/index.mjs +0 -64
- package/dist/adapters/fetch/index.d.mts +0 -140
- package/dist/adapters/fetch/index.mjs +0 -204
- package/dist/adapters/message-port/index.d.mts +0 -74
- package/dist/adapters/message-port/index.mjs +0 -90
- package/dist/adapters/node/index.d.mts +0 -121
- package/dist/adapters/node/index.mjs +0 -179
- package/dist/adapters/standard/index.d.mts +0 -19
- package/dist/adapters/standard/index.mjs +0 -8
- package/dist/adapters/standard-peer/index.d.mts +0 -16
- package/dist/adapters/standard-peer/index.mjs +0 -2
- package/dist/adapters/websocket/index.d.mts +0 -61
- package/dist/adapters/websocket/index.mjs +0 -76
- package/dist/extensions/callable.d.mts +0 -10
- package/dist/extensions/callable.mjs +0 -11
- package/dist/helpers/index.d.mts +0 -149
- package/dist/helpers/index.mjs +0 -198
- package/dist/index.d.mts +0 -196
- package/dist/index.mjs +0 -385
- package/dist/plugins/index.d.mts +0 -197
- package/dist/plugins/index.mjs +0 -357
- package/dist/shared/server.BL22TloH.d.mts +0 -184
- package/dist/shared/server.BL22TloH.d.ts +0 -184
- package/dist/shared/server.BsNNjG5J.d.mts +0 -61
- package/dist/shared/server.BwHnWUuN.mjs +0 -222
- package/dist/shared/server.CX4vUnDk.mjs +0 -11
- package/dist/shared/server.Cj5lgPuG.d.mts +0 -66
- package/dist/shared/server.CjOb6ItT.mjs +0 -41
- package/dist/shared/server.CrlKQucM.mjs +0 -233
- package/dist/shared/server.DBANIheG.d.ts +0 -104
- package/dist/shared/server.DJIkub_t.d.mts +0 -104
- package/dist/shared/server.D_QauotT.mjs +0 -30
- package/dist/shared/server.GDpX6Df8.mjs +0 -271
- package/dist/shared/server.Pa0F03f_.d.ts +0 -61
- package/dist/shared/server.W91HSRkE.mjs +0 -9
- package/dist/shared/server.d_2NS3g5.d.ts +0 -66
package/dist/plugins/index.d.mts
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { Value, Promisable, ThrowableError } from '@orpc/shared';
|
|
2
|
-
import { StandardLazyRequest, StandardHeaders } from '@standardserver/core';
|
|
3
|
-
import { C as Context } from '../shared/server.BL22TloH.mjs';
|
|
4
|
-
import { e as StandardHandlerPlugin, f as StandardHandlerRoutingInterceptorOptions, a as StandardHandlerOptions, g as StandardHandlerInterceptorOptions } from '../shared/server.DJIkub_t.mjs';
|
|
5
|
-
import '@orpc/client';
|
|
6
|
-
import '@orpc/contract';
|
|
7
|
-
|
|
8
|
-
interface BatchHandlerPluginOptions<T extends Context> {
|
|
9
|
-
/**
|
|
10
|
-
* The max size of the batch allowed.
|
|
11
|
-
*
|
|
12
|
-
* @default 10
|
|
13
|
-
*/
|
|
14
|
-
maxSize?: Value<Promisable<number>, [options: StandardHandlerRoutingInterceptorOptions<T>]>;
|
|
15
|
-
/**
|
|
16
|
-
* Map each subrequest in the batch before it is processed.
|
|
17
|
-
*
|
|
18
|
-
* @default merges the batch request headers into the subrequest and remove `orpc-batch` header to prevent nested batching
|
|
19
|
-
*/
|
|
20
|
-
mapSubrequest?: (subrequest: StandardLazyRequest, batchOptions: StandardHandlerRoutingInterceptorOptions<T>) => StandardLazyRequest;
|
|
21
|
-
/**
|
|
22
|
-
* Success batch response status code.
|
|
23
|
-
*
|
|
24
|
-
* @default 207
|
|
25
|
-
*/
|
|
26
|
-
successStatus?: Value<Promisable<number>, [batchOptions: StandardHandlerRoutingInterceptorOptions<T>]>;
|
|
27
|
-
/**
|
|
28
|
-
* Success batch response headers.
|
|
29
|
-
*
|
|
30
|
-
* @default {}
|
|
31
|
-
*/
|
|
32
|
-
headers?: Value<Promisable<StandardHeaders>, [batchOptions: StandardHandlerRoutingInterceptorOptions<T>]>;
|
|
33
|
-
}
|
|
34
|
-
declare class BatchHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
35
|
-
name: string;
|
|
36
|
-
/**
|
|
37
|
-
* Run batch interceptors before OpenTelemetry interceptors
|
|
38
|
-
* so each subrequest gets its own span instead of sharing one batch-level span.
|
|
39
|
-
*/
|
|
40
|
-
after: string[];
|
|
41
|
-
private readonly maxSize;
|
|
42
|
-
private readonly mapSubrequest;
|
|
43
|
-
private readonly successStatus;
|
|
44
|
-
private readonly headers;
|
|
45
|
-
constructor(options?: BatchHandlerPluginOptions<T>);
|
|
46
|
-
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
interface CORSHandlerPluginOptions<T extends Context> {
|
|
50
|
-
/**
|
|
51
|
-
* Configures the `Access-Control-Allow-Origin` header.
|
|
52
|
-
* Can be a string, an array of allowed origins, or a function that returns the allowed origin(s).
|
|
53
|
-
*
|
|
54
|
-
* @default (origin) => origin
|
|
55
|
-
*/
|
|
56
|
-
origin?: Value<Promisable<string | readonly string[] | null | undefined>, [origin: string, options: StandardHandlerRoutingInterceptorOptions<T>]>;
|
|
57
|
-
/**
|
|
58
|
-
* Configures the `Timing-Allow-Origin` header.
|
|
59
|
-
* Can be a string, an array of allowed origins, or a function that returns the allowed origin(s).
|
|
60
|
-
*
|
|
61
|
-
* @default undefined
|
|
62
|
-
*/
|
|
63
|
-
timingOrigin?: Value<Promisable<string | readonly string[] | null | undefined>, [origin: string, options: StandardHandlerRoutingInterceptorOptions<T>]>;
|
|
64
|
-
/**
|
|
65
|
-
* Configures the `Access-Control-Allow-Methods` header for preflight requests.
|
|
66
|
-
*
|
|
67
|
-
* @default ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']
|
|
68
|
-
*/
|
|
69
|
-
allowMethods?: readonly string[];
|
|
70
|
-
/**
|
|
71
|
-
* Configures the `Access-Control-Allow-Headers` header for preflight requests.
|
|
72
|
-
* Falls back to the request's `Access-Control-Request-Headers` if not set.
|
|
73
|
-
*
|
|
74
|
-
* @default undefined
|
|
75
|
-
*/
|
|
76
|
-
allowHeaders?: readonly string[];
|
|
77
|
-
/**
|
|
78
|
-
* Configures the `Access-Control-Max-Age` header (in seconds) for preflight requests.
|
|
79
|
-
*
|
|
80
|
-
* @default undefined
|
|
81
|
-
*/
|
|
82
|
-
maxAge?: number;
|
|
83
|
-
/**
|
|
84
|
-
* Configures the `Access-Control-Allow-Credentials` header.
|
|
85
|
-
*
|
|
86
|
-
* @default undefined
|
|
87
|
-
*/
|
|
88
|
-
credentials?: boolean;
|
|
89
|
-
/**
|
|
90
|
-
* Configures the `Access-Control-Expose-Headers` header.
|
|
91
|
-
*
|
|
92
|
-
* @default undefined
|
|
93
|
-
*/
|
|
94
|
-
exposeHeaders?: readonly string[];
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* CORSHandlerPlugin is a plugin for oRPC that allows you to configure CORS for your API.
|
|
98
|
-
*
|
|
99
|
-
* @see {@link https://orpc.dev/docs/plugins/cors CORS Plugin Docs}
|
|
100
|
-
*/
|
|
101
|
-
declare class CORSHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
102
|
-
private readonly options;
|
|
103
|
-
name: string;
|
|
104
|
-
/**
|
|
105
|
-
* - Do not create spans for CORS preflight requests.
|
|
106
|
-
* - Run CORS interceptors before batch interceptors so headers are applied to
|
|
107
|
-
* the actual response rather than sub-responses.
|
|
108
|
-
*/
|
|
109
|
-
after: string[];
|
|
110
|
-
constructor(options?: CORSHandlerPluginOptions<T>);
|
|
111
|
-
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Adds basic Cross-Site Request Forgery (CSRF) protection to your oRPC application.
|
|
116
|
-
* When a request includes cookies, it helps ensure the request originates from JavaScript
|
|
117
|
-
* (for example, fetch/XHR) rather than from standard HTML forms or direct browser navigation.
|
|
118
|
-
*
|
|
119
|
-
* @info This plugin is enabled by default for `RPCHandler` over HTTP.
|
|
120
|
-
*/
|
|
121
|
-
declare class CSRFGuardHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
122
|
-
name: string;
|
|
123
|
-
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
interface RequestHeadersHandlerPluginContext {
|
|
127
|
-
/**
|
|
128
|
-
* Request headers as a Headers instance. This is injected by the Request Headers Plugin.
|
|
129
|
-
*/
|
|
130
|
-
reqHeaders?: Headers | undefined;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* The Request Headers Plugin injects a `reqHeaders` instance into the context,
|
|
134
|
-
* allowing access to request headers in oRPC.
|
|
135
|
-
*
|
|
136
|
-
* @see {@link https://orpc.dev/docs/plugins/request-headers Request Headers Plugin Docs}
|
|
137
|
-
*/
|
|
138
|
-
declare class RequestHeadersHandlerPlugin<T extends RequestHeadersHandlerPluginContext> implements StandardHandlerPlugin<T> {
|
|
139
|
-
name: string;
|
|
140
|
-
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
interface ResponseHeadersHandlerPluginContext {
|
|
144
|
-
/**
|
|
145
|
-
* Response headers as a Headers instance. This is injected by the Response Headers Plugin.
|
|
146
|
-
* When set before the response is sent, these headers will be included in the response. If not set, no additional headers will be added.
|
|
147
|
-
*/
|
|
148
|
-
resHeaders?: Headers | undefined;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* The Response Headers Plugin allows you to set response headers in oRPC.
|
|
152
|
-
* It injects a resHeaders instance into the context, enabling you to modify response headers easily.
|
|
153
|
-
*
|
|
154
|
-
* @see {@link https://orpc.dev/docs/plugins/response-headers Response Headers Plugin Docs}
|
|
155
|
-
*/
|
|
156
|
-
declare class ResponseHeadersHandlerPlugin<T extends ResponseHeadersHandlerPluginContext> implements StandardHandlerPlugin<T> {
|
|
157
|
-
name: string;
|
|
158
|
-
/**
|
|
159
|
-
* Interceptors should run after batch interceptors so headers are applied to each sub-response.
|
|
160
|
-
*/
|
|
161
|
-
before: string[];
|
|
162
|
-
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
interface RethrowHandlerPluginOptions<T extends Context> {
|
|
166
|
-
/**
|
|
167
|
-
* Decide which errors should be rethrown.
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```ts
|
|
171
|
-
* const rethrowPlugin = new RethrowHandlerPlugin({
|
|
172
|
-
* filter: (error) => {
|
|
173
|
-
* // Rethrow all non-ORPCError errors
|
|
174
|
-
* return !(error instanceof ORPCError)
|
|
175
|
-
* }
|
|
176
|
-
* })
|
|
177
|
-
* ```
|
|
178
|
-
*/
|
|
179
|
-
filter: (error: ThrowableError, options: StandardHandlerInterceptorOptions<T>) => boolean;
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* The plugin can bypass oRPC's built-in error handling
|
|
183
|
-
* and rethrow matching errors directly to your framework's error handling mechanism
|
|
184
|
-
* (e.g., NestJS exception filters, Express error middleware).
|
|
185
|
-
*
|
|
186
|
-
* @see {@link https://orpc.dev/docs/plugins/rethrow Rethrow Plugin Documentation}
|
|
187
|
-
*/
|
|
188
|
-
declare class RethrowHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
189
|
-
name: string;
|
|
190
|
-
private readonly filter;
|
|
191
|
-
private readonly CONTEXT_SYMBOL;
|
|
192
|
-
constructor(options: RethrowHandlerPluginOptions<T>);
|
|
193
|
-
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export { BatchHandlerPlugin, CORSHandlerPlugin, CSRFGuardHandlerPlugin, RequestHeadersHandlerPlugin, ResponseHeadersHandlerPlugin, RethrowHandlerPlugin };
|
|
197
|
-
export type { BatchHandlerPluginOptions, CORSHandlerPluginOptions, RequestHeadersHandlerPluginContext, ResponseHeadersHandlerPluginContext, RethrowHandlerPluginOptions };
|
package/dist/plugins/index.mjs
DELETED
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
import { toArray, value } from '@orpc/shared';
|
|
2
|
-
import { flattenStandardHeader, parseStandardUrl, mergeStandardHeaders } from '@standardserver/core';
|
|
3
|
-
import { isClientPeerSendMessage, ServerPeer, encodePeerMessage } from '@standardserver/peer';
|
|
4
|
-
export { C as CSRFGuardHandlerPlugin } from '../shared/server.D_QauotT.mjs';
|
|
5
|
-
import { toFetchHeaders, toStandardHeaders } from '@standardserver/fetch';
|
|
6
|
-
import '@orpc/client';
|
|
7
|
-
|
|
8
|
-
class BatchHandlerPlugin {
|
|
9
|
-
name = "~batch";
|
|
10
|
-
/**
|
|
11
|
-
* Run batch interceptors before OpenTelemetry interceptors
|
|
12
|
-
* so each subrequest gets its own span instead of sharing one batch-level span.
|
|
13
|
-
*/
|
|
14
|
-
after = ["~opentelemetry"];
|
|
15
|
-
maxSize;
|
|
16
|
-
mapSubrequest;
|
|
17
|
-
successStatus;
|
|
18
|
-
headers;
|
|
19
|
-
constructor(options = {}) {
|
|
20
|
-
this.maxSize = options.maxSize ?? 10;
|
|
21
|
-
this.mapSubrequest = options.mapSubrequest ?? ((subRequest, { request: batchRequest }) => ({
|
|
22
|
-
...subRequest,
|
|
23
|
-
headers: {
|
|
24
|
-
...batchRequest.headers,
|
|
25
|
-
...subRequest.headers,
|
|
26
|
-
"orpc-batch": void 0
|
|
27
|
-
// useful in case batch plugin is used multiple times
|
|
28
|
-
}
|
|
29
|
-
}));
|
|
30
|
-
this.successStatus = options.successStatus ?? 207;
|
|
31
|
-
this.headers = options.headers ?? {};
|
|
32
|
-
}
|
|
33
|
-
init(options) {
|
|
34
|
-
const routingInterceptor = async (interceptorOptions) => {
|
|
35
|
-
const batchHeader = flattenStandardHeader(interceptorOptions.request.headers["orpc-batch"]);
|
|
36
|
-
if (batchHeader === void 0) {
|
|
37
|
-
return interceptorOptions.next();
|
|
38
|
-
}
|
|
39
|
-
const mode = batchHeader === "buffered" ? "buffered" : "streaming";
|
|
40
|
-
let messages;
|
|
41
|
-
try {
|
|
42
|
-
if (interceptorOptions.request.method === "GET") {
|
|
43
|
-
const [, search] = parseStandardUrl(interceptorOptions.request.url);
|
|
44
|
-
const params = new URLSearchParams(search);
|
|
45
|
-
const data = params.getAll("data").at(-1);
|
|
46
|
-
if (!data) {
|
|
47
|
-
return {
|
|
48
|
-
matched: true,
|
|
49
|
-
response: { status: 400, headers: {}, body: "Missing data parameter for batch request" }
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
const mightBeMessages = JSON.parse(data);
|
|
53
|
-
if (!Array.isArray(mightBeMessages) || mightBeMessages.some((m) => !isClientPeerSendMessage(m))) {
|
|
54
|
-
return {
|
|
55
|
-
matched: true,
|
|
56
|
-
response: { status: 400, headers: {}, body: "Invalid batch request data parameter" }
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
messages = mightBeMessages;
|
|
60
|
-
} else {
|
|
61
|
-
const mightBeMessages = await interceptorOptions.request.resolveBody();
|
|
62
|
-
if (!Array.isArray(mightBeMessages)) {
|
|
63
|
-
return {
|
|
64
|
-
matched: true,
|
|
65
|
-
response: { status: 400, headers: {}, body: "Invalid batch request body" }
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
messages = mightBeMessages;
|
|
69
|
-
}
|
|
70
|
-
} catch {
|
|
71
|
-
return {
|
|
72
|
-
matched: true,
|
|
73
|
-
response: { status: 400, headers: {}, body: "Invalid batch request" }
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
const maxSize = await value(this.maxSize, interceptorOptions);
|
|
77
|
-
if (messages.length > maxSize) {
|
|
78
|
-
return {
|
|
79
|
-
matched: true,
|
|
80
|
-
response: { status: 413, headers: {}, body: "Batch request size exceeds the maximum allowed size" }
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
const handleIndividualRequest = async (request) => {
|
|
84
|
-
try {
|
|
85
|
-
request = this.mapSubrequest(request, interceptorOptions);
|
|
86
|
-
const { matched, response } = await interceptorOptions.next({ ...interceptorOptions, request });
|
|
87
|
-
if (!matched) {
|
|
88
|
-
return { status: 404, headers: {}, body: "No procedure matched" };
|
|
89
|
-
}
|
|
90
|
-
return response;
|
|
91
|
-
} catch (err) {
|
|
92
|
-
Promise.reject(err);
|
|
93
|
-
return { status: 500, headers: {}, body: "Internal server error" };
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
const status = await value(this.successStatus, interceptorOptions);
|
|
97
|
-
const headers = await value(this.headers, interceptorOptions);
|
|
98
|
-
if (mode === "buffered") {
|
|
99
|
-
const responseMessages = [];
|
|
100
|
-
const peer2 = new ServerPeer(async (message) => {
|
|
101
|
-
responseMessages.push(message);
|
|
102
|
-
});
|
|
103
|
-
await Promise.all(messages.map((msg) => peer2.message(msg, handleIndividualRequest)));
|
|
104
|
-
await peer2.close();
|
|
105
|
-
if (responseMessages.some((msg) => msg.binary !== void 0)) {
|
|
106
|
-
const chunks = [];
|
|
107
|
-
for (const message of responseMessages) {
|
|
108
|
-
const encoded = await encodePeerMessage(message);
|
|
109
|
-
const bytes = typeof encoded === "string" ? new TextEncoder().encode(encoded) : encoded;
|
|
110
|
-
const lengthBuffer = new ArrayBuffer(4);
|
|
111
|
-
new DataView(lengthBuffer).setUint32(0, bytes.byteLength, false);
|
|
112
|
-
chunks.push(new Uint8Array(lengthBuffer));
|
|
113
|
-
chunks.push(bytes);
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
matched: true,
|
|
117
|
-
response: {
|
|
118
|
-
status,
|
|
119
|
-
headers,
|
|
120
|
-
body: new Blob(chunks, { type: "application/octet-stream" })
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
return {
|
|
125
|
-
matched: true,
|
|
126
|
-
response: { status, headers, body: responseMessages }
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
let streamController;
|
|
130
|
-
const stream = new ReadableStream({
|
|
131
|
-
start(controller) {
|
|
132
|
-
streamController = controller;
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
const peer = new ServerPeer(async (message) => {
|
|
136
|
-
const encoded = await encodePeerMessage(message);
|
|
137
|
-
const bytes = typeof encoded === "string" ? new TextEncoder().encode(encoded) : encoded;
|
|
138
|
-
const lengthBuffer = new ArrayBuffer(4);
|
|
139
|
-
new DataView(lengthBuffer).setUint32(0, bytes.byteLength, false);
|
|
140
|
-
streamController.enqueue(new Uint8Array(lengthBuffer));
|
|
141
|
-
streamController.enqueue(bytes);
|
|
142
|
-
});
|
|
143
|
-
Promise.all(messages.map((msg) => peer.message(msg, handleIndividualRequest))).then(async () => {
|
|
144
|
-
streamController.close();
|
|
145
|
-
await peer.close();
|
|
146
|
-
}).catch(async (error) => {
|
|
147
|
-
streamController.error(error);
|
|
148
|
-
await peer.close(error);
|
|
149
|
-
});
|
|
150
|
-
return {
|
|
151
|
-
matched: true,
|
|
152
|
-
response: { status, headers, body: stream }
|
|
153
|
-
};
|
|
154
|
-
};
|
|
155
|
-
return {
|
|
156
|
-
...options,
|
|
157
|
-
routingInterceptors: [routingInterceptor, ...toArray(options.routingInterceptors)]
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
class CORSHandlerPlugin {
|
|
163
|
-
options;
|
|
164
|
-
name = "~cors";
|
|
165
|
-
/**
|
|
166
|
-
* - Do not create spans for CORS preflight requests.
|
|
167
|
-
* - Run CORS interceptors before batch interceptors so headers are applied to
|
|
168
|
-
* the actual response rather than sub-responses.
|
|
169
|
-
*/
|
|
170
|
-
after = ["~opentelemetry", "~batch"];
|
|
171
|
-
constructor(options = {}) {
|
|
172
|
-
const defaults = {
|
|
173
|
-
origin: (origin) => origin,
|
|
174
|
-
allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"]
|
|
175
|
-
};
|
|
176
|
-
this.options = {
|
|
177
|
-
...defaults,
|
|
178
|
-
...options
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
init(options) {
|
|
182
|
-
const corsHeadersInterceptor = async (interceptorOptions) => {
|
|
183
|
-
const result = await interceptorOptions.next();
|
|
184
|
-
if (!result.matched) {
|
|
185
|
-
return result;
|
|
186
|
-
}
|
|
187
|
-
const resHeaders = { ...result.response.headers };
|
|
188
|
-
const origin = flattenStandardHeader(interceptorOptions.request.headers.origin) ?? "";
|
|
189
|
-
const allowedOrigins = toArray(await value(this.options.origin, origin, interceptorOptions));
|
|
190
|
-
if (allowedOrigins.includes("*")) {
|
|
191
|
-
resHeaders["access-control-allow-origin"] = "*";
|
|
192
|
-
} else {
|
|
193
|
-
if (allowedOrigins.includes(origin)) {
|
|
194
|
-
resHeaders["access-control-allow-origin"] = origin;
|
|
195
|
-
}
|
|
196
|
-
resHeaders.vary = interceptorOptions.request.headers.vary ?? "origin";
|
|
197
|
-
}
|
|
198
|
-
const allowedTimingOrigins = toArray(await value(this.options.timingOrigin, origin, interceptorOptions));
|
|
199
|
-
if (allowedTimingOrigins.includes("*")) {
|
|
200
|
-
resHeaders["timing-allow-origin"] = "*";
|
|
201
|
-
} else if (allowedTimingOrigins.includes(origin)) {
|
|
202
|
-
resHeaders["timing-allow-origin"] = origin;
|
|
203
|
-
}
|
|
204
|
-
if (this.options.credentials) {
|
|
205
|
-
resHeaders["access-control-allow-credentials"] = "true";
|
|
206
|
-
}
|
|
207
|
-
if (this.options.exposeHeaders?.length) {
|
|
208
|
-
resHeaders["access-control-expose-headers"] = flattenStandardHeader(this.options.exposeHeaders);
|
|
209
|
-
}
|
|
210
|
-
return { ...result, response: { ...result.response, headers: resHeaders } };
|
|
211
|
-
};
|
|
212
|
-
const preflightInterceptor = async (interceptorOptions) => {
|
|
213
|
-
if (interceptorOptions.request.method === "OPTIONS") {
|
|
214
|
-
const resHeaders = {};
|
|
215
|
-
if (this.options.maxAge !== void 0) {
|
|
216
|
-
resHeaders["access-control-max-age"] = this.options.maxAge.toString();
|
|
217
|
-
}
|
|
218
|
-
if (this.options.allowMethods?.length) {
|
|
219
|
-
resHeaders["access-control-allow-methods"] = flattenStandardHeader(this.options.allowMethods);
|
|
220
|
-
}
|
|
221
|
-
const allowHeaders = this.options.allowHeaders ?? interceptorOptions.request.headers["access-control-request-headers"];
|
|
222
|
-
if (typeof allowHeaders === "string" || allowHeaders?.length) {
|
|
223
|
-
resHeaders["access-control-allow-headers"] = flattenStandardHeader(allowHeaders);
|
|
224
|
-
}
|
|
225
|
-
return {
|
|
226
|
-
matched: true,
|
|
227
|
-
response: {
|
|
228
|
-
status: 204,
|
|
229
|
-
headers: resHeaders,
|
|
230
|
-
body: void 0
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
return interceptorOptions.next();
|
|
235
|
-
};
|
|
236
|
-
return {
|
|
237
|
-
...options,
|
|
238
|
-
routingInterceptors: [
|
|
239
|
-
corsHeadersInterceptor,
|
|
240
|
-
preflightInterceptor,
|
|
241
|
-
...toArray(options.routingInterceptors)
|
|
242
|
-
]
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
class RequestHeadersHandlerPlugin {
|
|
248
|
-
name = "~request-headers";
|
|
249
|
-
init(options) {
|
|
250
|
-
return {
|
|
251
|
-
...options,
|
|
252
|
-
interceptors: [
|
|
253
|
-
(interceptorOptions) => {
|
|
254
|
-
const reqHeaders = interceptorOptions.context.reqHeaders ?? toFetchHeaders(interceptorOptions.request.headers);
|
|
255
|
-
return interceptorOptions.next({
|
|
256
|
-
...interceptorOptions,
|
|
257
|
-
context: {
|
|
258
|
-
...interceptorOptions.context,
|
|
259
|
-
reqHeaders
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
},
|
|
263
|
-
...toArray(options.interceptors)
|
|
264
|
-
]
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
class ResponseHeadersHandlerPlugin {
|
|
270
|
-
name = "~response-headers";
|
|
271
|
-
/**
|
|
272
|
-
* Interceptors should run after batch interceptors so headers are applied to each sub-response.
|
|
273
|
-
*/
|
|
274
|
-
before = ["~batch"];
|
|
275
|
-
init(options) {
|
|
276
|
-
return {
|
|
277
|
-
...options,
|
|
278
|
-
routingInterceptors: [
|
|
279
|
-
async (interceptorOptions) => {
|
|
280
|
-
const resHeaders = new Headers(interceptorOptions.context.resHeaders);
|
|
281
|
-
const result = await interceptorOptions.next({
|
|
282
|
-
...interceptorOptions,
|
|
283
|
-
context: {
|
|
284
|
-
...interceptorOptions.context,
|
|
285
|
-
resHeaders
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
if (!result.response) {
|
|
289
|
-
return result;
|
|
290
|
-
}
|
|
291
|
-
return {
|
|
292
|
-
...result,
|
|
293
|
-
response: {
|
|
294
|
-
...result.response,
|
|
295
|
-
headers: mergeStandardHeaders(result.response.headers, toStandardHeaders(resHeaders))
|
|
296
|
-
}
|
|
297
|
-
};
|
|
298
|
-
},
|
|
299
|
-
...toArray(options.routingInterceptors)
|
|
300
|
-
]
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
class RethrowHandlerPlugin {
|
|
306
|
-
name = "~rethrow";
|
|
307
|
-
filter;
|
|
308
|
-
CONTEXT_SYMBOL = Symbol("ORPC_RETHROW_HANDLER_PLUGIN_CONTEXT");
|
|
309
|
-
constructor(options) {
|
|
310
|
-
this.filter = options.filter;
|
|
311
|
-
}
|
|
312
|
-
init(options) {
|
|
313
|
-
const routingInterceptor = async (options2) => {
|
|
314
|
-
const pluginContext = {};
|
|
315
|
-
const result = await options2.next({
|
|
316
|
-
...options2,
|
|
317
|
-
context: {
|
|
318
|
-
...options2.context,
|
|
319
|
-
[this.CONTEXT_SYMBOL]: pluginContext
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
if (pluginContext.error) {
|
|
323
|
-
throw pluginContext.error.value;
|
|
324
|
-
}
|
|
325
|
-
return result;
|
|
326
|
-
};
|
|
327
|
-
const interceptor = async (options2) => {
|
|
328
|
-
const pluginContext = options2.context[this.CONTEXT_SYMBOL];
|
|
329
|
-
if (!pluginContext) {
|
|
330
|
-
throw new TypeError("[RethrowHandlerPlugin] Rethrow handler context has been corrupted or modified by another plugin or interceptor");
|
|
331
|
-
}
|
|
332
|
-
try {
|
|
333
|
-
return await options2.next();
|
|
334
|
-
} catch (error) {
|
|
335
|
-
if (this.filter(error, options2)) {
|
|
336
|
-
pluginContext.error = { value: error };
|
|
337
|
-
}
|
|
338
|
-
throw error;
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
return {
|
|
342
|
-
...options,
|
|
343
|
-
routingInterceptors: [
|
|
344
|
-
...toArray(options.routingInterceptors),
|
|
345
|
-
routingInterceptor
|
|
346
|
-
// rethrow as early as possible and keep it close to `interceptor` to avoid a corrupted or modified context
|
|
347
|
-
],
|
|
348
|
-
interceptors: [
|
|
349
|
-
interceptor,
|
|
350
|
-
// catch as many errors as possible
|
|
351
|
-
...toArray(options.interceptors)
|
|
352
|
-
]
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
export { BatchHandlerPlugin, CORSHandlerPlugin, RequestHeadersHandlerPlugin, ResponseHeadersHandlerPlugin, RethrowHandlerPlugin };
|