lambda-reactor 1.0.0 → 1.0.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 (69) hide show
  1. package/{src/build-handlers.ts → dist/build-handlers.d.ts} +3 -16
  2. package/dist/build-handlers.js +13 -0
  3. package/dist/build-handlers.js.map +10 -0
  4. package/dist/dispatch.d.ts +21 -0
  5. package/dist/dispatch.js +58 -0
  6. package/dist/dispatch.js.map +10 -0
  7. package/dist/env.d.ts +6 -0
  8. package/dist/env.js +13 -0
  9. package/dist/env.js.map +10 -0
  10. package/dist/handler.d.ts +26 -0
  11. package/dist/handler.js +29 -0
  12. package/dist/handler.js.map +10 -0
  13. package/dist/logger.d.ts +8 -0
  14. package/dist/logger.js +21 -0
  15. package/dist/logger.js.map +10 -0
  16. package/dist/method.d.ts +53 -0
  17. package/dist/method.js +57 -0
  18. package/dist/method.js.map +10 -0
  19. package/{src/middleware.ts → dist/middleware.d.ts} +5 -22
  20. package/dist/middleware.js +19 -0
  21. package/dist/middleware.js.map +10 -0
  22. package/dist/response.d.ts +48 -0
  23. package/dist/response.js +46 -0
  24. package/dist/response.js.map +10 -0
  25. package/{src/route-handler.ts → dist/route-handler.d.ts} +12 -14
  26. package/dist/route-handler.js +2 -0
  27. package/dist/route-handler.js.map +9 -0
  28. package/dist/router-class.d.ts +54 -0
  29. package/dist/router-class.js +46 -0
  30. package/dist/router-class.js.map +10 -0
  31. package/{src/router.ts → dist/router.d.ts} +4 -16
  32. package/dist/router.js +18 -0
  33. package/dist/router.js.map +10 -0
  34. package/package.json +12 -2
  35. package/.prettierrc +0 -8
  36. package/AGENTS.md +0 -7
  37. package/bun.lock +0 -477
  38. package/eslint.config.ts +0 -31
  39. package/examples/cdk-stack.ts +0 -20
  40. package/examples/health.ts +0 -7
  41. package/examples/items.ts +0 -25
  42. package/examples/users-get.ts +0 -20
  43. package/examples/users-post.ts +0 -26
  44. package/lefthook.yml +0 -16
  45. package/src/dispatch.ts +0 -91
  46. package/src/env.ts +0 -23
  47. package/src/handler.ts +0 -58
  48. package/src/logger.ts +0 -19
  49. package/src/method.ts +0 -92
  50. package/src/response.ts +0 -86
  51. package/src/router-class.ts +0 -98
  52. package/tests/api-get-methods.test.ts +0 -14
  53. package/tests/api-router-factory.test.ts +0 -46
  54. package/tests/api-router.test.ts +0 -72
  55. package/tests/config-cors.test.ts +0 -50
  56. package/tests/config.test.ts +0 -79
  57. package/tests/dispatch-error-logging.test.ts +0 -61
  58. package/tests/env.test.ts +0 -38
  59. package/tests/handler-error-logging.test.ts +0 -61
  60. package/tests/handler-routing-validation.test.ts +0 -86
  61. package/tests/handler-routing.test.ts +0 -37
  62. package/tests/handler.test.ts +0 -48
  63. package/tests/method.test.ts +0 -40
  64. package/tests/response.test.ts +0 -29
  65. package/tsconfig.build.json +0 -26
  66. package/tsconfig.json +0 -3
  67. package/tsconfig.node.json +0 -24
  68. package/vitest.config.ts +0 -21
  69. package/vitest.setup.ts +0 -2
@@ -1,12 +1,9 @@
1
- import {join} from "path"
2
-
3
- import type {IFunction} from "aws-cdk-lib/aws-lambda"
1
+ import type { IFunction } from "aws-cdk-lib/aws-lambda";
4
2
  /**
5
3
  * A factory function that constructs an AWS Lambda {@link IFunction} from a
6
4
  * source-file entry path and a logical identifier string.
7
5
  */
8
- export type FunctionFactory = (entry: string, id: string) => IFunction
9
-
6
+ export type FunctionFactory = (entry: string, id: string) => IFunction;
10
7
  /**
11
8
  * Builds a map of route paths to Lambda functions by invoking `factory` for
12
9
  * each path.
@@ -17,14 +14,4 @@ export type FunctionFactory = (entry: string, id: string) => IFunction
17
14
  * @param paths - Array of route path strings (e.g. `["/users", "/items"]`).
18
15
  * @param factory - {@link FunctionFactory} used to construct each Lambda function.
19
16
  */
20
- export function buildHandlers<TPaths extends string>(
21
- paths: TPaths[],
22
- factory: FunctionFactory,
23
- ): Record<TPaths, IFunction> {
24
- return Object.fromEntries(
25
- paths.map((path) => [
26
- path,
27
- factory(join(process.cwd(), "src", `${path}.ts`), path),
28
- ]),
29
- ) as Record<TPaths, IFunction>
30
- }
17
+ export declare function buildHandlers<TPaths extends string>(paths: TPaths[], factory: FunctionFactory): Record<TPaths, IFunction>;
@@ -0,0 +1,13 @@
1
+ // src/build-handlers.ts
2
+ import { join } from "path";
3
+ function buildHandlers(paths, factory) {
4
+ return Object.fromEntries(paths.map((path) => [
5
+ path,
6
+ factory(join(process.cwd(), "src", `${path}.ts`), path)
7
+ ]));
8
+ }
9
+ export {
10
+ buildHandlers
11
+ };
12
+
13
+ //# debugId=824ABC51E353D52E64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/build-handlers.ts"],
4
+ "sourcesContent": [
5
+ "import {join} from \"path\"\n\nimport type {IFunction} from \"aws-cdk-lib/aws-lambda\"\n/**\n * A factory function that constructs an AWS Lambda {@link IFunction} from a\n * source-file entry path and a logical identifier string.\n */\nexport type FunctionFactory = (entry: string, id: string) => IFunction\n\n/**\n * Builds a map of route paths to Lambda functions by invoking `factory` for\n * each path.\n *\n * The `entry` passed to `factory` is the absolute path\n * `<cwd>/src/<path>.ts`, and the `id` is the route path string itself.\n *\n * @param paths - Array of route path strings (e.g. `[\"/users\", \"/items\"]`).\n * @param factory - {@link FunctionFactory} used to construct each Lambda function.\n */\nexport function buildHandlers<TPaths extends string>(\n paths: TPaths[],\n factory: FunctionFactory,\n): Record<TPaths, IFunction> {\n return Object.fromEntries(\n paths.map((path) => [\n path,\n factory(join(process.cwd(), \"src\", `${path}.ts`), path),\n ]),\n ) as Record<TPaths, IFunction>\n}\n"
6
+ ],
7
+ "mappings": ";AAAA;AAmBO,SAAS,aAAoC,CAChD,OACA,SACyB;AAAA,EACzB,OAAO,OAAO,YACV,MAAM,IAAI,CAAC,SAAS;AAAA,IAChB;AAAA,IACA,QAAQ,KAAK,QAAQ,IAAI,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI;AAAA,EAC1D,CAAC,CACL;AAAA;",
8
+ "debugId": "824ABC51E353D52E64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,21 @@
1
+ import { RouteHandler } from "#src/method";
2
+ import type { APIGatewayProxyEvent, Context } from "aws-lambda";
3
+ /**
4
+ * Executes a single {@link RouteHandler} for an incoming Lambda proxy event.
5
+ *
6
+ * Processing order:
7
+ * 1. Parse `event.body` as JSON when possible.
8
+ * 2. Validate the body against `route.bodySchema` (Zod); return `400` on
9
+ * failure.
10
+ * 3. Invoke `route.callback` with the validated body, event, and context.
11
+ * 4. If the callback returns a {@link Response}, optionally validate its body
12
+ * against `route.outputSchema`; return `500` on failure.
13
+ * 5. If the callback returns a plain value, wrap it in a `200 JSON` response,
14
+ * optionally validating against `route.outputSchema`.
15
+ * 6. Apply all middlewares left-to-right before returning.
16
+ *
17
+ * @param route - The route handler to execute.
18
+ * @param event - Raw API Gateway proxy event.
19
+ * @param context - Lambda execution context.
20
+ */
21
+ export declare function dispatch(route: RouteHandler, event: APIGatewayProxyEvent, context: Context): Promise<import("aws-lambda").APIGatewayProxyResult>;
@@ -0,0 +1,58 @@
1
+ // src/dispatch.ts
2
+ import { logError } from "#src/logger";
3
+ import { Response } from "#src/response";
4
+ import { z } from "zod";
5
+ import { applyMiddlewares } from "./middleware";
6
+ async function dispatch(route, event, context) {
7
+ let body;
8
+ try {
9
+ body = event.body ? JSON.parse(event.body) : undefined;
10
+ } catch (error) {
11
+ if (error instanceof Error) {
12
+ return Response.text(400, error.message).toAPIGatewayProxyResult();
13
+ }
14
+ throw error;
15
+ }
16
+ if (route.bodySchema) {
17
+ const parsed = route.bodySchema.safeParse(body);
18
+ if (!parsed.success) {
19
+ return Response.text(400, z.treeifyError(parsed.error).errors.join(`
20
+ `)).toAPIGatewayProxyResult();
21
+ }
22
+ body = parsed.data;
23
+ }
24
+ if (!route.callback) {
25
+ const err = new Error("Route has no handler defined");
26
+ logError(err);
27
+ return Response.text(500, err.message).toAPIGatewayProxyResult();
28
+ }
29
+ const cb = route.callback;
30
+ const result = await cb({ body, event, context });
31
+ if (result instanceof Response) {
32
+ if (route.outputSchema) {
33
+ const parsed = route.outputSchema.safeParse(result.body);
34
+ if (!parsed.success) {
35
+ logError(parsed.error);
36
+ return Response.text(500, z.treeifyError(parsed.error).errors.join(`
37
+ `)).toAPIGatewayProxyResult();
38
+ }
39
+ result.body = parsed.data;
40
+ }
41
+ return applyMiddlewares(result.toAPIGatewayProxyResult(), route);
42
+ }
43
+ if (route.outputSchema) {
44
+ const parsed = route.outputSchema.safeParse(result);
45
+ if (!parsed.success) {
46
+ logError(parsed.error);
47
+ return Response.text(500, z.treeifyError(parsed.error).errors.join(`
48
+ `)).toAPIGatewayProxyResult();
49
+ }
50
+ return applyMiddlewares(Response.json(200, parsed.data).toAPIGatewayProxyResult(), route);
51
+ }
52
+ return applyMiddlewares(Response.json(200, result).toAPIGatewayProxyResult(), route);
53
+ }
54
+ export {
55
+ dispatch
56
+ };
57
+
58
+ //# debugId=618322748EAF9B8C64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/dispatch.ts"],
4
+ "sourcesContent": [
5
+ "import {logError} from \"#src/logger\"\nimport {RouteHandler} from \"#src/method\"\nimport {Response} from \"#src/response\"\nimport type {APIGatewayProxyEvent, Context} from \"aws-lambda\"\nimport {z} from \"zod\"\n\nimport {applyMiddlewares} from \"./middleware\"\n\n/**\n * Executes a single {@link RouteHandler} for an incoming Lambda proxy event.\n *\n * Processing order:\n * 1. Parse `event.body` as JSON when possible.\n * 2. Validate the body against `route.bodySchema` (Zod); return `400` on\n * failure.\n * 3. Invoke `route.callback` with the validated body, event, and context.\n * 4. If the callback returns a {@link Response}, optionally validate its body\n * against `route.outputSchema`; return `500` on failure.\n * 5. If the callback returns a plain value, wrap it in a `200 JSON` response,\n * optionally validating against `route.outputSchema`.\n * 6. Apply all middlewares left-to-right before returning.\n *\n * @param route - The route handler to execute.\n * @param event - Raw API Gateway proxy event.\n * @param context - Lambda execution context.\n */\nexport async function dispatch(\n route: RouteHandler,\n event: APIGatewayProxyEvent,\n context: Context,\n) {\n let body\n try {\n body = event.body ? JSON.parse(event.body) : undefined\n } catch (error) {\n if (error instanceof Error) {\n return Response.text(400, error.message).toAPIGatewayProxyResult()\n }\n throw error\n }\n if (route.bodySchema) {\n const parsed = route.bodySchema.safeParse(body)\n if (!parsed.success) {\n return Response.text(\n 400,\n z.treeifyError(parsed.error).errors.join(\"\\n\"),\n ).toAPIGatewayProxyResult()\n }\n body = parsed.data\n }\n if (!route.callback) {\n const err = new Error(\"Route has no handler defined\")\n logError(err)\n return Response.text(500, err.message).toAPIGatewayProxyResult()\n }\n const cb = route.callback as (props: {\n body: unknown\n event: APIGatewayProxyEvent\n context: Context\n }) => Promise<unknown>\n const result = await cb({body, event, context})\n if (result instanceof Response) {\n if (route.outputSchema) {\n const parsed = route.outputSchema.safeParse(result.body)\n if (!parsed.success) {\n logError(parsed.error)\n return Response.text(\n 500,\n z.treeifyError(parsed.error).errors.join(\"\\n\"),\n ).toAPIGatewayProxyResult()\n }\n result.body = parsed.data\n }\n return applyMiddlewares(result.toAPIGatewayProxyResult(), route)\n }\n if (route.outputSchema) {\n const parsed = route.outputSchema.safeParse(result)\n if (!parsed.success) {\n logError(parsed.error)\n return Response.text(\n 500,\n z.treeifyError(parsed.error).errors.join(\"\\n\"),\n ).toAPIGatewayProxyResult()\n }\n return applyMiddlewares(\n Response.json(200, parsed.data).toAPIGatewayProxyResult(),\n route,\n )\n }\n return applyMiddlewares(Response.json(200, result).toAPIGatewayProxyResult(), route)\n}\n"
6
+ ],
7
+ "mappings": ";AAAA;AAEA;AAEA;AAEA;AAoBA,eAAsB,QAAQ,CAC1B,OACA,OACA,SACF;AAAA,EACE,IAAI;AAAA,EACJ,IAAI;AAAA,IACA,OAAO,MAAM,OAAO,KAAK,MAAM,MAAM,IAAI,IAAI;AAAA,IAC/C,OAAO,OAAO;AAAA,IACZ,IAAI,iBAAiB,OAAO;AAAA,MACxB,OAAO,SAAS,KAAK,KAAK,MAAM,OAAO,EAAE,wBAAwB;AAAA,IACrE;AAAA,IACA,MAAM;AAAA;AAAA,EAEV,IAAI,MAAM,YAAY;AAAA,IAClB,MAAM,SAAS,MAAM,WAAW,UAAU,IAAI;AAAA,IAC9C,IAAI,CAAC,OAAO,SAAS;AAAA,MACjB,OAAO,SAAS,KACZ,KACA,EAAE,aAAa,OAAO,KAAK,EAAE,OAAO,KAAK;AAAA,CAAI,CACjD,EAAE,wBAAwB;AAAA,IAC9B;AAAA,IACA,OAAO,OAAO;AAAA,EAClB;AAAA,EACA,IAAI,CAAC,MAAM,UAAU;AAAA,IACjB,MAAM,MAAM,IAAI,MAAM,8BAA8B;AAAA,IACpD,SAAS,GAAG;AAAA,IACZ,OAAO,SAAS,KAAK,KAAK,IAAI,OAAO,EAAE,wBAAwB;AAAA,EACnE;AAAA,EACA,MAAM,KAAK,MAAM;AAAA,EAKjB,MAAM,SAAS,MAAM,GAAG,EAAC,MAAM,OAAO,QAAO,CAAC;AAAA,EAC9C,IAAI,kBAAkB,UAAU;AAAA,IAC5B,IAAI,MAAM,cAAc;AAAA,MACpB,MAAM,SAAS,MAAM,aAAa,UAAU,OAAO,IAAI;AAAA,MACvD,IAAI,CAAC,OAAO,SAAS;AAAA,QACjB,SAAS,OAAO,KAAK;AAAA,QACrB,OAAO,SAAS,KACZ,KACA,EAAE,aAAa,OAAO,KAAK,EAAE,OAAO,KAAK;AAAA,CAAI,CACjD,EAAE,wBAAwB;AAAA,MAC9B;AAAA,MACA,OAAO,OAAO,OAAO;AAAA,IACzB;AAAA,IACA,OAAO,iBAAiB,OAAO,wBAAwB,GAAG,KAAK;AAAA,EACnE;AAAA,EACA,IAAI,MAAM,cAAc;AAAA,IACpB,MAAM,SAAS,MAAM,aAAa,UAAU,MAAM;AAAA,IAClD,IAAI,CAAC,OAAO,SAAS;AAAA,MACjB,SAAS,OAAO,KAAK;AAAA,MACrB,OAAO,SAAS,KACZ,KACA,EAAE,aAAa,OAAO,KAAK,EAAE,OAAO,KAAK;AAAA,CAAI,CACjD,EAAE,wBAAwB;AAAA,IAC9B;AAAA,IACA,OAAO,iBACH,SAAS,KAAK,KAAK,OAAO,IAAI,EAAE,wBAAwB,GACxD,KACJ;AAAA,EACJ;AAAA,EACA,OAAO,iBAAiB,SAAS,KAAK,KAAK,MAAM,EAAE,wBAAwB,GAAG,KAAK;AAAA;",
8
+ "debugId": "618322748EAF9B8C64756E2164756E21",
9
+ "names": []
10
+ }
package/dist/env.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Returns `true` when any of the conventional environment variables
3
+ * (`NODE_ENV`, `STAGE`, `ENV`, `ENVIRONMENT`) indicate a production
4
+ * deployment.
5
+ */
6
+ export declare function isProduction(): boolean;
package/dist/env.js ADDED
@@ -0,0 +1,13 @@
1
+ // src/env.ts
2
+ var PROD_VALUES = new Set(["production", "prod"]);
3
+ function isProductionValue(value) {
4
+ return value !== undefined && PROD_VALUES.has(value.toLowerCase());
5
+ }
6
+ function isProduction() {
7
+ return isProductionValue(process.env["NODE_ENV"]) || isProductionValue(process.env["STAGE"]) || isProductionValue(process.env["ENV"]) || isProductionValue(process.env["ENVIRONMENT"]);
8
+ }
9
+ export {
10
+ isProduction
11
+ };
12
+
13
+ //# debugId=B04BC044C8E167A264756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/env.ts"],
4
+ "sourcesContent": [
5
+ "const PROD_VALUES = new Set([\"production\", \"prod\"])\n\n/**\n * Returns `true` if the given environment variable value represents a\n * production environment (`\"production\"` or `\"prod\"`, case-insensitive).\n */\nfunction isProductionValue(value: string | undefined): boolean {\n return value !== undefined && PROD_VALUES.has(value.toLowerCase())\n}\n\n/**\n * Returns `true` when any of the conventional environment variables\n * (`NODE_ENV`, `STAGE`, `ENV`, `ENVIRONMENT`) indicate a production\n * deployment.\n */\nexport function isProduction(): boolean {\n return (\n isProductionValue(process.env[\"NODE_ENV\"]) ||\n isProductionValue(process.env[\"STAGE\"]) ||\n isProductionValue(process.env[\"ENV\"]) ||\n isProductionValue(process.env[\"ENVIRONMENT\"])\n )\n}\n"
6
+ ],
7
+ "mappings": ";AAAA,IAAM,cAAc,IAAI,IAAI,CAAC,cAAc,MAAM,CAAC;AAMlD,SAAS,iBAAiB,CAAC,OAAoC;AAAA,EAC3D,OAAO,UAAU,aAAa,YAAY,IAAI,MAAM,YAAY,CAAC;AAAA;AAQ9D,SAAS,YAAY,GAAY;AAAA,EACpC,OACI,kBAAkB,QAAQ,IAAI,WAAW,KACzC,kBAAkB,QAAQ,IAAI,QAAQ,KACtC,kBAAkB,QAAQ,IAAI,MAAM,KACpC,kBAAkB,QAAQ,IAAI,cAAc;AAAA;",
8
+ "debugId": "B04BC044C8E167A264756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,26 @@
1
+ import { RouteHandler } from "#src/method";
2
+ import type { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from "aws-lambda";
3
+ /**
4
+ * Creates an AWS Lambda handler function from a map of HTTP-method names to
5
+ * {@link RouteHandler} instances.
6
+ *
7
+ * The returned handler:
8
+ * - Returns `405 Method Not Allowed` (with an `Allow` header) for any HTTP
9
+ * method not present in `routes`.
10
+ * - Delegates matching requests to {@link dispatch}.
11
+ * - Catches any `Error` thrown by `dispatch`, logs it, and returns
12
+ * `500 Internal Server Error`. In non-production environments the error
13
+ * message and stack trace are included in the response body.
14
+ * - Re-throws non-`Error` throwables so they propagate to the Lambda runtime.
15
+ *
16
+ * @param routes - Map of upper-case HTTP method names (e.g. `"GET"`, `"POST"`)
17
+ * to their corresponding {@link RouteHandler}.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * export const handler = createHandler({
22
+ * GET: method().handle(async () => Response.json(200, {ok: true})),
23
+ * })
24
+ * ```
25
+ */
26
+ export declare function createHandler<T extends Record<string, RouteHandler>>(routes: T): (event: APIGatewayProxyEvent, context: Context) => Promise<APIGatewayProxyResult>;
@@ -0,0 +1,29 @@
1
+ // src/handler.ts
2
+ import { dispatch } from "#src/dispatch";
3
+ import { isProduction } from "#src/env";
4
+ import { formatError, logError } from "#src/logger";
5
+ import { Response } from "#src/response";
6
+ import { install } from "source-map-support";
7
+ install();
8
+ function createHandler(routes) {
9
+ return async (event, context) => {
10
+ const route = routes[event.httpMethod];
11
+ if (!route) {
12
+ return Response.text(405, "Method Not Allowed").header("Allow", Object.keys(routes).join(", ")).toAPIGatewayProxyResult();
13
+ }
14
+ try {
15
+ return await dispatch(route, event, context);
16
+ } catch (error) {
17
+ if (error instanceof Error) {
18
+ logError(error);
19
+ return Response.text(500, isProduction() ? "Internal Server Error" : formatError(error)).toAPIGatewayProxyResult();
20
+ }
21
+ throw error;
22
+ }
23
+ };
24
+ }
25
+ export {
26
+ createHandler
27
+ };
28
+
29
+ //# debugId=BD00AEC1624B40DE64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/handler.ts"],
4
+ "sourcesContent": [
5
+ "import {dispatch} from \"#src/dispatch\"\nimport {isProduction} from \"#src/env\"\nimport {formatError, logError} from \"#src/logger\"\nimport {RouteHandler} from \"#src/method\"\nimport {Response} from \"#src/response\"\nimport type {APIGatewayProxyEvent, APIGatewayProxyResult, Context} from \"aws-lambda\"\nimport {install} from \"source-map-support\"\n\ninstall()\n\n/**\n * Creates an AWS Lambda handler function from a map of HTTP-method names to\n * {@link RouteHandler} instances.\n *\n * The returned handler:\n * - Returns `405 Method Not Allowed` (with an `Allow` header) for any HTTP\n * method not present in `routes`.\n * - Delegates matching requests to {@link dispatch}.\n * - Catches any `Error` thrown by `dispatch`, logs it, and returns\n * `500 Internal Server Error`. In non-production environments the error\n * message and stack trace are included in the response body.\n * - Re-throws non-`Error` throwables so they propagate to the Lambda runtime.\n *\n * @param routes - Map of upper-case HTTP method names (e.g. `\"GET\"`, `\"POST\"`)\n * to their corresponding {@link RouteHandler}.\n *\n * @example\n * ```ts\n * export const handler = createHandler({\n * GET: method().handle(async () => Response.json(200, {ok: true})),\n * })\n * ```\n */\nexport function createHandler<T extends Record<string, RouteHandler>>(routes: T) {\n return async (\n event: APIGatewayProxyEvent,\n context: Context,\n ): Promise<APIGatewayProxyResult> => {\n const route = routes[event.httpMethod as keyof T]\n if (!route) {\n return Response.text(405, \"Method Not Allowed\")\n .header(\"Allow\", Object.keys(routes).join(\", \"))\n .toAPIGatewayProxyResult()\n }\n try {\n return await dispatch(route, event, context)\n } catch (error) {\n if (error instanceof Error) {\n logError(error)\n return Response.text(\n 500,\n isProduction() ? \"Internal Server Error\" : formatError(error),\n ).toAPIGatewayProxyResult()\n }\n throw error\n }\n }\n}\n"
6
+ ],
7
+ "mappings": ";AAAA;AACA;AACA;AAEA;AAEA;AAEA,QAAQ;AAyBD,SAAS,aAAqD,CAAC,QAAW;AAAA,EAC7E,OAAO,OACH,OACA,YACiC;AAAA,IACjC,MAAM,QAAQ,OAAO,MAAM;AAAA,IAC3B,IAAI,CAAC,OAAO;AAAA,MACR,OAAO,SAAS,KAAK,KAAK,oBAAoB,EACzC,OAAO,SAAS,OAAO,KAAK,MAAM,EAAE,KAAK,IAAI,CAAC,EAC9C,wBAAwB;AAAA,IACjC;AAAA,IACA,IAAI;AAAA,MACA,OAAO,MAAM,SAAS,OAAO,OAAO,OAAO;AAAA,MAC7C,OAAO,OAAO;AAAA,MACZ,IAAI,iBAAiB,OAAO;AAAA,QACxB,SAAS,KAAK;AAAA,QACd,OAAO,SAAS,KACZ,KACA,aAAa,IAAI,0BAA0B,YAAY,KAAK,CAChE,EAAE,wBAAwB;AAAA,MAC9B;AAAA,MACA,MAAM;AAAA;AAAA;AAAA;",
8
+ "debugId": "BD00AEC1624B40DE64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Formats an `Error` into a human-readable string that includes the error
3
+ * name, message, an optional Zod validation detail block, and the stack
4
+ * trace when available.
5
+ */
6
+ export declare function formatError(error: Error): string;
7
+ /** Writes a formatted error to `stderr` via `console.error`. */
8
+ export declare function logError(error: Error): void;
package/dist/logger.js ADDED
@@ -0,0 +1,21 @@
1
+ // src/logger.ts
2
+ import * as z from "zod";
3
+ function formatError(error) {
4
+ let detail;
5
+ if (error instanceof z.ZodError) {
6
+ detail = z.treeifyError(error).errors.join(`
7
+ `);
8
+ }
9
+ return `${error.name}: ${error.message}${detail ? `
10
+ ${detail}` : ""}${error.stack ? `
11
+ ${error.stack}` : ""}`;
12
+ }
13
+ function logError(error) {
14
+ console.error(formatError(error));
15
+ }
16
+ export {
17
+ logError,
18
+ formatError
19
+ };
20
+
21
+ //# debugId=FB33B340A398C49564756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/logger.ts"],
4
+ "sourcesContent": [
5
+ "import * as z from \"zod\"\n\n/**\n * Formats an `Error` into a human-readable string that includes the error\n * name, message, an optional Zod validation detail block, and the stack\n * trace when available.\n */\nexport function formatError(error: Error): string {\n let detail\n if (error instanceof z.ZodError) {\n detail = z.treeifyError(error).errors.join(\"\\n\")\n }\n return `${error.name}: ${error.message}${detail ? `\\n${detail}` : \"\"}${error.stack ? `\\n${error.stack}` : \"\"}`\n}\n\n/** Writes a formatted error to `stderr` via `console.error`. */\nexport function logError(error: Error): void {\n console.error(formatError(error))\n}\n"
6
+ ],
7
+ "mappings": ";AAAA;AAOO,SAAS,WAAW,CAAC,OAAsB;AAAA,EAC9C,IAAI;AAAA,EACJ,IAAI,iBAAmB,YAAU;AAAA,IAC7B,SAAW,eAAa,KAAK,EAAE,OAAO,KAAK;AAAA,CAAI;AAAA,EACnD;AAAA,EACA,OAAO,GAAG,MAAM,SAAS,MAAM,UAAU,SAAS;AAAA,EAAK,WAAW,KAAK,MAAM,QAAQ;AAAA,EAAK,MAAM,UAAU;AAAA;AAIvG,SAAS,QAAQ,CAAC,OAAoB;AAAA,EACzC,QAAQ,MAAM,YAAY,KAAK,CAAC;AAAA;",
8
+ "debugId": "FB33B340A398C49564756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,53 @@
1
+ import { type Middleware } from "#src/middleware";
2
+ import { EndpointCallback, RouteHandler } from "#src/route-handler";
3
+ import type { ZodType } from "zod";
4
+ export type { EndpointCallback, RouteHandler };
5
+ /**
6
+ * Fluent, immutable builder for a single HTTP-method handler.
7
+ *
8
+ * Every method returns a new `Method` instance, leaving the original
9
+ * unchanged. Build a method with the following chain:
10
+ *
11
+ * ```ts
12
+ * method().use(cors()).input(schema).output(schema).handle(async ({body}) => …)
13
+ * ```
14
+ *
15
+ * @typeParam TInput - Shape of the validated request body.
16
+ * @typeParam TOutput - Return type of the handler callback.
17
+ */
18
+ export declare class Method<TInput = unknown, TOutput = unknown> {
19
+ middlewares: Middleware[];
20
+ bodySchema?: ZodType<TInput>;
21
+ outputSchema?: ZodType<TOutput>;
22
+ callback?: EndpointCallback<TInput, TOutput>;
23
+ /**
24
+ * Appends a middleware to the chain. Middlewares are applied
25
+ * left-to-right after the callback resolves.
26
+ *
27
+ * @param middleware - The {@link Middleware} to append.
28
+ */
29
+ use(middleware: Middleware): Method<TInput, TOutput>;
30
+ /**
31
+ * Attaches a Zod schema used to validate (and narrow) the request body.
32
+ * When validation fails, `dispatch` returns a `400` response automatically.
33
+ *
34
+ * @param bodySchema - Zod schema for the request body.
35
+ */
36
+ input<U>(bodySchema: ZodType<U>): Method<U, TOutput>;
37
+ /**
38
+ * Attaches a Zod schema that describes the expected response shape.
39
+ * Currently stored for documentation / code-generation purposes.
40
+ *
41
+ * @param schema - Zod schema for the response body.
42
+ */
43
+ output<U>(schema: ZodType<U>): Method<TInput, U>;
44
+ /**
45
+ * Registers the async handler callback for this method.
46
+ *
47
+ * @param callback - Function that receives the validated body, the raw
48
+ * Lambda event, and the Lambda context, and returns the response.
49
+ */
50
+ handle(callback: EndpointCallback<TInput, TOutput>): Method<TInput, TOutput>;
51
+ }
52
+ /** Creates a new, empty {@link Method} builder. */
53
+ export declare function method(): Method;
package/dist/method.js ADDED
@@ -0,0 +1,57 @@
1
+ // src/method.ts
2
+ class Method {
3
+ middlewares = [];
4
+ bodySchema;
5
+ outputSchema;
6
+ callback;
7
+ use(middleware) {
8
+ const r = new Method;
9
+ r.middlewares = [...this.middlewares, middleware];
10
+ if (this.bodySchema)
11
+ r.bodySchema = this.bodySchema;
12
+ if (this.outputSchema)
13
+ r.outputSchema = this.outputSchema;
14
+ if (this.callback)
15
+ r.callback = this.callback;
16
+ return r;
17
+ }
18
+ input(bodySchema) {
19
+ const r = new Method;
20
+ r.middlewares = this.middlewares;
21
+ r.bodySchema = bodySchema;
22
+ if (this.outputSchema)
23
+ r.outputSchema = this.outputSchema;
24
+ if (this.callback)
25
+ r.callback = this.callback;
26
+ return r;
27
+ }
28
+ output(schema) {
29
+ const r = new Method;
30
+ r.middlewares = this.middlewares;
31
+ if (this.bodySchema)
32
+ r.bodySchema = this.bodySchema;
33
+ r.outputSchema = schema;
34
+ if (this.callback)
35
+ r.callback = this.callback;
36
+ return r;
37
+ }
38
+ handle(callback) {
39
+ const r = new Method;
40
+ r.middlewares = this.middlewares;
41
+ if (this.bodySchema)
42
+ r.bodySchema = this.bodySchema;
43
+ if (this.outputSchema)
44
+ r.outputSchema = this.outputSchema;
45
+ r.callback = callback;
46
+ return r;
47
+ }
48
+ }
49
+ function method() {
50
+ return new Method;
51
+ }
52
+ export {
53
+ method,
54
+ Method
55
+ };
56
+
57
+ //# debugId=5EADB1A7B72CB4BE64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/method.ts"],
4
+ "sourcesContent": [
5
+ "import {type Middleware} from \"#src/middleware\"\nimport {EndpointCallback, RouteHandler} from \"#src/route-handler\"\nimport type {ZodType} from \"zod\"\n\nexport type {EndpointCallback, RouteHandler}\n\n/**\n * Fluent, immutable builder for a single HTTP-method handler.\n *\n * Every method returns a new `Method` instance, leaving the original\n * unchanged. Build a method with the following chain:\n *\n * ```ts\n * method().use(cors()).input(schema).output(schema).handle(async ({body}) => …)\n * ```\n *\n * @typeParam TInput - Shape of the validated request body.\n * @typeParam TOutput - Return type of the handler callback.\n */\nexport class Method<TInput = unknown, TOutput = unknown> {\n middlewares: Middleware[] = []\n bodySchema?: ZodType<TInput>\n outputSchema?: ZodType<TOutput>\n callback?: EndpointCallback<TInput, TOutput>\n\n /**\n * Appends a middleware to the chain. Middlewares are applied\n * left-to-right after the callback resolves.\n *\n * @param middleware - The {@link Middleware} to append.\n */\n use(middleware: Middleware): Method<TInput, TOutput> {\n const r = new Method<TInput, TOutput>()\n r.middlewares = [...this.middlewares, middleware]\n if (this.bodySchema) r.bodySchema = this.bodySchema\n if (this.outputSchema) r.outputSchema = this.outputSchema\n if (this.callback) r.callback = this.callback\n return r\n }\n\n /**\n * Attaches a Zod schema used to validate (and narrow) the request body.\n * When validation fails, `dispatch` returns a `400` response automatically.\n *\n * @param bodySchema - Zod schema for the request body.\n */\n input<U>(bodySchema: ZodType<U>): Method<U, TOutput> {\n const r = new Method<U, TOutput>()\n r.middlewares = this.middlewares\n r.bodySchema = bodySchema\n if (this.outputSchema) r.outputSchema = this.outputSchema as ZodType<TOutput>\n if (this.callback)\n r.callback = this.callback as unknown as EndpointCallback<U, TOutput>\n return r\n }\n\n /**\n * Attaches a Zod schema that describes the expected response shape.\n * Currently stored for documentation / code-generation purposes.\n *\n * @param schema - Zod schema for the response body.\n */\n output<U>(schema: ZodType<U>): Method<TInput, U> {\n const r = new Method<TInput, U>()\n r.middlewares = this.middlewares\n if (this.bodySchema) r.bodySchema = this.bodySchema\n r.outputSchema = schema\n if (this.callback)\n r.callback = this.callback as unknown as EndpointCallback<TInput, U>\n return r\n }\n\n /**\n * Registers the async handler callback for this method.\n *\n * @param callback - Function that receives the validated body, the raw\n * Lambda event, and the Lambda context, and returns the response.\n */\n handle(callback: EndpointCallback<TInput, TOutput>): Method<TInput, TOutput> {\n const r = new Method<TInput, TOutput>()\n r.middlewares = this.middlewares\n if (this.bodySchema) r.bodySchema = this.bodySchema\n if (this.outputSchema) r.outputSchema = this.outputSchema\n r.callback = callback\n return r\n }\n}\n\n/** Creates a new, empty {@link Method} builder. */\nexport function method(): Method {\n return new Method()\n}\n"
6
+ ],
7
+ "mappings": ";AAmBO,MAAM,OAA4C;AAAA,EACrD,cAA4B,CAAC;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EAQA,GAAG,CAAC,YAAiD;AAAA,IACjD,MAAM,IAAI,IAAI;AAAA,IACd,EAAE,cAAc,CAAC,GAAG,KAAK,aAAa,UAAU;AAAA,IAChD,IAAI,KAAK;AAAA,MAAY,EAAE,aAAa,KAAK;AAAA,IACzC,IAAI,KAAK;AAAA,MAAc,EAAE,eAAe,KAAK;AAAA,IAC7C,IAAI,KAAK;AAAA,MAAU,EAAE,WAAW,KAAK;AAAA,IACrC,OAAO;AAAA;AAAA,EASX,KAAQ,CAAC,YAA4C;AAAA,IACjD,MAAM,IAAI,IAAI;AAAA,IACd,EAAE,cAAc,KAAK;AAAA,IACrB,EAAE,aAAa;AAAA,IACf,IAAI,KAAK;AAAA,MAAc,EAAE,eAAe,KAAK;AAAA,IAC7C,IAAI,KAAK;AAAA,MACL,EAAE,WAAW,KAAK;AAAA,IACtB,OAAO;AAAA;AAAA,EASX,MAAS,CAAC,QAAuC;AAAA,IAC7C,MAAM,IAAI,IAAI;AAAA,IACd,EAAE,cAAc,KAAK;AAAA,IACrB,IAAI,KAAK;AAAA,MAAY,EAAE,aAAa,KAAK;AAAA,IACzC,EAAE,eAAe;AAAA,IACjB,IAAI,KAAK;AAAA,MACL,EAAE,WAAW,KAAK;AAAA,IACtB,OAAO;AAAA;AAAA,EASX,MAAM,CAAC,UAAsE;AAAA,IACzE,MAAM,IAAI,IAAI;AAAA,IACd,EAAE,cAAc,KAAK;AAAA,IACrB,IAAI,KAAK;AAAA,MAAY,EAAE,aAAa,KAAK;AAAA,IACzC,IAAI,KAAK;AAAA,MAAc,EAAE,eAAe,KAAK;AAAA,IAC7C,EAAE,WAAW;AAAA,IACb,OAAO;AAAA;AAEf;AAGO,SAAS,MAAM,GAAW;AAAA,EAC7B,OAAO,IAAI;AAAA;",
8
+ "debugId": "5EADB1A7B72CB4BE64756E2164756E21",
9
+ "names": []
10
+ }
@@ -1,14 +1,11 @@
1
- import type {APIGatewayProxyResult} from "aws-lambda"
2
-
3
- import {RouteHandler} from "./route-handler"
4
-
1
+ import type { APIGatewayProxyResult } from "aws-lambda";
2
+ import { RouteHandler } from "./route-handler";
5
3
  /**
6
4
  * A pure function that receives an {@link APIGatewayProxyResult} and returns
7
5
  * a (possibly modified) copy of it. Middlewares are composed left-to-right
8
6
  * by {@link dispatch}.
9
7
  */
10
- export type Middleware = (result: APIGatewayProxyResult) => APIGatewayProxyResult
11
-
8
+ export type Middleware = (result: APIGatewayProxyResult) => APIGatewayProxyResult;
12
9
  /**
13
10
  * Creates a middleware that injects CORS response headers.
14
11
  *
@@ -19,23 +16,9 @@ export type Middleware = (result: APIGatewayProxyResult) => APIGatewayProxyResul
19
16
  * @param headers - Map of unprefixed CORS header names to their values.
20
17
  * Defaults to an empty object (no CORS headers added).
21
18
  */
22
- export function cors(headers: Record<string, string> = {}): Middleware {
23
- return (result) => {
24
- const corsHeaders: Record<string, string> = {}
25
- for (const [key, value] of Object.entries(headers)) {
26
- corsHeaders[`Access-Control-${key}`] = value
27
- }
28
- return {...result, headers: {...result.headers, ...corsHeaders}}
29
- }
30
- }
31
-
19
+ export declare function cors(headers?: Record<string, string>): Middleware;
32
20
  /**
33
21
  * Folds all middlewares registered on `route` over `result`, applying them
34
22
  * left-to-right, and returns the final {@link APIGatewayProxyResult}.
35
23
  */
36
- export function applyMiddlewares(
37
- result: APIGatewayProxyResult,
38
- route: RouteHandler,
39
- ): APIGatewayProxyResult {
40
- return route.middlewares.reduce((r, middleware) => middleware(r), result)
41
- }
24
+ export declare function applyMiddlewares(result: APIGatewayProxyResult, route: RouteHandler): APIGatewayProxyResult;
@@ -0,0 +1,19 @@
1
+ // src/middleware.ts
2
+ function cors(headers = {}) {
3
+ return (result) => {
4
+ const corsHeaders = {};
5
+ for (const [key, value] of Object.entries(headers)) {
6
+ corsHeaders[`Access-Control-${key}`] = value;
7
+ }
8
+ return { ...result, headers: { ...result.headers, ...corsHeaders } };
9
+ };
10
+ }
11
+ function applyMiddlewares(result, route) {
12
+ return route.middlewares.reduce((r, middleware) => middleware(r), result);
13
+ }
14
+ export {
15
+ cors,
16
+ applyMiddlewares
17
+ };
18
+
19
+ //# debugId=235C7399F968D7AF64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/middleware.ts"],
4
+ "sourcesContent": [
5
+ "import type {APIGatewayProxyResult} from \"aws-lambda\"\n\nimport {RouteHandler} from \"./route-handler\"\n\n/**\n * A pure function that receives an {@link APIGatewayProxyResult} and returns\n * a (possibly modified) copy of it. Middlewares are composed left-to-right\n * by {@link dispatch}.\n */\nexport type Middleware = (result: APIGatewayProxyResult) => APIGatewayProxyResult\n\n/**\n * Creates a middleware that injects CORS response headers.\n *\n * Each key in `headers` is prefixed with `\"Access-Control-\"` before being\n * merged into the response, so passing `{\"Allow-Origin\": \"*\"}` produces the\n * `Access-Control-Allow-Origin: *` header.\n *\n * @param headers - Map of unprefixed CORS header names to their values.\n * Defaults to an empty object (no CORS headers added).\n */\nexport function cors(headers: Record<string, string> = {}): Middleware {\n return (result) => {\n const corsHeaders: Record<string, string> = {}\n for (const [key, value] of Object.entries(headers)) {\n corsHeaders[`Access-Control-${key}`] = value\n }\n return {...result, headers: {...result.headers, ...corsHeaders}}\n }\n}\n\n/**\n * Folds all middlewares registered on `route` over `result`, applying them\n * left-to-right, and returns the final {@link APIGatewayProxyResult}.\n */\nexport function applyMiddlewares(\n result: APIGatewayProxyResult,\n route: RouteHandler,\n): APIGatewayProxyResult {\n return route.middlewares.reduce((r, middleware) => middleware(r), result)\n}\n"
6
+ ],
7
+ "mappings": ";AAqBO,SAAS,IAAI,CAAC,UAAkC,CAAC,GAAe;AAAA,EACnE,OAAO,CAAC,WAAW;AAAA,IACf,MAAM,cAAsC,CAAC;AAAA,IAC7C,YAAY,KAAK,UAAU,OAAO,QAAQ,OAAO,GAAG;AAAA,MAChD,YAAY,kBAAkB,SAAS;AAAA,IAC3C;AAAA,IACA,OAAO,KAAI,QAAQ,SAAS,KAAI,OAAO,YAAY,YAAW,EAAC;AAAA;AAAA;AAQhE,SAAS,gBAAgB,CAC5B,QACA,OACqB;AAAA,EACrB,OAAO,MAAM,YAAY,OAAO,CAAC,GAAG,eAAe,WAAW,CAAC,GAAG,MAAM;AAAA;",
8
+ "debugId": "235C7399F968D7AF64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,48 @@
1
+ import type { APIGatewayProxyResult } from "aws-lambda";
2
+ /**
3
+ * Immutable builder for AWS Lambda proxy responses.
4
+ *
5
+ * All mutation methods return a new `Response` instance so that existing
6
+ * instances are never modified. Construct instances through the static
7
+ * factory methods {@link Response.text} and {@link Response.json}.
8
+ */
9
+ export declare class Response {
10
+ status?: number;
11
+ body?: unknown;
12
+ text?: string;
13
+ headers?: Record<string, string>;
14
+ private constructor();
15
+ /**
16
+ * Creates a plain-text response.
17
+ *
18
+ * @param status - HTTP status code.
19
+ * @param text - Response body as a plain string.
20
+ */
21
+ static text(status: number, text: string): Response;
22
+ /**
23
+ * Creates a JSON response.
24
+ *
25
+ * @param status - HTTP status code.
26
+ * @param body - Value to be serialised with `JSON.stringify`.
27
+ */
28
+ static json(status: number, body: unknown): Response;
29
+ /**
30
+ * Returns a new `Response` with an additional HTTP response header.
31
+ *
32
+ * @param name - Header name (e.g. `"Allow"`).
33
+ * @param value - Header value.
34
+ */
35
+ header(name: string, value: string): Response;
36
+ /**
37
+ * Serialises this `Response` into the shape expected by the AWS Lambda
38
+ * proxy integration.
39
+ *
40
+ * - When constructed via {@link Response.json} the body is JSON-encoded
41
+ * and `Content-Type` is set to `application/json; charset=utf-8`.
42
+ * - When constructed via {@link Response.text} the body is returned as-is
43
+ * and `Content-Type` is set to `text/plain; charset=utf-8`.
44
+ * - Additional headers set via {@link Response.header} are merged last and
45
+ * therefore take precedence over the defaults above.
46
+ */
47
+ toAPIGatewayProxyResult(): APIGatewayProxyResult;
48
+ }
@@ -0,0 +1,46 @@
1
+ // src/response.ts
2
+ class Response {
3
+ status;
4
+ body;
5
+ text;
6
+ headers;
7
+ constructor() {}
8
+ static text(status, text) {
9
+ const r = new Response;
10
+ r.status = status;
11
+ r.text = text;
12
+ return r;
13
+ }
14
+ static json(status, body) {
15
+ const r = new Response;
16
+ r.status = status;
17
+ r.body = body;
18
+ return r;
19
+ }
20
+ header(name, value) {
21
+ const r = new Response;
22
+ if (this.status !== undefined)
23
+ r.status = this.status;
24
+ if (this.body !== undefined)
25
+ r.body = this.body;
26
+ if (this.text !== undefined)
27
+ r.text = this.text;
28
+ r.headers = { ...this.headers, [name]: value };
29
+ return r;
30
+ }
31
+ toAPIGatewayProxyResult() {
32
+ return {
33
+ statusCode: this.status ?? 200,
34
+ body: this.text === undefined ? JSON.stringify(this.body) ?? "null" : this.text,
35
+ headers: {
36
+ "Content-Type": this.text === undefined ? "application/json; charset=utf-8" : "text/plain; charset=utf-8",
37
+ ...this.headers
38
+ }
39
+ };
40
+ }
41
+ }
42
+ export {
43
+ Response
44
+ };
45
+
46
+ //# debugId=908F48F107B3C11764756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/response.ts"],
4
+ "sourcesContent": [
5
+ "import type {APIGatewayProxyResult} from \"aws-lambda\"\n\n/**\n * Immutable builder for AWS Lambda proxy responses.\n *\n * All mutation methods return a new `Response` instance so that existing\n * instances are never modified. Construct instances through the static\n * factory methods {@link Response.text} and {@link Response.json}.\n */\nexport class Response {\n status?: number\n body?: unknown\n text?: string\n headers?: Record<string, string>\n\n private constructor() {}\n\n /**\n * Creates a plain-text response.\n *\n * @param status - HTTP status code.\n * @param text - Response body as a plain string.\n */\n static text(status: number, text: string) {\n const r = new Response()\n r.status = status\n r.text = text\n return r\n }\n\n /**\n * Creates a JSON response.\n *\n * @param status - HTTP status code.\n * @param body - Value to be serialised with `JSON.stringify`.\n */\n static json(status: number, body: unknown) {\n const r = new Response()\n r.status = status\n r.body = body\n return r\n }\n\n /**\n * Returns a new `Response` with an additional HTTP response header.\n *\n * @param name - Header name (e.g. `\"Allow\"`).\n * @param value - Header value.\n */\n header(name: string, value: string): Response {\n const r = new Response()\n if (this.status !== undefined) r.status = this.status\n if (this.body !== undefined) r.body = this.body\n if (this.text !== undefined) r.text = this.text\n r.headers = {...this.headers, [name]: value}\n return r\n }\n\n /**\n * Serialises this `Response` into the shape expected by the AWS Lambda\n * proxy integration.\n *\n * - When constructed via {@link Response.json} the body is JSON-encoded\n * and `Content-Type` is set to `application/json; charset=utf-8`.\n * - When constructed via {@link Response.text} the body is returned as-is\n * and `Content-Type` is set to `text/plain; charset=utf-8`.\n * - Additional headers set via {@link Response.header} are merged last and\n * therefore take precedence over the defaults above.\n */\n toAPIGatewayProxyResult(): APIGatewayProxyResult {\n return {\n statusCode: this.status ?? 200,\n body:\n this.text === undefined ?\n (JSON.stringify(this.body) ?? \"null\")\n : this.text,\n headers: {\n \"Content-Type\":\n this.text === undefined ?\n \"application/json; charset=utf-8\"\n : \"text/plain; charset=utf-8\",\n ...this.headers,\n },\n }\n }\n}\n"
6
+ ],
7
+ "mappings": ";AASO,MAAM,SAAS;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEQ,WAAW,GAAG;AAAA,SAQf,IAAI,CAAC,QAAgB,MAAc;AAAA,IACtC,MAAM,IAAI,IAAI;AAAA,IACd,EAAE,SAAS;AAAA,IACX,EAAE,OAAO;AAAA,IACT,OAAO;AAAA;AAAA,SASJ,IAAI,CAAC,QAAgB,MAAe;AAAA,IACvC,MAAM,IAAI,IAAI;AAAA,IACd,EAAE,SAAS;AAAA,IACX,EAAE,OAAO;AAAA,IACT,OAAO;AAAA;AAAA,EASX,MAAM,CAAC,MAAc,OAAyB;AAAA,IAC1C,MAAM,IAAI,IAAI;AAAA,IACd,IAAI,KAAK,WAAW;AAAA,MAAW,EAAE,SAAS,KAAK;AAAA,IAC/C,IAAI,KAAK,SAAS;AAAA,MAAW,EAAE,OAAO,KAAK;AAAA,IAC3C,IAAI,KAAK,SAAS;AAAA,MAAW,EAAE,OAAO,KAAK;AAAA,IAC3C,EAAE,UAAU,KAAI,KAAK,UAAU,OAAO,MAAK;AAAA,IAC3C,OAAO;AAAA;AAAA,EAcX,uBAAuB,GAA0B;AAAA,IAC7C,OAAO;AAAA,MACH,YAAY,KAAK,UAAU;AAAA,MAC3B,MACI,KAAK,SAAS,YACT,KAAK,UAAU,KAAK,IAAI,KAAK,SAC9B,KAAK;AAAA,MACb,SAAS;AAAA,QACL,gBACI,KAAK,SAAS,YACV,oCACA;AAAA,WACL,KAAK;AAAA,MACZ;AAAA,IACJ;AAAA;AAER;",
8
+ "debugId": "908F48F107B3C11764756E2164756E21",
9
+ "names": []
10
+ }