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

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 (173) 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 +7 -76
  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 +12 -63
  18. package/dist/adapters/fastify/fastifyRequestHandler.mjs +13 -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/fetch/fetchRequestHandler.d.ts +2 -2
  22. package/dist/adapters/fetch/fetchRequestHandler.d.ts.map +1 -1
  23. package/dist/adapters/fetch/fetchRequestHandler.js +28 -85
  24. package/dist/adapters/fetch/fetchRequestHandler.mjs +29 -86
  25. package/dist/adapters/fetch/types.d.ts +2 -2
  26. package/dist/adapters/fetch/types.d.ts.map +1 -1
  27. package/dist/adapters/next.js +1 -1
  28. package/dist/adapters/next.mjs +1 -1
  29. package/dist/adapters/node-http/incomingMessageToRequest.d.ts +18 -0
  30. package/dist/adapters/node-http/incomingMessageToRequest.d.ts.map +1 -0
  31. package/dist/adapters/node-http/incomingMessageToRequest.js +71 -0
  32. package/dist/adapters/node-http/incomingMessageToRequest.mjs +69 -0
  33. package/dist/adapters/node-http/index.d.ts +1 -0
  34. package/dist/adapters/node-http/index.d.ts.map +1 -1
  35. package/dist/adapters/node-http/index.js +2 -0
  36. package/dist/adapters/node-http/index.mjs +1 -0
  37. package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts +1 -1
  38. package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
  39. package/dist/adapters/node-http/nodeHTTPRequestHandler.js +27 -70
  40. package/dist/adapters/node-http/nodeHTTPRequestHandler.mjs +28 -71
  41. package/dist/adapters/node-http/types.d.ts +7 -8
  42. package/dist/adapters/node-http/types.d.ts.map +1 -1
  43. package/dist/adapters/ws.js +1 -1
  44. package/dist/adapters/ws.mjs +1 -1
  45. package/dist/bundle-analysis.json +180 -277
  46. package/dist/http.js +4 -2
  47. package/dist/http.mjs +2 -1
  48. package/dist/index.js +2 -4
  49. package/dist/index.mjs +1 -2
  50. package/dist/unstable-core-do-not-import/http/contentType.d.ts +8 -20
  51. package/dist/unstable-core-do-not-import/http/contentType.d.ts.map +1 -1
  52. package/dist/unstable-core-do-not-import/http/contentType.js +180 -0
  53. package/dist/unstable-core-do-not-import/http/contentType.mjs +178 -0
  54. package/dist/unstable-core-do-not-import/http/contentTypeParsers.d.ts +14 -0
  55. package/dist/unstable-core-do-not-import/http/contentTypeParsers.d.ts.map +1 -0
  56. package/dist/unstable-core-do-not-import/http/contentTypeParsers.js +14 -0
  57. package/dist/unstable-core-do-not-import/http/contentTypeParsers.mjs +12 -0
  58. package/dist/unstable-core-do-not-import/http/getHTTPStatusCode.d.ts +1 -1
  59. package/dist/unstable-core-do-not-import/http/getHTTPStatusCode.d.ts.map +1 -1
  60. package/dist/unstable-core-do-not-import/http/resolveHTTPResponse.d.ts +7 -43
  61. package/dist/unstable-core-do-not-import/http/resolveHTTPResponse.d.ts.map +1 -1
  62. package/dist/unstable-core-do-not-import/http/resolveHTTPResponse.js +119 -134
  63. package/dist/unstable-core-do-not-import/http/resolveHTTPResponse.mjs +119 -134
  64. package/dist/unstable-core-do-not-import/http/types.d.ts +25 -27
  65. package/dist/unstable-core-do-not-import/http/types.d.ts.map +1 -1
  66. package/dist/unstable-core-do-not-import/initTRPC.d.ts +1 -1
  67. package/dist/unstable-core-do-not-import/procedureBuilder.d.ts +1 -3
  68. package/dist/unstable-core-do-not-import/procedureBuilder.d.ts.map +1 -1
  69. package/dist/unstable-core-do-not-import/procedureBuilder.js +0 -2
  70. package/dist/unstable-core-do-not-import/procedureBuilder.mjs +1 -2
  71. package/dist/unstable-core-do-not-import/rootConfig.d.ts +0 -9
  72. package/dist/unstable-core-do-not-import/rootConfig.d.ts.map +1 -1
  73. package/dist/unstable-core-do-not-import/utils.d.ts +3 -0
  74. package/dist/unstable-core-do-not-import/utils.d.ts.map +1 -1
  75. package/dist/unstable-core-do-not-import/utils.js +2 -0
  76. package/dist/unstable-core-do-not-import/utils.mjs +2 -1
  77. package/dist/unstable-core-do-not-import.d.ts +9 -3
  78. package/dist/unstable-core-do-not-import.d.ts.map +1 -1
  79. package/dist/unstable-core-do-not-import.js +11 -7
  80. package/dist/unstable-core-do-not-import.mjs +7 -5
  81. package/package.json +3 -13
  82. package/src/@trpc/server/http.ts +7 -12
  83. package/src/@trpc/server/index.ts +0 -3
  84. package/src/adapters/aws-lambda/getPlanner.ts +191 -0
  85. package/src/adapters/aws-lambda/index.ts +43 -107
  86. package/src/adapters/express.ts +1 -1
  87. package/src/adapters/fastify/fastifyRequestHandler.ts +40 -89
  88. package/src/adapters/fastify/fastifyTRPCPlugin.ts +1 -1
  89. package/src/adapters/fetch/fetchRequestHandler.ts +35 -111
  90. package/src/adapters/fetch/types.ts +4 -2
  91. package/src/adapters/next.ts +1 -1
  92. package/src/adapters/node-http/incomingMessageToRequest.ts +94 -0
  93. package/src/adapters/node-http/index.ts +1 -0
  94. package/src/adapters/node-http/nodeHTTPRequestHandler.ts +31 -97
  95. package/src/adapters/node-http/types.ts +27 -37
  96. package/src/adapters/standalone.ts +1 -1
  97. package/src/unstable-core-do-not-import/http/contentType.ts +214 -22
  98. package/src/unstable-core-do-not-import/http/contentTypeParsers.ts +29 -0
  99. package/src/unstable-core-do-not-import/http/getHTTPStatusCode.ts +2 -2
  100. package/src/unstable-core-do-not-import/http/resolveHTTPResponse.ts +135 -210
  101. package/src/unstable-core-do-not-import/http/types.ts +25 -30
  102. package/src/unstable-core-do-not-import/procedureBuilder.ts +2 -4
  103. package/src/unstable-core-do-not-import/rootConfig.ts +0 -10
  104. package/src/unstable-core-do-not-import/utils.ts +4 -0
  105. package/src/unstable-core-do-not-import.ts +9 -3
  106. package/adapters/node-http/content-type/form-data/index.d.ts +0 -1
  107. package/adapters/node-http/content-type/form-data/index.js +0 -1
  108. package/adapters/node-http/content-type/json/index.d.ts +0 -1
  109. package/adapters/node-http/content-type/json/index.js +0 -1
  110. package/dist/adapters/aws-lambda/content-type/json/index.d.ts +0 -10
  111. package/dist/adapters/aws-lambda/content-type/json/index.d.ts.map +0 -1
  112. package/dist/adapters/aws-lambda/content-type/json/index.js +0 -62
  113. package/dist/adapters/aws-lambda/content-type/json/index.mjs +0 -60
  114. package/dist/adapters/aws-lambda/utils.d.ts +0 -31
  115. package/dist/adapters/aws-lambda/utils.d.ts.map +0 -1
  116. package/dist/adapters/aws-lambda/utils.js +0 -111
  117. package/dist/adapters/aws-lambda/utils.mjs +0 -103
  118. package/dist/adapters/content-handlers/concurrentCache.d.ts +0 -7
  119. package/dist/adapters/content-handlers/concurrentCache.d.ts.map +0 -1
  120. package/dist/adapters/content-handlers/concurrentCache.js +0 -17
  121. package/dist/adapters/content-handlers/concurrentCache.mjs +0 -15
  122. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.d.ts +0 -10
  123. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.d.ts.map +0 -1
  124. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.js +0 -33
  125. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.mjs +0 -31
  126. package/dist/adapters/fastify/content-type/json/index.d.ts +0 -8
  127. package/dist/adapters/fastify/content-type/json/index.d.ts.map +0 -1
  128. package/dist/adapters/fastify/content-type/json/index.js +0 -62
  129. package/dist/adapters/fastify/content-type/json/index.mjs +0 -60
  130. package/dist/adapters/fastify/types.d.ts +0 -11
  131. package/dist/adapters/fastify/types.d.ts.map +0 -1
  132. package/dist/adapters/fetch/content-type/json/index.d.ts +0 -9
  133. package/dist/adapters/fetch/content-type/json/index.d.ts.map +0 -1
  134. package/dist/adapters/fetch/content-type/json/index.js +0 -55
  135. package/dist/adapters/fetch/content-type/json/index.mjs +0 -53
  136. package/dist/adapters/node-http/content-type/form-data/index.d.ts +0 -5
  137. package/dist/adapters/node-http/content-type/form-data/index.d.ts.map +0 -1
  138. package/dist/adapters/node-http/content-type/form-data/index.js +0 -32
  139. package/dist/adapters/node-http/content-type/form-data/index.mjs +0 -30
  140. package/dist/adapters/node-http/content-type/json/getPostBody.d.ts +0 -7
  141. package/dist/adapters/node-http/content-type/json/getPostBody.d.ts.map +0 -1
  142. package/dist/adapters/node-http/content-type/json/getPostBody.js +0 -45
  143. package/dist/adapters/node-http/content-type/json/getPostBody.mjs +0 -43
  144. package/dist/adapters/node-http/content-type/json/index.d.ts +0 -5
  145. package/dist/adapters/node-http/content-type/json/index.d.ts.map +0 -1
  146. package/dist/adapters/node-http/content-type/json/index.js +0 -68
  147. package/dist/adapters/node-http/content-type/json/index.mjs +0 -66
  148. package/dist/adapters/node-http/content-type/octet/index.d.ts +0 -5
  149. package/dist/adapters/node-http/content-type/octet/index.d.ts.map +0 -1
  150. package/dist/adapters/node-http/content-type/octet/index.js +0 -19
  151. package/dist/adapters/node-http/content-type/octet/index.mjs +0 -17
  152. package/dist/adapters/node-http/content-type/types.d.ts +0 -8
  153. package/dist/adapters/node-http/content-type/types.d.ts.map +0 -1
  154. package/dist/unstable-core-do-not-import/contentTypeParsers.d.ts +0 -16
  155. package/dist/unstable-core-do-not-import/contentTypeParsers.d.ts.map +0 -1
  156. package/dist/unstable-core-do-not-import/contentTypeParsers.js +0 -23
  157. package/dist/unstable-core-do-not-import/contentTypeParsers.mjs +0 -21
  158. package/dist/unstable-core-do-not-import/http/index.d.ts +0 -11
  159. package/dist/unstable-core-do-not-import/http/index.d.ts.map +0 -1
  160. package/src/adapters/aws-lambda/content-type/json/index.ts +0 -108
  161. package/src/adapters/aws-lambda/utils.ts +0 -170
  162. package/src/adapters/content-handlers/concurrentCache.ts +0 -16
  163. package/src/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.ts +0 -45
  164. package/src/adapters/fastify/content-type/json/index.ts +0 -106
  165. package/src/adapters/fastify/types.ts +0 -22
  166. package/src/adapters/fetch/content-type/json/index.ts +0 -90
  167. package/src/adapters/node-http/content-type/form-data/index.ts +0 -37
  168. package/src/adapters/node-http/content-type/json/getPostBody.ts +0 -49
  169. package/src/adapters/node-http/content-type/json/index.ts +0 -100
  170. package/src/adapters/node-http/content-type/octet/index.ts +0 -27
  171. package/src/adapters/node-http/content-type/types.ts +0 -19
  172. package/src/unstable-core-do-not-import/contentTypeParsers.ts +0 -37
  173. package/src/unstable-core-do-not-import/http/index.ts +0 -28
@@ -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