@trpc/server
Version:
139 lines (127 loc) • 4.01 kB
text/typescript
/**
* If you're making an adapter for tRPC and looking at this file for reference, you should import types and functions from `@trpc/server` and `@trpc/server/http`
*
* @example
* ```ts
* import type { AnyTRPCRouter } from '@trpc/server'
* import type { HTTPBaseHandlerOptions } from '@trpc/server/http'
* ```
*/
import type { Context as APIGWContext, StreamifyHandler } from 'aws-lambda';
// @trpc/server
import type {
AnyRouter,
CreateContextCallback,
inferRouterContext,
} from '../../@trpc/server';
// @trpc/server
import type {
HTTPBaseHandlerOptions,
ResolveHTTPRequestOptionsContextFn,
TRPCRequestInfo,
} from '../../@trpc/server/http';
import { resolveResponse } from '../../@trpc/server/http';
import type { inferAPIGWReturn, LambdaEvent } from './getPlanner';
import { getPlanner } from './getPlanner';
/**
* What `createContext` gets in the AWS Lambda adapter: the event, the
* Lambda context and the request's `info`.
* @see https://trpc.io/docs/server/adapters/aws-lambda#2-create-a-trpc-router
*/
export type CreateAWSLambdaContextOptions<TEvent extends LambdaEvent> = {
/** The API Gateway or function URL event. */
event: TEvent;
/** The Lambda invocation's context. */
context: APIGWContext;
info: TRPCRequestInfo;
};
/**
* The options of `awsLambdaRequestHandler` and
* `awsLambdaStreamingRequestHandler`.
* @see https://trpc.io/docs/server/adapters/aws-lambda
*/
export type AWSLambdaOptions<
TRouter extends AnyRouter,
TEvent extends LambdaEvent,
> = HTTPBaseHandlerOptions<TRouter, TEvent> &
CreateContextCallback<
inferRouterContext<AnyRouter>,
AWSLambdaCreateContextFn<TRouter, TEvent>
>;
/** The `createContext` function the AWS Lambda adapter takes. */
export type AWSLambdaCreateContextFn<
TRouter extends AnyRouter,
TEvent extends LambdaEvent,
> = ({
event,
context,
info,
}: CreateAWSLambdaContextOptions<TEvent>) =>
| inferRouterContext<TRouter>
| Promise<inferRouterContext<TRouter>>;
/**
* Creates a Lambda handler for a router, for API Gateway (REST and HTTP
* APIs) and Lambda function URLs.
* @see https://trpc.io/docs/server/adapters/aws-lambda#3-use-the-amazon-api-gateway-adapter
*/
export function awsLambdaRequestHandler<
TRouter extends AnyRouter,
TEvent extends LambdaEvent,
>(
opts: AWSLambdaOptions<TRouter, TEvent>,
): (event: TEvent, context: APIGWContext) => Promise<inferAPIGWReturn<TEvent>> {
return async (event, context) => {
const planner = getPlanner(event);
const createContext: ResolveHTTPRequestOptionsContextFn<TRouter> = async (
innerOpts,
) => {
return await opts.createContext?.({ event, context, ...innerOpts });
};
const response = await resolveResponse({
...opts,
createContext,
req: planner.request,
path: planner.path,
error: null,
onError(o) {
opts?.onError?.({
...o,
req: event,
});
},
});
return await planner.toResult(response);
};
}
/**
* Creates a Lambda handler that streams its response, for use with
* `awslambda.streamifyResponse()`.
* @see https://trpc.io/docs/server/adapters/aws-lambda#aws-lambda-response-streaming-adapter
*/
export function awsLambdaStreamingRequestHandler<
TRouter extends AnyRouter,
TEvent extends LambdaEvent,
>(opts: AWSLambdaOptions<TRouter, TEvent>): StreamifyHandler<TEvent> {
return async (event, responseStream, context) => {
const planner = getPlanner(event);
const createContext: ResolveHTTPRequestOptionsContextFn<TRouter> = async (
innerOpts,
) => {
return await opts.createContext?.({ event, context, ...innerOpts });
};
const response = await resolveResponse({
...opts,
createContext,
req: planner.request,
path: planner.path,
error: null,
onError(o) {
opts?.onError?.({
...o,
req: event,
});
},
});
await planner.toStream(response, responseStream);
};
}