@orpc/server 2.0.0-beta.49 → 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 (139) hide show
  1. package/dist/adapters/aws-lambda/handler.d.ts +17 -15
  2. package/dist/adapters/aws-lambda/handler.js +23 -23
  3. package/dist/adapters/aws-lambda/index.d.ts +4 -16
  4. package/dist/adapters/aws-lambda/index.js +2 -2
  5. package/dist/adapters/aws-lambda/rpc-handler.d.ts +9 -9
  6. package/dist/adapters/aws-lambda/rpc-handler.js +20 -17
  7. package/dist/adapters/crossws/handler.d.ts +44 -42
  8. package/dist/adapters/crossws/handler.js +53 -60
  9. package/dist/adapters/crossws/index.d.ts +3 -2
  10. package/dist/adapters/crossws/index.js +2 -2
  11. package/dist/adapters/crossws/rpc-handler.d.ts +10 -10
  12. package/dist/adapters/crossws/rpc-handler.js +17 -14
  13. package/dist/adapters/fastify/handler.d.ts +17 -15
  14. package/dist/adapters/fastify/handler.js +20 -20
  15. package/dist/adapters/fastify/index.d.ts +3 -2
  16. package/dist/adapters/fastify/index.js +2 -2
  17. package/dist/adapters/fastify/rpc-handler.d.ts +9 -9
  18. package/dist/adapters/fastify/rpc-handler.js +16 -13
  19. package/dist/adapters/fetch/handler.d.ts +19 -17
  20. package/dist/adapters/fetch/handler.js +22 -22
  21. package/dist/adapters/fetch/index.d.ts +4 -7
  22. package/dist/adapters/fetch/index.js +3 -7
  23. package/dist/adapters/fetch/rpc-handler.d.ts +9 -9
  24. package/dist/adapters/fetch/rpc-handler.js +18 -15
  25. package/dist/adapters/message-port/handler.d.ts +58 -60
  26. package/dist/adapters/message-port/handler.js +72 -86
  27. package/dist/adapters/message-port/index.d.ts +3 -2
  28. package/dist/adapters/message-port/index.js +2 -2
  29. package/dist/adapters/message-port/rpc-handler.d.ts +9 -9
  30. package/dist/adapters/message-port/rpc-handler.js +17 -14
  31. package/dist/adapters/node/handler.d.ts +17 -15
  32. package/dist/adapters/node/handler.js +20 -20
  33. package/dist/adapters/node/index.d.ts +4 -7
  34. package/dist/adapters/node/index.js +3 -7
  35. package/dist/adapters/node/rpc-handler.d.ts +9 -9
  36. package/dist/adapters/node/rpc-handler.js +17 -14
  37. package/dist/adapters/standard/codec.d.ts +13 -13
  38. package/dist/adapters/standard/handler.d.ts +49 -49
  39. package/dist/adapters/standard/handler.js +205 -205
  40. package/dist/adapters/standard/index.d.ts +7 -6
  41. package/dist/adapters/standard/index.js +4 -5
  42. package/dist/adapters/standard/plugin.d.ts +25 -31
  43. package/dist/adapters/standard/plugin.js +14 -16
  44. package/dist/adapters/standard/rpc-handler-codec.d.ts +39 -43
  45. package/dist/adapters/standard/rpc-handler-codec.js +50 -51
  46. package/dist/adapters/standard/rpc-matcher.d.ts +40 -40
  47. package/dist/adapters/standard/rpc-matcher.js +103 -149
  48. package/dist/adapters/standard/utils.d.ts +8 -8
  49. package/dist/adapters/standard/utils.js +7 -5
  50. package/dist/adapters/standard-peer/index.d.ts +2 -1
  51. package/dist/adapters/standard-peer/index.js +1 -1
  52. package/dist/adapters/standard-peer/utils.d.ts +6 -4
  53. package/dist/adapters/standard-peer/utils.js +12 -6
  54. package/dist/adapters/websocket/handler.d.ts +52 -50
  55. package/dist/adapters/websocket/handler.js +75 -85
  56. package/dist/adapters/websocket/index.d.ts +3 -2
  57. package/dist/adapters/websocket/index.js +2 -2
  58. package/dist/adapters/websocket/rpc-handler.d.ts +9 -9
  59. package/dist/adapters/websocket/rpc-handler.js +17 -14
  60. package/dist/builder-variants.d.ts +195 -195
  61. package/dist/builder.d.ts +103 -104
  62. package/dist/builder.js +198 -224
  63. package/dist/constants.d.ts +1 -1
  64. package/dist/constants.js +4 -2
  65. package/dist/context.d.ts +3 -3
  66. package/dist/extensions/callable.d.ts +11 -11
  67. package/dist/extensions/callable.js +6 -5
  68. package/dist/helpers/base64url.d.ts +1 -1
  69. package/dist/helpers/base64url.js +44 -49
  70. package/dist/helpers/cookie.d.ts +10 -11
  71. package/dist/helpers/cookie.js +56 -63
  72. package/dist/helpers/encryption.d.ts +1 -1
  73. package/dist/helpers/encryption.js +80 -70
  74. package/dist/helpers/index.d.ts +5 -4
  75. package/dist/helpers/index.js +4 -4
  76. package/dist/helpers/signing.d.ts +1 -1
  77. package/dist/helpers/signing.js +72 -82
  78. package/dist/implementer-procedure.d.ts +12 -13
  79. package/dist/implementer-procedure.js +37 -44
  80. package/dist/implementer-router.d.ts +30 -36
  81. package/dist/implementer-router.js +92 -111
  82. package/dist/implementer.d.ts +8 -8
  83. package/dist/implementer.js +28 -35
  84. package/dist/index.d.ts +22 -61
  85. package/dist/index.js +16 -48
  86. package/dist/lazy.d.ts +14 -14
  87. package/dist/lazy.js +19 -30
  88. package/dist/middleware-decorated.d.ts +8 -9
  89. package/dist/middleware-decorated.js +66 -70
  90. package/dist/middleware.d.ts +34 -34
  91. package/dist/plugins/batch.d.ts +75 -75
  92. package/dist/plugins/batch.js +345 -379
  93. package/dist/plugins/cors.d.ts +60 -64
  94. package/dist/plugins/cors.js +118 -111
  95. package/dist/plugins/get-method-csrf-protection.d.ts +8 -6
  96. package/dist/plugins/get-method-csrf-protection.js +47 -63
  97. package/dist/plugins/head-method.d.ts +11 -9
  98. package/dist/plugins/head-method.js +97 -94
  99. package/dist/plugins/index.d.ts +15 -39
  100. package/dist/plugins/index.js +14 -29
  101. package/dist/plugins/method-override.d.ts +30 -28
  102. package/dist/plugins/method-override.js +53 -49
  103. package/dist/plugins/request-compression.d.ts +11 -9
  104. package/dist/plugins/request-compression.js +52 -79
  105. package/dist/plugins/request-headers.d.ts +10 -8
  106. package/dist/plugins/request-headers.js +27 -29
  107. package/dist/plugins/request-limit.d.ts +21 -19
  108. package/dist/plugins/request-limit.js +60 -67
  109. package/dist/plugins/response-compression.d.ts +42 -39
  110. package/dist/plugins/response-compression.js +150 -202
  111. package/dist/plugins/response-headers.d.ts +15 -13
  112. package/dist/plugins/response-headers.js +43 -46
  113. package/dist/plugins/rethrow.d.ts +25 -23
  114. package/dist/plugins/rethrow.js +46 -58
  115. package/dist/plugins/signal-sync.d.ts +7 -5
  116. package/dist/plugins/signal-sync.js +71 -86
  117. package/dist/plugins/timeout.d.ts +29 -27
  118. package/dist/plugins/timeout.js +61 -58
  119. package/dist/procedure-client.d.ts +14 -15
  120. package/dist/procedure-client.js +149 -166
  121. package/dist/procedure-decorated.d.ts +9 -9
  122. package/dist/procedure-decorated.js +36 -44
  123. package/dist/procedure-utils.d.ts +10 -30
  124. package/dist/procedure-utils.js +39 -40
  125. package/dist/procedure.d.ts +60 -60
  126. package/dist/procedure.js +18 -24
  127. package/dist/router-client.d.ts +9 -11
  128. package/dist/router-client.js +33 -41
  129. package/dist/router-hidden.js +10 -12
  130. package/dist/router-utils.d.ts +13 -30
  131. package/dist/router-utils.js +146 -191
  132. package/dist/router.d.ts +12 -26
  133. package/package.json +10 -10
  134. package/dist/adapters/standard/codec.js +0 -1
  135. package/dist/builder-variants.js +0 -1
  136. package/dist/context.js +0 -1
  137. package/dist/middleware.js +0 -1
  138. package/dist/router-hidden.d.ts +0 -5
  139. package/dist/router.js +0 -1
@@ -1,82 +1,55 @@
1
- import { ORPCError } from '@orpc/client';
2
- import { toArray } from '@orpc/shared';
3
- import { flattenStandardHeader } from '@standard-server/core';
4
- import { toFetchHeaders, toStandardBody } from '@standard-server/fetch';
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
5
6
  /**
6
- * Each coding adds a decompressor to the chain, so an unbounded list lets a tiny
7
- * request cost unbounded CPU and memory. Same limit as undici and curl.
8
- */
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
+ */
9
10
  const MAX_CONTENT_ENCODINGS = 5;
10
11
  /**
11
- * Decompresses incoming request bodies based on the Content-Encoding header,
12
- * supporting gzip, deflate, and deflate-raw.
13
- *
14
- * @see {@link https://orpc.dev/docs/plugins/request-compression | Request Compression Plugin}
15
- */
16
- export class RequestCompressionHandlerPlugin {
17
- name = '~request-compression';
18
- /**
19
- * Should decompress the original batch request body instead of sub-requests.
20
- */
21
- after = ['~batch'];
22
- init(options) {
23
- // oxlint-disable-next-line unicorn/consistent-function-scoping
24
- const routingInterceptor = async ({ next, ...interceptorOptions }) => {
25
- const encodings = parseContentEncodings(flattenStandardHeader(interceptorOptions.request.headers['content-encoding']));
26
- if (encodings.length === 0 || !encodings.every(isSupportedEncoding)) {
27
- return next();
28
- }
29
- const decompressedHeaders = {
30
- ...interceptorOptions.request.headers,
31
- 'content-length': undefined,
32
- 'content-encoding': undefined,
33
- };
34
- return next({
35
- ...interceptorOptions,
36
- request: {
37
- ...interceptorOptions.request,
38
- headers: decompressedHeaders,
39
- async resolveBody(hint) {
40
- const stream = await interceptorOptions.request.resolveBody('octet-stream');
41
- // adapter might not support hint (e.g peer adapter)
42
- if (!(stream instanceof ReadableStream)) {
43
- return stream;
44
- }
45
- if (encodings.length > MAX_CONTENT_ENCODINGS) {
46
- throw new ORPCError('UNSUPPORTED_MEDIA_TYPE', {
47
- message: 'Too many content encodings.',
48
- });
49
- }
50
- let decompressedStream = stream;
51
- for (let i = encodings.length - 1; i >= 0; i--) {
52
- decompressedStream = decompressedStream.pipeThrough(new DecompressionStream(encodings[i]));
53
- }
54
- const response = new Response(decompressedStream, {
55
- headers: toFetchHeaders(decompressedHeaders),
56
- });
57
- return toStandardBody(response, { hint });
58
- },
59
- },
60
- });
61
- };
62
- return {
63
- ...options,
64
- routingInterceptors: [routingInterceptor, ...toArray(options.routingInterceptors)],
65
- };
66
- }
67
- }
68
- const SUPPORTED_ENCODINGS = ['gzip', 'deflate', 'deflate-raw'];
69
- function isSupportedEncoding(encoding) {
70
- return SUPPORTED_ENCODINGS.includes(encoding);
71
- }
72
- /**
73
- * Parse Content-Encoding into ordered codings (order applied).
74
- *
75
- * @see https://www.rfc-editor.org/rfc/rfc9110.html#name-content-encoding
76
- */
77
- function parseContentEncodings(header) {
78
- if (header === undefined) {
79
- return [];
80
- }
81
- return header.split(',').map((part) => part.trim().toLowerCase());
82
- }
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 };
@@ -1,14 +1,16 @@
1
- import type { StandardHandlerOptions, StandardHandlerPlugin } from '../adapters/standard/index.ts';
1
+ import { StandardHandlerPlugin } from "../adapters/standard/plugin.js";
2
+ import { StandardHandlerOptions } from "../adapters/standard/handler.js";
3
+ import "../adapters/standard/index.js";
2
4
  /**
3
5
  * The context shape into which the Request Headers Plugin injects `reqHeaders`.
4
6
  *
5
7
  * @see {@link https://orpc.dev/docs/plugins/request-headers | Request Headers Plugin}
6
8
  */
7
9
  export interface RequestHeadersHandlerPluginContext {
8
- /**
9
- * Request headers as a Headers instance. This is injected by the Request Headers Plugin.
10
- */
11
- reqHeaders?: Headers | undefined;
10
+ /**
11
+ * Request headers as a Headers instance. This is injected by the Request Headers Plugin.
12
+ */
13
+ reqHeaders?: Headers | undefined;
12
14
  }
13
15
  /**
14
16
  * The Request Headers Plugin injects a `reqHeaders` instance into the context,
@@ -17,6 +19,6 @@ export interface RequestHeadersHandlerPluginContext {
17
19
  * @see {@link https://orpc.dev/docs/plugins/request-headers | Request Headers Plugin}
18
20
  */
19
21
  export declare class RequestHeadersHandlerPlugin<T extends RequestHeadersHandlerPluginContext> implements StandardHandlerPlugin<T> {
20
- name: string;
21
- init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
22
- }
22
+ name: string;
23
+ init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
24
+ }
@@ -1,30 +1,28 @@
1
- import { toArray } from '@orpc/shared';
2
- import { toFetchHeaders } from '@standard-server/fetch';
1
+ import { toArray } from "@orpc/shared";
2
+ import { toFetchHeaders } from "@standard-server/fetch";
3
+ // src/plugins/request-headers.ts
3
4
  /**
4
- * The Request Headers Plugin injects a `reqHeaders` instance into the context,
5
- * allowing access to request headers in oRPC.
6
- *
7
- * @see {@link https://orpc.dev/docs/plugins/request-headers | Request Headers Plugin}
8
- */
9
- export class RequestHeadersHandlerPlugin {
10
- name = '~request-headers';
11
- init(options) {
12
- return {
13
- ...options,
14
- interceptors: [
15
- (interceptorOptions) => {
16
- const reqHeaders = interceptorOptions.context.reqHeaders ??
17
- toFetchHeaders(interceptorOptions.request.headers);
18
- return interceptorOptions.next({
19
- ...interceptorOptions,
20
- context: {
21
- ...interceptorOptions.context,
22
- reqHeaders,
23
- },
24
- });
25
- },
26
- ...toArray(options.interceptors),
27
- ],
28
- };
29
- }
30
- }
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 };
@@ -1,10 +1,12 @@
1
- import type { StandardHandlerOptions, StandardHandlerPlugin } from '../adapters/standard/index.ts';
2
- import type { Context } from '../context.ts';
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";
3
5
  export interface RequestLimitHandlerPluginOptions {
4
- /**
5
- * The maximum allowed request body size in bytes.
6
- */
7
- maxBodySize: number;
6
+ /**
7
+ * The maximum allowed request body size in bytes.
8
+ */
9
+ maxBodySize: number;
8
10
  }
9
11
  /**
10
12
  * Rejects requests whose body exceeds `maxBodySize`.
@@ -15,16 +17,16 @@ export interface RequestLimitHandlerPluginOptions {
15
17
  * @see {@link https://orpc.dev/docs/plugins/request-limit | Request Limit Plugin}
16
18
  */
17
19
  export declare class RequestLimitHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
18
- name: string;
19
- /**
20
- * Should limit the original batch request body instead of sub-requests.
21
- */
22
- after: string[];
23
- /**
24
- * Should limit the final body size instead of the compressed one.
25
- */
26
- before: string[];
27
- private readonly maxBodySize;
28
- constructor(options: RequestLimitHandlerPluginOptions);
29
- init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
30
- }
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
+ }
@@ -1,68 +1,61 @@
1
- import { ORPCError } from '@orpc/client';
2
- import { toArray } from '@orpc/shared';
3
- import { flattenStandardHeader } from '@standard-server/core';
4
- import { toFetchHeaders, toStandardBody } from '@standard-server/fetch';
1
+ import { 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-limit.ts
5
6
  /**
6
- * Rejects requests whose body exceeds `maxBodySize`.
7
- *
8
- * When used with the request compression plugin, the limit applies to the
9
- * decompressed payload rather than the compressed wire size.
10
- *
11
- * @see {@link https://orpc.dev/docs/plugins/request-limit | Request Limit Plugin}
12
- */
13
- export class RequestLimitHandlerPlugin {
14
- name = '~request-limit';
15
- /**
16
- * Should limit the original batch request body instead of sub-requests.
17
- */
18
- after = ['~batch'];
19
- /**
20
- * Should limit the final body size instead of the compressed one.
21
- */
22
- before = ['~request-compression'];
23
- maxBodySize;
24
- constructor(options) {
25
- this.maxBodySize = options.maxBodySize;
26
- }
27
- init(options) {
28
- const maxBodySize = this.maxBodySize;
29
- const routingInterceptor = async ({ next, ...interceptorOptions }) => {
30
- return next({
31
- ...interceptorOptions,
32
- request: {
33
- ...interceptorOptions.request,
34
- async resolveBody(hint) {
35
- const contentLength = Number(flattenStandardHeader(interceptorOptions.request.headers['content-length']));
36
- if (Number.isFinite(contentLength) && contentLength > maxBodySize) {
37
- throw new ORPCError('PAYLOAD_TOO_LARGE');
38
- }
39
- const stream = await interceptorOptions.request.resolveBody('octet-stream');
40
- // adapter might not support hint (e.g. peer adapter)
41
- if (!(stream instanceof ReadableStream)) {
42
- return stream;
43
- }
44
- let currentBodySize = 0;
45
- const limitedStream = stream.pipeThrough(new TransformStream({
46
- transform(chunk, controller) {
47
- currentBodySize += chunk.byteLength;
48
- if (currentBodySize > maxBodySize) {
49
- controller.error(new ORPCError('PAYLOAD_TOO_LARGE'));
50
- return;
51
- }
52
- controller.enqueue(chunk);
53
- },
54
- }));
55
- const response = new Response(limitedStream, {
56
- headers: toFetchHeaders(interceptorOptions.request.headers),
57
- });
58
- return toStandardBody(response, { hint });
59
- },
60
- },
61
- });
62
- };
63
- return {
64
- ...options,
65
- routingInterceptors: [routingInterceptor, ...toArray(options.routingInterceptors)],
66
- };
67
- }
68
- }
7
+ * Rejects requests whose body exceeds `maxBodySize`.
8
+ *
9
+ * When used with the request compression plugin, the limit applies to the
10
+ * decompressed payload rather than the compressed wire size.
11
+ *
12
+ * @see {@link https://orpc.dev/docs/plugins/request-limit | Request Limit Plugin}
13
+ */
14
+ var RequestLimitHandlerPlugin = class {
15
+ name = "~request-limit";
16
+ /**
17
+ * Should limit the original batch request body instead of sub-requests.
18
+ */
19
+ after = ["~batch"];
20
+ /**
21
+ * Should limit the final body size instead of the compressed one.
22
+ */
23
+ before = ["~request-compression"];
24
+ maxBodySize;
25
+ constructor(options) {
26
+ this.maxBodySize = options.maxBodySize;
27
+ }
28
+ init(options) {
29
+ const maxBodySize = this.maxBodySize;
30
+ const routingInterceptor = async ({ next, ...interceptorOptions }) => {
31
+ return next({
32
+ ...interceptorOptions,
33
+ request: {
34
+ ...interceptorOptions.request,
35
+ async resolveBody(hint) {
36
+ const contentLength = Number(flattenStandardHeader(interceptorOptions.request.headers["content-length"]));
37
+ if (Number.isFinite(contentLength) && contentLength > maxBodySize) throw new ORPCError("PAYLOAD_TOO_LARGE");
38
+ const stream = await interceptorOptions.request.resolveBody("octet-stream");
39
+ if (!(stream instanceof ReadableStream)) return stream;
40
+ let currentBodySize = 0;
41
+ const limitedStream = stream.pipeThrough(new TransformStream({ transform(chunk, controller) {
42
+ currentBodySize += chunk.byteLength;
43
+ if (currentBodySize > maxBodySize) {
44
+ controller.error(new ORPCError("PAYLOAD_TOO_LARGE"));
45
+ return;
46
+ }
47
+ controller.enqueue(chunk);
48
+ } }));
49
+ const response = new Response(limitedStream, { headers: toFetchHeaders(interceptorOptions.request.headers) });
50
+ return toStandardBody(response, { hint });
51
+ }
52
+ }
53
+ });
54
+ };
55
+ return {
56
+ ...options,
57
+ routingInterceptors: [routingInterceptor, ...toArray(options.routingInterceptors)]
58
+ };
59
+ }
60
+ };
61
+ export { RequestLimitHandlerPlugin };
@@ -1,31 +1,34 @@
1
- import type { StandardHeaders, StandardResponse } from '@standard-server/core';
2
- import type { StandardHandlerOptions, StandardHandlerPlugin, StandardHandlerRoutingInterceptorOptions } from '../adapters/standard/index.ts';
3
- import type { Context } from '../context.ts';
1
+ import "../adapters/standard/index.js";
2
+ import { StandardHandlerPlugin } from "../adapters/standard/plugin.js";
3
+ import { StandardHandlerOptions, StandardHandlerRoutingInterceptorOptions } from "../adapters/standard/handler.js";
4
+ import { Context } from "../context.js";
5
+ import { CompressionEncoding } from "@orpc/shared";
6
+ import { StandardHeaders, StandardResponse } from "@standard-server/core";
4
7
  export interface ResponseCompressionHandlerPluginOptions<T extends Context> {
5
- /**
6
- * The compression schemes to use for response compression.
7
- * Schemes are prioritized by their order in this array and
8
- * only applied if the client supports them (via Accept-Encoding).
9
- *
10
- * @default ['gzip', 'deflate']
11
- */
12
- encodings?: readonly ('gzip' | 'deflate' | 'deflate-raw')[] | undefined;
13
- /**
14
- * The minimum response size in bytes required to trigger compression.
15
- * Responses smaller than this threshold will not be compressed to avoid overhead.
16
- * If the response size cannot be determined, compression will still be applied.
17
- *
18
- * @default 1024 (1KB)
19
- */
20
- threshold?: number | undefined;
21
- /**
22
- * Determines whether a response with the given Content-Type should be compressed.
23
- * Only consulted for binary transfers (streams, files, and file form-data parts).
24
- * Also receives the routing interceptor options for per-request decisions.
25
- *
26
- * @default isCompressibleContentType (covers common text-based formats)
27
- */
28
- isCompressibleContentType?: ((contentType: string | null | undefined, options: StandardHandlerRoutingInterceptorOptions<T>) => boolean) | undefined;
8
+ /**
9
+ * The compression schemes to use for response compression.
10
+ * Schemes are prioritized by their order in this array and
11
+ * only applied if the client supports them (via Accept-Encoding).
12
+ *
13
+ * @default ['gzip', 'deflate']
14
+ */
15
+ encodings?: readonly CompressionEncoding[] | undefined;
16
+ /**
17
+ * The minimum response size in bytes required to trigger compression.
18
+ * Responses smaller than this threshold will not be compressed to avoid overhead.
19
+ * If the response size cannot be determined, compression will still be applied.
20
+ *
21
+ * @default 1024 (1KB)
22
+ */
23
+ threshold?: number | undefined;
24
+ /**
25
+ * Determines whether a response with the given Content-Type should be compressed.
26
+ * Only consulted for binary transfers (streams, files, and file form-data parts).
27
+ * Also receives the routing interceptor options for per-request decisions.
28
+ *
29
+ * @default isCompressibleContentType (covers common text-based formats)
30
+ */
31
+ isCompressibleContentType?: ((contentType: string | null | undefined, options: StandardHandlerRoutingInterceptorOptions<T>) => boolean) | undefined;
29
32
  }
30
33
  /**
31
34
  * Compresses response bodies based on the client's Accept-Encoding header.
@@ -34,17 +37,17 @@ export interface ResponseCompressionHandlerPluginOptions<T extends Context> {
34
37
  * @see {@link https://orpc.dev/docs/plugins/response-compression | Response Compression Plugin}
35
38
  */
36
39
  export declare class ResponseCompressionHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
37
- name: string;
38
- /**
39
- * Compression should be done after batching, to compress the final response.
40
- * Compression should also be done after response headers are set, to access final headers like Content-Type and Cache-Control.
41
- */
42
- after: string[];
43
- private readonly encodings;
44
- private readonly threshold;
45
- private readonly isCompressibleContentType;
46
- constructor(options?: ResponseCompressionHandlerPluginOptions<T>);
47
- init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
40
+ name: string;
41
+ /**
42
+ * Compression should be done after batching, to compress the final response.
43
+ * Compression should also be done after response headers are set, to access final headers like Content-Type and Cache-Control.
44
+ */
45
+ after: string[];
46
+ private readonly encodings;
47
+ private readonly threshold;
48
+ private readonly isCompressibleContentType;
49
+ constructor(options?: ResponseCompressionHandlerPluginOptions<T>);
50
+ init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
48
51
  }
49
52
  /**
50
53
  * Picks the first of `encodings` the client accepts, or `undefined` when the response
@@ -56,4 +59,4 @@ export declare function negotiateResponseCompressionEncoding<TEncoding extends s
56
59
  * The headers of a response whose body is compressed with `encoding`.
57
60
  * Shared by the response compression plugins so compressed responses carry the same headers.
58
61
  */
59
- export declare function toCompressedHeaders(headers: StandardHeaders, encoding: string): StandardHeaders;
62
+ export declare function toCompressedHeaders(headers: StandardHeaders, encoding: string): StandardHeaders;