@trpc/server
Version:
1 lines • 19.8 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/vendor/cookie-es/set-cookie/split.ts","../../../src/adapters/aws-lambda/getPlanner.ts","../../../src/adapters/aws-lambda/index.ts"],"sourcesContent":["/**\n * Based on https://github.com/unjs/cookie-es/tree/v1.2.2\n * MIT License\n * \n * Cookie-es copyright (c) Pooya Parsa <pooya@pi0.io>\n * Set-Cookie parsing based on https://github.com/nfriedly/set-cookie-parser\n * Copyright (c) 2015 Nathan Friedly <nathan@nfriedly.com> (http://nfriedly.com/)\n * \n * @see https://github.com/unjs/cookie-es/blob/main/src/set-cookie/split.ts\n */\n\n/**\n * Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas\n * that are within a single set-cookie field-value, such as in the Expires portion.\n *\n * See https://tools.ietf.org/html/rfc2616#section-4.2\n */\nexport function splitSetCookieString(\n cookiesString: string | string[],\n ): string[] {\n if (Array.isArray(cookiesString)) {\n return cookiesString.flatMap((c) => splitSetCookieString(c));\n }\n \n if (typeof cookiesString !== \"string\") {\n return [];\n }\n \n const cookiesStrings: string[] = [];\n let pos: number = 0;\n let start: number;\n let ch: string;\n let lastComma: number;\n let nextStart: number;\n let cookiesSeparatorFound: boolean;\n \n const skipWhitespace = () => {\n while (pos < cookiesString.length && /\\s/.test(cookiesString.charAt(pos))) {\n pos += 1;\n }\n return pos < cookiesString.length;\n };\n \n const notSpecialChar = () => {\n ch = cookiesString.charAt(pos);\n return ch !== \"=\" && ch !== \";\" && ch !== \",\";\n };\n \n while (pos < cookiesString.length) {\n start = pos;\n cookiesSeparatorFound = false;\n \n while (skipWhitespace()) {\n ch = cookiesString.charAt(pos);\n if (ch === \",\") {\n // ',' is a cookie separator if we have later first '=', not ';' or ','\n lastComma = pos;\n pos += 1;\n \n skipWhitespace();\n nextStart = pos;\n \n while (pos < cookiesString.length && notSpecialChar()) {\n pos += 1;\n }\n \n // currently special character\n if (pos < cookiesString.length && cookiesString.charAt(pos) === \"=\") {\n // we found cookies separator\n cookiesSeparatorFound = true;\n // pos is inside the next cookie, so back up and return it.\n pos = nextStart;\n cookiesStrings.push(cookiesString.slice(start, lastComma));\n start = pos;\n } else {\n // in param ',' or param separator ';',\n // we continue from that comma\n pos = lastComma + 1;\n }\n } else {\n pos += 1;\n }\n }\n \n if (!cookiesSeparatorFound || pos >= cookiesString.length) {\n cookiesStrings.push(cookiesString.slice(start));\n }\n }\n \n return cookiesStrings;\n }","import { Readable, type Writable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport type {\n APIGatewayProxyEvent,\n APIGatewayProxyEventV2,\n APIGatewayProxyResult,\n APIGatewayProxyStructuredResultV2,\n} from 'aws-lambda';\nimport { splitSetCookieString } from '../../vendor/cookie-es/set-cookie/split';\n\nexport type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2;\n\nexport type APIGatewayResult =\n APIGatewayProxyResult | APIGatewayProxyStructuredResultV2;\n\nfunction determinePayloadFormat(event: LambdaEvent): string {\n // https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html\n // According to AWS support, version is is extracted from the version property in the event.\n // If there is no version property, then the version is implied as 1.0\n const unknownEvent = event as { version?: string };\n if (typeof unknownEvent.version === 'undefined') {\n return '1.0';\n } else {\n return unknownEvent.version;\n }\n}\n\n/** 1:1 mapping of v1 or v2 input events, deduces which is which.\n * @internal\n **/\nexport type inferAPIGWReturn<TEvent> = TEvent extends APIGatewayProxyEvent\n ? APIGatewayProxyResult\n : TEvent extends APIGatewayProxyEventV2\n ? APIGatewayProxyStructuredResultV2\n : never;\n\ninterface Processor<TEvent extends LambdaEvent> {\n getTRPCPath: (event: TEvent) => string;\n url(event: TEvent): Pick<URL, 'hostname' | 'pathname' | 'search'>;\n getHeaders: (event: TEvent) => Headers;\n getMethod: (event: TEvent) => string;\n toResult: (response: Response) => Promise<inferAPIGWReturn<TEvent>>;\n toStream: (response: Response, stream: Writable) => Promise<void>;\n}\n\nfunction getHeadersAndCookiesFromResponse(response: Response) {\n const headers = Object.fromEntries(response.headers.entries());\n\n const cookies: string[] = splitSetCookieString(\n response.headers.getSetCookie(),\n ).map((cookie) => cookie.trim());\n\n delete headers['set-cookie'];\n\n return { headers, cookies };\n}\n\nconst v1Processor: Processor<APIGatewayProxyEvent> = {\n // same as getPath above\n getTRPCPath: (event) => {\n if (!event.pathParameters) {\n // Then this event was not triggered by a resource denoted with {proxy+}\n return event.path.split('/').pop() ?? '';\n }\n const matches = event.resource.matchAll(/\\{(.*?)\\}/g);\n for (const match of matches) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const group = match[1]!;\n if (group.includes('+') && event.pathParameters) {\n return event.pathParameters[group.replace('+', '')] ?? '';\n }\n }\n return event.path.slice(1);\n },\n url(event) {\n const hostname: string =\n event.requestContext.domainName ??\n event.headers['host'] ??\n event.multiValueHeaders?.['host']?.[0] ??\n 'localhost';\n\n const searchParams = new URLSearchParams();\n\n for (const [key, value] of Object.entries(\n event.queryStringParameters ?? {},\n )) {\n if (value !== undefined) {\n searchParams.append(key, value);\n }\n }\n const qs = searchParams.toString();\n return {\n hostname,\n pathname: event.path,\n search: qs && `?${qs}`,\n };\n },\n getHeaders: (event) => {\n const headers = new Headers();\n\n // Process multiValueHeaders first (takes precedence per AWS docs)\n // This handles headers that can have multiple values\n for (const [k, values] of Object.entries(event.multiValueHeaders ?? {})) {\n if (values) {\n values.forEach((v) => headers.append(k, v));\n }\n }\n\n // Then process single-value headers, but skip any that were already\n // added from multiValueHeaders to avoid duplication\n for (const [key, value] of Object.entries(event.headers ?? {})) {\n if (value !== undefined && !headers.has(key)) {\n headers.append(key, value);\n }\n }\n\n return headers;\n },\n getMethod: (event) => event.httpMethod,\n toResult: async (response) => {\n const { headers, cookies } = getHeadersAndCookiesFromResponse(response);\n\n const result: APIGatewayProxyResult = {\n ...(cookies.length && { multiValueHeaders: { 'set-cookie': cookies } }),\n statusCode: response.status,\n body: await response.text(),\n headers,\n };\n\n return result;\n },\n toStream: async (response, stream) => {\n const { headers, cookies } = getHeadersAndCookiesFromResponse(response);\n\n const metadata = {\n statusCode: response.status,\n headers,\n cookies,\n };\n\n const responseStream = awslambda.HttpResponseStream.from(stream, metadata);\n\n if (response.body) {\n await pipeline(Readable.fromWeb(response.body as any), responseStream);\n } else {\n responseStream.end();\n }\n },\n};\n\nconst v2Processor: Processor<APIGatewayProxyEventV2> = {\n getTRPCPath: (event) => {\n const matches = event.routeKey.matchAll(/\\{(.*?)\\}/g);\n for (const match of matches) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const group = match[1]!;\n if (group.includes('+') && event.pathParameters) {\n return event.pathParameters[group.replace('+', '')] ?? '';\n }\n }\n return event.rawPath.slice(1);\n },\n url(event) {\n return {\n hostname: event.requestContext.domainName,\n pathname: event.rawPath,\n search: event.rawQueryString && `?${event.rawQueryString}`,\n };\n },\n getHeaders: (event) => {\n const headers = new Headers();\n for (const [key, value] of Object.entries(event.headers ?? {})) {\n if (value !== undefined) {\n headers.append(key, value);\n }\n }\n\n if (event.cookies) {\n headers.append('cookie', event.cookies.join('; '));\n }\n return headers;\n },\n getMethod: (event) => event.requestContext.http.method,\n toResult: async (response) => {\n const { headers, cookies } = getHeadersAndCookiesFromResponse(response);\n\n const result: APIGatewayProxyStructuredResultV2 = {\n cookies,\n statusCode: response.status,\n body: await response.text(),\n headers,\n };\n\n return result;\n },\n\n toStream: async (response, stream) => {\n const { headers, cookies } = getHeadersAndCookiesFromResponse(response);\n\n const metadata = {\n statusCode: response.status,\n headers,\n cookies,\n };\n\n const responseStream = awslambda.HttpResponseStream.from(stream, metadata);\n\n if (response.body) {\n await pipeline(Readable.fromWeb(response.body as any), responseStream);\n } else {\n responseStream.end();\n }\n },\n};\n\nexport function getPlanner<TEvent extends LambdaEvent>(event: TEvent) {\n const version = determinePayloadFormat(event);\n let processor: Processor<TEvent>;\n switch (version) {\n case '1.0':\n processor = v1Processor as Processor<TEvent>;\n break;\n case '2.0':\n processor = v2Processor as Processor<TEvent>;\n break;\n default:\n throw new Error(`Unsupported version: ${version}`);\n }\n\n const urlParts = processor.url(event);\n const url = `https://${urlParts.hostname}${urlParts.pathname}${urlParts.search}`;\n\n const init: RequestInit = {\n headers: processor.getHeaders(event),\n method: processor.getMethod(event),\n // @ts-expect-error this is fine\n duplex: 'half',\n };\n if (event.body) {\n init.body = event.isBase64Encoded\n ? Buffer.from(event.body, 'base64')\n : event.body;\n }\n\n const request = new Request(url, init);\n\n return {\n path: processor.getTRPCPath(event),\n request,\n toResult: processor.toResult,\n toStream: processor.toStream,\n };\n}\n","/**\n * 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`\n *\n * @example\n * ```ts\n * import type { AnyTRPCRouter } from '@trpc/server'\n * import type { HTTPBaseHandlerOptions } from '@trpc/server/http'\n * ```\n */\nimport type { Context as APIGWContext, StreamifyHandler } from 'aws-lambda';\n// @trpc/server\nimport type {\n AnyRouter,\n CreateContextCallback,\n inferRouterContext,\n} from '../../@trpc/server';\n// @trpc/server\nimport type {\n HTTPBaseHandlerOptions,\n ResolveHTTPRequestOptionsContextFn,\n TRPCRequestInfo,\n} from '../../@trpc/server/http';\nimport { resolveResponse } from '../../@trpc/server/http';\nimport type { inferAPIGWReturn, LambdaEvent } from './getPlanner';\nimport { getPlanner } from './getPlanner';\n\nexport type CreateAWSLambdaContextOptions<TEvent extends LambdaEvent> = {\n event: TEvent;\n context: APIGWContext;\n info: TRPCRequestInfo;\n};\n\nexport type AWSLambdaOptions<\n TRouter extends AnyRouter,\n TEvent extends LambdaEvent,\n> = HTTPBaseHandlerOptions<TRouter, TEvent> &\n CreateContextCallback<\n inferRouterContext<AnyRouter>,\n AWSLambdaCreateContextFn<TRouter, TEvent>\n >;\n\nexport type AWSLambdaCreateContextFn<\n TRouter extends AnyRouter,\n TEvent extends LambdaEvent,\n> = ({\n event,\n context,\n info,\n}: CreateAWSLambdaContextOptions<TEvent>) =>\n inferRouterContext<TRouter> | Promise<inferRouterContext<TRouter>>;\n\nexport function awsLambdaRequestHandler<\n TRouter extends AnyRouter,\n TEvent extends LambdaEvent,\n>(\n opts: AWSLambdaOptions<TRouter, TEvent>,\n): (event: TEvent, context: APIGWContext) => Promise<inferAPIGWReturn<TEvent>> {\n return async (event, context) => {\n const planner = getPlanner(event);\n\n const createContext: ResolveHTTPRequestOptionsContextFn<TRouter> = async (\n innerOpts,\n ) => {\n return await opts.createContext?.({ event, context, ...innerOpts });\n };\n\n const response = await resolveResponse({\n ...opts,\n createContext,\n req: planner.request,\n path: planner.path,\n error: null,\n onError(o) {\n opts?.onError?.({\n ...o,\n req: event,\n });\n },\n });\n\n return await planner.toResult(response);\n };\n}\n\nexport function awsLambdaStreamingRequestHandler<\n TRouter extends AnyRouter,\n TEvent extends LambdaEvent,\n>(opts: AWSLambdaOptions<TRouter, TEvent>): StreamifyHandler<TEvent> {\n return async (event, responseStream, context) => {\n const planner = getPlanner(event);\n\n const createContext: ResolveHTTPRequestOptionsContextFn<TRouter> = async (\n innerOpts,\n ) => {\n return await opts.createContext?.({ event, context, ...innerOpts });\n };\n\n const response = await resolveResponse({\n ...opts,\n createContext,\n req: planner.request,\n path: planner.path,\n error: null,\n onError(o) {\n opts?.onError?.({\n ...o,\n req: event,\n });\n },\n });\n\n await planner.toStream(response, responseStream);\n };\n}\n"],"mappings":"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"}