@trpc/server 11.0.0-rc.348 → 11.0.0-rc.354

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 (160) hide show
  1. package/dist/@trpc/server/http.d.ts +1 -0
  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/index.d.ts.map +1 -1
  6. package/dist/adapters/aws-lambda/index.js +9 -19
  7. package/dist/adapters/aws-lambda/index.mjs +9 -19
  8. package/dist/adapters/aws-lambda/utils.d.ts +12 -3
  9. package/dist/adapters/aws-lambda/utils.d.ts.map +1 -1
  10. package/dist/adapters/aws-lambda/utils.js +1 -12
  11. package/dist/adapters/aws-lambda/utils.mjs +2 -12
  12. package/dist/adapters/express.d.ts.map +1 -1
  13. package/dist/adapters/express.js +1 -0
  14. package/dist/adapters/express.mjs +1 -0
  15. package/dist/adapters/fastify/fastifyRequestHandler.d.ts +9 -1
  16. package/dist/adapters/fastify/fastifyRequestHandler.d.ts.map +1 -1
  17. package/dist/adapters/fastify/fastifyRequestHandler.js +2 -10
  18. package/dist/adapters/fastify/fastifyRequestHandler.mjs +2 -10
  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 +5 -1
  22. package/dist/adapters/fetch/fetchRequestHandler.d.ts.map +1 -1
  23. package/dist/adapters/fetch/fetchRequestHandler.js +2 -16
  24. package/dist/adapters/fetch/fetchRequestHandler.mjs +2 -16
  25. package/dist/adapters/fetch/types.d.ts +12 -9
  26. package/dist/adapters/fetch/types.d.ts.map +1 -1
  27. package/dist/adapters/next-app-dir/nextAppDirCaller.d.ts +7 -2
  28. package/dist/adapters/next-app-dir/nextAppDirCaller.d.ts.map +1 -1
  29. package/dist/adapters/next.d.ts.map +1 -1
  30. package/dist/adapters/next.js +1 -0
  31. package/dist/adapters/next.mjs +1 -0
  32. package/dist/adapters/node-http/content-type/form-data/fileUploadHandler.d.ts +73 -0
  33. package/dist/adapters/node-http/content-type/form-data/fileUploadHandler.d.ts.map +1 -0
  34. package/dist/adapters/node-http/content-type/form-data/fileUploadHandler.js +161 -0
  35. package/dist/adapters/node-http/content-type/form-data/fileUploadHandler.mjs +157 -0
  36. package/dist/adapters/node-http/content-type/form-data/index.d.ts +25 -4
  37. package/dist/adapters/node-http/content-type/form-data/index.d.ts.map +1 -1
  38. package/dist/adapters/node-http/content-type/form-data/index.js +128 -25
  39. package/dist/adapters/node-http/content-type/form-data/index.mjs +103 -25
  40. package/dist/adapters/node-http/content-type/form-data/memoryUploadHandler.d.ts +31 -0
  41. package/dist/adapters/node-http/content-type/form-data/memoryUploadHandler.d.ts.map +1 -0
  42. package/dist/adapters/node-http/content-type/form-data/memoryUploadHandler.js +29 -0
  43. package/dist/adapters/node-http/content-type/form-data/memoryUploadHandler.mjs +27 -0
  44. package/dist/adapters/node-http/content-type/form-data/streamSlice.d.ts +16 -0
  45. package/dist/adapters/node-http/content-type/form-data/streamSlice.d.ts.map +1 -0
  46. package/dist/adapters/node-http/content-type/form-data/streamSlice.js +46 -0
  47. package/dist/adapters/node-http/content-type/form-data/streamSlice.mjs +44 -0
  48. package/dist/adapters/node-http/content-type/form-data/uploadHandler.d.ts +45 -0
  49. package/dist/adapters/node-http/content-type/form-data/uploadHandler.d.ts.map +1 -0
  50. package/dist/adapters/node-http/content-type/form-data/uploadHandler.js +30 -0
  51. package/dist/adapters/node-http/content-type/form-data/uploadHandler.mjs +26 -0
  52. package/dist/adapters/node-http/content-type/json/getPostBody.d.ts.map +1 -1
  53. package/dist/adapters/node-http/content-type/json/getPostBody.js +12 -4
  54. package/dist/adapters/node-http/content-type/json/getPostBody.mjs +12 -4
  55. package/dist/adapters/node-http/content-type/json/index.d.ts +1 -4
  56. package/dist/adapters/node-http/content-type/json/index.d.ts.map +1 -1
  57. package/dist/adapters/node-http/content-type/json/index.js +10 -59
  58. package/dist/adapters/node-http/content-type/json/index.mjs +10 -59
  59. package/dist/adapters/node-http/internals/contentType.d.ts +9 -0
  60. package/dist/adapters/node-http/internals/contentType.d.ts.map +1 -0
  61. package/dist/adapters/node-http/internals/contentType.js +8 -0
  62. package/dist/adapters/node-http/internals/contentType.mjs +6 -0
  63. package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
  64. package/dist/adapters/node-http/nodeHTTPRequestHandler.js +21 -19
  65. package/dist/adapters/node-http/nodeHTTPRequestHandler.mjs +22 -20
  66. package/dist/adapters/node-http/types.d.ts +19 -8
  67. package/dist/adapters/node-http/types.d.ts.map +1 -1
  68. package/dist/adapters/standalone.d.ts.map +1 -1
  69. package/dist/adapters/standalone.js +1 -0
  70. package/dist/adapters/standalone.mjs +1 -0
  71. package/dist/adapters/ws.d.ts +12 -2
  72. package/dist/adapters/ws.d.ts.map +1 -1
  73. package/dist/bundle-analysis.json +225 -219
  74. package/dist/http.js +2 -0
  75. package/dist/http.mjs +1 -0
  76. package/dist/index.js +0 -2
  77. package/dist/index.mjs +0 -1
  78. package/dist/unstable-core-do-not-import/http/contentType.d.ts +15 -7
  79. package/dist/unstable-core-do-not-import/http/contentType.d.ts.map +1 -1
  80. package/dist/unstable-core-do-not-import/http/contentType.js +54 -0
  81. package/dist/unstable-core-do-not-import/http/contentType.mjs +52 -0
  82. package/dist/unstable-core-do-not-import/http/index.d.ts +1 -0
  83. package/dist/unstable-core-do-not-import/http/index.d.ts.map +1 -1
  84. package/dist/unstable-core-do-not-import/http/resolveHTTPResponse.d.ts +5 -5
  85. package/dist/unstable-core-do-not-import/http/resolveHTTPResponse.d.ts.map +1 -1
  86. package/dist/unstable-core-do-not-import/http/resolveHTTPResponse.js +22 -25
  87. package/dist/unstable-core-do-not-import/http/resolveHTTPResponse.mjs +22 -25
  88. package/dist/unstable-core-do-not-import/http/types.d.ts +2 -0
  89. package/dist/unstable-core-do-not-import/http/types.d.ts.map +1 -1
  90. package/dist/unstable-core-do-not-import/initTRPC.d.ts +1 -1
  91. package/dist/unstable-core-do-not-import/initTRPC.d.ts.map +1 -1
  92. package/dist/unstable-core-do-not-import/rootConfig.d.ts +0 -21
  93. package/dist/unstable-core-do-not-import/rootConfig.d.ts.map +1 -1
  94. package/dist/unstable-core-do-not-import.js +2 -0
  95. package/dist/unstable-core-do-not-import.mjs +1 -0
  96. package/package.json +3 -2
  97. package/src/@trpc/server/http.ts +1 -0
  98. package/src/@trpc/server/index.ts +1 -4
  99. package/src/adapters/aws-lambda/index.ts +9 -24
  100. package/src/adapters/aws-lambda/utils.ts +15 -21
  101. package/src/adapters/express.ts +6 -1
  102. package/src/adapters/fastify/fastifyRequestHandler.ts +21 -15
  103. package/src/adapters/fastify/fastifyTRPCPlugin.ts +1 -1
  104. package/src/adapters/fetch/fetchRequestHandler.ts +10 -22
  105. package/src/adapters/fetch/types.ts +15 -22
  106. package/src/adapters/next-app-dir/nextAppDirCaller.ts +9 -2
  107. package/src/adapters/next.ts +6 -1
  108. package/src/adapters/node-http/content-type/form-data/fileUploadHandler.ts +277 -0
  109. package/src/adapters/node-http/content-type/form-data/index.ts +159 -33
  110. package/src/adapters/node-http/content-type/form-data/memoryUploadHandler.ts +56 -0
  111. package/src/adapters/node-http/content-type/form-data/streamSlice.ts +56 -0
  112. package/src/adapters/node-http/content-type/form-data/uploadHandler.ts +89 -0
  113. package/src/adapters/node-http/content-type/json/getPostBody.ts +18 -9
  114. package/src/adapters/node-http/content-type/json/index.ts +7 -87
  115. package/src/adapters/node-http/{content-type/types.ts → internals/contentType.ts} +14 -2
  116. package/src/adapters/node-http/nodeHTTPRequestHandler.ts +35 -22
  117. package/src/adapters/node-http/types.ts +46 -46
  118. package/src/adapters/standalone.ts +2 -1
  119. package/src/adapters/ws.ts +14 -9
  120. package/src/unstable-core-do-not-import/http/contentType.ts +85 -10
  121. package/src/unstable-core-do-not-import/http/index.ts +1 -0
  122. package/src/unstable-core-do-not-import/http/resolveHTTPResponse.ts +28 -29
  123. package/src/unstable-core-do-not-import/http/types.ts +2 -0
  124. package/src/unstable-core-do-not-import/initTRPC.ts +1 -0
  125. package/src/unstable-core-do-not-import/rootConfig.ts +0 -31
  126. package/dist/adapters/aws-lambda/content-type/json/index.d.ts +0 -10
  127. package/dist/adapters/aws-lambda/content-type/json/index.d.ts.map +0 -1
  128. package/dist/adapters/aws-lambda/content-type/json/index.js +0 -59
  129. package/dist/adapters/aws-lambda/content-type/json/index.mjs +0 -57
  130. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.d.ts +0 -10
  131. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.d.ts.map +0 -1
  132. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.js +0 -33
  133. package/dist/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.mjs +0 -31
  134. package/dist/adapters/fastify/content-type/json/index.d.ts +0 -8
  135. package/dist/adapters/fastify/content-type/json/index.d.ts.map +0 -1
  136. package/dist/adapters/fastify/content-type/json/index.js +0 -59
  137. package/dist/adapters/fastify/content-type/json/index.mjs +0 -57
  138. package/dist/adapters/fastify/types.d.ts +0 -11
  139. package/dist/adapters/fastify/types.d.ts.map +0 -1
  140. package/dist/adapters/fetch/content-type/json/index.d.ts +0 -9
  141. package/dist/adapters/fetch/content-type/json/index.d.ts.map +0 -1
  142. package/dist/adapters/fetch/content-type/json/index.js +0 -58
  143. package/dist/adapters/fetch/content-type/json/index.mjs +0 -56
  144. package/dist/adapters/node-http/content-type/octet/index.d.ts +0 -5
  145. package/dist/adapters/node-http/content-type/octet/index.d.ts.map +0 -1
  146. package/dist/adapters/node-http/content-type/octet/index.js +0 -19
  147. package/dist/adapters/node-http/content-type/octet/index.mjs +0 -17
  148. package/dist/adapters/node-http/content-type/types.d.ts +0 -8
  149. package/dist/adapters/node-http/content-type/types.d.ts.map +0 -1
  150. package/dist/unstable-core-do-not-import/contentTypeParsers.d.ts +0 -16
  151. package/dist/unstable-core-do-not-import/contentTypeParsers.d.ts.map +0 -1
  152. package/dist/unstable-core-do-not-import/contentTypeParsers.js +0 -23
  153. package/dist/unstable-core-do-not-import/contentTypeParsers.mjs +0 -21
  154. package/src/adapters/aws-lambda/content-type/json/index.ts +0 -99
  155. package/src/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.ts +0 -45
  156. package/src/adapters/fastify/content-type/json/index.ts +0 -97
  157. package/src/adapters/fastify/types.ts +0 -22
  158. package/src/adapters/fetch/content-type/json/index.ts +0 -94
  159. package/src/adapters/node-http/content-type/octet/index.ts +0 -27
  160. package/src/unstable-core-do-not-import/contentTypeParsers.ts +0 -37
@@ -9,12 +9,7 @@
9
9
  */
10
10
  import type * as http from 'http';
11
11
  // @trpc/server
12
- import type {
13
- AnyRouter,
14
- CreateContextCallback,
15
- inferRouterContext,
16
- WrapCreateContext,
17
- } from '../../@trpc/server';
12
+ import type { AnyRouter, inferRouterContext } from '../../@trpc/server';
18
13
  // @trpc/server/http
19
14
  import type {
20
15
  HTTPBaseHandlerOptions,
@@ -22,6 +17,7 @@ import type {
22
17
  } from '../../@trpc/server/http';
23
18
  // eslint-disable-next-line no-restricted-imports
24
19
  import type { MaybePromise } from '../../unstable-core-do-not-import';
20
+ import type { NodeHTTPContentTypeHandler } from './internals/contentType';
25
21
 
26
22
  interface ParsedQs {
27
23
  [key: string]: ParsedQs | ParsedQs[] | string[] | string | undefined;
@@ -43,14 +39,23 @@ export type NodeHTTPResponse = http.ServerResponse & {
43
39
  flush?: () => void;
44
40
  };
45
41
 
46
- export type NodeHTTPConditionCreateContextOption<
42
+ export type NodeHTTPCreateContextOption<
47
43
  TRouter extends AnyRouter,
48
44
  TRequest,
49
45
  TResponse,
50
- > = CreateContextCallback<
51
- inferRouterContext<TRouter>,
52
- NodeHTTPCreateContextFn<TRouter, TRequest, TResponse>
53
- >;
46
+ > = object extends inferRouterContext<TRouter>
47
+ ? {
48
+ /**
49
+ * @link https://trpc.io/docs/v11/context
50
+ **/
51
+ createContext?: NodeHTTPCreateContextFn<TRouter, TRequest, TResponse>;
52
+ }
53
+ : {
54
+ /**
55
+ * @link https://trpc.io/docs/v11/context
56
+ **/
57
+ createContext: NodeHTTPCreateContextFn<TRouter, TRequest, TResponse>;
58
+ };
54
59
 
55
60
  /**
56
61
  * @internal
@@ -60,50 +65,45 @@ type ConnectMiddleware<
60
65
  TResponse extends NodeHTTPResponse = NodeHTTPResponse,
61
66
  > = (req: TRequest, res: TResponse, next: (err?: any) => any) => void;
62
67
 
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
68
  export type NodeHTTPHandlerOptions<
90
69
  TRouter extends AnyRouter,
91
70
  TRequest extends NodeHTTPRequest,
92
71
  TResponse extends NodeHTTPResponse,
93
- > = CoreNodeHTTPHandlerOptions<TRouter, TRequest, TResponse> &
94
- NodeHTTPConditionCreateContextOption<TRouter, TRequest, TResponse>;
72
+ > = HTTPBaseHandlerOptions<TRouter, TRequest> &
73
+ NodeHTTPCreateContextOption<TRouter, TRequest, TResponse> & {
74
+ /**
75
+ * By default, http `OPTIONS` requests are not handled, and CORS headers are not returned.
76
+ *
77
+ * This can be used to handle them manually or via the `cors` npm package: https://www.npmjs.com/package/cors
78
+ *
79
+ * ```ts
80
+ * import cors from 'cors'
81
+ *
82
+ * nodeHTTPRequestHandler({
83
+ * cors: cors()
84
+ * })
85
+ * ```
86
+ *
87
+ * You can also use it for other needs which a connect/node.js compatible middleware can solve,
88
+ * though you might wish to consider an alternative solution like the Express adapter if your needs are complex.
89
+ */
90
+ middleware?: ConnectMiddleware;
91
+ maxBodySize?: number;
92
+ experimental_contentTypeHandlers?: NodeHTTPContentTypeHandler<
93
+ TRequest,
94
+ TResponse
95
+ >[];
96
+ };
95
97
 
96
- // Internal user
97
98
  export type NodeHTTPRequestHandlerOptions<
98
99
  TRouter extends AnyRouter,
99
100
  TRequest extends NodeHTTPRequest,
100
101
  TResponse extends NodeHTTPResponse,
101
- > = CoreNodeHTTPHandlerOptions<TRouter, TRequest, TResponse> &
102
- WrapCreateContext<NodeHTTPCreateContextFn<TRouter, TRequest, TResponse>> & {
103
- req: TRequest;
104
- res: TResponse;
105
- path: string;
106
- };
102
+ > = {
103
+ req: TRequest;
104
+ res: TResponse;
105
+ path: string;
106
+ } & NodeHTTPHandlerOptions<TRouter, TRequest, TResponse>;
107
107
 
108
108
  export type NodeHTTPCreateContextFnOptions<TRequest, TResponse> = {
109
109
  req: TRequest;
@@ -37,7 +37,8 @@ export function createHTTPHandler<TRouter extends AnyRouter>(
37
37
  const path = url.pathname.slice(1);
38
38
 
39
39
  await nodeHTTPRequestHandler({
40
- ...opts,
40
+ // FIXME: no typecasting should be needed here
41
+ ...(opts as CreateHTTPHandlerOptions<AnyRouter>),
41
42
  req,
42
43
  res,
43
44
  path,
@@ -1,10 +1,6 @@
1
1
  import type { IncomingMessage } from 'http';
2
2
  import type ws from 'ws';
3
- import type {
4
- AnyRouter,
5
- CreateContextCallback,
6
- inferRouterContext,
7
- } from '../@trpc/server';
3
+ import type { AnyRouter, inferRouterContext } from '../@trpc/server';
8
4
  import {
9
5
  callProcedure,
10
6
  getErrorShape,
@@ -50,10 +46,19 @@ export type CreateWSSContextFn<TRouter extends AnyRouter> = (
50
46
 
51
47
  export type WSConnectionHandlerOptions<TRouter extends AnyRouter> =
52
48
  BaseHandlerOptions<TRouter, IncomingMessage> &
53
- CreateContextCallback<
54
- inferRouterContext<TRouter>,
55
- CreateWSSContextFn<TRouter>
56
- >;
49
+ (object extends inferRouterContext<TRouter>
50
+ ? {
51
+ /**
52
+ * @link https://trpc.io/docs/v11/context
53
+ **/
54
+ createContext?: CreateWSSContextFn<TRouter>;
55
+ }
56
+ : {
57
+ /**
58
+ * @link https://trpc.io/docs/v11/context
59
+ **/
60
+ createContext: CreateWSSContextFn<TRouter>;
61
+ });
57
62
 
58
63
  /**
59
64
  * Web socket server handler
@@ -1,4 +1,16 @@
1
- import type { TRPCError } from '../error/TRPCError';
1
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
+ import { TRPCError } from '../error/TRPCError';
3
+ import type { AnyRouter } from '../router';
4
+ import type { CombinedDataTransformer } from '../transformer';
5
+ import type { MaybePromise } from '../types';
6
+ import type { HTTPRequest } from './types';
7
+
8
+ type GetInputs = (opts: {
9
+ req: HTTPRequest;
10
+ isBatchCall: boolean;
11
+ router: AnyRouter;
12
+ preprocessedBody: boolean;
13
+ }) => MaybePromise<Record<number, unknown>>;
2
14
 
3
15
  export type BodyResult =
4
16
  | {
@@ -12,13 +24,76 @@ export type BodyResult =
12
24
  | { ok: false; error: TRPCError };
13
25
 
14
26
  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;
22
- },
23
- ) => Promise<unknown>;
27
+ isMatch(opts: TOptions): boolean;
28
+ getBody: (opts: TOptions) => MaybePromise<BodyResult>;
29
+ getInputs: GetInputs;
30
+ };
31
+
32
+ function getRawProcedureInputOrThrow(opts: {
33
+ req: HTTPRequest;
34
+ preprocessedBody: boolean;
35
+ }) {
36
+ const { req } = opts;
37
+ try {
38
+ if (req.method === 'GET') {
39
+ if (!req.query.has('input')) {
40
+ return undefined;
41
+ }
42
+ const raw = req.query.get('input');
43
+ return JSON.parse(raw!);
44
+ }
45
+ if (!opts.preprocessedBody && typeof req.body === 'string') {
46
+ // A mutation with no inputs will have req.body === ''
47
+ return req.body.length === 0 ? undefined : JSON.parse(req.body);
48
+ }
49
+ return req.body;
50
+ } catch (cause) {
51
+ throw new TRPCError({
52
+ code: 'PARSE_ERROR',
53
+ cause,
54
+ });
55
+ }
56
+ }
57
+
58
+ const deserializeInputValue = (
59
+ rawValue: unknown,
60
+ transformer: CombinedDataTransformer,
61
+ ) => {
62
+ return typeof rawValue !== 'undefined'
63
+ ? transformer.input.deserialize(rawValue)
64
+ : rawValue;
65
+ };
66
+
67
+ export const getJsonContentTypeInputs: GetInputs = (opts) => {
68
+ const rawInput = getRawProcedureInputOrThrow(opts);
69
+ const transformer = opts.router._def._config.transformer;
70
+
71
+ if (!opts.isBatchCall) {
72
+ return {
73
+ 0: deserializeInputValue(rawInput, transformer),
74
+ };
75
+ }
76
+
77
+ /* istanbul ignore if */
78
+ if (
79
+ rawInput == null ||
80
+ typeof rawInput !== 'object' ||
81
+ Array.isArray(rawInput)
82
+ ) {
83
+ throw new TRPCError({
84
+ code: 'BAD_REQUEST',
85
+ message: '"input" needs to be an object when doing a batch call',
86
+ });
87
+ }
88
+ const input: Record<number, unknown> = {};
89
+ for (const key in rawInput) {
90
+ const k = key as any as number;
91
+ const rawValue = rawInput[k];
92
+
93
+ const value = deserializeInputValue(rawValue, transformer);
94
+
95
+ input[k] = value;
96
+ }
97
+
98
+ return input;
24
99
  };
@@ -24,5 +24,6 @@ export type {
24
24
 
25
25
  export { getBatchStreamFormatter } from './batchStreamFormatter';
26
26
  export type { BaseContentTypeHandler, BodyResult } from './contentType';
27
+ export { getJsonContentTypeInputs } from './contentType';
27
28
 
28
29
  export { toURL } from './toURL';
@@ -9,6 +9,9 @@ import type {
9
9
  import { callProcedure } from '../router';
10
10
  import type { TRPCResponse } from '../rpc';
11
11
  import { transformTRPCResponse } from '../transformer';
12
+ import type { Maybe } from '../types';
13
+ import type { BaseContentTypeHandler } from './contentType';
14
+ import { getJsonContentTypeInputs } from './contentType';
12
15
  import { getHTTPStatusCode } from './getHTTPStatusCode';
13
16
  import type {
14
17
  HTTPBaseHandlerOptions,
@@ -28,6 +31,10 @@ const HTTP_METHOD_PROCEDURE_TYPE_MAP: Record<
28
31
  POST: 'mutation',
29
32
  };
30
33
 
34
+ const fallbackContentTypeHandler = {
35
+ getInputs: getJsonContentTypeInputs,
36
+ };
37
+
31
38
  type PartialBy<TBaseType, TKey extends keyof TBaseType> = Omit<
32
39
  TBaseType,
33
40
  TKey
@@ -41,8 +48,9 @@ interface ResolveHTTPRequestOptions<
41
48
  createContext: ResolveHTTPRequestOptionsContextFn<TRouter>;
42
49
  req: TRequest;
43
50
  path: string;
44
- getInput: (opts: { isBatchCall: boolean; batch: number }) => Promise<unknown>;
45
- error?: TRPCError;
51
+ error?: Maybe<TRPCError>;
52
+ contentTypeHandler?: BaseContentTypeHandler<any>;
53
+ preprocessedBody?: boolean;
46
54
  /**
47
55
  * Called as soon as the response head is known.
48
56
  * When streaming, headers will have been generated
@@ -223,6 +231,8 @@ export async function resolveHTTPResponse<
223
231
  unstable_onChunk?.([-1, '']);
224
232
  return headResponse;
225
233
  }
234
+ const contentTypeHandler =
235
+ opts.contentTypeHandler ?? fallbackContentTypeHandler;
226
236
  const allowBatching = opts.allowBatching ?? opts.batching?.enabled ?? true;
227
237
  const allowMethodOverride = opts.allowMethodOverride ?? false;
228
238
 
@@ -239,6 +249,9 @@ export async function resolveHTTPResponse<
239
249
  req.headers['trpc-batch-mode'] === 'stream';
240
250
 
241
251
  try {
252
+ if (opts.error) {
253
+ throw opts.error;
254
+ }
242
255
  if (isBatchCall && !allowBatching) {
243
256
  throw new TRPCError({
244
257
  code: 'BAD_REQUEST',
@@ -259,26 +272,22 @@ export async function resolveHTTPResponse<
259
272
  });
260
273
  }
261
274
 
262
- const batchesCache: Record<number, unknown> = {};
263
- async function getRawInputForBatch(batch: number) {
264
- if (!batchesCache.hasOwnProperty(batch)) {
265
- batchesCache[batch] = await opts.getInput({
266
- isBatchCall,
267
- batch,
268
- });
269
- }
270
-
271
- return batchesCache[batch];
272
- }
275
+ const inputs = await contentTypeHandler.getInputs({
276
+ isBatchCall,
277
+ req,
278
+ router,
279
+ preprocessedBody: opts.preprocessedBody ?? false,
280
+ });
273
281
 
274
282
  paths = isBatchCall
275
283
  ? decodeURIComponent(opts.path).split(',')
276
284
  : [opts.path];
277
285
  const info: TRPCRequestInfo = {
278
286
  isBatchCall,
279
- calls: paths.map((path) => ({
287
+ calls: paths.map((path, idx) => ({
280
288
  path,
281
289
  type,
290
+ input: inputs[idx] ?? undefined,
282
291
  })),
283
292
  };
284
293
  ctx = await opts.createContext({ info });
@@ -288,22 +297,12 @@ export async function resolveHTTPResponse<
288
297
  const promises: Promise<
289
298
  TRPCResponse<unknown, inferRouterError<TRouter>>
290
299
  >[] = paths.map(async (path, index) => {
291
- async function getRawInput() {
292
- return await getRawInputForBatch(index);
293
- }
294
-
300
+ const input = inputs[index];
295
301
  try {
296
- if (opts.error) {
297
- // sometimes an error may be generated above this function in the stack
298
- // for instance a 405 error if the method is not supported
299
- // But we need to handle it here to ensure the error is formatted correctly
300
- throw opts.error;
301
- }
302
-
303
302
  const data = await callProcedure({
304
303
  procedures: opts.router._def.procedures,
305
304
  path,
306
- getRawInput: getRawInput,
305
+ getRawInput: async () => input,
307
306
  ctx,
308
307
  type,
309
308
  allowMethodOverride,
@@ -320,7 +319,7 @@ export async function resolveHTTPResponse<
320
319
  opts.onError?.({
321
320
  error,
322
321
  path,
323
- input: getRawInput(),
322
+ input,
324
323
  ctx,
325
324
  type: type,
326
325
  req: opts.req,
@@ -332,7 +331,7 @@ export async function resolveHTTPResponse<
332
331
  error,
333
332
  type,
334
333
  path,
335
- input: getRawInput(),
334
+ input,
336
335
  ctx,
337
336
  }),
338
337
  };
@@ -411,7 +410,7 @@ export async function resolveHTTPResponse<
411
410
  unstable_onChunk([index, body]);
412
411
  } catch (cause) {
413
412
  const path = paths[index];
414
- const input = await getRawInputForBatch(index);
413
+ const input = inputs[index];
415
414
  const { body } = caughtErrorToData(cause, {
416
415
  opts,
417
416
  ctx,
@@ -47,6 +47,7 @@ export interface HTTPRequest {
47
47
  method: string;
48
48
  query: URLSearchParams;
49
49
  headers: HTTPHeaders;
50
+ body: unknown;
50
51
  }
51
52
 
52
53
  /**
@@ -65,6 +66,7 @@ export interface HTTPBaseHandlerOptions<TRouter extends AnyRouter, TRequest>
65
66
  /** @internal */
66
67
  export type ProcedureCall = {
67
68
  type: ProcedureType;
69
+ input?: unknown;
68
70
  path: string;
69
71
  };
70
72
 
@@ -149,3 +149,4 @@ class TRPCBuilder<TContext extends object, TMeta extends object> {
149
149
  * @link https://trpc.io/docs/v11/quickstart
150
150
  */
151
151
  export const initTRPC = new TRPCBuilder();
152
+ export type { TRPCBuilder };
@@ -76,34 +76,3 @@ export type AnyRootTypes = CreateRootTypes<{
76
76
  errorShape: any;
77
77
  transformer: any;
78
78
  }>;
79
-
80
- type PartialIf<TCondition extends boolean, TType> = TCondition extends true
81
- ? Partial<TType>
82
- : TType;
83
-
84
- /**
85
- * Adds a `createContext` option with a given callback function
86
- * If context is the default value, then the `createContext` option is optional
87
- */
88
- export type CreateContextCallback<
89
- TContext,
90
- TFunction extends (...args: any[]) => any,
91
- > = PartialIf<
92
- object extends TContext ? true : false,
93
- {
94
- /**
95
- * @link https://trpc.io/docs/v11/context
96
- **/
97
- createContext: TFunction;
98
- }
99
- >;
100
-
101
- /**
102
- * @internal
103
- */
104
- export type WrapCreateContext<TFunction extends (...args: any[]) => any> = {
105
- /**
106
- * @link https://trpc.io/docs/v11/context
107
- **/
108
- createContext?: TFunction;
109
- };
@@ -1,10 +0,0 @@
1
- import type { AnyRouter } from '../../../../@trpc/server';
2
- import type { BaseContentTypeHandler, HTTPRequest } from '../../../../@trpc/server/http';
3
- import { type APIGatewayEvent, type AWSLambdaOptions } from '../../utils';
4
- export interface LambdaHTTPContentTypeHandler<TRouter extends AnyRouter, TEvent extends APIGatewayEvent> extends BaseContentTypeHandler<AWSLambdaOptions<TRouter, TEvent> & {
5
- event: TEvent;
6
- req: HTTPRequest;
7
- }> {
8
- }
9
- export declare const getLambdaHTTPJSONContentTypeHandler: <TRouter extends AnyRouter, TEvent extends APIGatewayEvent>() => LambdaHTTPContentTypeHandler<TRouter, TEvent>;
10
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/aws-lambda/content-type/json/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EAEV,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,sBAAsB,EACtB,WAAW,EACZ,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,4BAA4B,CAC3C,OAAO,SAAS,SAAS,EACzB,MAAM,SAAS,eAAe,CAC9B,SAAQ,sBAAsB,CAC5B,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,WAAW,CAAC;CAClB,CACF;CAAG;AAEN,eAAO,MAAM,mCAAmC,EAAE,CAChD,OAAO,SAAS,SAAS,EACzB,MAAM,SAAS,eAAe,OACzB,4BAA4B,CAAC,OAAO,EAAE,MAAM,CAqEjD,CAAC"}
@@ -1,59 +0,0 @@
1
- 'use strict';
2
-
3
- var TRPCError = require('../../../../unstable-core-do-not-import/error/TRPCError.js');
4
- require('../../../../unstable-core-do-not-import/rootConfig.js');
5
- var utils = require('../../utils.js');
6
-
7
- // @trpc/server
8
- const getLambdaHTTPJSONContentTypeHandler = ()=>({
9
- name: 'lambda-json',
10
- isMatch: (headers)=>{
11
- return !!headers.get('content-type')?.startsWith('application/json');
12
- },
13
- getInputs: async (opts, info)=>{
14
- function getRawProcedureInputOrThrow() {
15
- const { event , req } = opts;
16
- try {
17
- if (req.method === 'GET') {
18
- const input = req.query.get('input');
19
- if (!input) {
20
- return undefined;
21
- }
22
- return JSON.parse(input);
23
- }
24
- const body = utils.lambdaEventToHTTPBody(opts.event);
25
- if (typeof body === 'string') {
26
- // A mutation with no inputs will have req.body === ''
27
- return body.length === 0 ? undefined : JSON.parse(body);
28
- }
29
- return event.body;
30
- } catch (cause) {
31
- throw new TRPCError.TRPCError({
32
- code: 'PARSE_ERROR',
33
- cause
34
- });
35
- }
36
- }
37
- const deserializeInputValue = (rawValue, transformer)=>{
38
- return typeof rawValue !== 'undefined' ? transformer.input.deserialize(rawValue) : rawValue;
39
- };
40
- const rawInput = getRawProcedureInputOrThrow();
41
- if (rawInput === undefined) {
42
- return undefined;
43
- }
44
- const transformer = opts.router._def._config.transformer;
45
- if (!info.isBatchCall) {
46
- return deserializeInputValue(rawInput, transformer);
47
- }
48
- /* istanbul ignore if */ if (rawInput == null || typeof rawInput !== 'object' || Array.isArray(rawInput)) {
49
- throw new TRPCError.TRPCError({
50
- code: 'BAD_REQUEST',
51
- message: '"input" needs to be an object when doing a batch call'
52
- });
53
- }
54
- const rawValue = rawInput[info.batch];
55
- return deserializeInputValue(rawValue, transformer);
56
- }
57
- });
58
-
59
- exports.getLambdaHTTPJSONContentTypeHandler = getLambdaHTTPJSONContentTypeHandler;
@@ -1,57 +0,0 @@
1
- import { TRPCError } from '../../../../unstable-core-do-not-import/error/TRPCError.mjs';
2
- import '../../../../unstable-core-do-not-import/rootConfig.mjs';
3
- import { lambdaEventToHTTPBody } from '../../utils.mjs';
4
-
5
- // @trpc/server
6
- const getLambdaHTTPJSONContentTypeHandler = ()=>({
7
- name: 'lambda-json',
8
- isMatch: (headers)=>{
9
- return !!headers.get('content-type')?.startsWith('application/json');
10
- },
11
- getInputs: async (opts, info)=>{
12
- function getRawProcedureInputOrThrow() {
13
- const { event , req } = opts;
14
- try {
15
- if (req.method === 'GET') {
16
- const input = req.query.get('input');
17
- if (!input) {
18
- return undefined;
19
- }
20
- return JSON.parse(input);
21
- }
22
- const body = lambdaEventToHTTPBody(opts.event);
23
- if (typeof body === 'string') {
24
- // A mutation with no inputs will have req.body === ''
25
- return body.length === 0 ? undefined : JSON.parse(body);
26
- }
27
- return event.body;
28
- } catch (cause) {
29
- throw new TRPCError({
30
- code: 'PARSE_ERROR',
31
- cause
32
- });
33
- }
34
- }
35
- const deserializeInputValue = (rawValue, transformer)=>{
36
- return typeof rawValue !== 'undefined' ? transformer.input.deserialize(rawValue) : rawValue;
37
- };
38
- const rawInput = getRawProcedureInputOrThrow();
39
- if (rawInput === undefined) {
40
- return undefined;
41
- }
42
- const transformer = opts.router._def._config.transformer;
43
- if (!info.isBatchCall) {
44
- return deserializeInputValue(rawInput, transformer);
45
- }
46
- /* istanbul ignore if */ if (rawInput == null || typeof rawInput !== 'object' || Array.isArray(rawInput)) {
47
- throw new TRPCError({
48
- code: 'BAD_REQUEST',
49
- message: '"input" needs to be an object when doing a batch call'
50
- });
51
- }
52
- const rawValue = rawInput[info.batch];
53
- return deserializeInputValue(rawValue, transformer);
54
- }
55
- });
56
-
57
- export { getLambdaHTTPJSONContentTypeHandler };
@@ -1,10 +0,0 @@
1
- import { TRPCError } from '../../@trpc/server';
2
- import type { BaseContentTypeHandler, HTTPHeaders } from '../../@trpc/server/http';
3
- interface MinimalHandlerOpts {
4
- req: {
5
- headers: HTTPHeaders | Headers;
6
- };
7
- }
8
- export declare function selectContentHandlerOrUnsupportedMediaType<THandlerOpts extends MinimalHandlerOpts, THandler extends BaseContentTypeHandler<THandlerOpts>>(handlers: THandler[], opts: THandlerOpts): readonly [undefined, TRPCError] | readonly [THandler];
9
- export {};
10
- //# sourceMappingURL=selectContentHandlerOrUnsupportedMediaType.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"selectContentHandlerOrUnsupportedMediaType.d.ts","sourceRoot":"","sources":["../../../src/adapters/content-handlers/selectContentHandlerOrUnsupportedMediaType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,KAAK,EACV,sBAAsB,EACtB,WAAW,EACZ,MAAM,yBAAyB,CAAC;AAEjC,UAAU,kBAAkB;IAC1B,GAAG,EAAE;QAGH,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;KAChC,CAAC;CACH;AAED,wBAAgB,0CAA0C,CACxD,YAAY,SAAS,kBAAkB,EACvC,QAAQ,SAAS,sBAAsB,CAAC,YAAY,CAAC,EACrD,QAAQ,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,yDA2BzC"}
@@ -1,33 +0,0 @@
1
- 'use strict';
2
-
3
- var TRPCError = require('../../unstable-core-do-not-import/error/TRPCError.js');
4
- require('../../unstable-core-do-not-import/rootConfig.js');
5
-
6
- function selectContentHandlerOrUnsupportedMediaType(handlers, opts) {
7
- const headers = new Headers(opts.req.headers);
8
- const contentType = headers.get('content-type');
9
- if (contentType === null) {
10
- return [
11
- undefined,
12
- new TRPCError.TRPCError({
13
- code: 'UNSUPPORTED_MEDIA_TYPE',
14
- message: 'No Content-Type header detected on the incoming request. This request may not be supported by your tRPC Adapter, or possibly by tRPC at all'
15
- })
16
- ];
17
- }
18
- const handler = handlers.find((handler)=>handler.isMatch(headers));
19
- if (!handler) {
20
- return [
21
- undefined,
22
- new TRPCError.TRPCError({
23
- code: 'UNSUPPORTED_MEDIA_TYPE',
24
- message: `Invalid Content-Type header '${contentType}'. This request may not be supported by your tRPC Adapter, or possibly by tRPC at all`
25
- })
26
- ];
27
- }
28
- return [
29
- handler
30
- ];
31
- }
32
-
33
- exports.selectContentHandlerOrUnsupportedMediaType = selectContentHandlerOrUnsupportedMediaType;