@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,51 +1,50 @@
1
- import { COMMON_ERROR_STATUS_MAP, RPCSerializer } from '@orpc/client';
2
- import { getOwn, parseEmptyableJSON, value } from '@orpc/shared';
3
- import { parseStandardUrl } from '@standard-server/core';
4
- import { DEFAULT_ERROR_STATUS, DEFAULT_SUCCESS_STATUS } from '../../constants.js';
5
- import { RPCMatcher } from './rpc-matcher.js';
6
- export class RPCHandlerCodec {
7
- matcher;
8
- serializer;
9
- errorStatusMap;
10
- outputStatus;
11
- constructor(router, options = {}) {
12
- this.matcher = new RPCMatcher(router, options);
13
- this.serializer = options.serializer ?? new RPCSerializer();
14
- this.errorStatusMap = options.errorStatusMap ?? COMMON_ERROR_STATUS_MAP;
15
- this.outputStatus = options.outputStatus ?? DEFAULT_SUCCESS_STATUS;
16
- }
17
- async resolveProcedure(request, options) {
18
- const [pathname, query] = parseStandardUrl(request.url);
19
- const matched = await this.matcher.match(request.method, pathname, options.prefix);
20
- if (!matched) {
21
- return undefined;
22
- }
23
- return {
24
- procedure: matched.procedure,
25
- path: matched.path,
26
- decodeInput: async () => {
27
- if (request.method === 'GET') {
28
- const dataString = new URLSearchParams(query).getAll('data').at(-1);
29
- return this.serializer.deserialize(parseEmptyableJSON(dataString));
30
- }
31
- const body = await request.resolveBody();
32
- return this.serializer.deserialize(body);
33
- },
34
- };
35
- }
36
- encodeOutput(output, procedure, path, options) {
37
- return {
38
- headers: {},
39
- status: value(this.outputStatus, output, procedure, path, options),
40
- body: this.serializer.serialize(output),
41
- };
42
- }
43
- encodeError(error, _procedure, _path, _options) {
44
- const status = getOwn(this.errorStatusMap, error.code) ?? DEFAULT_ERROR_STATUS;
45
- return {
46
- headers: {},
47
- status,
48
- body: this.serializer.serialize(error.toJSON()),
49
- };
50
- }
51
- }
1
+ import "../../constants.js";
2
+ import { RPCMatcher } from "./rpc-matcher.js";
3
+ import { getOwn, parseEmptyableJSON, value } from "@orpc/shared";
4
+ import { COMMON_ERROR_STATUS_MAP, RPCSerializer } from "@orpc/client";
5
+ import { parseStandardUrl } from "@standard-server/core";
6
+ // src/adapters/standard/rpc-handler-codec.ts
7
+ var RPCHandlerCodec = class {
8
+ matcher;
9
+ serializer;
10
+ errorStatusMap;
11
+ outputStatus;
12
+ constructor(router, options = {}) {
13
+ this.matcher = new RPCMatcher(router, options);
14
+ this.serializer = options.serializer ?? new RPCSerializer();
15
+ this.errorStatusMap = options.errorStatusMap ?? COMMON_ERROR_STATUS_MAP;
16
+ this.outputStatus = options.outputStatus ?? 200;
17
+ }
18
+ async resolveProcedure(request, options) {
19
+ const [pathname, query] = parseStandardUrl(request.url);
20
+ const matched = await this.matcher.match(request.method, pathname, options.prefix);
21
+ if (!matched) return;
22
+ return {
23
+ procedure: matched.procedure,
24
+ path: matched.path,
25
+ decodeInput: async () => {
26
+ if (request.method === "GET") {
27
+ const dataString = new URLSearchParams(query).getAll("data").at(-1);
28
+ return this.serializer.deserialize(parseEmptyableJSON(dataString));
29
+ }
30
+ const body = await request.resolveBody();
31
+ return this.serializer.deserialize(body);
32
+ }
33
+ };
34
+ }
35
+ encodeOutput(output, procedure, path, options) {
36
+ return {
37
+ headers: {},
38
+ status: value(this.outputStatus, output, procedure, path, options),
39
+ body: this.serializer.serialize(output)
40
+ };
41
+ }
42
+ encodeError(error, _procedure, _path, _options) {
43
+ return {
44
+ headers: {},
45
+ status: getOwn(this.errorStatusMap, error.code) ?? 400,
46
+ body: this.serializer.serialize(error.toJSON())
47
+ };
48
+ }
49
+ };
50
+ export { RPCHandlerCodec };
@@ -1,8 +1,8 @@
1
- import type { AnyProcedureContract } from '@orpc/contract';
2
- import type { Value } from '@orpc/shared';
3
- import type { StandardMethod } from '@standard-server/core';
4
- import type { AnyProcedure } from '../../procedure.ts';
5
- import type { AnyRouter } from '../../router.ts';
1
+ import { AnyProcedure } from "../../procedure.js";
2
+ import { AnyRouter } from "../../router.js";
3
+ import { AnyProcedureContract } from "@orpc/contract";
4
+ import { Value } from "@orpc/shared";
5
+ import { StandardMethod } from "@standard-server/core";
6
6
  /**
7
7
  * Methods that can invoke procedures by default. Browsers cannot trigger them
8
8
  * cross-site without a CORS preflight or an HTML form, unlike `GET`, which a plain
@@ -14,40 +14,40 @@ import type { AnyRouter } from '../../router.ts';
14
14
  */
15
15
  export declare const RPC_DEFAULT_ALLOW_METHODS: readonly StandardMethod[];
16
16
  export interface RPCMatcherOptions {
17
- /**
18
- * Filter which procedures are exposed for matching. Return `false` to exclude.
19
- *
20
- * @default true
21
- */
22
- filter?: Value<boolean, [procedure: AnyProcedureContract | AnyProcedure, path: string[]]> | undefined;
23
- /**
24
- * Restricts which HTTP methods can invoke procedures, either with a list of allowed
25
- * methods or decided per request via a function. Requests using a disallowed method
26
- * are treated as unmatched. `GET` is excluded by default because it is exposed to
27
- * Cross-Site Request Forgery (CSRF) attacks.
28
- *
29
- * @default RPC_DEFAULT_ALLOW_METHODS (['POST', 'PUT', 'PATCH', 'DELETE'])
30
- * @see {@link https://orpc.dev/docs/rpc/handler#supported-http-methods | RPC Handler - Supported HTTP Methods}
31
- */
32
- allowMethods?: readonly StandardMethod[] | ((method: StandardMethod, procedure: AnyProcedure, path: string[]) => boolean) | undefined;
17
+ /**
18
+ * Filter which procedures are exposed for matching. Return `false` to exclude.
19
+ *
20
+ * @default true
21
+ */
22
+ filter?: Value<boolean, [procedure: AnyProcedureContract | AnyProcedure, path: string[]]> | undefined;
23
+ /**
24
+ * Restricts which HTTP methods can invoke procedures, either with a list of allowed
25
+ * methods or decided per request via a function. Requests using a disallowed method
26
+ * are treated as unmatched. `GET` is excluded by default because it is exposed to
27
+ * Cross-Site Request Forgery (CSRF) attacks.
28
+ *
29
+ * @default RPC_DEFAULT_ALLOW_METHODS (['POST', 'PUT', 'PATCH', 'DELETE'])
30
+ * @see {@link https://orpc.dev/docs/rpc/handler#supported-http-methods | RPC Handler - Supported HTTP Methods}
31
+ */
32
+ allowMethods?: readonly StandardMethod[] | ((method: StandardMethod, procedure: AnyProcedure, path: string[]) => boolean) | undefined;
33
33
  }
34
34
  export declare class RPCMatcher {
35
- private readonly filter;
36
- private readonly allowMethodsSet;
37
- private readonly allowMethodsFn;
38
- private readonly rootRouter;
39
- private readonly tree;
40
- private readonly pendingLazyRouters;
41
- /** segment count of the deepest pending key, never lowered so it stays an upper bound */
42
- private maxPendingLazyRouterDepth;
43
- constructor(router: AnyRouter, options?: RPCMatcherOptions);
44
- private index;
45
- match(method: StandardMethod, pathname: `/${string}`, prefix: `/${string}` | undefined): Promise<{
46
- path: string[];
47
- procedure: AnyProcedure;
48
- } | undefined>;
49
- private resolvePendingLazyRouters;
50
- private loadPendingLazyRouter;
51
- private indexPendingLazyRouter;
52
- private resolveProcedure;
53
- }
35
+ private readonly filter;
36
+ private readonly allowMethodsSet;
37
+ private readonly allowMethodsFn;
38
+ private readonly rootRouter;
39
+ private readonly tree;
40
+ private readonly pendingLazyRouters;
41
+ /** segment count of the deepest pending key, never lowered so it stays an upper bound */
42
+ private maxPendingLazyRouterDepth;
43
+ constructor(router: AnyRouter, options?: RPCMatcherOptions);
44
+ private index;
45
+ match(method: StandardMethod, pathname: `/${string}`, prefix: `/${string}` | undefined): Promise<{
46
+ path: string[];
47
+ procedure: AnyProcedure;
48
+ } | undefined>;
49
+ private resolvePendingLazyRouters;
50
+ private loadPendingLazyRouter;
51
+ private indexPendingLazyRouter;
52
+ private resolveProcedure;
53
+ }
@@ -1,152 +1,106 @@
1
- import { normalizeHttpPath, pathToHttpPath, value } from '@orpc/shared';
2
- import { unlazy } from '../../lazy.js';
3
- import { Procedure } from '../../procedure.js';
4
- import { resolveContractProcedure, walkProcedureContractsSync } from '../../router-utils.js';
1
+ import { unlazy } from "../../lazy.js";
2
+ import { Procedure } from "../../procedure.js";
3
+ import { resolveContractProcedure, walkProcedureContractsSync } from "../../router-utils.js";
4
+ import { normalizeHttpPath, pathToHttpPath, stripHttpPathPrefix, value } from "@orpc/shared";
5
+ // src/adapters/standard/rpc-matcher.ts
5
6
  /**
6
- * Methods that can invoke procedures by default. Browsers cannot trigger them
7
- * cross-site without a CORS preflight or an HTML form, unlike `GET`, which a plain
8
- * `<a>` click or redirect can trigger with `SameSite=Lax` cookies attached. Other
9
- * methods (`HEAD`, `OPTIONS`, `QUERY`, ...) have safe semantics that should not
10
- * invoke a procedure that can modify data.
11
- *
12
- * @see {@link https://orpc.dev/docs/rpc/handler#supported-http-methods | RPC Handler - Supported HTTP Methods}
13
- */
14
- export const RPC_DEFAULT_ALLOW_METHODS = [
15
- 'POST',
16
- 'PUT',
17
- 'PATCH',
18
- 'DELETE',
7
+ * Methods that can invoke procedures by default. Browsers cannot trigger them
8
+ * cross-site without a CORS preflight or an HTML form, unlike `GET`, which a plain
9
+ * `<a>` click or redirect can trigger with `SameSite=Lax` cookies attached. Other
10
+ * methods (`HEAD`, `OPTIONS`, `QUERY`, ...) have safe semantics that should not
11
+ * invoke a procedure that can modify data.
12
+ *
13
+ * @see {@link https://orpc.dev/docs/rpc/handler#supported-http-methods | RPC Handler - Supported HTTP Methods}
14
+ */
15
+ const RPC_DEFAULT_ALLOW_METHODS = [
16
+ "POST",
17
+ "PUT",
18
+ "PATCH",
19
+ "DELETE"
19
20
  ];
20
- // `%` or a char `encodeURIComponent` encodes, meaning normalization may change the pathname
21
21
  const NORMALIZABLE_PATHNAME_REGEX = /[^\w\-.!~*'()/]/;
22
- export class RPCMatcher {
23
- filter;
24
- allowMethodsSet;
25
- allowMethodsFn;
26
- rootRouter;
27
- tree = new Map();
28
- pendingLazyRouters = new Map();
29
- /** segment count of the deepest pending key, never lowered so it stays an upper bound */
30
- maxPendingLazyRouterDepth = 0;
31
- constructor(router, options = {}) {
32
- this.filter = options.filter ?? true;
33
- const allowMethods = options.allowMethods ?? RPC_DEFAULT_ALLOW_METHODS;
34
- if (typeof allowMethods !== 'function') {
35
- this.allowMethodsSet = new Set(allowMethods);
36
- }
37
- else {
38
- this.allowMethodsFn = allowMethods;
39
- }
40
- this.rootRouter = router;
41
- this.index(router);
42
- }
43
- index(router, path = []) {
44
- const lazyResults = walkProcedureContractsSync(router, (procedure, procedurePath) => {
45
- if (!value(this.filter, procedure, procedurePath)) {
46
- return;
47
- }
48
- this.tree.set(pathToHttpPath(procedurePath), {
49
- path: procedurePath,
50
- contract: procedure,
51
- // contract-first entries have no implementation yet, resolveProcedure fills it in on demand
52
- procedure: procedure instanceof Procedure ? procedure : undefined,
53
- });
54
- }, path);
55
- for (const result of lazyResults) {
56
- this.pendingLazyRouters.set(pathToHttpPath(result.path), result);
57
- this.maxPendingLazyRouterDepth = Math.max(this.maxPendingLazyRouterDepth, result.path.length);
58
- }
59
- }
60
- async match(method, pathname, prefix) {
61
- if (this.allowMethodsSet && !this.allowMethodsSet.has(method)) {
62
- return undefined;
63
- }
64
- if (prefix) {
65
- if (!pathname.startsWith(prefix)) {
66
- return undefined;
67
- }
68
- const charAfterPrefix = pathname[prefix.length];
69
- if (charAfterPrefix === '/') {
70
- pathname = pathname.slice(prefix.length);
71
- }
72
- else if (charAfterPrefix === undefined) {
73
- pathname = '/';
74
- }
75
- else if (prefix[prefix.length - 1] === '/') {
76
- pathname = pathname.slice(prefix.length - 1);
77
- }
78
- else {
79
- return undefined;
80
- }
81
- }
82
- if (pathname.length > 1 && pathname.endsWith('/')) {
83
- pathname = pathname.slice(0, -1);
84
- }
85
- // most requests `await undefined` so conditionally await it to save a microtask turn
86
- const loading = this.resolvePendingLazyRouters(pathname);
87
- if (loading !== undefined) {
88
- await loading;
89
- }
90
- let entry = this.tree.get(pathname);
91
- if (entry === undefined && NORMALIZABLE_PATHNAME_REGEX.test(pathname)) {
92
- // Retry with a normalized path: users may percent-encode characters that we store
93
- // unencoded ("a%62c" vs "abc"), or leave raw characters that we store encoded
94
- // ("a^b" vs "a%5Eb"), so normalization handles both without duplicate entries.
95
- const normalizedPathname = normalizeHttpPath(pathname);
96
- // most requests `await undefined` so conditionally await it to save a microtask turn
97
- const normalizedLoading = this.resolvePendingLazyRouters(normalizedPathname);
98
- if (normalizedLoading !== undefined) {
99
- await normalizedLoading;
100
- }
101
- entry = this.tree.get(normalizedPathname);
102
- }
103
- if (entry === undefined) {
104
- return undefined;
105
- }
106
- const procedure = entry.procedure ?? (await this.resolveProcedure(entry));
107
- if (this.allowMethodsFn && !this.allowMethodsFn(method, procedure, entry.path)) {
108
- return undefined;
109
- }
110
- return {
111
- path: entry.path,
112
- procedure,
113
- };
114
- }
115
- resolvePendingLazyRouters(pathname) {
116
- if (this.pendingLazyRouters.size === 0) {
117
- return;
118
- }
119
- let slashIndex = 0;
120
- // a pending key has as many segments as its path, so deeper prefixes can never match,
121
- // and scanning them would cost quadratic time on slash-heavy pathnames
122
- for (let depth = 1; slashIndex !== -1 && depth <= this.maxPendingLazyRouterDepth; depth++) {
123
- const nextSlashIndex = pathname.indexOf('/', slashIndex + 1);
124
- const httpPathPrefix = nextSlashIndex === -1 ? pathname : pathname.slice(0, nextSlashIndex);
125
- const pending = this.pendingLazyRouters.get(httpPathPrefix);
126
- if (pending !== undefined) {
127
- return this.loadPendingLazyRouter(httpPathPrefix, pending).then(() => this.resolvePendingLazyRouters(pathname));
128
- }
129
- slashIndex = nextSlashIndex;
130
- }
131
- }
132
- loadPendingLazyRouter(httpPathPrefix, pending) {
133
- if (pending.loading === undefined) {
134
- pending.loading = this.indexPendingLazyRouter(httpPathPrefix, pending).catch((error) => {
135
- pending.loading = undefined;
136
- throw error;
137
- });
138
- }
139
- return pending.loading;
140
- }
141
- async indexPendingLazyRouter(httpPathPrefix, pending) {
142
- const { default: router } = await unlazy(pending.router);
143
- this.index(router, pending.path);
144
- // removed only once indexed, so a concurrent match never observes this router as
145
- // neither pending nor indexed
146
- this.pendingLazyRouters.delete(httpPathPrefix);
147
- }
148
- async resolveProcedure(entry) {
149
- entry.procedure = await resolveContractProcedure(this.rootRouter, entry.contract, entry.path);
150
- return entry.procedure;
151
- }
152
- }
22
+ var RPCMatcher = class {
23
+ filter;
24
+ allowMethodsSet;
25
+ allowMethodsFn;
26
+ rootRouter;
27
+ tree = /* @__PURE__ */ new Map();
28
+ pendingLazyRouters = /* @__PURE__ */ new Map();
29
+ /** segment count of the deepest pending key, never lowered so it stays an upper bound */
30
+ maxPendingLazyRouterDepth = 0;
31
+ constructor(router, options = {}) {
32
+ this.filter = options.filter ?? true;
33
+ const allowMethods = options.allowMethods ?? RPC_DEFAULT_ALLOW_METHODS;
34
+ if (typeof allowMethods !== "function") this.allowMethodsSet = new Set(allowMethods);
35
+ else this.allowMethodsFn = allowMethods;
36
+ this.rootRouter = router;
37
+ this.index(router);
38
+ }
39
+ index(router, path = []) {
40
+ const lazyResults = walkProcedureContractsSync(router, (procedure, procedurePath) => {
41
+ if (!value(this.filter, procedure, procedurePath)) return;
42
+ this.tree.set(pathToHttpPath(procedurePath), {
43
+ path: procedurePath,
44
+ contract: procedure,
45
+ procedure: procedure instanceof Procedure ? procedure : void 0
46
+ });
47
+ }, path);
48
+ for (const result of lazyResults) {
49
+ this.pendingLazyRouters.set(pathToHttpPath(result.path), result);
50
+ this.maxPendingLazyRouterDepth = Math.max(this.maxPendingLazyRouterDepth, result.path.length);
51
+ }
52
+ }
53
+ async match(method, pathname, prefix) {
54
+ if (this.allowMethodsSet && !this.allowMethodsSet.has(method)) return;
55
+ if (prefix) {
56
+ const stripped = stripHttpPathPrefix(pathname, prefix);
57
+ if (stripped === void 0) return;
58
+ pathname = stripped;
59
+ }
60
+ if (pathname.length > 1 && pathname.endsWith("/")) pathname = pathname.slice(0, -1);
61
+ const loading = this.resolvePendingLazyRouters(pathname);
62
+ if (loading !== void 0) await loading;
63
+ let entry = this.tree.get(pathname);
64
+ if (entry === void 0 && NORMALIZABLE_PATHNAME_REGEX.test(pathname)) {
65
+ const normalizedPathname = normalizeHttpPath(pathname);
66
+ const normalizedLoading = this.resolvePendingLazyRouters(normalizedPathname);
67
+ if (normalizedLoading !== void 0) await normalizedLoading;
68
+ entry = this.tree.get(normalizedPathname);
69
+ }
70
+ if (entry === void 0) return;
71
+ const procedure = entry.procedure ?? await this.resolveProcedure(entry);
72
+ if (this.allowMethodsFn && !this.allowMethodsFn(method, procedure, entry.path)) return;
73
+ return {
74
+ path: entry.path,
75
+ procedure
76
+ };
77
+ }
78
+ resolvePendingLazyRouters(pathname) {
79
+ if (this.pendingLazyRouters.size === 0) return;
80
+ let slashIndex = 0;
81
+ for (let depth = 1; slashIndex !== -1 && depth <= this.maxPendingLazyRouterDepth; depth++) {
82
+ const nextSlashIndex = pathname.indexOf("/", slashIndex + 1);
83
+ const httpPathPrefix = nextSlashIndex === -1 ? pathname : pathname.slice(0, nextSlashIndex);
84
+ const pending = this.pendingLazyRouters.get(httpPathPrefix);
85
+ if (pending !== void 0) return this.loadPendingLazyRouter(httpPathPrefix, pending).then(() => this.resolvePendingLazyRouters(pathname));
86
+ slashIndex = nextSlashIndex;
87
+ }
88
+ }
89
+ loadPendingLazyRouter(httpPathPrefix, pending) {
90
+ if (pending.loading === void 0) pending.loading = this.indexPendingLazyRouter(httpPathPrefix, pending).catch((error) => {
91
+ pending.loading = void 0;
92
+ throw error;
93
+ });
94
+ return pending.loading;
95
+ }
96
+ async indexPendingLazyRouter(httpPathPrefix, pending) {
97
+ const { default: router } = await unlazy(pending.router);
98
+ this.index(router, pending.path);
99
+ this.pendingLazyRouters.delete(httpPathPrefix);
100
+ }
101
+ async resolveProcedure(entry) {
102
+ entry.procedure = await resolveContractProcedure(this.rootRouter, entry.contract, entry.path);
103
+ return entry.procedure;
104
+ }
105
+ };
106
+ export { RPCMatcher, RPC_DEFAULT_ALLOW_METHODS };
@@ -1,10 +1,10 @@
1
- import type { Promisable, Value } from '@orpc/shared';
2
- import type { StandardLazyRequest } from '@standard-server/core';
3
- import type { Context } from '../../context.ts';
4
- import type { StandardHandlerHandleOptions } from './handler.ts';
5
- export type FriendlyStandardHandlerHandleOptions<T extends Context> = Omit<StandardHandlerHandleOptions<T>, 'context'> & (object extends T ? {
6
- context?: Value<Promisable<T>, [request: StandardLazyRequest]> | undefined;
1
+ import { Context } from "../../context.js";
2
+ import { StandardHandlerHandleOptions } from "./handler.js";
3
+ import { Promisable, Value } from "@orpc/shared";
4
+ import { StandardLazyRequest } from "@standard-server/core";
5
+ export type FriendlyStandardHandlerHandleOptions<T extends Context> = Omit<StandardHandlerHandleOptions<T>, "context"> & (object extends T ? {
6
+ context?: Value<Promisable<T>, [request: StandardLazyRequest]> | undefined;
7
7
  } : {
8
- context: Value<Promisable<T>, [request: StandardLazyRequest]>;
8
+ context: Value<Promisable<T>, [request: StandardLazyRequest]>;
9
9
  });
10
- export declare function resolveFriendlyStandardHandlerHandleOptions<T extends Context>(options: FriendlyStandardHandlerHandleOptions<T>): StandardHandlerHandleOptions<T>;
10
+ export declare function resolveFriendlyStandardHandlerHandleOptions<T extends Context>(options: FriendlyStandardHandlerHandleOptions<T>): StandardHandlerHandleOptions<T>;
@@ -1,6 +1,8 @@
1
- export function resolveFriendlyStandardHandlerHandleOptions(options) {
2
- return {
3
- ...options,
4
- context: options.context ?? {}, // Context only optional if all fields are optional
5
- };
1
+ // src/adapters/standard/utils.ts
2
+ function resolveFriendlyStandardHandlerHandleOptions(options) {
3
+ return {
4
+ ...options,
5
+ context: options.context ?? {}
6
+ };
6
7
  }
8
+ export { resolveFriendlyStandardHandlerHandleOptions };
@@ -1 +1,2 @@
1
- export * from './utils.ts';
1
+ import { createStandardPeerRequestHandler } from "./utils.js";
2
+ export { createStandardPeerRequestHandler };
@@ -1 +1 @@
1
- export * from './utils.js';
1
+ export { createStandardPeerRequestHandler } from "./utils.js";
@@ -1,4 +1,6 @@
1
- import type { StandardLazyRequest, StandardResponse } from '@standard-server/core';
2
- import type { Context } from '../../context.ts';
3
- import type { FriendlyStandardHandlerHandleOptions, StandardHandler } from '../standard/index.ts';
4
- export declare function createStandardPeerRequestHandler<T extends Context>(handler: StandardHandler<T>, options: FriendlyStandardHandlerHandleOptions<T>): (request: StandardLazyRequest) => Promise<StandardResponse>;
1
+ import { Context } from "../../context.js";
2
+ import { StandardHandler } from "../standard/handler.js";
3
+ import { FriendlyStandardHandlerHandleOptions } from "../standard/utils.js";
4
+ import "../standard/index.js";
5
+ import { StandardLazyRequest, StandardResponse } from "@standard-server/core";
6
+ export declare function createStandardPeerRequestHandler<T extends Context>(handler: StandardHandler<T>, options: FriendlyStandardHandlerHandleOptions<T>): (request: StandardLazyRequest) => Promise<StandardResponse>;
@@ -1,7 +1,13 @@
1
- import { resolveFriendlyStandardHandlerHandleOptions } from '../standard/index.js';
2
- export function createStandardPeerRequestHandler(handler, options) {
3
- return async (request) => {
4
- const { response } = await handler.handle(request, resolveFriendlyStandardHandlerHandleOptions(options));
5
- return response ?? { status: 404, headers: {}, body: 'No procedure matched' };
6
- };
1
+ import { resolveFriendlyStandardHandlerHandleOptions } from "../standard/utils.js";
2
+ // src/adapters/standard-peer/utils.ts
3
+ function createStandardPeerRequestHandler(handler, options) {
4
+ return async (request) => {
5
+ const { response } = await handler.handle(request, resolveFriendlyStandardHandlerHandleOptions(options));
6
+ return response ?? {
7
+ status: 404,
8
+ headers: {},
9
+ body: "No procedure matched"
10
+ };
11
+ };
7
12
  }
13
+ export { createStandardPeerRequestHandler };