@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.
Files changed (171) hide show
  1. package/README.md +137 -102
  2. package/dist/adapters/aws-lambda/handler.d.ts +27 -0
  3. package/dist/adapters/aws-lambda/handler.js +24 -0
  4. package/dist/adapters/aws-lambda/index.d.ts +4 -0
  5. package/dist/adapters/aws-lambda/index.js +2 -0
  6. package/dist/adapters/aws-lambda/rpc-handler.d.ts +19 -0
  7. package/dist/adapters/aws-lambda/rpc-handler.js +21 -0
  8. package/dist/adapters/crossws/handler.d.ts +47 -0
  9. package/dist/adapters/crossws/handler.js +53 -0
  10. package/dist/adapters/crossws/index.d.ts +3 -54
  11. package/dist/adapters/crossws/index.js +2 -0
  12. package/dist/adapters/crossws/rpc-handler.d.ts +16 -0
  13. package/dist/adapters/crossws/rpc-handler.js +18 -0
  14. package/dist/adapters/fastify/handler.d.ts +23 -0
  15. package/dist/adapters/fastify/handler.js +20 -0
  16. package/dist/adapters/fastify/index.d.ts +3 -0
  17. package/dist/adapters/fastify/index.js +2 -0
  18. package/dist/adapters/fastify/rpc-handler.d.ts +15 -0
  19. package/dist/adapters/fastify/rpc-handler.js +17 -0
  20. package/dist/adapters/fetch/handler.d.ts +25 -0
  21. package/dist/adapters/fetch/handler.js +22 -0
  22. package/dist/adapters/fetch/index.d.ts +4 -140
  23. package/dist/adapters/fetch/index.js +3 -0
  24. package/dist/adapters/fetch/rpc-handler.d.ts +17 -0
  25. package/dist/adapters/fetch/rpc-handler.js +19 -0
  26. package/dist/adapters/message-port/handler.d.ts +62 -0
  27. package/dist/adapters/message-port/handler.js +72 -0
  28. package/dist/adapters/message-port/index.d.ts +3 -74
  29. package/dist/adapters/message-port/index.js +2 -0
  30. package/dist/adapters/message-port/rpc-handler.d.ts +16 -0
  31. package/dist/adapters/message-port/rpc-handler.js +18 -0
  32. package/dist/adapters/node/handler.d.ts +23 -0
  33. package/dist/adapters/node/handler.js +20 -0
  34. package/dist/adapters/node/index.d.ts +4 -121
  35. package/dist/adapters/node/index.js +3 -0
  36. package/dist/adapters/node/rpc-handler.d.ts +16 -0
  37. package/dist/adapters/node/rpc-handler.js +18 -0
  38. package/dist/adapters/standard/codec.d.ts +16 -0
  39. package/dist/adapters/standard/handler.d.ts +68 -0
  40. package/dist/adapters/standard/handler.js +205 -0
  41. package/dist/adapters/standard/index.d.ts +7 -19
  42. package/dist/adapters/standard/index.js +4 -0
  43. package/dist/adapters/standard/plugin.d.ts +26 -0
  44. package/dist/adapters/standard/plugin.js +14 -0
  45. package/dist/adapters/standard/rpc-handler-codec.d.ts +42 -0
  46. package/dist/adapters/standard/rpc-handler-codec.js +50 -0
  47. package/dist/adapters/standard/rpc-matcher.d.ts +53 -0
  48. package/dist/adapters/standard/rpc-matcher.js +106 -0
  49. package/dist/adapters/standard/utils.d.ts +10 -0
  50. package/dist/adapters/standard/utils.js +8 -0
  51. package/dist/adapters/standard-peer/index.d.ts +2 -16
  52. package/dist/adapters/standard-peer/index.js +1 -0
  53. package/dist/adapters/standard-peer/utils.d.ts +6 -0
  54. package/dist/adapters/standard-peer/utils.js +13 -0
  55. package/dist/adapters/websocket/handler.d.ts +61 -0
  56. package/dist/adapters/websocket/handler.js +75 -0
  57. package/dist/adapters/websocket/index.d.ts +3 -61
  58. package/dist/adapters/websocket/index.js +2 -0
  59. package/dist/adapters/websocket/rpc-handler.d.ts +16 -0
  60. package/dist/adapters/websocket/rpc-handler.js +18 -0
  61. package/dist/builder-variants.d.ts +226 -0
  62. package/dist/builder.d.ts +126 -0
  63. package/dist/builder.js +200 -0
  64. package/dist/constants.d.ts +2 -0
  65. package/dist/constants.js +4 -0
  66. package/dist/context.d.ts +6 -0
  67. package/dist/extensions/callable.d.ts +11 -10
  68. package/dist/extensions/callable.js +8 -0
  69. package/dist/helpers/base64url.d.ts +31 -0
  70. package/dist/helpers/base64url.js +48 -0
  71. package/dist/helpers/cookie.d.ts +50 -0
  72. package/dist/helpers/cookie.js +62 -0
  73. package/dist/helpers/encryption.d.ts +28 -0
  74. package/dist/helpers/encryption.js +90 -0
  75. package/dist/helpers/index.d.ts +5 -149
  76. package/dist/helpers/index.js +4 -0
  77. package/dist/helpers/signing.d.ts +50 -0
  78. package/dist/helpers/signing.js +78 -0
  79. package/dist/implementer-procedure.d.ts +15 -0
  80. package/dist/implementer-procedure.js +37 -0
  81. package/dist/implementer-router.d.ts +34 -0
  82. package/dist/implementer-router.js +98 -0
  83. package/dist/implementer.d.ts +16 -0
  84. package/dist/implementer.js +30 -0
  85. package/dist/index.d.ts +22 -196
  86. package/dist/index.js +16 -0
  87. package/dist/lazy.d.ts +20 -0
  88. package/dist/lazy.js +20 -0
  89. package/dist/middleware-decorated.d.ts +9 -0
  90. package/dist/middleware-decorated.js +67 -0
  91. package/dist/middleware.d.ts +54 -0
  92. package/dist/plugins/batch.d.ts +102 -0
  93. package/dist/plugins/batch.js +371 -0
  94. package/dist/plugins/cors.d.ts +69 -0
  95. package/dist/plugins/cors.js +119 -0
  96. package/dist/plugins/get-method-csrf-protection.d.ts +25 -0
  97. package/dist/plugins/get-method-csrf-protection.js +48 -0
  98. package/dist/plugins/head-method.d.ts +25 -0
  99. package/dist/plugins/head-method.js +107 -0
  100. package/dist/plugins/index.d.ts +15 -197
  101. package/dist/plugins/index.js +14 -0
  102. package/dist/plugins/method-override.d.ts +40 -0
  103. package/dist/plugins/method-override.js +54 -0
  104. package/dist/plugins/request-compression.d.ts +18 -0
  105. package/dist/plugins/request-compression.js +55 -0
  106. package/dist/plugins/request-headers.d.ts +24 -0
  107. package/dist/plugins/request-headers.js +28 -0
  108. package/dist/plugins/request-limit.d.ts +32 -0
  109. package/dist/plugins/request-limit.js +61 -0
  110. package/dist/plugins/response-compression.d.ts +62 -0
  111. package/dist/plugins/response-compression.js +157 -0
  112. package/dist/plugins/response-headers.d.ts +32 -0
  113. package/dist/plugins/response-headers.js +44 -0
  114. package/dist/plugins/rethrow.d.ts +35 -0
  115. package/dist/plugins/rethrow.js +47 -0
  116. package/dist/plugins/signal-sync.d.ts +15 -0
  117. package/dist/plugins/signal-sync.js +76 -0
  118. package/dist/plugins/timeout.d.ts +39 -0
  119. package/dist/plugins/timeout.js +62 -0
  120. package/dist/procedure-client.d.ts +18 -0
  121. package/dist/procedure-client.js +158 -0
  122. package/dist/procedure-decorated.d.ts +10 -0
  123. package/dist/procedure-decorated.js +36 -0
  124. package/dist/procedure-utils.d.ts +21 -0
  125. package/dist/procedure-utils.js +48 -0
  126. package/dist/procedure.d.ts +72 -0
  127. package/dist/procedure.js +18 -0
  128. package/dist/router-client.d.ts +21 -0
  129. package/dist/router-client.js +35 -0
  130. package/dist/router-hidden.js +12 -0
  131. package/dist/router-utils.d.ts +31 -0
  132. package/dist/router-utils.js +157 -0
  133. package/dist/router.d.ts +58 -0
  134. package/package.json +95 -63
  135. package/dist/adapters/crossws/index.d.mts +0 -54
  136. package/dist/adapters/crossws/index.mjs +0 -64
  137. package/dist/adapters/fetch/index.d.mts +0 -140
  138. package/dist/adapters/fetch/index.mjs +0 -204
  139. package/dist/adapters/message-port/index.d.mts +0 -74
  140. package/dist/adapters/message-port/index.mjs +0 -90
  141. package/dist/adapters/node/index.d.mts +0 -121
  142. package/dist/adapters/node/index.mjs +0 -179
  143. package/dist/adapters/standard/index.d.mts +0 -19
  144. package/dist/adapters/standard/index.mjs +0 -8
  145. package/dist/adapters/standard-peer/index.d.mts +0 -16
  146. package/dist/adapters/standard-peer/index.mjs +0 -2
  147. package/dist/adapters/websocket/index.d.mts +0 -61
  148. package/dist/adapters/websocket/index.mjs +0 -76
  149. package/dist/extensions/callable.d.mts +0 -10
  150. package/dist/extensions/callable.mjs +0 -11
  151. package/dist/helpers/index.d.mts +0 -149
  152. package/dist/helpers/index.mjs +0 -198
  153. package/dist/index.d.mts +0 -196
  154. package/dist/index.mjs +0 -385
  155. package/dist/plugins/index.d.mts +0 -197
  156. package/dist/plugins/index.mjs +0 -357
  157. package/dist/shared/server.BL22TloH.d.mts +0 -184
  158. package/dist/shared/server.BL22TloH.d.ts +0 -184
  159. package/dist/shared/server.BsNNjG5J.d.mts +0 -61
  160. package/dist/shared/server.BwHnWUuN.mjs +0 -222
  161. package/dist/shared/server.CX4vUnDk.mjs +0 -11
  162. package/dist/shared/server.Cj5lgPuG.d.mts +0 -66
  163. package/dist/shared/server.CjOb6ItT.mjs +0 -41
  164. package/dist/shared/server.CrlKQucM.mjs +0 -233
  165. package/dist/shared/server.DBANIheG.d.ts +0 -104
  166. package/dist/shared/server.DJIkub_t.d.mts +0 -104
  167. package/dist/shared/server.D_QauotT.mjs +0 -30
  168. package/dist/shared/server.GDpX6Df8.mjs +0 -271
  169. package/dist/shared/server.Pa0F03f_.d.ts +0 -61
  170. package/dist/shared/server.W91HSRkE.mjs +0 -9
  171. package/dist/shared/server.d_2NS3g5.d.ts +0 -66
@@ -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 };
@@ -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 };