@trpc/server 9.23.6 → 9.25.1

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 (51) hide show
  1. package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.d.ts +1 -0
  2. package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.dev.js +170 -0
  3. package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.js +7 -0
  4. package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.prod.js +170 -0
  5. package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.esm.js +166 -0
  6. package/adapters/aws-lambda/package.json +4 -0
  7. package/adapters/lambda/dist/trpc-server-adapters-lambda.cjs.d.ts +1 -0
  8. package/adapters/lambda/dist/trpc-server-adapters-lambda.cjs.dev.js +25 -0
  9. package/adapters/lambda/dist/trpc-server-adapters-lambda.cjs.js +7 -0
  10. package/adapters/lambda/dist/trpc-server-adapters-lambda.cjs.prod.js +25 -0
  11. package/adapters/lambda/dist/trpc-server-adapters-lambda.esm.js +21 -0
  12. package/adapters/lambda/package.json +4 -0
  13. package/dist/declarations/src/adapters/aws-lambda/index.d.ts +14 -0
  14. package/dist/declarations/src/adapters/aws-lambda/index.d.ts.map +1 -0
  15. package/dist/declarations/src/adapters/aws-lambda/utils.d.ts +34 -0
  16. package/dist/declarations/src/adapters/aws-lambda/utils.d.ts.map +1 -0
  17. package/dist/declarations/src/adapters/lambda/index.d.ts +12 -0
  18. package/dist/declarations/src/adapters/lambda/index.d.ts.map +1 -0
  19. package/dist/declarations/src/adapters/ws.d.ts +1 -1
  20. package/dist/declarations/src/deprecated/{LegacyRouter.d.ts → legacyRouter.d.ts} +1 -1
  21. package/dist/declarations/src/deprecated/legacyRouter.d.ts.map +1 -0
  22. package/dist/declarations/src/http/index.d.ts +1 -1
  23. package/dist/declarations/src/http/internals/types.d.ts +2 -3
  24. package/dist/declarations/src/http/internals/types.d.ts.map +1 -1
  25. package/dist/declarations/src/http/{ResponseMeta.d.ts → responseMeta.d.ts} +1 -1
  26. package/dist/declarations/src/http/responseMeta.d.ts.map +1 -0
  27. package/dist/declarations/src/index.d.ts +1 -1
  28. package/dist/declarations/src/internals/{BaseHandlerOptions.d.ts → baseHandlerOptions.d.ts} +2 -2
  29. package/dist/declarations/src/internals/{BaseHandlerOptions.d.ts.map → baseHandlerOptions.d.ts.map} +1 -1
  30. package/dist/declarations/src/internals/{OnErrorFunction.d.ts → onErrorFunction.d.ts} +1 -1
  31. package/dist/declarations/src/internals/{OnErrorFunction.d.ts.map → onErrorFunction.d.ts.map} +1 -1
  32. package/dist/router-2f54c292.cjs.dev.js +507 -0
  33. package/dist/router-459409c8.cjs.prod.js +503 -0
  34. package/dist/router-93491dae.esm.js +504 -0
  35. package/dist/trpc-server.cjs.dev.js +5 -503
  36. package/dist/trpc-server.cjs.prod.js +5 -499
  37. package/dist/trpc-server.esm.js +3 -503
  38. package/package.json +5 -2
  39. package/src/adapters/aws-lambda/index.ts +156 -0
  40. package/src/adapters/aws-lambda/utils.ts +91 -0
  41. package/src/adapters/lambda/index.ts +18 -0
  42. package/src/adapters/ws.ts +1 -1
  43. package/src/deprecated/{LegacyRouter.ts → legacyRouter.ts} +0 -0
  44. package/src/http/index.ts +1 -1
  45. package/src/http/internals/types.ts +2 -2
  46. package/src/http/{ResponseMeta.ts → responseMeta.ts} +0 -0
  47. package/src/index.ts +1 -1
  48. package/src/internals/{BaseHandlerOptions.ts → baseHandlerOptions.ts} +1 -1
  49. package/src/internals/{OnErrorFunction.ts → onErrorFunction.ts} +0 -0
  50. package/dist/declarations/src/deprecated/LegacyRouter.d.ts.map +0 -1
  51. package/dist/declarations/src/http/ResponseMeta.d.ts.map +0 -1
@@ -1,17 +1,14 @@
1
- import { a as assertNotBrowser, g as getHTTPStatusCodeFromError } from './resolveHTTPResponse-ddb56677.esm.js';
2
1
  export { a as assertNotBrowser, r as resolveHTTPResponse } from './resolveHTTPResponse-ddb56677.esm.js';
2
+ export { L as LegacyRouter, L as Router, r as router } from './router-93491dae.esm.js';
3
3
  export { S as Subscription, s as subscriptionPullFactory } from './subscription-2ea469a3.esm.js';
4
- import { T as TRPCError, g as getErrorFromUnknown } from './transformTRPCResponse-45c225c3.esm.js';
5
4
  export { T as TRPCError } from './transformTRPCResponse-45c225c3.esm.js';
6
5
  import { createHTTPServer, createHTTPHandler } from '../adapters/standalone/dist/trpc-server-adapters-standalone.esm.js';
7
6
  import { n as nodeHTTPRequestHandler } from './nodeHTTPRequestHandler-372a4a4f.esm.js';
8
- import { T as TRPC_ERROR_CODES_BY_KEY } from './codes-5678cc97.esm.js';
7
+ import './codes-5678cc97.esm.js';
9
8
  import 'events';
10
9
  import 'http';
11
10
  import 'url';
12
11
 
13
- assertNotBrowser();
14
-
15
12
  // this has been moved to separate package
16
13
 
17
14
  /**
@@ -36,501 +33,4 @@ const requestHandler = nodeHTTPRequestHandler;
36
33
  * @deprecated use `NodeHTTPCreateContextFn` from `@trpc/server/adapters/node-http`
37
34
  */
38
35
 
39
- const middlewareMarker = 'middlewareMarker';
40
-
41
- /* eslint-disable @typescript-eslint/no-explicit-any */
42
- assertNotBrowser();
43
-
44
- function getParseFn(procedureParser) {
45
- const parser = procedureParser;
46
-
47
- if (typeof parser === 'function') {
48
- // ProcedureParserCustomValidatorEsque
49
- return parser;
50
- }
51
-
52
- if (typeof parser.parseAsync === 'function') {
53
- // ProcedureParserZodEsque
54
- return parser.parseAsync.bind(parser);
55
- }
56
-
57
- if (typeof parser.parse === 'function') {
58
- // ProcedureParserZodEsque
59
- return parser.parse.bind(parser);
60
- }
61
-
62
- if (typeof parser.validateSync === 'function') {
63
- // ProcedureParserYupEsque
64
- return parser.validateSync.bind(parser);
65
- }
66
-
67
- if (typeof parser.create === 'function') {
68
- // ProcedureParserSuperstructEsque
69
- return parser.create.bind(parser);
70
- }
71
-
72
- throw new Error('Could not find a validator fn');
73
- }
74
- /**
75
- * @internal
76
- */
77
-
78
-
79
- class Procedure {
80
- constructor(opts) {
81
- this.middlewares = void 0;
82
- this.resolver = void 0;
83
- this.inputParser = void 0;
84
- this.parseInputFn = void 0;
85
- this.outputParser = void 0;
86
- this.parseOutputFn = void 0;
87
- this.meta = void 0;
88
- this.middlewares = opts.middlewares;
89
- this.resolver = opts.resolver;
90
- this.inputParser = opts.inputParser;
91
- this.parseInputFn = getParseFn(this.inputParser);
92
- this.outputParser = opts.outputParser;
93
- this.parseOutputFn = getParseFn(this.outputParser);
94
- this.meta = opts.meta;
95
- }
96
-
97
- async parseInput(rawInput) {
98
- try {
99
- return await this.parseInputFn(rawInput);
100
- } catch (cause) {
101
- throw new TRPCError({
102
- code: 'BAD_REQUEST',
103
- cause
104
- });
105
- }
106
- }
107
-
108
- async parseOutput(rawOutput) {
109
- try {
110
- return await this.parseOutputFn(rawOutput);
111
- } catch (cause) {
112
- throw new TRPCError({
113
- code: 'INTERNAL_SERVER_ERROR',
114
- cause,
115
- message: 'Output validation failed'
116
- });
117
- }
118
- }
119
- /**
120
- * Trigger middlewares in order, parse raw input, call resolver & parse raw output
121
- * @internal
122
- */
123
-
124
-
125
- async call(opts) {
126
- // wrap the actual resolver and treat as the last "middleware"
127
- const middlewaresWithResolver = this.middlewares.concat([async ({
128
- ctx
129
- }) => {
130
- const input = await this.parseInput(opts.rawInput);
131
- const rawOutput = await this.resolver({ ...opts,
132
- ctx,
133
- input
134
- });
135
- const data = await this.parseOutput(rawOutput);
136
- return {
137
- marker: middlewareMarker,
138
- ok: true,
139
- data,
140
- ctx
141
- };
142
- }]); // run the middlewares recursively with the resolver as the last one
143
-
144
- const callRecursive = async (callOpts = {
145
- index: 0,
146
- ctx: opts.ctx
147
- }) => {
148
- try {
149
- const result = await middlewaresWithResolver[callOpts.index]({
150
- ctx: callOpts.ctx,
151
- type: opts.type,
152
- path: opts.path,
153
- rawInput: opts.rawInput,
154
- meta: this.meta,
155
- next: async nextOpts => {
156
- return await callRecursive({
157
- index: callOpts.index + 1,
158
- ctx: nextOpts ? nextOpts.ctx : callOpts.ctx
159
- });
160
- }
161
- });
162
- return result;
163
- } catch (cause) {
164
- return {
165
- ctx: callOpts.ctx,
166
- ok: false,
167
- error: getErrorFromUnknown(cause),
168
- marker: middlewareMarker
169
- };
170
- }
171
- }; // there's always at least one "next" since we wrap this.resolver in a middleware
172
-
173
-
174
- const result = await callRecursive();
175
-
176
- if (!result) {
177
- throw new TRPCError({
178
- code: 'INTERNAL_SERVER_ERROR',
179
- message: 'No result from middlewares - did you forget to `return next()`?'
180
- });
181
- }
182
-
183
- if (!result.ok) {
184
- // re-throw original error
185
- throw result.error;
186
- }
187
-
188
- return result.data;
189
- }
190
- /**
191
- * Create new procedure with passed middlewares
192
- * @param middlewares
193
- */
194
-
195
-
196
- inheritMiddlewares(middlewares) {
197
- const Constructor = this.constructor;
198
- const instance = new Constructor({
199
- middlewares: [...middlewares, ...this.middlewares],
200
- resolver: this.resolver,
201
- inputParser: this.inputParser,
202
- outputParser: this.outputParser,
203
- meta: this.meta
204
- });
205
- return instance;
206
- }
207
-
208
- }
209
- function createProcedure(opts) {
210
- const inputParser = 'input' in opts ? opts.input : input => {
211
- if (input != null) {
212
- throw new TRPCError({
213
- code: 'BAD_REQUEST',
214
- message: 'No input expected'
215
- });
216
- }
217
-
218
- return undefined;
219
- };
220
- const outputParser = 'output' in opts && opts.output ? opts.output : output => output;
221
- return new Procedure({
222
- inputParser: inputParser,
223
- resolver: opts.resolve,
224
- middlewares: [],
225
- outputParser: outputParser,
226
- meta: opts.meta
227
- });
228
- }
229
-
230
- /* eslint-disable @typescript-eslint/ban-types */
231
- assertNotBrowser();
232
- /**
233
- * @public
234
- */
235
-
236
- function getDataTransformer(transformer) {
237
- if ('input' in transformer) {
238
- return transformer;
239
- }
240
-
241
- return {
242
- input: transformer,
243
- output: transformer
244
- };
245
- }
246
- /**
247
- * @internal
248
- */
249
-
250
-
251
- const PROCEDURE_DEFINITION_MAP = {
252
- query: 'queries',
253
- mutation: 'mutations',
254
- subscription: 'subscriptions'
255
- };
256
- /**
257
- * @internal
258
- */
259
-
260
- function safeObject(...args) {
261
- return Object.assign(Object.create(null), ...args);
262
- }
263
-
264
- const defaultFormatter = ({
265
- shape
266
- }) => {
267
- return shape;
268
- };
269
-
270
- const defaultTransformer = {
271
- input: {
272
- serialize: obj => obj,
273
- deserialize: obj => obj
274
- },
275
- output: {
276
- serialize: obj => obj,
277
- deserialize: obj => obj
278
- }
279
- };
280
-
281
- /**
282
- * @internal The type signature of this class may change without warning.
283
- */
284
- class Router {
285
- constructor(def) {
286
- var _def$queries, _def$mutations, _def$subscriptions, _def$middlewares, _def$errorFormatter, _def$transformer;
287
-
288
- this._def = void 0;
289
- this._def = {
290
- queries: (_def$queries = def === null || def === void 0 ? void 0 : def.queries) !== null && _def$queries !== void 0 ? _def$queries : safeObject(),
291
- mutations: (_def$mutations = def === null || def === void 0 ? void 0 : def.mutations) !== null && _def$mutations !== void 0 ? _def$mutations : safeObject(),
292
- subscriptions: (_def$subscriptions = def === null || def === void 0 ? void 0 : def.subscriptions) !== null && _def$subscriptions !== void 0 ? _def$subscriptions : safeObject(),
293
- middlewares: (_def$middlewares = def === null || def === void 0 ? void 0 : def.middlewares) !== null && _def$middlewares !== void 0 ? _def$middlewares : [],
294
- errorFormatter: (_def$errorFormatter = def === null || def === void 0 ? void 0 : def.errorFormatter) !== null && _def$errorFormatter !== void 0 ? _def$errorFormatter : defaultFormatter,
295
- transformer: (_def$transformer = def === null || def === void 0 ? void 0 : def.transformer) !== null && _def$transformer !== void 0 ? _def$transformer : defaultTransformer
296
- };
297
- }
298
-
299
- static prefixProcedures(procedures, prefix) {
300
- const eps = safeObject();
301
-
302
- for (const key in procedures) {
303
- eps[prefix + key] = procedures[key];
304
- }
305
-
306
- return eps;
307
- }
308
-
309
- query(path, procedure) {
310
- const router = new Router({
311
- queries: safeObject({
312
- [path]: createProcedure(procedure)
313
- })
314
- });
315
- return this.merge(router);
316
- }
317
-
318
- mutation(path, procedure) {
319
- const router = new Router({
320
- mutations: safeObject({
321
- [path]: createProcedure(procedure)
322
- })
323
- });
324
- return this.merge(router);
325
- }
326
- /**
327
- * @beta Might change without a major version bump
328
- */
329
-
330
-
331
- subscription(path, procedure) {
332
- const router = new Router({
333
- subscriptions: safeObject({
334
- [path]: createProcedure(procedure)
335
- })
336
- });
337
- return this.merge(router);
338
- }
339
- /**
340
- * Merge router with other router
341
- * @param router
342
- */
343
-
344
-
345
- merge(prefixOrRouter, maybeRouter) {
346
- let prefix = '';
347
- let childRouter;
348
-
349
- if (typeof prefixOrRouter === 'string' && maybeRouter instanceof Router) {
350
- prefix = prefixOrRouter;
351
- childRouter = maybeRouter;
352
- } else if (prefixOrRouter instanceof Router) {
353
- childRouter = prefixOrRouter;
354
- }
355
- /* istanbul ignore next */
356
- else {
357
- throw new Error('Invalid args');
358
- }
359
-
360
- const duplicateQueries = Object.keys(childRouter._def.queries).filter(key => !!this._def['queries'][prefix + key]);
361
- const duplicateMutations = Object.keys(childRouter._def.mutations).filter(key => !!this._def['mutations'][prefix + key]);
362
- const duplicateSubscriptions = Object.keys(childRouter._def.subscriptions).filter(key => !!this._def['subscriptions'][prefix + key]);
363
- const duplicates = [...duplicateQueries, ...duplicateMutations, ...duplicateSubscriptions];
364
-
365
- if (duplicates.length) {
366
- throw new Error(`Duplicate endpoint(s): ${duplicates.join(', ')}`);
367
- }
368
-
369
- const mergeProcedures = defs => {
370
- const newDefs = safeObject();
371
-
372
- for (const key in defs) {
373
- const procedure = defs[key];
374
- const newProcedure = procedure.inheritMiddlewares(this._def.middlewares);
375
- newDefs[key] = newProcedure;
376
- }
377
-
378
- return Router.prefixProcedures(newDefs, prefix);
379
- };
380
-
381
- return new Router({ ...this._def,
382
- queries: safeObject(this._def.queries, mergeProcedures(childRouter._def.queries)),
383
- mutations: safeObject(this._def.mutations, mergeProcedures(childRouter._def.mutations)),
384
- subscriptions: safeObject(this._def.subscriptions, mergeProcedures(childRouter._def.subscriptions))
385
- });
386
- }
387
- /**
388
- * Invoke procedure. Only for internal use within library.
389
- */
390
-
391
-
392
- async call(opts) {
393
- const {
394
- type,
395
- path
396
- } = opts;
397
- const defTarget = PROCEDURE_DEFINITION_MAP[type];
398
- const defs = this._def[defTarget];
399
- const procedure = defs[path];
400
-
401
- if (!procedure) {
402
- throw new TRPCError({
403
- code: 'NOT_FOUND',
404
- message: `No "${type}"-procedure on path "${path}"`
405
- });
406
- }
407
-
408
- return procedure.call(opts);
409
- }
410
-
411
- createCaller(ctx) {
412
- return {
413
- query: (path, ...args) => {
414
- return this.call({
415
- type: 'query',
416
- ctx,
417
- path,
418
- rawInput: args[0]
419
- });
420
- },
421
- mutation: (path, ...args) => {
422
- return this.call({
423
- type: 'mutation',
424
- ctx,
425
- path,
426
- rawInput: args[0]
427
- });
428
- },
429
- subscription: (path, ...args) => {
430
- return this.call({
431
- type: 'subscription',
432
- ctx,
433
- path,
434
- rawInput: args[0]
435
- });
436
- }
437
- };
438
- }
439
- /**
440
- * Function to be called before any procedure is invoked
441
- * @link https://trpc.io/docs/middlewares
442
- */
443
-
444
-
445
- middleware(middleware) {
446
- return new Router({ ...this._def,
447
- middlewares: [...this._def.middlewares, middleware]
448
- });
449
- }
450
- /**
451
- * Format errors
452
- * @link https://trpc.io/docs/error-formatting
453
- */
454
-
455
-
456
- formatError(errorFormatter) {
457
- if (this._def.errorFormatter !== defaultFormatter) {
458
- throw new Error('You seem to have double `formatError()`-calls in your router tree');
459
- }
460
-
461
- return new Router({ ...this._def,
462
- errorFormatter: errorFormatter
463
- });
464
- }
465
-
466
- getErrorShape(opts) {
467
- const {
468
- path,
469
- error
470
- } = opts;
471
- const {
472
- code
473
- } = opts.error;
474
- const shape = {
475
- message: error.message,
476
- code: TRPC_ERROR_CODES_BY_KEY[code],
477
- data: {
478
- code,
479
- httpStatus: getHTTPStatusCodeFromError(error)
480
- }
481
- };
482
-
483
- if (process.env.NODE_ENV !== 'production' && typeof opts.error.stack === 'string') {
484
- shape.data.stack = opts.error.stack;
485
- }
486
-
487
- if (typeof path === 'string') {
488
- shape.data.path = path;
489
- }
490
-
491
- return this._def.errorFormatter({ ...opts,
492
- shape
493
- });
494
- }
495
- /**
496
- * Add data transformer to serialize/deserialize input args + output
497
- * @link https://trpc.io/docs/data-transformers
498
- */
499
-
500
-
501
- transformer(_transformer) {
502
- const transformer = getDataTransformer(_transformer);
503
-
504
- if (this._def.transformer !== defaultTransformer) {
505
- throw new Error('You seem to have double `transformer()`-calls in your router tree');
506
- }
507
-
508
- return new Router({ ...this._def,
509
- transformer
510
- });
511
- }
512
- /**
513
- * Flattens the generics of TQueries/TMutations/TSubscriptions.
514
- * ⚠️ Experimental - might disappear. ⚠️
515
- *
516
- * @alpha
517
- */
518
-
519
-
520
- flat() {
521
- return this;
522
- }
523
-
524
- }
525
- /**
526
- * Subclass of `VNextRouter` with `TInputContext` and `TContext` set to the same type, for backcompat.
527
- *
528
- * @deprecated
529
- */
530
-
531
- class LegacyRouter extends Router {}
532
- function router() {
533
- return new Router();
534
- }
535
-
536
- export { LegacyRouter, LegacyRouter as Router, createHttpHandler, createHttpServer, requestHandler, router };
36
+ export { createHttpHandler, createHttpServer, requestHandler };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trpc/server",
3
- "version": "9.23.6",
3
+ "version": "9.25.1",
4
4
  "description": "tRPC Server",
5
5
  "author": "KATT",
6
6
  "license": "MIT",
@@ -24,6 +24,8 @@
24
24
  "adapters/node-http/index.ts",
25
25
  "adapters/standalone.ts",
26
26
  "adapters/ws.ts",
27
+ "adapters/lambda/index.ts",
28
+ "adapters/aws-lambda/index.ts",
27
29
  "ws/index.ts",
28
30
  "rpc/index.ts"
29
31
  ]
@@ -47,6 +49,7 @@
47
49
  },
48
50
  "devDependencies": {
49
51
  "@fastify/websocket": "^5.0.0",
52
+ "@types/aws-lambda": "^8.10.97",
50
53
  "@types/express": "^4.17.12",
51
54
  "@types/hash-sum": "^1.0.0",
52
55
  "@types/ws": "^8.2.0",
@@ -67,5 +70,5 @@
67
70
  "yup": "^0.32.8",
68
71
  "zod": "^3.0.0"
69
72
  },
70
- "gitHead": "c4138897578949d910dd0bce9e1471a6ae73137e"
73
+ "gitHead": "2f26e632a648ebfdc9da10f57a127d588162b976"
71
74
  }
@@ -0,0 +1,156 @@
1
+ import type {
2
+ Context as APIGWContext,
3
+ APIGatewayProxyEvent,
4
+ APIGatewayProxyEventV2,
5
+ APIGatewayProxyResult,
6
+ APIGatewayProxyStructuredResultV2,
7
+ } from 'aws-lambda';
8
+ import { TRPCError, resolveHTTPResponse } from '../..';
9
+ import { HTTPHeaders, HTTPRequest } from '../../http/internals/types';
10
+ import type { HTTPResponse } from '../../http/internals/types';
11
+ import { AnyRouter, inferRouterContext } from '../../router';
12
+ import {
13
+ APIGatewayEvent,
14
+ APIGatewayResult,
15
+ AWSLambdaOptions,
16
+ UNKNOWN_PAYLOAD_FORMAT_VERSION_ERROR_MESSAGE,
17
+ isPayloadV1,
18
+ isPayloadV2,
19
+ } from './utils';
20
+
21
+ export type { CreateAWSLambdaContextOptions, AWSLambdaOptions } from './utils';
22
+
23
+ function lambdaEventToHTTPRequest(event: APIGatewayEvent): HTTPRequest {
24
+ const query = new URLSearchParams();
25
+ for (const [key, value] of Object.entries(
26
+ event.queryStringParameters ?? {},
27
+ )) {
28
+ if (typeof value !== 'undefined') {
29
+ query.append(key, value);
30
+ }
31
+ }
32
+
33
+ return {
34
+ method: getHTTPMethod(event),
35
+ query: query,
36
+ headers: event.headers,
37
+ body: event.body,
38
+ };
39
+ }
40
+
41
+ function getHTTPMethod(event: APIGatewayEvent) {
42
+ if (isPayloadV1(event)) {
43
+ return event.httpMethod;
44
+ }
45
+ if (isPayloadV2(event)) {
46
+ return event.requestContext.http.method;
47
+ }
48
+ throw new TRPCError({
49
+ code: 'INTERNAL_SERVER_ERROR',
50
+ message: UNKNOWN_PAYLOAD_FORMAT_VERSION_ERROR_MESSAGE,
51
+ });
52
+ }
53
+ function getPath(event: APIGatewayEvent) {
54
+ if (isPayloadV1(event)) {
55
+ return event.path.slice(1);
56
+ }
57
+ if (isPayloadV2(event)) {
58
+ return event.rawPath.slice(1);
59
+ }
60
+ throw new TRPCError({
61
+ code: 'INTERNAL_SERVER_ERROR',
62
+ message: UNKNOWN_PAYLOAD_FORMAT_VERSION_ERROR_MESSAGE,
63
+ });
64
+ }
65
+ function transformHeaders(headers: HTTPHeaders): APIGatewayResult['headers'] {
66
+ const obj: APIGatewayResult['headers'] = {};
67
+
68
+ for (const [key, value] of Object.entries(headers)) {
69
+ if (typeof value === 'undefined') {
70
+ continue;
71
+ }
72
+ obj[key] = Array.isArray(value) ? value.join(',') : value;
73
+ }
74
+ return obj;
75
+ }
76
+ function tRPCOutputToAPIGatewayOutput<
77
+ TEvent extends APIGatewayEvent,
78
+ TResult extends APIGatewayResult,
79
+ >(event: TEvent, response: HTTPResponse): TResult {
80
+ if (isPayloadV1(event)) {
81
+ const resp: APIGatewayProxyResult = {
82
+ statusCode: response.status,
83
+ body: response.body ?? '',
84
+ headers: transformHeaders(response.headers ?? {}),
85
+ };
86
+ return resp as TResult;
87
+ } else if (isPayloadV2(event)) {
88
+ const resp: APIGatewayProxyStructuredResultV2 = {
89
+ statusCode: response.status,
90
+ body: response.body ?? undefined,
91
+ headers: transformHeaders(response.headers ?? {}),
92
+ };
93
+ return resp as TResult;
94
+ } else {
95
+ throw new TRPCError({
96
+ code: 'INTERNAL_SERVER_ERROR',
97
+ message: UNKNOWN_PAYLOAD_FORMAT_VERSION_ERROR_MESSAGE,
98
+ });
99
+ }
100
+ }
101
+
102
+ /** Will check the createContext of the TRouter and get the parameter of event.
103
+ * @internal
104
+ **/
105
+ type inferAPIGWEvent<
106
+ TRouter extends AnyRouter,
107
+ TEvent extends APIGatewayEvent,
108
+ > = AWSLambdaOptions<TRouter, TEvent>['createContext'] extends NonNullable<
109
+ AWSLambdaOptions<TRouter, TEvent>['createContext']
110
+ >
111
+ ? Parameters<AWSLambdaOptions<TRouter, TEvent>['createContext']>[0]['event']
112
+ : APIGatewayEvent;
113
+
114
+ /** 1:1 mapping of v1 or v2 input events, deduces which is which.
115
+ * @internal
116
+ **/
117
+ type inferAPIGWReturn<T> = T extends APIGatewayProxyEvent
118
+ ? APIGatewayProxyResult
119
+ : T extends APIGatewayProxyEventV2
120
+ ? APIGatewayProxyStructuredResultV2
121
+ : never;
122
+ export function awsLambdaRequestHandler<
123
+ TRouter extends AnyRouter,
124
+ TEvent extends inferAPIGWEvent<TRouter, TEvent>,
125
+ TResult extends inferAPIGWReturn<TEvent>,
126
+ >(
127
+ opts: AWSLambdaOptions<TRouter, TEvent>,
128
+ ): (event: TEvent, context: APIGWContext) => Promise<TResult> {
129
+ return async (event, context) => {
130
+ const req = lambdaEventToHTTPRequest(event);
131
+ const path = getPath(event);
132
+ const createContext = async function _createContext(): Promise<
133
+ inferRouterContext<TRouter>
134
+ > {
135
+ return await opts.createContext?.({ event, context });
136
+ };
137
+
138
+ const response = await resolveHTTPResponse({
139
+ router: opts.router,
140
+ batching: opts.batching,
141
+ responseMeta: opts?.responseMeta,
142
+ createContext,
143
+ req,
144
+ path,
145
+ error: null,
146
+ onError(o) {
147
+ opts?.onError?.({
148
+ ...o,
149
+ req: event,
150
+ });
151
+ },
152
+ });
153
+
154
+ return tRPCOutputToAPIGatewayOutput<TEvent, TResult>(event, response);
155
+ };
156
+ }