@trpc/server 11.0.0-rc.361 → 11.0.0-rc.363

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 (178) hide show
  1. package/dist/@trpc/server/http.d.ts +7 -5
  2. package/dist/@trpc/server/http.d.ts.map +1 -1
  3. package/dist/@trpc/server/index.d.ts +1 -2
  4. package/dist/@trpc/server/index.d.ts.map +1 -1
  5. package/dist/adapters/aws-lambda/getPlanner.d.ts +13 -0
  6. package/dist/adapters/aws-lambda/getPlanner.d.ts.map +1 -0
  7. package/dist/adapters/aws-lambda/getPlanner.js +143 -0
  8. package/dist/adapters/aws-lambda/getPlanner.mjs +141 -0
  9. package/dist/adapters/aws-lambda/index.d.ts +12 -9
  10. package/dist/adapters/aws-lambda/index.d.ts.map +1 -1
  11. package/dist/adapters/aws-lambda/index.js +8 -77
  12. package/dist/adapters/aws-lambda/index.mjs +9 -72
  13. package/dist/adapters/express.js +1 -0
  14. package/dist/adapters/express.mjs +1 -0
  15. package/dist/adapters/fastify/fastifyRequestHandler.d.ts +19 -2
  16. package/dist/adapters/fastify/fastifyRequestHandler.d.ts.map +1 -1
  17. package/dist/adapters/fastify/fastifyRequestHandler.js +22 -64
  18. package/dist/adapters/fastify/fastifyRequestHandler.mjs +22 -64
  19. package/dist/adapters/fastify/fastifyTRPCPlugin.d.ts +1 -1
  20. package/dist/adapters/fastify/fastifyTRPCPlugin.d.ts.map +1 -1
  21. package/dist/adapters/fastify/fastifyTRPCPlugin.js +1 -0
  22. package/dist/adapters/fastify/fastifyTRPCPlugin.mjs +1 -0
  23. package/dist/adapters/fetch/fetchRequestHandler.d.ts +2 -2
  24. package/dist/adapters/fetch/fetchRequestHandler.d.ts.map +1 -1
  25. package/dist/adapters/fetch/fetchRequestHandler.js +29 -86
  26. package/dist/adapters/fetch/fetchRequestHandler.mjs +29 -86
  27. package/dist/adapters/fetch/types.d.ts +2 -2
  28. package/dist/adapters/fetch/types.d.ts.map +1 -1
  29. package/dist/adapters/next.js +1 -1
  30. package/dist/adapters/next.mjs +1 -1
  31. package/dist/adapters/node-http/incomingMessageToRequest.d.ts +18 -0
  32. package/dist/adapters/node-http/incomingMessageToRequest.d.ts.map +1 -0
  33. package/dist/adapters/node-http/incomingMessageToRequest.js +71 -0
  34. package/dist/adapters/node-http/incomingMessageToRequest.mjs +69 -0
  35. package/dist/adapters/node-http/index.d.ts +1 -0
  36. package/dist/adapters/node-http/index.d.ts.map +1 -1
  37. package/dist/adapters/node-http/index.js +2 -0
  38. package/dist/adapters/node-http/index.mjs +1 -0
  39. package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts +1 -1
  40. package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
  41. package/dist/adapters/node-http/nodeHTTPRequestHandler.js +28 -71
  42. package/dist/adapters/node-http/nodeHTTPRequestHandler.mjs +28 -71
  43. package/dist/adapters/node-http/types.d.ts +7 -8
  44. package/dist/adapters/node-http/types.d.ts.map +1 -1
  45. package/dist/adapters/ws.js +1 -1
  46. package/dist/adapters/ws.mjs +1 -1
  47. package/dist/bundle-analysis.json +174 -271
  48. package/dist/http.js +4 -2
  49. package/dist/http.mjs +2 -1
  50. package/dist/index.js +2 -4
  51. package/dist/index.mjs +1 -2
  52. package/dist/unstable-core-do-not-import/http/contentType.d.ts +8 -20
  53. package/dist/unstable-core-do-not-import/http/contentType.d.ts.map +1 -1
  54. package/dist/unstable-core-do-not-import/http/contentType.js +180 -0
  55. package/dist/unstable-core-do-not-import/http/contentType.mjs +178 -0
  56. package/dist/unstable-core-do-not-import/http/contentTypeParsers.d.ts +14 -0
  57. package/dist/unstable-core-do-not-import/http/contentTypeParsers.d.ts.map +1 -0
  58. package/dist/unstable-core-do-not-import/http/contentTypeParsers.js +14 -0
  59. package/dist/unstable-core-do-not-import/http/contentTypeParsers.mjs +12 -0
  60. package/dist/unstable-core-do-not-import/http/getHTTPStatusCode.d.ts +1 -1
  61. package/dist/unstable-core-do-not-import/http/getHTTPStatusCode.d.ts.map +1 -1
  62. package/dist/unstable-core-do-not-import/http/resolveResponse.d.ts +15 -0
  63. package/dist/unstable-core-do-not-import/http/resolveResponse.d.ts.map +1 -0
  64. package/dist/unstable-core-do-not-import/http/{resolveHTTPResponse.js → resolveResponse.js} +119 -134
  65. package/dist/unstable-core-do-not-import/http/{resolveHTTPResponse.mjs → resolveResponse.mjs} +119 -134
  66. package/dist/unstable-core-do-not-import/http/types.d.ts +25 -27
  67. package/dist/unstable-core-do-not-import/http/types.d.ts.map +1 -1
  68. package/dist/unstable-core-do-not-import/initTRPC.d.ts +1 -1
  69. package/dist/unstable-core-do-not-import/procedureBuilder.d.ts +1 -3
  70. package/dist/unstable-core-do-not-import/procedureBuilder.d.ts.map +1 -1
  71. package/dist/unstable-core-do-not-import/procedureBuilder.js +0 -2
  72. package/dist/unstable-core-do-not-import/procedureBuilder.mjs +1 -2
  73. package/dist/unstable-core-do-not-import/rootConfig.d.ts +0 -9
  74. package/dist/unstable-core-do-not-import/rootConfig.d.ts.map +1 -1
  75. package/dist/unstable-core-do-not-import/utils.d.ts +3 -0
  76. package/dist/unstable-core-do-not-import/utils.d.ts.map +1 -1
  77. package/dist/unstable-core-do-not-import/utils.js +2 -0
  78. package/dist/unstable-core-do-not-import/utils.mjs +2 -1
  79. package/dist/unstable-core-do-not-import.d.ts +9 -3
  80. package/dist/unstable-core-do-not-import.d.ts.map +1 -1
  81. package/dist/unstable-core-do-not-import.js +12 -8
  82. package/dist/unstable-core-do-not-import.mjs +7 -5
  83. package/package.json +3 -13
  84. package/src/@trpc/server/http.ts +7 -12
  85. package/src/@trpc/server/index.ts +0 -3
  86. package/src/adapters/aws-lambda/getPlanner.ts +191 -0
  87. package/src/adapters/aws-lambda/index.ts +43 -107
  88. package/src/adapters/express.ts +1 -1
  89. package/src/adapters/fastify/fastifyRequestHandler.ts +43 -90
  90. package/src/adapters/fastify/fastifyTRPCPlugin.ts +4 -3
  91. package/src/adapters/fetch/fetchRequestHandler.ts +35 -111
  92. package/src/adapters/fetch/types.ts +4 -2
  93. package/src/adapters/next.ts +1 -1
  94. package/src/adapters/node-http/incomingMessageToRequest.ts +94 -0
  95. package/src/adapters/node-http/index.ts +1 -0
  96. package/src/adapters/node-http/nodeHTTPRequestHandler.ts +31 -97
  97. package/src/adapters/node-http/types.ts +27 -37
  98. package/src/adapters/standalone.ts +1 -1
  99. package/src/unstable-core-do-not-import/http/contentType.ts +214 -22
  100. package/src/unstable-core-do-not-import/http/contentTypeParsers.ts +29 -0
  101. package/src/unstable-core-do-not-import/http/getHTTPStatusCode.ts +2 -2
  102. package/src/unstable-core-do-not-import/http/resolveResponse.ts +386 -0
  103. package/src/unstable-core-do-not-import/http/types.ts +25 -30
  104. package/src/unstable-core-do-not-import/procedureBuilder.ts +2 -4
  105. package/src/unstable-core-do-not-import/rootConfig.ts +0 -10
  106. package/src/unstable-core-do-not-import/utils.ts +4 -0
  107. package/src/unstable-core-do-not-import.ts +9 -3
  108. package/adapters/node-http/content-type/form-data/index.d.ts +0 -1
  109. package/adapters/node-http/content-type/form-data/index.js +0 -1
  110. package/adapters/node-http/content-type/json/index.d.ts +0 -1
  111. package/adapters/node-http/content-type/json/index.js +0 -1
  112. package/dist/adapters/aws-lambda/content-type/json/index.d.ts +0 -10
  113. package/dist/adapters/aws-lambda/content-type/json/index.d.ts.map +0 -1
  114. package/dist/adapters/aws-lambda/content-type/json/index.js +0 -62
  115. package/dist/adapters/aws-lambda/content-type/json/index.mjs +0 -60
  116. package/dist/adapters/aws-lambda/utils.d.ts +0 -31
  117. package/dist/adapters/aws-lambda/utils.d.ts.map +0 -1
  118. package/dist/adapters/aws-lambda/utils.js +0 -111
  119. package/dist/adapters/aws-lambda/utils.mjs +0 -103
  120. package/dist/adapters/content-handlers/concurrentCache.d.ts +0 -7
  121. package/dist/adapters/content-handlers/concurrentCache.d.ts.map +0 -1
  122. package/dist/adapters/content-handlers/concurrentCache.js +0 -17
  123. package/dist/adapters/content-handlers/concurrentCache.mjs +0 -15
  124. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.d.ts +0 -10
  125. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.d.ts.map +0 -1
  126. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.js +0 -33
  127. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.mjs +0 -31
  128. package/dist/adapters/fastify/content-type/json/index.d.ts +0 -8
  129. package/dist/adapters/fastify/content-type/json/index.d.ts.map +0 -1
  130. package/dist/adapters/fastify/content-type/json/index.js +0 -62
  131. package/dist/adapters/fastify/content-type/json/index.mjs +0 -60
  132. package/dist/adapters/fastify/types.d.ts +0 -11
  133. package/dist/adapters/fastify/types.d.ts.map +0 -1
  134. package/dist/adapters/fetch/content-type/json/index.d.ts +0 -9
  135. package/dist/adapters/fetch/content-type/json/index.d.ts.map +0 -1
  136. package/dist/adapters/fetch/content-type/json/index.js +0 -55
  137. package/dist/adapters/fetch/content-type/json/index.mjs +0 -53
  138. package/dist/adapters/node-http/content-type/form-data/index.d.ts +0 -5
  139. package/dist/adapters/node-http/content-type/form-data/index.d.ts.map +0 -1
  140. package/dist/adapters/node-http/content-type/form-data/index.js +0 -32
  141. package/dist/adapters/node-http/content-type/form-data/index.mjs +0 -30
  142. package/dist/adapters/node-http/content-type/json/getPostBody.d.ts +0 -7
  143. package/dist/adapters/node-http/content-type/json/getPostBody.d.ts.map +0 -1
  144. package/dist/adapters/node-http/content-type/json/getPostBody.js +0 -45
  145. package/dist/adapters/node-http/content-type/json/getPostBody.mjs +0 -43
  146. package/dist/adapters/node-http/content-type/json/index.d.ts +0 -5
  147. package/dist/adapters/node-http/content-type/json/index.d.ts.map +0 -1
  148. package/dist/adapters/node-http/content-type/json/index.js +0 -68
  149. package/dist/adapters/node-http/content-type/json/index.mjs +0 -66
  150. package/dist/adapters/node-http/content-type/octet/index.d.ts +0 -5
  151. package/dist/adapters/node-http/content-type/octet/index.d.ts.map +0 -1
  152. package/dist/adapters/node-http/content-type/octet/index.js +0 -19
  153. package/dist/adapters/node-http/content-type/octet/index.mjs +0 -17
  154. package/dist/adapters/node-http/content-type/types.d.ts +0 -8
  155. package/dist/adapters/node-http/content-type/types.d.ts.map +0 -1
  156. package/dist/unstable-core-do-not-import/contentTypeParsers.d.ts +0 -16
  157. package/dist/unstable-core-do-not-import/contentTypeParsers.d.ts.map +0 -1
  158. package/dist/unstable-core-do-not-import/contentTypeParsers.js +0 -23
  159. package/dist/unstable-core-do-not-import/contentTypeParsers.mjs +0 -21
  160. package/dist/unstable-core-do-not-import/http/index.d.ts +0 -11
  161. package/dist/unstable-core-do-not-import/http/index.d.ts.map +0 -1
  162. package/dist/unstable-core-do-not-import/http/resolveHTTPResponse.d.ts +0 -51
  163. package/dist/unstable-core-do-not-import/http/resolveHTTPResponse.d.ts.map +0 -1
  164. package/src/adapters/aws-lambda/content-type/json/index.ts +0 -108
  165. package/src/adapters/aws-lambda/utils.ts +0 -170
  166. package/src/adapters/content-handlers/concurrentCache.ts +0 -16
  167. package/src/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.ts +0 -45
  168. package/src/adapters/fastify/content-type/json/index.ts +0 -106
  169. package/src/adapters/fastify/types.ts +0 -22
  170. package/src/adapters/fetch/content-type/json/index.ts +0 -90
  171. package/src/adapters/node-http/content-type/form-data/index.ts +0 -37
  172. package/src/adapters/node-http/content-type/json/getPostBody.ts +0 -49
  173. package/src/adapters/node-http/content-type/json/index.ts +0 -100
  174. package/src/adapters/node-http/content-type/octet/index.ts +0 -27
  175. package/src/adapters/node-http/content-type/types.ts +0 -19
  176. package/src/unstable-core-do-not-import/contentTypeParsers.ts +0 -37
  177. package/src/unstable-core-do-not-import/http/index.ts +0 -28
  178. package/src/unstable-core-do-not-import/http/resolveHTTPResponse.ts +0 -461
@@ -13,7 +13,6 @@ import type {
13
13
  AnyRouter,
14
14
  CreateContextCallback,
15
15
  inferRouterContext,
16
- WrapCreateContext,
17
16
  } from '../../@trpc/server';
18
17
  // @trpc/server/http
19
18
  import type {
@@ -43,7 +42,7 @@ export type NodeHTTPResponse = http.ServerResponse & {
43
42
  flush?: () => void;
44
43
  };
45
44
 
46
- export type NodeHTTPConditionCreateContextOption<
45
+ export type NodeHTTPCreateContextOption<
47
46
  TRouter extends AnyRouter,
48
47
  TRequest,
49
48
  TResponse,
@@ -60,50 +59,41 @@ type ConnectMiddleware<
60
59
  TResponse extends NodeHTTPResponse = NodeHTTPResponse,
61
60
  > = (req: TRequest, res: TResponse, next: (err?: any) => any) => void;
62
61
 
63
- interface CoreNodeHTTPHandlerOptions<
64
- TRouter extends AnyRouter,
65
- TRequest extends NodeHTTPRequest,
66
- TResponse extends NodeHTTPResponse,
67
- > extends HTTPBaseHandlerOptions<TRouter, TRequest> {
68
- /**
69
- * By default, http `OPTIONS` requests are not handled, and CORS headers are not returned.
70
- *
71
- * This can be used to handle them manually or via the `cors` npm package: https://www.npmjs.com/package/cors
72
- *
73
- * ```ts
74
- * import cors from 'cors'
75
- *
76
- * nodeHTTPRequestHandler({
77
- * cors: cors()
78
- * })
79
- * ```
80
- *
81
- * You can also use it for other needs which a connect/node.js compatible middleware can solve,
82
- * though you might wish to consider an alternative solution like the Express adapter if your needs are complex.
83
- */
84
- middleware?: ConnectMiddleware<TRequest, TResponse>;
85
- maxBodySize?: number;
86
- }
87
-
88
- // Public API
89
62
  export type NodeHTTPHandlerOptions<
90
63
  TRouter extends AnyRouter,
91
64
  TRequest extends NodeHTTPRequest,
92
65
  TResponse extends NodeHTTPResponse,
93
- > = CoreNodeHTTPHandlerOptions<TRouter, TRequest, TResponse> &
94
- NodeHTTPConditionCreateContextOption<TRouter, TRequest, TResponse>;
66
+ > = HTTPBaseHandlerOptions<TRouter, TRequest> &
67
+ NodeHTTPCreateContextOption<TRouter, TRequest, TResponse> & {
68
+ /**
69
+ * By default, http `OPTIONS` requests are not handled, and CORS headers are not returned.
70
+ *
71
+ * This can be used to handle them manually or via the `cors` npm package: https://www.npmjs.com/package/cors
72
+ *
73
+ * ```ts
74
+ * import cors from 'cors'
75
+ *
76
+ * nodeHTTPRequestHandler({
77
+ * cors: cors()
78
+ * })
79
+ * ```
80
+ *
81
+ * You can also use it for other needs which a connect/node.js compatible middleware can solve,
82
+ * though you might wish to consider an alternative solution like the Express adapter if your needs are complex.
83
+ */
84
+ middleware?: ConnectMiddleware;
85
+ maxBodySize?: number;
86
+ };
95
87
 
96
- // Internal user
97
88
  export type NodeHTTPRequestHandlerOptions<
98
89
  TRouter extends AnyRouter,
99
90
  TRequest extends NodeHTTPRequest,
100
91
  TResponse extends NodeHTTPResponse,
101
- > = CoreNodeHTTPHandlerOptions<TRouter, TRequest, TResponse> &
102
- WrapCreateContext<NodeHTTPCreateContextFn<TRouter, TRequest, TResponse>> & {
103
- req: TRequest;
104
- res: TResponse;
105
- path: string;
106
- };
92
+ > = {
93
+ req: TRequest;
94
+ res: TResponse;
95
+ path: string;
96
+ } & NodeHTTPHandlerOptions<TRouter, TRequest, TResponse>;
107
97
 
108
98
  export type NodeHTTPCreateContextFnOptions<TRequest, TResponse> = {
109
99
  req: TRequest;
@@ -37,7 +37,7 @@ export function createHTTPHandler<TRouter extends AnyRouter>(
37
37
  const path = url.pathname.slice(1);
38
38
 
39
39
  await nodeHTTPRequestHandler({
40
- ...opts,
40
+ ...(opts as any),
41
41
  req,
42
42
  res,
43
43
  path,
@@ -1,24 +1,216 @@
1
- import type { TRPCError } from '../error/TRPCError';
2
-
3
- export type BodyResult =
4
- | {
5
- ok: true;
6
- data: unknown;
7
- /**
8
- * If the HTTP handler has already parsed the body
9
- */
10
- preprocessed: boolean;
11
- }
12
- | { ok: false; error: TRPCError };
13
-
14
- export type BaseContentTypeHandler<TOptions> = {
15
- name: string;
16
- isMatch(headers: Headers): boolean;
17
- getInputs: (
18
- opts: TOptions,
19
- info: {
20
- isBatchCall: boolean;
21
- batch: number;
1
+ import { TRPCError } from '../error/TRPCError';
2
+ import type { RootConfig } from '../rootConfig';
3
+ import { isObject, unsetMarker } from '../utils';
4
+ import type { TRPCRequestInfo } from './types';
5
+
6
+ type ContentTypeHandler = {
7
+ isMatch: (opts: Request) => boolean;
8
+ parse: (opts: {
9
+ path: string;
10
+ req: Request;
11
+ searchParams: URLSearchParams;
12
+ config: RootConfig<any>;
13
+ }) => TRPCRequestInfo;
14
+ };
15
+
16
+ /**
17
+ * Memoize a function that takes no arguments
18
+ * @internal
19
+ */
20
+ function memo<TReturn>(fn: () => Promise<TReturn>) {
21
+ let promise: Promise<TReturn> | null = null;
22
+ let value: TReturn | typeof unsetMarker = unsetMarker;
23
+ return {
24
+ /**
25
+ * Lazily read the value
26
+ */
27
+ read: async (): Promise<TReturn> => {
28
+ if (value !== unsetMarker) {
29
+ return value;
30
+ }
31
+ if (promise === null) {
32
+ // dedupes promises and catches errors
33
+ promise = fn().catch((cause) => {
34
+ if (cause instanceof TRPCError) {
35
+ throw cause;
36
+ }
37
+ throw new TRPCError({
38
+ code: 'BAD_REQUEST',
39
+ message: cause instanceof Error ? cause.message : 'Invalid input',
40
+ cause,
41
+ });
42
+ });
43
+ }
44
+
45
+ value = await promise;
46
+ promise = null;
47
+
48
+ return value;
22
49
  },
23
- ) => Promise<unknown>;
50
+ /**
51
+ * Get an already stored result
52
+ */
53
+ result: (): TReturn | undefined => {
54
+ return value !== unsetMarker ? value : undefined;
55
+ },
56
+ };
57
+ }
58
+
59
+ const jsonContentTypeHandler: ContentTypeHandler = {
60
+ isMatch(req) {
61
+ return !!req.headers.get('content-type')?.startsWith('application/json');
62
+ },
63
+ parse(opts) {
64
+ const { req } = opts;
65
+ const isBatchCall = opts.searchParams.get('batch') === '1';
66
+ const paths = isBatchCall ? opts.path.split(',') : [opts.path];
67
+
68
+ type InputRecord = Record<number, unknown>;
69
+ const getInputs = memo(async (): Promise<InputRecord> => {
70
+ let inputs: unknown = undefined;
71
+ if (req.method === 'GET') {
72
+ const queryInput = opts.searchParams.get('input');
73
+ if (queryInput) {
74
+ inputs = JSON.parse(queryInput);
75
+ }
76
+ } else {
77
+ inputs = await req.json();
78
+ }
79
+ if (inputs === undefined) {
80
+ return {};
81
+ }
82
+
83
+ if (!isBatchCall) {
84
+ return {
85
+ 0: opts.config.transformer.input.deserialize(inputs),
86
+ };
87
+ }
88
+
89
+ if (!isObject(inputs)) {
90
+ throw new TRPCError({
91
+ code: 'BAD_REQUEST',
92
+ message: '"input" needs to be an object when doing a batch call',
93
+ });
94
+ }
95
+ const acc: InputRecord = {};
96
+ for (const index of paths.keys()) {
97
+ const input = inputs[index];
98
+ if (input !== undefined) {
99
+ acc[index] = opts.config.transformer.input.deserialize(input);
100
+ }
101
+ }
102
+
103
+ return acc;
104
+ });
105
+
106
+ return {
107
+ isBatchCall,
108
+ calls: paths.map((path, index) => ({
109
+ path,
110
+ getRawInput: async () => {
111
+ const inputs = await getInputs.read();
112
+ return inputs[index];
113
+ },
114
+ result: () => {
115
+ return getInputs.result()?.[index];
116
+ },
117
+ })),
118
+ };
119
+ },
120
+ };
121
+
122
+ const formDataContentTypeHandler: ContentTypeHandler = {
123
+ isMatch(req) {
124
+ return !!req.headers.get('content-type')?.startsWith('multipart/form-data');
125
+ },
126
+ parse(opts) {
127
+ const { req } = opts;
128
+ if (req.method !== 'POST') {
129
+ throw new TRPCError({
130
+ code: 'METHOD_NOT_SUPPORTED',
131
+ message:
132
+ 'Only POST requests are supported for multipart/form-data requests',
133
+ });
134
+ }
135
+ const getInputs = memo(async () => {
136
+ const fd = await req.formData();
137
+ return fd;
138
+ });
139
+ return {
140
+ calls: [
141
+ {
142
+ path: opts.path,
143
+ getRawInput: getInputs.read,
144
+ result: getInputs.result,
145
+ },
146
+ ],
147
+ isBatchCall: false,
148
+ };
149
+ },
150
+ };
151
+
152
+ const octetStreamContentTypeHandler: ContentTypeHandler = {
153
+ isMatch(req) {
154
+ return !!req.headers
155
+ .get('content-type')
156
+ ?.startsWith('application/octet-stream');
157
+ },
158
+ parse(opts) {
159
+ const { req } = opts;
160
+ if (req.method !== 'POST') {
161
+ throw new TRPCError({
162
+ code: 'METHOD_NOT_SUPPORTED',
163
+ message:
164
+ 'Only POST requests are supported for application/octet-stream requests',
165
+ });
166
+ }
167
+ const getInputs = memo(async () => {
168
+ return req.body;
169
+ });
170
+ return {
171
+ calls: [
172
+ {
173
+ path: opts.path,
174
+ getRawInput: getInputs.read,
175
+ result: getInputs.result,
176
+ },
177
+ ],
178
+ isBatchCall: false,
179
+ };
180
+ },
24
181
  };
182
+
183
+ const handlers = [
184
+ jsonContentTypeHandler,
185
+ formDataContentTypeHandler,
186
+ octetStreamContentTypeHandler,
187
+ ];
188
+
189
+ function getContentTypeHandler(req: Request): ContentTypeHandler {
190
+ const handler = handlers.find((handler) => handler.isMatch(req));
191
+ if (handler) {
192
+ return handler;
193
+ }
194
+
195
+ if (!handler && req.method === 'GET') {
196
+ // fallback to JSON for get requests so GET-requests can be opened in browser easily
197
+ return jsonContentTypeHandler;
198
+ }
199
+
200
+ throw new TRPCError({
201
+ code: 'UNSUPPORTED_MEDIA_TYPE',
202
+ message: req.headers.has('content-type')
203
+ ? `Unsupported content-type "${req.headers.get('content-type')}`
204
+ : 'Missing content-type header',
205
+ });
206
+ }
207
+
208
+ export function getRequestInfo(opts: {
209
+ path: string;
210
+ req: Request;
211
+ searchParams: URLSearchParams;
212
+ config: RootConfig<any>;
213
+ }): TRPCRequestInfo {
214
+ const handler = getContentTypeHandler(opts.req);
215
+ return handler.parse(opts);
216
+ }
@@ -0,0 +1,29 @@
1
+ import type { ParserZodEsque } from '../parser';
2
+
3
+ type UtilityParser<TInput, TOutput> = ParserZodEsque<TInput, TOutput> & {
4
+ parse: (input: unknown) => TOutput;
5
+ };
6
+
7
+ // Should be the same possible types as packages/client/src/links/internals/contentTypes.ts isOctetType
8
+
9
+ /**
10
+ * File is only available from Node19+ but it always extends Blob so we can use that as a type until we eventually drop Node18
11
+ */
12
+ interface FileLike extends Blob {
13
+ readonly name: string;
14
+ }
15
+
16
+ type OctetInput = Blob | Uint8Array | FileLike;
17
+ export const octetInputParser: UtilityParser<OctetInput, ReadableStream> = {
18
+ _input: null as any as OctetInput,
19
+ _output: null as any as ReadableStream,
20
+ parse(input) {
21
+ if (input instanceof ReadableStream) {
22
+ return input;
23
+ }
24
+
25
+ throw new Error(
26
+ `Parsed input was expected to be a ReadableStream but was: ${typeof input}`,
27
+ );
28
+ },
29
+ };
@@ -29,9 +29,9 @@ function getStatusCodeFromKey(code: keyof typeof TRPC_ERROR_CODES_BY_KEY) {
29
29
  return JSONRPC2_TO_HTTP_CODE[code] ?? 500;
30
30
  }
31
31
 
32
- export function getHTTPStatusCode(json: TRPCResponse | TRPCResponse[]) {
32
+ export function getHTTPStatusCode(json: TRPCResponse | TRPCResponse[]): number {
33
33
  const arr = Array.isArray(json) ? json : [json];
34
- const httpStatuses = new Set(
34
+ const httpStatuses = new Set<number>(
35
35
  arr.map((res) => {
36
36
  if ('error' in res) {
37
37
  const data = res.error.data as