@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
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { toArray } from "@orpc/shared";
|
|
2
|
+
import { ORPCError } from "@orpc/client";
|
|
3
|
+
import { flattenStandardHeader } from "@standard-server/core";
|
|
4
|
+
// src/plugins/get-method-csrf-protection.ts
|
|
5
|
+
/**
|
|
6
|
+
* Adds Cross-Site Request Forgery (CSRF) protection that makes the safe `GET` method as
|
|
7
|
+
* secure as unsafe ones such as `POST`. It rejects `GET` requests arriving as top-level
|
|
8
|
+
* navigations initiated cross-site or from outside the browser, the only context where
|
|
9
|
+
* another site can make a browser attach `SameSite=Lax` cookies to a safe-method request.
|
|
10
|
+
* Requests matching no procedure stay unmatched, so they can fall through to whatever
|
|
11
|
+
* serves the rest of the site.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* **Note**: Requests browsers send without `SameSite=Lax` cookies, such as cross-site `fetch`
|
|
15
|
+
* and `<img>`, pass through, so procedures stay reachable from other sites. This safeguard
|
|
16
|
+
* requires authentication cookies explicitly marked `SameSite=Lax` or `SameSite=Strict`,
|
|
17
|
+
* since browsers may attach other cookies to the requests that pass.
|
|
18
|
+
*
|
|
19
|
+
* @see {@link https://orpc.dev/docs/plugins/get-method-csrf-protection | GET Method CSRF Protection Plugin}
|
|
20
|
+
*/
|
|
21
|
+
var GetMethodCsrfProtectionHandlerPlugin = class {
|
|
22
|
+
name = "~get-method-csrf-protection";
|
|
23
|
+
init(options) {
|
|
24
|
+
/**
|
|
25
|
+
* Batch sub-requests are judged individually here, which is safe: navigations cannot
|
|
26
|
+
* carry the custom `orpc-batch` header, and the batch plugin's default `mapSubrequest`
|
|
27
|
+
* keeps the transport headers authoritative over client-authored sub-request headers.
|
|
28
|
+
*/
|
|
29
|
+
const interceptor = (interceptorOptions) => {
|
|
30
|
+
if (this.isAllowed(interceptorOptions)) return interceptorOptions.next();
|
|
31
|
+
throw new ORPCError("FORBIDDEN", { message: "Request blocked by CSRF protection." });
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
...options,
|
|
35
|
+
interceptors: [interceptor, ...toArray(options.interceptors)]
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
isAllowed({ request }) {
|
|
39
|
+
if (request.method !== "GET") return true;
|
|
40
|
+
const site = flattenStandardHeader(request.headers["sec-fetch-site"])?.toLowerCase();
|
|
41
|
+
if (site === void 0 || site === "same-origin" || site === "same-site") return true;
|
|
42
|
+
const mode = flattenStandardHeader(request.headers["sec-fetch-mode"])?.toLowerCase();
|
|
43
|
+
const dest = flattenStandardHeader(request.headers["sec-fetch-dest"])?.toLowerCase();
|
|
44
|
+
if (mode === void 0 || dest === void 0) return false;
|
|
45
|
+
return mode !== "navigate" || dest !== "document";
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
export { GetMethodCsrfProtectionHandlerPlugin };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import "../adapters/standard/index.js";
|
|
2
|
+
import { StandardHandlerPlugin } from "../adapters/standard/plugin.js";
|
|
3
|
+
import { StandardHandlerOptions } from "../adapters/standard/handler.js";
|
|
4
|
+
import { Context } from "../context.js";
|
|
5
|
+
/**
|
|
6
|
+
* Answers `HEAD` requests with the headers of the matching `GET` procedure, like Fastify's
|
|
7
|
+
* `exposeHeadRoutes`, so clients can check a resource's existence, type, and size without
|
|
8
|
+
* downloading it. A procedure routed as `HEAD` itself takes precedence over the `GET` one.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* - `HEAD` responses never carry a body: the plugin discards it, cancelling streams and
|
|
12
|
+
* event iterators, and keeps the headers it implies, such as `Content-Type`, and
|
|
13
|
+
* `Content-Length` when its size is known up front.
|
|
14
|
+
* - `GET` procedures still need to be reachable, so with `RPCHandler`, `GET` must be in `allowMethods`.
|
|
15
|
+
*
|
|
16
|
+
* @see {@link https://orpc.dev/docs/plugins/head-method | HEAD Method Plugin}
|
|
17
|
+
*/
|
|
18
|
+
export declare class HeadMethodHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
19
|
+
name: string;
|
|
20
|
+
/**
|
|
21
|
+
* Discard the body after response compression, so `HEAD` reports the same `Content-Encoding` as `GET`.
|
|
22
|
+
*/
|
|
23
|
+
after: string[];
|
|
24
|
+
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { isAsyncIteratorObject, toArray } from "@orpc/shared";
|
|
2
|
+
import { cancelStandardBody, getRequiredStandardBodyHint } from "@standard-server/core";
|
|
3
|
+
import { toFetchBody } from "@standard-server/fetch";
|
|
4
|
+
// src/plugins/head-method.ts
|
|
5
|
+
const textEncoder = /* @__PURE__ */ new TextEncoder();
|
|
6
|
+
/**
|
|
7
|
+
* Answers `HEAD` requests with the headers of the matching `GET` procedure, like Fastify's
|
|
8
|
+
* `exposeHeadRoutes`, so clients can check a resource's existence, type, and size without
|
|
9
|
+
* downloading it. A procedure routed as `HEAD` itself takes precedence over the `GET` one.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* - `HEAD` responses never carry a body: the plugin discards it, cancelling streams and
|
|
13
|
+
* event iterators, and keeps the headers it implies, such as `Content-Type`, and
|
|
14
|
+
* `Content-Length` when its size is known up front.
|
|
15
|
+
* - `GET` procedures still need to be reachable, so with `RPCHandler`, `GET` must be in `allowMethods`.
|
|
16
|
+
*
|
|
17
|
+
* @see {@link https://orpc.dev/docs/plugins/head-method | HEAD Method Plugin}
|
|
18
|
+
*/
|
|
19
|
+
var HeadMethodHandlerPlugin = class {
|
|
20
|
+
name = "~head-method";
|
|
21
|
+
/**
|
|
22
|
+
* Discard the body after response compression, so `HEAD` reports the same `Content-Encoding` as `GET`.
|
|
23
|
+
*/
|
|
24
|
+
after = ["~response-compression"];
|
|
25
|
+
init(options) {
|
|
26
|
+
const bodyInterceptor = async ({ next, request }) => {
|
|
27
|
+
if (request.method !== "HEAD") return next();
|
|
28
|
+
const result = await next();
|
|
29
|
+
if (!result.matched) return result;
|
|
30
|
+
return {
|
|
31
|
+
...result,
|
|
32
|
+
response: toHeadResponse(result.response)
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Placed last, so falling back to `GET` repeats routing rather than the routing interceptors before this one.
|
|
37
|
+
*/
|
|
38
|
+
const fallbackInterceptor = async (interceptorOptions) => {
|
|
39
|
+
const { next, request } = interceptorOptions;
|
|
40
|
+
if (request.method !== "HEAD") return next();
|
|
41
|
+
const result = await next();
|
|
42
|
+
if (result.matched) return result;
|
|
43
|
+
return next({
|
|
44
|
+
...interceptorOptions,
|
|
45
|
+
request: {
|
|
46
|
+
...request,
|
|
47
|
+
method: "GET"
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
...options,
|
|
53
|
+
routingInterceptors: [
|
|
54
|
+
bodyInterceptor,
|
|
55
|
+
...toArray(options.routingInterceptors),
|
|
56
|
+
fallbackInterceptor
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Replaces the body with an empty stream, keeping the headers adapters derive from it.
|
|
63
|
+
* An empty stream rather than no body, because adapters drop `Content-Type` and `Content-Length` when the body is `undefined`,
|
|
64
|
+
* and an empty `Standard-Server` hint rather than none, so they do not hint the stream as `octet-stream`.
|
|
65
|
+
*/
|
|
66
|
+
function toHeadResponse(response) {
|
|
67
|
+
const { body } = response;
|
|
68
|
+
if (body === void 0) return response;
|
|
69
|
+
if (isAsyncIteratorObject(body)) {
|
|
70
|
+
discardBody(body);
|
|
71
|
+
const headers = {
|
|
72
|
+
...response.headers,
|
|
73
|
+
"content-length": void 0
|
|
74
|
+
};
|
|
75
|
+
headers["content-type"] ??= "text/event-stream";
|
|
76
|
+
headers["standard-server"] = getRequiredStandardBodyHint("event-stream", headers) ?? [];
|
|
77
|
+
return {
|
|
78
|
+
...response,
|
|
79
|
+
headers,
|
|
80
|
+
body: createEmptyStream()
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const [encoded, headers] = toFetchBody(body, response.headers);
|
|
84
|
+
if (encoded instanceof ReadableStream) discardBody(encoded);
|
|
85
|
+
else if (encoded instanceof FormData) {
|
|
86
|
+
headers["standard-server"] = [];
|
|
87
|
+
headers["content-type"] = new Response(encoded).headers.get("content-type");
|
|
88
|
+
} else if (typeof encoded === "string" || encoded instanceof URLSearchParams) {
|
|
89
|
+
headers["standard-server"] ??= [];
|
|
90
|
+
headers["content-length"] = textEncoder.encode(encoded.toString()).byteLength.toString();
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
...response,
|
|
94
|
+
headers,
|
|
95
|
+
body: createEmptyStream()
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function createEmptyStream() {
|
|
99
|
+
return new ReadableStream({ start: (controller) => controller.close() });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Nothing reads the body anymore, so a failure to cancel it has nowhere to go.
|
|
103
|
+
*/
|
|
104
|
+
function discardBody(body) {
|
|
105
|
+
cancelStandardBody(body).catch(() => {});
|
|
106
|
+
}
|
|
107
|
+
export { HeadMethodHandlerPlugin };
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,197 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
+
import { BATCH_CONTENT_TYPE, BatchHandlerPlugin, BatchHandlerPluginOptions } from "./batch.js";
|
|
2
|
+
import { CORSHandlerPlugin, CORSHandlerPluginOptions } from "./cors.js";
|
|
3
|
+
import { GetMethodCsrfProtectionHandlerPlugin } from "./get-method-csrf-protection.js";
|
|
4
|
+
import { HeadMethodHandlerPlugin } from "./head-method.js";
|
|
5
|
+
import { MethodOverrideHandlerPlugin, MethodOverrideHandlerPluginOptions } from "./method-override.js";
|
|
6
|
+
import { RequestCompressionHandlerPlugin } from "./request-compression.js";
|
|
7
|
+
import { RequestHeadersHandlerPlugin, RequestHeadersHandlerPluginContext } from "./request-headers.js";
|
|
8
|
+
import { RequestLimitHandlerPlugin, RequestLimitHandlerPluginOptions } from "./request-limit.js";
|
|
9
|
+
import { ResponseCompressionHandlerPlugin, ResponseCompressionHandlerPluginOptions, negotiateResponseCompressionEncoding, toCompressedHeaders } from "./response-compression.js";
|
|
10
|
+
import { ResponseHeadersHandlerPlugin, ResponseHeadersHandlerPluginContext } from "./response-headers.js";
|
|
11
|
+
import { RethrowHandlerPlugin, RethrowHandlerPluginOptions } from "./rethrow.js";
|
|
12
|
+
import { SignalSyncHandlerPlugin } from "./signal-sync.js";
|
|
13
|
+
import { TimeoutHandlerPlugin, TimeoutHandlerPluginOptions } from "./timeout.js";
|
|
14
|
+
import { BATCH_HEADER, DEFAULT_BATCH_MAX_SIZE } from "@orpc/client/plugins";
|
|
15
|
+
export { BATCH_CONTENT_TYPE, BATCH_HEADER, BatchHandlerPlugin, BatchHandlerPluginOptions, CORSHandlerPlugin, CORSHandlerPluginOptions, CORSHandlerPlugin as CORSPlugin, DEFAULT_BATCH_MAX_SIZE, GetMethodCsrfProtectionHandlerPlugin, HeadMethodHandlerPlugin, MethodOverrideHandlerPlugin, MethodOverrideHandlerPluginOptions, RequestCompressionHandlerPlugin, RequestHeadersHandlerPlugin, RequestHeadersHandlerPluginContext, RequestHeadersHandlerPlugin as RequestHeadersPlugin, type RequestHeadersHandlerPluginContext as RequestHeadersPluginContext, RequestLimitHandlerPlugin, RequestLimitHandlerPluginOptions, ResponseCompressionHandlerPlugin, ResponseCompressionHandlerPluginOptions, ResponseHeadersHandlerPlugin, ResponseHeadersHandlerPluginContext, ResponseHeadersHandlerPlugin as ResponseHeadersPlugin, type ResponseHeadersHandlerPluginContext as ResponseHeadersPluginContext, RethrowHandlerPlugin, RethrowHandlerPluginOptions, SignalSyncHandlerPlugin, TimeoutHandlerPlugin, TimeoutHandlerPluginOptions, negotiateResponseCompressionEncoding, toCompressedHeaders };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { BATCH_CONTENT_TYPE, BatchHandlerPlugin } from "./batch.js";
|
|
2
|
+
export { CORSHandlerPlugin, CORSHandlerPlugin as CORSPlugin } from "./cors.js";
|
|
3
|
+
export { GetMethodCsrfProtectionHandlerPlugin } from "./get-method-csrf-protection.js";
|
|
4
|
+
export { HeadMethodHandlerPlugin } from "./head-method.js";
|
|
5
|
+
export { MethodOverrideHandlerPlugin } from "./method-override.js";
|
|
6
|
+
export { RequestCompressionHandlerPlugin } from "./request-compression.js";
|
|
7
|
+
export { RequestHeadersHandlerPlugin, RequestHeadersHandlerPlugin as RequestHeadersPlugin } from "./request-headers.js";
|
|
8
|
+
export { RequestLimitHandlerPlugin } from "./request-limit.js";
|
|
9
|
+
export { ResponseCompressionHandlerPlugin, negotiateResponseCompressionEncoding, toCompressedHeaders } from "./response-compression.js";
|
|
10
|
+
export { ResponseHeadersHandlerPlugin, ResponseHeadersHandlerPlugin as ResponseHeadersPlugin } from "./response-headers.js";
|
|
11
|
+
export { RethrowHandlerPlugin } from "./rethrow.js";
|
|
12
|
+
export { SignalSyncHandlerPlugin } from "./signal-sync.js";
|
|
13
|
+
export { TimeoutHandlerPlugin } from "./timeout.js";
|
|
14
|
+
export { BATCH_HEADER, DEFAULT_BATCH_MAX_SIZE } from "@orpc/client/plugins";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import "../adapters/standard/index.js";
|
|
2
|
+
import { StandardHandlerPlugin } from "../adapters/standard/plugin.js";
|
|
3
|
+
import { StandardHandlerOptions } from "../adapters/standard/handler.js";
|
|
4
|
+
import { Context } from "../context.js";
|
|
5
|
+
import { StandardMethod } from "@standard-server/core";
|
|
6
|
+
export interface MethodOverrideHandlerPluginOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The query parameter carrying the override method.
|
|
9
|
+
*
|
|
10
|
+
* @default 'method'
|
|
11
|
+
*/
|
|
12
|
+
param?: string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* The methods a POST request may be overridden to.
|
|
15
|
+
*
|
|
16
|
+
* GET and HEAD are excluded by default because they switch input decoding
|
|
17
|
+
* from the request body to the query string and widen the CSRF surface.
|
|
18
|
+
*
|
|
19
|
+
* @default ['PUT', 'PATCH', 'DELETE']
|
|
20
|
+
*/
|
|
21
|
+
methods?: readonly StandardMethod[] | undefined;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Overrides the HTTP method of a POST request based on a query parameter,
|
|
25
|
+
* so HTML forms (which only support GET and POST) can invoke procedures
|
|
26
|
+
* routed as PUT, PATCH, or DELETE.
|
|
27
|
+
*
|
|
28
|
+
* @see {@link https://orpc.dev/docs/plugins/method-override | Method Override Plugin}
|
|
29
|
+
*/
|
|
30
|
+
export declare class MethodOverrideHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
31
|
+
name: string;
|
|
32
|
+
/**
|
|
33
|
+
* Should override batch sub-request methods, not the original batch request.
|
|
34
|
+
*/
|
|
35
|
+
before: string[];
|
|
36
|
+
private readonly param;
|
|
37
|
+
private readonly methods;
|
|
38
|
+
constructor(options?: MethodOverrideHandlerPluginOptions);
|
|
39
|
+
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { toArray } from "@orpc/shared";
|
|
2
|
+
import { parseStandardUrl } from "@standard-server/core";
|
|
3
|
+
// src/plugins/method-override.ts
|
|
4
|
+
/**
|
|
5
|
+
* Overrides the HTTP method of a POST request based on a query parameter,
|
|
6
|
+
* so HTML forms (which only support GET and POST) can invoke procedures
|
|
7
|
+
* routed as PUT, PATCH, or DELETE.
|
|
8
|
+
*
|
|
9
|
+
* @see {@link https://orpc.dev/docs/plugins/method-override | Method Override Plugin}
|
|
10
|
+
*/
|
|
11
|
+
var MethodOverrideHandlerPlugin = class {
|
|
12
|
+
name = "~method-override";
|
|
13
|
+
/**
|
|
14
|
+
* Should override batch sub-request methods, not the original batch request.
|
|
15
|
+
*/
|
|
16
|
+
before = ["~batch"];
|
|
17
|
+
param;
|
|
18
|
+
methods;
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
this.param = options.param ?? "method";
|
|
21
|
+
this.methods = new Set((options.methods ?? [
|
|
22
|
+
"PUT",
|
|
23
|
+
"PATCH",
|
|
24
|
+
"DELETE"
|
|
25
|
+
]).map((method) => method.toUpperCase()));
|
|
26
|
+
}
|
|
27
|
+
init(options) {
|
|
28
|
+
const routingInterceptor = async ({ next, ...interceptorOptions }) => {
|
|
29
|
+
const { request } = interceptorOptions;
|
|
30
|
+
if (request.method !== "POST") return next();
|
|
31
|
+
const [pathname, search, hash] = parseStandardUrl(request.url);
|
|
32
|
+
const params = new URLSearchParams(search);
|
|
33
|
+
const raw = params.getAll(this.param).at(-1);
|
|
34
|
+
if (raw === void 0) return next();
|
|
35
|
+
const method = raw.toUpperCase();
|
|
36
|
+
if (!this.methods.has(method)) return next();
|
|
37
|
+
params.delete(this.param);
|
|
38
|
+
const url = `${pathname}${params.size ? `?${params}` : ""}${hash ?? ""}`;
|
|
39
|
+
return next({
|
|
40
|
+
...interceptorOptions,
|
|
41
|
+
request: {
|
|
42
|
+
...request,
|
|
43
|
+
method,
|
|
44
|
+
url
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
...options,
|
|
50
|
+
routingInterceptors: [routingInterceptor, ...toArray(options.routingInterceptors)]
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
export { MethodOverrideHandlerPlugin };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "../adapters/standard/index.js";
|
|
2
|
+
import { StandardHandlerPlugin } from "../adapters/standard/plugin.js";
|
|
3
|
+
import { StandardHandlerOptions } from "../adapters/standard/handler.js";
|
|
4
|
+
import { Context } from "../context.js";
|
|
5
|
+
/**
|
|
6
|
+
* Decompresses incoming request bodies based on the Content-Encoding header,
|
|
7
|
+
* supporting gzip, deflate, and deflate-raw.
|
|
8
|
+
*
|
|
9
|
+
* @see {@link https://orpc.dev/docs/plugins/request-compression | Request Compression Plugin}
|
|
10
|
+
*/
|
|
11
|
+
export declare class RequestCompressionHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
12
|
+
name: string;
|
|
13
|
+
/**
|
|
14
|
+
* Should decompress the original batch request body instead of sub-requests.
|
|
15
|
+
*/
|
|
16
|
+
after: string[];
|
|
17
|
+
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { isCompressionEncoding, parseContentEncodings, toArray } from "@orpc/shared";
|
|
2
|
+
import { ORPCError } from "@orpc/client";
|
|
3
|
+
import { flattenStandardHeader } from "@standard-server/core";
|
|
4
|
+
import { toFetchHeaders, toStandardBody } from "@standard-server/fetch";
|
|
5
|
+
// src/plugins/request-compression.ts
|
|
6
|
+
/**
|
|
7
|
+
* Each coding adds a decompressor to the chain, so an unbounded list lets a tiny
|
|
8
|
+
* request cost unbounded CPU and memory. Same limit as undici and curl.
|
|
9
|
+
*/
|
|
10
|
+
const MAX_CONTENT_ENCODINGS = 5;
|
|
11
|
+
/**
|
|
12
|
+
* Decompresses incoming request bodies based on the Content-Encoding header,
|
|
13
|
+
* supporting gzip, deflate, and deflate-raw.
|
|
14
|
+
*
|
|
15
|
+
* @see {@link https://orpc.dev/docs/plugins/request-compression | Request Compression Plugin}
|
|
16
|
+
*/
|
|
17
|
+
var RequestCompressionHandlerPlugin = class {
|
|
18
|
+
name = "~request-compression";
|
|
19
|
+
/**
|
|
20
|
+
* Should decompress the original batch request body instead of sub-requests.
|
|
21
|
+
*/
|
|
22
|
+
after = ["~batch"];
|
|
23
|
+
init(options) {
|
|
24
|
+
const routingInterceptor = async ({ next, ...interceptorOptions }) => {
|
|
25
|
+
const encodings = parseContentEncodings(flattenStandardHeader(interceptorOptions.request.headers["content-encoding"]));
|
|
26
|
+
if (encodings.length === 0 || !encodings.every(isCompressionEncoding)) return next();
|
|
27
|
+
const decompressedHeaders = {
|
|
28
|
+
...interceptorOptions.request.headers,
|
|
29
|
+
"content-length": void 0,
|
|
30
|
+
"content-encoding": void 0
|
|
31
|
+
};
|
|
32
|
+
return next({
|
|
33
|
+
...interceptorOptions,
|
|
34
|
+
request: {
|
|
35
|
+
...interceptorOptions.request,
|
|
36
|
+
headers: decompressedHeaders,
|
|
37
|
+
async resolveBody(hint) {
|
|
38
|
+
const stream = await interceptorOptions.request.resolveBody("octet-stream");
|
|
39
|
+
if (!(stream instanceof ReadableStream)) return stream;
|
|
40
|
+
if (encodings.length > MAX_CONTENT_ENCODINGS) throw new ORPCError("UNSUPPORTED_MEDIA_TYPE", { message: "Too many content encodings." });
|
|
41
|
+
let decompressedStream = stream;
|
|
42
|
+
for (let i = encodings.length - 1; i >= 0; i--) decompressedStream = decompressedStream.pipeThrough(new DecompressionStream(encodings[i]));
|
|
43
|
+
const response = new Response(decompressedStream, { headers: toFetchHeaders(decompressedHeaders) });
|
|
44
|
+
return toStandardBody(response, { hint });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
...options,
|
|
51
|
+
routingInterceptors: [routingInterceptor, ...toArray(options.routingInterceptors)]
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
export { RequestCompressionHandlerPlugin };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { StandardHandlerPlugin } from "../adapters/standard/plugin.js";
|
|
2
|
+
import { StandardHandlerOptions } from "../adapters/standard/handler.js";
|
|
3
|
+
import "../adapters/standard/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* The context shape into which the Request Headers Plugin injects `reqHeaders`.
|
|
6
|
+
*
|
|
7
|
+
* @see {@link https://orpc.dev/docs/plugins/request-headers | Request Headers Plugin}
|
|
8
|
+
*/
|
|
9
|
+
export interface RequestHeadersHandlerPluginContext {
|
|
10
|
+
/**
|
|
11
|
+
* Request headers as a Headers instance. This is injected by the Request Headers Plugin.
|
|
12
|
+
*/
|
|
13
|
+
reqHeaders?: Headers | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The Request Headers Plugin injects a `reqHeaders` instance into the context,
|
|
17
|
+
* allowing access to request headers in oRPC.
|
|
18
|
+
*
|
|
19
|
+
* @see {@link https://orpc.dev/docs/plugins/request-headers | Request Headers Plugin}
|
|
20
|
+
*/
|
|
21
|
+
export declare class RequestHeadersHandlerPlugin<T extends RequestHeadersHandlerPluginContext> implements StandardHandlerPlugin<T> {
|
|
22
|
+
name: string;
|
|
23
|
+
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { toArray } from "@orpc/shared";
|
|
2
|
+
import { toFetchHeaders } from "@standard-server/fetch";
|
|
3
|
+
// src/plugins/request-headers.ts
|
|
4
|
+
/**
|
|
5
|
+
* The Request Headers Plugin injects a `reqHeaders` instance into the context,
|
|
6
|
+
* allowing access to request headers in oRPC.
|
|
7
|
+
*
|
|
8
|
+
* @see {@link https://orpc.dev/docs/plugins/request-headers | Request Headers Plugin}
|
|
9
|
+
*/
|
|
10
|
+
var RequestHeadersHandlerPlugin = class {
|
|
11
|
+
name = "~request-headers";
|
|
12
|
+
init(options) {
|
|
13
|
+
return {
|
|
14
|
+
...options,
|
|
15
|
+
interceptors: [(interceptorOptions) => {
|
|
16
|
+
const reqHeaders = interceptorOptions.context.reqHeaders ?? toFetchHeaders(interceptorOptions.request.headers);
|
|
17
|
+
return interceptorOptions.next({
|
|
18
|
+
...interceptorOptions,
|
|
19
|
+
context: {
|
|
20
|
+
...interceptorOptions.context,
|
|
21
|
+
reqHeaders
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}, ...toArray(options.interceptors)]
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
export { RequestHeadersHandlerPlugin };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import "../adapters/standard/index.js";
|
|
2
|
+
import { StandardHandlerPlugin } from "../adapters/standard/plugin.js";
|
|
3
|
+
import { StandardHandlerOptions } from "../adapters/standard/handler.js";
|
|
4
|
+
import { Context } from "../context.js";
|
|
5
|
+
export interface RequestLimitHandlerPluginOptions {
|
|
6
|
+
/**
|
|
7
|
+
* The maximum allowed request body size in bytes.
|
|
8
|
+
*/
|
|
9
|
+
maxBodySize: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Rejects requests whose body exceeds `maxBodySize`.
|
|
13
|
+
*
|
|
14
|
+
* When used with the request compression plugin, the limit applies to the
|
|
15
|
+
* decompressed payload rather than the compressed wire size.
|
|
16
|
+
*
|
|
17
|
+
* @see {@link https://orpc.dev/docs/plugins/request-limit | Request Limit Plugin}
|
|
18
|
+
*/
|
|
19
|
+
export declare class RequestLimitHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
20
|
+
name: string;
|
|
21
|
+
/**
|
|
22
|
+
* Should limit the original batch request body instead of sub-requests.
|
|
23
|
+
*/
|
|
24
|
+
after: string[];
|
|
25
|
+
/**
|
|
26
|
+
* Should limit the final body size instead of the compressed one.
|
|
27
|
+
*/
|
|
28
|
+
before: string[];
|
|
29
|
+
private readonly maxBodySize;
|
|
30
|
+
constructor(options: RequestLimitHandlerPluginOptions);
|
|
31
|
+
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
32
|
+
}
|