@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,56 +1,52 @@
1
- import type { Promisable, Value } from '@orpc/shared';
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 { Promisable, Value } from "@orpc/shared";
4
6
  export interface CORSHandlerPluginOptions<T extends Context> {
5
- /**
6
- * Configures the `Access-Control-Allow-Origin` header.
7
- * Can be a string, an array of allowed origins, or a function (optionally async) that returns the allowed origin(s).
8
- *
9
- * A function must only return origins it has validated: returning the incoming origin
10
- * unchecked allows every origin.
11
- *
12
- * @default '*'
13
- */
14
- origin?: Value<Promisable<string | readonly string[] | null | undefined>, [
15
- origin: string,
16
- options: StandardHandlerRoutingInterceptorOptions<T>
17
- ]> | undefined;
18
- /**
19
- * Configures the `Timing-Allow-Origin` header.
20
- * Can be a string, an array of allowed origins, or a function (optionally async) that returns the allowed origin(s).
21
- */
22
- timingOrigin?: Value<Promisable<string | readonly string[] | null | undefined>, [
23
- origin: string,
24
- options: StandardHandlerRoutingInterceptorOptions<T>
25
- ]> | undefined;
26
- /**
27
- * Configures the `Access-Control-Allow-Methods` header for preflight requests.
28
- *
29
- * @default ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH', 'QUERY']
30
- */
31
- allowMethods?: readonly string[] | undefined;
32
- /**
33
- * Configures the `Access-Control-Allow-Headers` header for preflight requests.
34
- * Falls back to the request's `Access-Control-Request-Headers` if not set.
35
- * When set, it replaces that fallback, so include every non-safelisted header
36
- * clients send, such as `Content-Type`.
37
- */
38
- allowHeaders?: readonly string[] | undefined;
39
- /**
40
- * Configures the `Access-Control-Max-Age` header (in seconds) for preflight requests.
41
- */
42
- maxAge?: number | undefined;
43
- /**
44
- * Configures the `Access-Control-Allow-Credentials` header.
45
- *
46
- * When enabled, `origin` must allow trusted origins only: every allowed origin can send
47
- * authenticated requests as your users and read the responses.
48
- */
49
- credentials?: boolean | undefined;
50
- /**
51
- * Configures the `Access-Control-Expose-Headers` header.
52
- */
53
- exposeHeaders?: readonly string[] | undefined;
7
+ /**
8
+ * Configures the `Access-Control-Allow-Origin` header.
9
+ * Can be a string, an array of allowed origins, or a function (optionally async) that returns the allowed origin(s).
10
+ *
11
+ * A function must only return origins it has validated: returning the incoming origin
12
+ * unchecked allows every origin.
13
+ *
14
+ * @default '*'
15
+ */
16
+ origin?: Value<Promisable<string | readonly string[] | null | undefined>, [origin: string, options: StandardHandlerRoutingInterceptorOptions<T>]> | undefined;
17
+ /**
18
+ * Configures the `Timing-Allow-Origin` header.
19
+ * Can be a string, an array of allowed origins, or a function (optionally async) that returns the allowed origin(s).
20
+ */
21
+ timingOrigin?: Value<Promisable<string | readonly string[] | null | undefined>, [origin: string, options: StandardHandlerRoutingInterceptorOptions<T>]> | undefined;
22
+ /**
23
+ * Configures the `Access-Control-Allow-Methods` header for preflight requests.
24
+ *
25
+ * @default ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH', 'QUERY']
26
+ */
27
+ allowMethods?: readonly string[] | undefined;
28
+ /**
29
+ * Configures the `Access-Control-Allow-Headers` header for preflight requests.
30
+ * Falls back to the request's `Access-Control-Request-Headers` if not set.
31
+ * When set, it replaces that fallback, so include every non-safelisted header
32
+ * clients send, such as `Content-Type`.
33
+ */
34
+ allowHeaders?: readonly string[] | undefined;
35
+ /**
36
+ * Configures the `Access-Control-Max-Age` header (in seconds) for preflight requests.
37
+ */
38
+ maxAge?: number | undefined;
39
+ /**
40
+ * Configures the `Access-Control-Allow-Credentials` header.
41
+ *
42
+ * When enabled, `origin` must allow trusted origins only: every allowed origin can send
43
+ * authenticated requests as your users and read the responses.
44
+ */
45
+ credentials?: boolean | undefined;
46
+ /**
47
+ * Configures the `Access-Control-Expose-Headers` header.
48
+ */
49
+ exposeHeaders?: readonly string[] | undefined;
54
50
  }
55
51
  /**
56
52
  * Configures the [CORS Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
@@ -59,15 +55,15 @@ export interface CORSHandlerPluginOptions<T extends Context> {
59
55
  * @see {@link https://orpc.dev/docs/plugins/cors | CORS Handler Plugin}
60
56
  */
61
57
  export declare class CORSHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
62
- private readonly options;
63
- name: string;
64
- /**
65
- * - Do not create spans for CORS preflight requests.
66
- * - Run CORS interceptors before batch interceptors so headers are applied to
67
- * the actual response rather than sub-responses.
68
- */
69
- after: string[];
70
- constructor(options?: CORSHandlerPluginOptions<T>);
71
- init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
72
- private resolveOrigin;
73
- }
58
+ private readonly options;
59
+ name: string;
60
+ /**
61
+ * - Do not create spans for CORS preflight requests.
62
+ * - Run CORS interceptors before batch interceptors so headers are applied to
63
+ * the actual response rather than sub-responses.
64
+ */
65
+ after: string[];
66
+ constructor(options?: CORSHandlerPluginOptions<T>);
67
+ init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
68
+ private resolveOrigin;
69
+ }
@@ -1,112 +1,119 @@
1
- import { toArray } from '@orpc/shared';
2
- import { flattenStandardHeader } from '@standard-server/core';
1
+ import { toArray } from "@orpc/shared";
2
+ import { flattenStandardHeader } from "@standard-server/core";
3
+ // src/plugins/cors.ts
3
4
  /**
4
- * Configures the [CORS Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
5
- * for your API, including preflight requests.
6
- *
7
- * @see {@link https://orpc.dev/docs/plugins/cors | CORS Handler Plugin}
8
- */
9
- export class CORSHandlerPlugin {
10
- options;
11
- name = '~cors';
12
- /**
13
- * - Do not create spans for CORS preflight requests.
14
- * - Run CORS interceptors before batch interceptors so headers are applied to
15
- * the actual response rather than sub-responses.
16
- */
17
- after = ['~tracing', '~batch'];
18
- constructor(options = {}) {
19
- const defaults = {
20
- origin: '*',
21
- allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH', 'QUERY'],
22
- };
23
- this.options = {
24
- ...defaults,
25
- ...options,
26
- };
27
- }
28
- init(options) {
29
- const corsHeadersInterceptor = async (interceptorOptions) => {
30
- const result = await interceptorOptions.next();
31
- if (!result.matched) {
32
- return result;
33
- }
34
- const resHeaders = { ...result.response.headers };
35
- const origin = flattenStandardHeader(interceptorOptions.request.headers.origin);
36
- const allowOrigin = await this.resolveOrigin(this.options.origin, origin, interceptorOptions);
37
- const timingAllowOrigin = await this.resolveOrigin(this.options.timingOrigin, origin, interceptorOptions);
38
- if (allowOrigin.value !== undefined) {
39
- resHeaders['access-control-allow-origin'] = allowOrigin.value;
40
- }
41
- if (timingAllowOrigin.value !== undefined) {
42
- resHeaders['timing-allow-origin'] = timingAllowOrigin.value;
43
- }
44
- if (allowOrigin.varies || timingAllowOrigin.varies) {
45
- const existingVary = flattenStandardHeader(resHeaders.vary);
46
- if (!existingVary?.split(',').some((v) => v.trim().toLowerCase() === 'origin')) {
47
- resHeaders.vary = existingVary ? `${existingVary}, Origin` : 'Origin';
48
- }
49
- }
50
- if (this.options.credentials) {
51
- resHeaders['access-control-allow-credentials'] = 'true';
52
- }
53
- if (this.options.exposeHeaders?.length) {
54
- resHeaders['access-control-expose-headers'] = flattenStandardHeader(this.options.exposeHeaders);
55
- }
56
- return { ...result, response: { ...result.response, headers: resHeaders } };
57
- };
58
- const preflightInterceptor = async (interceptorOptions) => {
59
- if (interceptorOptions.request.method === 'OPTIONS') {
60
- const resHeaders = {};
61
- if (this.options.maxAge !== undefined) {
62
- resHeaders['access-control-max-age'] = this.options.maxAge.toString();
63
- }
64
- if (this.options.allowMethods?.length) {
65
- resHeaders['access-control-allow-methods'] = flattenStandardHeader(this.options.allowMethods);
66
- }
67
- const allowHeaders = this.options.allowHeaders ??
68
- interceptorOptions.request.headers['access-control-request-headers'];
69
- if (typeof allowHeaders === 'string' || allowHeaders?.length) {
70
- resHeaders['access-control-allow-headers'] = flattenStandardHeader(allowHeaders);
71
- }
72
- return {
73
- matched: true,
74
- response: {
75
- status: 204,
76
- headers: resHeaders,
77
- body: undefined,
78
- },
79
- };
80
- }
81
- return interceptorOptions.next();
82
- };
83
- return {
84
- ...options,
85
- routingInterceptors: [
86
- corsHeadersInterceptor,
87
- preflightInterceptor,
88
- ...toArray(options.routingInterceptors),
89
- ],
90
- };
91
- }
92
- async resolveOrigin(option, origin, interceptorOptions) {
93
- if (typeof option === 'function') {
94
- if (origin === undefined) {
95
- return { value: undefined, varies: true };
96
- }
97
- const allowed = toArray(await option(origin, interceptorOptions));
98
- if (allowed.includes('*')) {
99
- return { value: '*', varies: true };
100
- }
101
- return { value: allowed.includes(origin) ? origin : undefined, varies: true };
102
- }
103
- const allowed = toArray(await option);
104
- if (allowed.includes('*')) {
105
- return { value: '*', varies: false };
106
- }
107
- if (origin !== undefined && allowed.includes(origin)) {
108
- return { value: origin, varies: true };
109
- }
110
- return { value: undefined, varies: allowed.length > 0 };
111
- }
112
- }
5
+ * Configures the [CORS Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
6
+ * for your API, including preflight requests.
7
+ *
8
+ * @see {@link https://orpc.dev/docs/plugins/cors | CORS Handler Plugin}
9
+ */
10
+ var CORSHandlerPlugin = class {
11
+ options;
12
+ name = "~cors";
13
+ /**
14
+ * - Do not create spans for CORS preflight requests.
15
+ * - Run CORS interceptors before batch interceptors so headers are applied to
16
+ * the actual response rather than sub-responses.
17
+ */
18
+ after = ["~tracing", "~batch"];
19
+ constructor(options = {}) {
20
+ const defaults = {
21
+ origin: "*",
22
+ allowMethods: [
23
+ "GET",
24
+ "HEAD",
25
+ "PUT",
26
+ "POST",
27
+ "DELETE",
28
+ "PATCH",
29
+ "QUERY"
30
+ ]
31
+ };
32
+ this.options = {
33
+ ...defaults,
34
+ ...options
35
+ };
36
+ }
37
+ init(options) {
38
+ const corsHeadersInterceptor = async (interceptorOptions) => {
39
+ const result = await interceptorOptions.next();
40
+ if (!result.matched) return result;
41
+ const resHeaders = { ...result.response.headers };
42
+ const origin = flattenStandardHeader(interceptorOptions.request.headers.origin);
43
+ const allowOrigin = await this.resolveOrigin(this.options.origin, origin, interceptorOptions);
44
+ const timingAllowOrigin = await this.resolveOrigin(this.options.timingOrigin, origin, interceptorOptions);
45
+ if (allowOrigin.value !== void 0) resHeaders["access-control-allow-origin"] = allowOrigin.value;
46
+ if (timingAllowOrigin.value !== void 0) resHeaders["timing-allow-origin"] = timingAllowOrigin.value;
47
+ if (allowOrigin.varies || timingAllowOrigin.varies) {
48
+ const existingVary = flattenStandardHeader(resHeaders.vary);
49
+ if (!existingVary?.split(",").some((v) => v.trim().toLowerCase() === "origin")) resHeaders.vary = existingVary ? `${existingVary}, Origin` : "Origin";
50
+ }
51
+ if (this.options.credentials) resHeaders["access-control-allow-credentials"] = "true";
52
+ if (this.options.exposeHeaders?.length) resHeaders["access-control-expose-headers"] = flattenStandardHeader(this.options.exposeHeaders);
53
+ return {
54
+ ...result,
55
+ response: {
56
+ ...result.response,
57
+ headers: resHeaders
58
+ }
59
+ };
60
+ };
61
+ const preflightInterceptor = async (interceptorOptions) => {
62
+ if (interceptorOptions.request.method === "OPTIONS") {
63
+ const resHeaders = {};
64
+ if (this.options.maxAge !== void 0) resHeaders["access-control-max-age"] = this.options.maxAge.toString();
65
+ if (this.options.allowMethods?.length) resHeaders["access-control-allow-methods"] = flattenStandardHeader(this.options.allowMethods);
66
+ const allowHeaders = this.options.allowHeaders ?? interceptorOptions.request.headers["access-control-request-headers"];
67
+ if (typeof allowHeaders === "string" || allowHeaders?.length) resHeaders["access-control-allow-headers"] = flattenStandardHeader(allowHeaders);
68
+ return {
69
+ matched: true,
70
+ response: {
71
+ status: 204,
72
+ headers: resHeaders,
73
+ body: void 0
74
+ }
75
+ };
76
+ }
77
+ return interceptorOptions.next();
78
+ };
79
+ return {
80
+ ...options,
81
+ routingInterceptors: [
82
+ corsHeadersInterceptor,
83
+ preflightInterceptor,
84
+ ...toArray(options.routingInterceptors)
85
+ ]
86
+ };
87
+ }
88
+ async resolveOrigin(option, origin, interceptorOptions) {
89
+ if (typeof option === "function") {
90
+ if (origin === void 0) return {
91
+ value: void 0,
92
+ varies: true
93
+ };
94
+ const allowed = toArray(await option(origin, interceptorOptions));
95
+ if (allowed.includes("*")) return {
96
+ value: "*",
97
+ varies: true
98
+ };
99
+ return {
100
+ value: allowed.includes(origin) ? origin : void 0,
101
+ varies: true
102
+ };
103
+ }
104
+ const allowed = toArray(await option);
105
+ if (allowed.includes("*")) return {
106
+ value: "*",
107
+ varies: false
108
+ };
109
+ if (origin !== void 0 && allowed.includes(origin)) return {
110
+ value: origin,
111
+ varies: true
112
+ };
113
+ return {
114
+ value: void 0,
115
+ varies: allowed.length > 0
116
+ };
117
+ }
118
+ };
119
+ export { CORSHandlerPlugin };
@@ -1,5 +1,7 @@
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
  /**
4
6
  * Adds Cross-Site Request Forgery (CSRF) protection that makes the safe `GET` method as
5
7
  * secure as unsafe ones such as `POST`. It rejects `GET` requests arriving as top-level
@@ -17,7 +19,7 @@ import type { Context } from '../context.ts';
17
19
  * @see {@link https://orpc.dev/docs/plugins/get-method-csrf-protection | GET Method CSRF Protection Plugin}
18
20
  */
19
21
  export declare class GetMethodCsrfProtectionHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
20
- name: string;
21
- init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
22
- private isAllowed;
23
- }
22
+ name: string;
23
+ init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
24
+ private isAllowed;
25
+ }
@@ -1,64 +1,48 @@
1
- import { ORPCError } from '@orpc/client';
2
- import { toArray } from '@orpc/shared';
3
- import { flattenStandardHeader } from '@standard-server/core';
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
4
5
  /**
5
- * Adds Cross-Site Request Forgery (CSRF) protection that makes the safe `GET` method as
6
- * secure as unsafe ones such as `POST`. It rejects `GET` requests arriving as top-level
7
- * navigations initiated cross-site or from outside the browser, the only context where
8
- * another site can make a browser attach `SameSite=Lax` cookies to a safe-method request.
9
- * Requests matching no procedure stay unmatched, so they can fall through to whatever
10
- * serves the rest of the site.
11
- *
12
- * @remarks
13
- * **Note**: Requests browsers send without `SameSite=Lax` cookies, such as cross-site `fetch`
14
- * and `<img>`, pass through, so procedures stay reachable from other sites. This safeguard
15
- * requires authentication cookies explicitly marked `SameSite=Lax` or `SameSite=Strict`,
16
- * since browsers may attach other cookies to the requests that pass.
17
- *
18
- * @see {@link https://orpc.dev/docs/plugins/get-method-csrf-protection | GET Method CSRF Protection Plugin}
19
- */
20
- export class GetMethodCsrfProtectionHandlerPlugin {
21
- name = '~get-method-csrf-protection';
22
- init(options) {
23
- /**
24
- * Batch sub-requests are judged individually here, which is safe: navigations cannot
25
- * carry the custom `orpc-batch` header, and the batch plugin's default `mapSubrequest`
26
- * keeps the transport headers authoritative over client-authored sub-request headers.
27
- */
28
- const interceptor = (interceptorOptions) => {
29
- if (this.isAllowed(interceptorOptions)) {
30
- return interceptorOptions.next();
31
- }
32
- throw new ORPCError('FORBIDDEN', { message: 'Request blocked by CSRF protection.' });
33
- };
34
- return {
35
- ...options,
36
- interceptors: [interceptor, ...toArray(options.interceptors)],
37
- };
38
- }
39
- isAllowed({ request }) {
40
- // Navigations can only use `GET` or `POST` per the HTML spec, and `POST` is unsafe, so
41
- // `GET` is the only method `SameSite=Lax` cookies ride cross-site.
42
- if (request.method !== 'GET') {
43
- return true;
44
- }
45
- const site = flattenStandardHeader(request.headers['sec-fetch-site'])?.toLowerCase();
46
- // Absent for non-browser clients, browsers too old to send Fetch Metadata, and any browser
47
- // over plain HTTP, where the headers are never appended. Nothing to judge in those cases.
48
- // Same-site origins are trusted, matching the `SameSite` cookie model where the site is
49
- // the trust boundary.
50
- if (site === undefined || site === 'same-origin' || site === 'same-site') {
51
- return true;
52
- }
53
- // Cross-site, and on browser-initiated requests such as email links, `Lax` cookies ride
54
- // only top-level navigations: mode `navigate` targeting dest `document`. Embedded
55
- // navigations such as `<iframe>` pass, since they are not top-level. Browsers send both
56
- // headers together, so a stripped one blocks the request rather than bypassing the check.
57
- const mode = flattenStandardHeader(request.headers['sec-fetch-mode'])?.toLowerCase();
58
- const dest = flattenStandardHeader(request.headers['sec-fetch-dest'])?.toLowerCase();
59
- if (mode === undefined || dest === undefined) {
60
- return false;
61
- }
62
- return mode !== 'navigate' || dest !== 'document';
63
- }
64
- }
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 };
@@ -1,5 +1,7 @@
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
  /**
4
6
  * Answers `HEAD` requests with the headers of the matching `GET` procedure, like Fastify's
5
7
  * `exposeHeadRoutes`, so clients can check a resource's existence, type, and size without
@@ -14,10 +16,10 @@ import type { Context } from '../context.ts';
14
16
  * @see {@link https://orpc.dev/docs/plugins/head-method | HEAD Method Plugin}
15
17
  */
16
18
  export declare class HeadMethodHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
17
- name: string;
18
- /**
19
- * Discard the body after response compression, so `HEAD` reports the same `Content-Encoding` as `GET`.
20
- */
21
- after: string[];
22
- init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
23
- }
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
+ }