Socket
Book a DemoInstallSign in
Socket

@aws-lambda-powertools/event-handler

Package Overview
Dependencies
Maintainers
3
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aws-lambda-powertools/event-handler - npm Package Compare versions

Comparing version

to
2.26.0

lib/cjs/appsync-graphql/ExceptionHandlerRegistry.d.ts

25

lib/cjs/appsync-graphql/AppSyncGraphQLResolver.js

@@ -152,3 +152,3 @@ "use strict";

}
return this.#withErrorHandling(() => this.#executeBatchResolvers(event, context, options), event[0]);
return this.#withErrorHandling(() => this.#executeBatchResolvers(event, context, options), event[0], options);
}

@@ -159,3 +159,3 @@ if (!(0, utils_js_1.isAppSyncGraphQLEvent)(event)) {

}
return this.#withErrorHandling(() => this.#executeSingleResolver(event, context, options), event);
return this.#withErrorHandling(() => this.#executeSingleResolver(event, context, options), event, options);
}

@@ -169,4 +169,5 @@ /**

* @param event - The AppSync resolver event (single or first of batch).
* @param options - Optional resolve options for customizing resolver behavior.
*/
async #withErrorHandling(fn, event) {
async #withErrorHandling(fn, event, options) {
try {

@@ -176,3 +177,3 @@ return await fn();

catch (error) {
return this.#handleError(error, `An error occurred in handler ${event.info.fieldName}`);
return this.#handleError(error, `An error occurred in handler ${event.info.fieldName}`, options);
}

@@ -185,2 +186,3 @@ }

* `InvalidBatchResponseException` or `ResolverNotFoundException`, it is re-thrown.
* Checks for registered exception handlers and calls them if available.
* Otherwise, the error is formatted into a response using `#formatErrorResponse`.

@@ -190,5 +192,6 @@ *

* @param errorMessage - A descriptive message to log alongside the error.
* @param options - Optional resolve options for customizing resolver behavior.
* @throws InvalidBatchResponseException | ResolverNotFoundException
*/
#handleError(error, errorMessage) {
async #handleError(error, errorMessage, options) {
this.logger.error(errorMessage, error);

@@ -199,2 +202,14 @@ if (error instanceof errors_js_1.InvalidBatchResponseException)

throw error;
if (error instanceof Error) {
const exceptionHandler = this.exceptionHandlerRegistry.resolve(error);
if (exceptionHandler) {
try {
this.logger.debug(`Calling exception handler for error: ${error.name}`);
return await exceptionHandler.apply(options?.scope ?? this, [error]);
}
catch (handlerError) {
this.logger.error(`Exception handler for ${error.name} threw an error`, handlerError);
}
}
}
return this.#formatErrorResponse(error);

@@ -201,0 +216,0 @@ }

85

lib/cjs/appsync-graphql/Router.d.ts
import type { GenericLogger } from '@aws-lambda-powertools/commons/types';
import type { BatchResolverHandler, GraphQlBatchRouteOptions, GraphQlRouteOptions, GraphQlRouterOptions, ResolverHandler } from '../types/appsync-graphql.js';
import type { BatchResolverHandler, ErrorClass, ExceptionHandler, GraphQlBatchRouteOptions, GraphQlRouteOptions, GraphQlRouterOptions, ResolverHandler } from '../types/appsync-graphql.js';
import { ExceptionHandlerRegistry } from './ExceptionHandlerRegistry.js';
import { RouteHandlerRegistry } from './RouteHandlerRegistry.js';

@@ -17,2 +18,6 @@ /**

/**
* A map of registered exception handlers for handling errors in GraphQL resolvers.
*/
protected readonly exceptionHandlerRegistry: ExceptionHandlerRegistry;
/**
* A logger instance to be used for logging debug, warning, and error messages.

@@ -642,4 +647,82 @@ *

onBatchMutation(fieldName: string, options?: Omit<GraphQlBatchRouteOptions<true, boolean>, 'fieldName' | 'typeName'>): MethodDecorator;
/**
* Register an exception handler for a specific error class.
*
* Registers a handler for a specific error class that can be thrown by GraphQL resolvers.
* The handler will be invoked when an error of the specified class is thrown from any
* resolver function.
*
* @example
* ```ts
* import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
* import { AssertionError } from 'assert';
*
* const app = new AppSyncGraphQLResolver();
*
* // Register an exception handler for AssertionError
* app.exceptionHandler(AssertionError, async (error) => {
* return {
* error: {
* message: error.message,
* type: error.name
* }
* };
* });
*
* // Register a resolver that might throw an AssertionError
* app.onQuery('createSomething', async () => {
* throw new AssertionError({
* message: 'This is an assertion Error',
* });
* });
*
* export const handler = async (event, context) =>
* app.resolve(event, context);
* ```
*
* As a decorator:
*
* @example
* ```ts
* import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
* import { AssertionError } from 'assert';
*
* const app = new AppSyncGraphQLResolver();
*
* class Lambda {
* ⁣@app.exceptionHandler(AssertionError)
* async handleAssertionError(error: AssertionError) {
* return {
* error: {
* message: error.message,
* type: error.name
* }
* };
* }
*
* ⁣@app.onQuery('getUser')
* async getUser() {
* throw new AssertionError({
* message: 'This is an assertion Error',
* });
* }
*
* async handler(event, context) {
* return app.resolve(event, context, {
* scope: this, // bind decorated methods to the class instance
* });
* }
* }
*
* const lambda = new Lambda();
* export const handler = lambda.handler.bind(lambda);
* ```
*
* @param error - The error class to handle.
* @param handler - The handler function to be called when the error is caught.
*/
exceptionHandler<T extends Error>(error: ErrorClass<T> | ErrorClass<T>[], handler: ExceptionHandler<T>): void;
exceptionHandler<T extends Error>(error: ErrorClass<T> | ErrorClass<T>[]): MethodDecorator;
}
export { Router };
//# sourceMappingURL=Router.d.ts.map

@@ -5,2 +5,3 @@ "use strict";

const env_1 = require("@aws-lambda-powertools/commons/utils/env");
const ExceptionHandlerRegistry_js_1 = require("./ExceptionHandlerRegistry.js");
const RouteHandlerRegistry_js_1 = require("./RouteHandlerRegistry.js");

@@ -20,2 +21,6 @@ /**

/**
* A map of registered exception handlers for handling errors in GraphQL resolvers.
*/
exceptionHandlerRegistry;
/**
* A logger instance to be used for logging debug, warning, and error messages.

@@ -46,2 +51,5 @@ *

});
this.exceptionHandlerRegistry = new ExceptionHandlerRegistry_js_1.ExceptionHandlerRegistry({
logger: this.logger,
});
this.isDev = (0, env_1.isDevMode)();

@@ -175,3 +183,19 @@ }

}
exceptionHandler(error, handler) {
if (typeof handler === 'function') {
this.exceptionHandlerRegistry.register({
error,
handler: handler,
});
return;
}
return (_target, _propertyKey, descriptor) => {
this.exceptionHandlerRegistry.register({
error,
handler: descriptor?.value,
});
return descriptor;
};
}
}
exports.Router = Router;

@@ -1,3 +0,34 @@

import type { APIGatewayProxyEvent } from 'aws-lambda';
import type { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import type { HandlerResponse } from '../types/rest.js';
/**
* Converts an API Gateway proxy event to a Web API Request object.
*
* @param event - The API Gateway proxy event
* @returns A Web API Request object
*/
export declare const proxyEventToWebRequest: (event: APIGatewayProxyEvent) => Request;
/**
* Converts a Web API Response object to an API Gateway proxy result.
*
* @param response - The Web API Response object
* @returns An API Gateway proxy result
*/
export declare const webResponseToProxyResult: (response: Response) => Promise<APIGatewayProxyResult>;
/**
* Converts a handler response to a Web API Response object.
* Handles APIGatewayProxyResult, Response objects, and plain objects.
*
* @param response - The handler response (APIGatewayProxyResult, Response, or plain object)
* @param headers - Optional headers to be included in the response
* @returns A Web API Response object
*/
export declare const handlerResultToWebResponse: (response: HandlerResponse, resHeaders?: Headers) => Response;
/**
* Converts a handler response to an API Gateway proxy result.
* Handles APIGatewayProxyResult, Response objects, and plain objects.
*
* @param response - The handler response (APIGatewayProxyResult, Response, or plain object)
* @returns An API Gateway proxy result
*/
export declare const handlerResultToProxyResult: (response: HandlerResponse) => Promise<APIGatewayProxyResult>;
//# sourceMappingURL=converters.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.proxyEventToWebRequest = void 0;
exports.handlerResultToProxyResult = exports.handlerResultToWebResponse = exports.webResponseToProxyResult = exports.proxyEventToWebRequest = void 0;
const utils_js_1 = require("./utils.js");
/**
* Creates a request body from API Gateway event body, handling base64 decoding if needed.
*
* @param body - The raw body from the API Gateway event
* @param isBase64Encoded - Whether the body is base64 encoded
* @returns The decoded body string or null
*/
const createBody = (body, isBase64Encoded) => {

@@ -12,16 +20,26 @@ if (body === null)

};
/**
* Converts an API Gateway proxy event to a Web API Request object.
*
* @param event - The API Gateway proxy event
* @returns A Web API Request object
*/
const proxyEventToWebRequest = (event) => {
const { httpMethod, path, domainName } = event.requestContext;
const { httpMethod, path } = event;
const { domainName } = event.requestContext;
const headers = new Headers();
for (const [name, value] of Object.entries(event.headers ?? {})) {
if (value != null)
headers.append(name, value);
headers.set(name, value);
}
for (const [name, values] of Object.entries(event.multiValueHeaders ?? {})) {
for (const value of values ?? []) {
headers.append(name, value);
const headerValue = headers.get(name);
if (!headerValue?.includes(value)) {
headers.append(name, value);
}
}
}
const hostname = headers.get('Host') ?? domainName;
const protocol = headers.get('X-Forwarded-Proto') ?? 'http';
const protocol = headers.get('X-Forwarded-Proto') ?? 'https';
const url = new URL(path, `${protocol}://${hostname}/`);

@@ -44,1 +62,86 @@ for (const [name, value] of Object.entries(event.queryStringParameters ?? {})) {

exports.proxyEventToWebRequest = proxyEventToWebRequest;
/**
* Converts a Web API Response object to an API Gateway proxy result.
*
* @param response - The Web API Response object
* @returns An API Gateway proxy result
*/
const webResponseToProxyResult = async (response) => {
const headers = {};
const multiValueHeaders = {};
for (const [key, value] of response.headers.entries()) {
const values = value.split(',').map((v) => v.trimStart());
if (values.length > 1) {
multiValueHeaders[key] = values;
}
else {
headers[key] = value;
}
}
const result = {
statusCode: response.status,
headers,
body: await response.text(),
isBase64Encoded: false,
};
if (Object.keys(multiValueHeaders).length > 0) {
result.multiValueHeaders = multiValueHeaders;
}
return result;
};
exports.webResponseToProxyResult = webResponseToProxyResult;
/**
* Converts a handler response to a Web API Response object.
* Handles APIGatewayProxyResult, Response objects, and plain objects.
*
* @param response - The handler response (APIGatewayProxyResult, Response, or plain object)
* @param headers - Optional headers to be included in the response
* @returns A Web API Response object
*/
const handlerResultToWebResponse = (response, resHeaders) => {
if (response instanceof Response) {
return response;
}
const headers = new Headers(resHeaders);
headers.set('Content-Type', 'application/json');
if ((0, utils_js_1.isAPIGatewayProxyResult)(response)) {
for (const [key, value] of Object.entries(response.headers ?? {})) {
if (value != null) {
headers.set(key, String(value));
}
}
for (const [key, values] of Object.entries(response.multiValueHeaders ?? {})) {
for (const value of values ?? []) {
headers.append(key, String(value));
}
}
return new Response(response.body, {
status: response.statusCode,
headers,
});
}
return Response.json(response, { headers });
};
exports.handlerResultToWebResponse = handlerResultToWebResponse;
/**
* Converts a handler response to an API Gateway proxy result.
* Handles APIGatewayProxyResult, Response objects, and plain objects.
*
* @param response - The handler response (APIGatewayProxyResult, Response, or plain object)
* @returns An API Gateway proxy result
*/
const handlerResultToProxyResult = async (response) => {
if ((0, utils_js_1.isAPIGatewayProxyResult)(response)) {
return response;
}
if (response instanceof Response) {
return await (0, exports.webResponseToProxyResult)(response);
}
return {
statusCode: 200,
body: JSON.stringify(response),
headers: { 'content-type': 'application/json' },
isBase64Encoded: false,
};
};
exports.handlerResultToProxyResult = handlerResultToProxyResult;

@@ -1,2 +0,2 @@

import type { HttpMethod, Path, RouteHandler } from '../types/rest.js';
import type { HttpMethod, Middleware, Path, RouteHandler } from '../types/rest.js';
declare class Route {

@@ -7,5 +7,6 @@ readonly id: string;

readonly handler: RouteHandler;
constructor(method: HttpMethod, path: Path, handler: RouteHandler);
readonly middleware: Middleware[];
constructor(method: HttpMethod, path: Path, handler: RouteHandler, middleware?: Middleware[]);
}
export { Route };
//# sourceMappingURL=Route.d.ts.map

@@ -9,3 +9,4 @@ "use strict";

handler;
constructor(method, path, handler) {
middleware;
constructor(method, path, handler, middleware = []) {
this.id = `${method}:${path}`;

@@ -15,4 +16,5 @@ this.method = method;

this.handler = handler;
this.middleware = middleware;
}
}
exports.Route = Route;

@@ -1,2 +0,2 @@

import type { HttpMethod, Path, RouteHandlerOptions, RouteRegistryOptions } from '../types/rest.js';
import type { HttpMethod, Path, RestRouteHandlerOptions, RouteRegistryOptions } from '../types/rest.js';
import type { Route } from './Route.js';

@@ -35,5 +35,5 @@ declare class RouteHandlerRegistry {

*/
resolve(method: HttpMethod, path: Path): RouteHandlerOptions | null;
resolve(method: HttpMethod, path: Path): RestRouteHandlerOptions | null;
}
export { RouteHandlerRegistry };
//# sourceMappingURL=RouteHandlerRegistry.d.ts.map

@@ -138,2 +138,3 @@ "use strict";

params: {},
middleware: staticRoute.middleware,
};

@@ -156,2 +157,3 @@ }

rawParams: params,
middleware: route.middleware,
};

@@ -158,0 +160,0 @@ }

@@ -1,3 +0,3 @@

import type { APIGatewayProxyEvent } from 'aws-lambda';
import type { CompiledRoute, Path, ValidationResult } from '../types/rest.js';
import type { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import type { CompiledRoute, HttpMethod, Middleware, Path, ValidationResult } from '../types/rest.js';
export declare function compilePath(path: Path): CompiledRoute;

@@ -14,2 +14,47 @@ export declare function validatePathPattern(path: Path): ValidationResult;

export declare const isAPIGatewayProxyEvent: (event: unknown) => event is APIGatewayProxyEvent;
export declare const isHttpMethod: (method: string) => method is HttpMethod;
/**
* Type guard to check if the provided result is an API Gateway Proxy result.
*
* We use this function to ensure that the result is an object and has the
* required properties without adding a dependency.
*
* @param result - The result to check
*/
export declare const isAPIGatewayProxyResult: (result: unknown) => result is APIGatewayProxyResult;
/**
* Composes multiple middleware functions into a single middleware function.
*
* Middleware functions are executed in order, with each middleware having the ability
* to call `next()` to proceed to the next middleware in the chain. The composed middleware
* follows the onion model where middleware executes in order before `next()` and in
* reverse order after `next()`.
*
* @param middleware - Array of middleware functions to compose
* @returns A single middleware function that executes all provided middleware in sequence
*
* @example
* ```typescript
* const middleware1: Middleware = async (params, options, next) => {
* console.log('middleware1 start');
* await next();
* console.log('middleware1 end');
* };
*
* const middleware2: Middleware = async (params, options, next) => {
* console.log('middleware2 start');
* await next();
* console.log('middleware2 end');
* };
*
* const composed: Middleware = composeMiddleware([middleware1, middleware2]);
* // Execution order:
* // middleware1 start
* // -> middleware2 start
* // -> handler
* // -> middleware2 end
* // -> middleware1 end
* ```
*/
export declare const composeMiddleware: (middleware: Middleware[]) => Middleware;
//# sourceMappingURL=utils.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isAPIGatewayProxyEvent = void 0;
exports.composeMiddleware = exports.isAPIGatewayProxyResult = exports.isHttpMethod = exports.isAPIGatewayProxyEvent = void 0;
exports.compilePath = compilePath;

@@ -55,7 +55,98 @@ exports.validatePathPattern = validatePathPattern;

(0, typeutils_1.isString)(event.resource) &&
(0, typeutils_1.isRecord)(event.headers) &&
(event.headers == null || (0, typeutils_1.isRecord)(event.headers)) &&
(event.multiValueHeaders == null || (0, typeutils_1.isRecord)(event.multiValueHeaders)) &&
(0, typeutils_1.isRecord)(event.requestContext) &&
typeof event.isBase64Encoded === 'boolean' &&
(event.body === null || (0, typeutils_1.isString)(event.body)));
(event.body === null || (0, typeutils_1.isString)(event.body)) &&
(event.pathParameters === null || (0, typeutils_1.isRecord)(event.pathParameters)) &&
(event.queryStringParameters === null ||
(0, typeutils_1.isRecord)(event.queryStringParameters)) &&
(event.multiValueQueryStringParameters === null ||
(0, typeutils_1.isRecord)(event.multiValueQueryStringParameters)) &&
(event.stageVariables === null || (0, typeutils_1.isRecord)(event.stageVariables)));
};
exports.isAPIGatewayProxyEvent = isAPIGatewayProxyEvent;
const isHttpMethod = (method) => {
return Object.keys(constants_js_1.HttpVerbs).includes(method);
};
exports.isHttpMethod = isHttpMethod;
/**
* Type guard to check if the provided result is an API Gateway Proxy result.
*
* We use this function to ensure that the result is an object and has the
* required properties without adding a dependency.
*
* @param result - The result to check
*/
const isAPIGatewayProxyResult = (result) => {
if (!(0, typeutils_1.isRecord)(result))
return false;
return (typeof result.statusCode === 'number' &&
(0, typeutils_1.isString)(result.body) &&
(result.headers === undefined || (0, typeutils_1.isRecord)(result.headers)) &&
(result.multiValueHeaders === undefined ||
(0, typeutils_1.isRecord)(result.multiValueHeaders)) &&
(result.isBase64Encoded === undefined ||
typeof result.isBase64Encoded === 'boolean'));
};
exports.isAPIGatewayProxyResult = isAPIGatewayProxyResult;
/**
* Composes multiple middleware functions into a single middleware function.
*
* Middleware functions are executed in order, with each middleware having the ability
* to call `next()` to proceed to the next middleware in the chain. The composed middleware
* follows the onion model where middleware executes in order before `next()` and in
* reverse order after `next()`.
*
* @param middleware - Array of middleware functions to compose
* @returns A single middleware function that executes all provided middleware in sequence
*
* @example
* ```typescript
* const middleware1: Middleware = async (params, options, next) => {
* console.log('middleware1 start');
* await next();
* console.log('middleware1 end');
* };
*
* const middleware2: Middleware = async (params, options, next) => {
* console.log('middleware2 start');
* await next();
* console.log('middleware2 end');
* };
*
* const composed: Middleware = composeMiddleware([middleware1, middleware2]);
* // Execution order:
* // middleware1 start
* // -> middleware2 start
* // -> handler
* // -> middleware2 end
* // -> middleware1 end
* ```
*/
const composeMiddleware = (middleware) => {
return async (params, reqCtx, next) => {
let index = -1;
let result;
const dispatch = async (i) => {
if (i <= index)
throw new Error('next() called multiple times');
index = i;
if (i === middleware.length) {
const nextResult = await next();
if (nextResult !== undefined) {
result = nextResult;
}
return;
}
const middlewareFn = middleware[i];
const middlewareResult = await middlewareFn(params, reqCtx, () => dispatch(i + 1));
if (middlewareResult !== undefined) {
result = middlewareResult;
}
};
await dispatch(0);
return result;
};
};
exports.composeMiddleware = composeMiddleware;

@@ -110,3 +110,33 @@ import type { GenericLogger } from '@aws-lambda-powertools/commons/types';

});
export type { RouteHandlerRegistryOptions, RouteHandlerOptions, GraphQlRouterOptions, GraphQlRouteOptions, GraphQlBatchRouteOptions, ResolverHandler, BatchResolverHandler, BatchResolverHandlerFn, BatchResolverAggregateHandlerFn, };
type ExceptionSyncHandlerFn<T extends Error> = (error: T) => unknown;
type ExceptionHandlerFn<T extends Error> = (error: T) => Promise<unknown>;
type ExceptionHandler<T extends Error = Error> = ExceptionSyncHandlerFn<T> | ExceptionHandlerFn<T>;
type ErrorClass<T extends Error> = new (...args: any[]) => T;
/**
* Options for handling exceptions in the event handler.
*
* @template T - The type of error that extends the base Error class
*/
type ExceptionHandlerOptions<T extends Error = Error> = {
/**
* The error class to handle (must be Error or a subclass)
*/
error: ErrorClass<T> | ErrorClass<T>[];
/**
* The handler function to be called when the error is caught
*/
handler: ExceptionHandler<T>;
};
/**
* Options for the {@link ExceptionHandlerRegistry | `ExceptionHandlerRegistry`} class
*/
type ExceptionHandlerRegistryOptions = {
/**
* A logger instance to be used for logging debug, warning, and error messages.
*
* When no logger is provided, we'll only log warnings and errors using the global `console` object.
*/
logger: Pick<GenericLogger, 'debug' | 'warn' | 'error'>;
};
export type { RouteHandlerRegistryOptions, RouteHandlerOptions, GraphQlRouterOptions, GraphQlRouteOptions, GraphQlBatchRouteOptions, ResolverHandler, BatchResolverHandler, BatchResolverHandlerFn, BatchResolverAggregateHandlerFn, ExceptionHandler, ErrorClass, ExceptionHandlerOptions, ExceptionHandlerRegistryOptions, };
//# sourceMappingURL=appsync-graphql.d.ts.map

@@ -5,2 +5,3 @@ export type { AppSyncEventsEvent, AppSyncEventsPublishEvent, AppSyncEventsSubscribeEvent, OnPublishAggregateOutput, OnPublishAggregatePayload, OnPublishEventPayload, OnPublishOutput, RouteOptions, RouterOptions, } from './appsync-events.js';

export type { Anything, ResolveOptions, } from './common.js';
export type { ErrorHandler, ErrorResolveOptions, ErrorResponse, HandlerResponse, HttpMethod, HttpStatusCode, Middleware, Path, RequestContext, RestRouteHandlerOptions, RestRouteOptions, RestRouterOptions, RouteHandler, } from './rest.js';
//# sourceMappingURL=index.d.ts.map

@@ -11,9 +11,10 @@ import type { GenericLogger, JSONObject } from '@aws-lambda-powertools/commons/types';

};
type RequestOptions = {
type RequestContext = {
request: Request;
event: APIGatewayProxyEvent;
context: Context;
res: Response;
};
type ErrorResolveOptions = RequestOptions & ResolveOptions;
type ErrorHandler<T extends Error = Error> = (error: T, options?: RequestOptions) => Promise<ErrorResponse>;
type ErrorResolveOptions = RequestContext & ResolveOptions;
type ErrorHandler<T extends Error = Error> = (error: T, reqCtx: RequestContext) => Promise<ErrorResponse>;
interface ErrorConstructor<T extends Error = Error> {

@@ -24,5 +25,5 @@ new (...args: any[]): T;

/**
* Options for the {@link BaseRouter} class
* Options for the {@link Router} class
*/
type RouterOptions = {
type RestRouterOptions = {
/**

@@ -42,15 +43,20 @@ * A logger instance to be used for logging debug, warning, and error messages.

type DynamicRoute = Route & CompiledRoute;
type RouteHandler<TParams = Record<string, unknown>, TReturn = Response | JSONObject> = (args: TParams, options?: RequestOptions) => Promise<TReturn>;
type HandlerResponse = Response | JSONObject;
type RouteHandler<TParams = Record<string, unknown>, TReturn = HandlerResponse> = (args: TParams, reqCtx: RequestContext) => Promise<TReturn>;
type HttpMethod = keyof typeof HttpVerbs;
type HttpStatusCode = (typeof HttpErrorCodes)[keyof typeof HttpErrorCodes];
type Path = `/${string}`;
type RouteHandlerOptions = {
type RestRouteHandlerOptions = {
handler: RouteHandler;
params: Record<string, string>;
rawParams: Record<string, string>;
middleware: Middleware[];
};
type RouteOptions = {
type RestRouteOptions = {
method: HttpMethod | HttpMethod[];
path: Path;
middleware?: Middleware[];
};
type NextFunction = () => Promise<HandlerResponse | void>;
type Middleware = (params: Record<string, string>, reqCtx: RequestContext, next: NextFunction) => Promise<void | HandlerResponse>;
type RouteRegistryOptions = {

@@ -76,3 +82,3 @@ /**

};
export type { CompiledRoute, DynamicRoute, ErrorResponse, ErrorConstructor, ErrorHandlerRegistryOptions, ErrorHandler, ErrorResolveOptions, HttpStatusCode, HttpMethod, Path, RequestOptions, RouterOptions, RouteHandler, RouteOptions, RouteHandlerOptions, RouteRegistryOptions, ValidationResult, };
export type { CompiledRoute, DynamicRoute, ErrorResponse, ErrorConstructor, ErrorHandlerRegistryOptions, ErrorHandler, ErrorResolveOptions, HandlerResponse, HttpStatusCode, HttpMethod, Middleware, Path, RequestContext, RestRouterOptions, RouteHandler, RestRouteOptions, RestRouteHandlerOptions, RouteRegistryOptions, ValidationResult, };
//# sourceMappingURL=rest.d.ts.map

@@ -149,3 +149,3 @@ import { InvalidBatchResponseException, ResolverNotFoundException, } from './errors.js';

}
return this.#withErrorHandling(() => this.#executeBatchResolvers(event, context, options), event[0]);
return this.#withErrorHandling(() => this.#executeBatchResolvers(event, context, options), event[0], options);
}

@@ -156,3 +156,3 @@ if (!isAppSyncGraphQLEvent(event)) {

}
return this.#withErrorHandling(() => this.#executeSingleResolver(event, context, options), event);
return this.#withErrorHandling(() => this.#executeSingleResolver(event, context, options), event, options);
}

@@ -166,4 +166,5 @@ /**

* @param event - The AppSync resolver event (single or first of batch).
* @param options - Optional resolve options for customizing resolver behavior.
*/
async #withErrorHandling(fn, event) {
async #withErrorHandling(fn, event, options) {
try {

@@ -173,3 +174,3 @@ return await fn();

catch (error) {
return this.#handleError(error, `An error occurred in handler ${event.info.fieldName}`);
return this.#handleError(error, `An error occurred in handler ${event.info.fieldName}`, options);
}

@@ -182,2 +183,3 @@ }

* `InvalidBatchResponseException` or `ResolverNotFoundException`, it is re-thrown.
* Checks for registered exception handlers and calls them if available.
* Otherwise, the error is formatted into a response using `#formatErrorResponse`.

@@ -187,5 +189,6 @@ *

* @param errorMessage - A descriptive message to log alongside the error.
* @param options - Optional resolve options for customizing resolver behavior.
* @throws InvalidBatchResponseException | ResolverNotFoundException
*/
#handleError(error, errorMessage) {
async #handleError(error, errorMessage, options) {
this.logger.error(errorMessage, error);

@@ -196,2 +199,14 @@ if (error instanceof InvalidBatchResponseException)

throw error;
if (error instanceof Error) {
const exceptionHandler = this.exceptionHandlerRegistry.resolve(error);
if (exceptionHandler) {
try {
this.logger.debug(`Calling exception handler for error: ${error.name}`);
return await exceptionHandler.apply(options?.scope ?? this, [error]);
}
catch (handlerError) {
this.logger.error(`Exception handler for ${error.name} threw an error`, handlerError);
}
}
}
return this.#formatErrorResponse(error);

@@ -198,0 +213,0 @@ }

import type { GenericLogger } from '@aws-lambda-powertools/commons/types';
import type { BatchResolverHandler, GraphQlBatchRouteOptions, GraphQlRouteOptions, GraphQlRouterOptions, ResolverHandler } from '../types/appsync-graphql.js';
import type { BatchResolverHandler, ErrorClass, ExceptionHandler, GraphQlBatchRouteOptions, GraphQlRouteOptions, GraphQlRouterOptions, ResolverHandler } from '../types/appsync-graphql.js';
import { ExceptionHandlerRegistry } from './ExceptionHandlerRegistry.js';
import { RouteHandlerRegistry } from './RouteHandlerRegistry.js';

@@ -17,2 +18,6 @@ /**

/**
* A map of registered exception handlers for handling errors in GraphQL resolvers.
*/
protected readonly exceptionHandlerRegistry: ExceptionHandlerRegistry;
/**
* A logger instance to be used for logging debug, warning, and error messages.

@@ -642,4 +647,82 @@ *

onBatchMutation(fieldName: string, options?: Omit<GraphQlBatchRouteOptions<true, boolean>, 'fieldName' | 'typeName'>): MethodDecorator;
/**
* Register an exception handler for a specific error class.
*
* Registers a handler for a specific error class that can be thrown by GraphQL resolvers.
* The handler will be invoked when an error of the specified class is thrown from any
* resolver function.
*
* @example
* ```ts
* import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
* import { AssertionError } from 'assert';
*
* const app = new AppSyncGraphQLResolver();
*
* // Register an exception handler for AssertionError
* app.exceptionHandler(AssertionError, async (error) => {
* return {
* error: {
* message: error.message,
* type: error.name
* }
* };
* });
*
* // Register a resolver that might throw an AssertionError
* app.onQuery('createSomething', async () => {
* throw new AssertionError({
* message: 'This is an assertion Error',
* });
* });
*
* export const handler = async (event, context) =>
* app.resolve(event, context);
* ```
*
* As a decorator:
*
* @example
* ```ts
* import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
* import { AssertionError } from 'assert';
*
* const app = new AppSyncGraphQLResolver();
*
* class Lambda {
* ⁣@app.exceptionHandler(AssertionError)
* async handleAssertionError(error: AssertionError) {
* return {
* error: {
* message: error.message,
* type: error.name
* }
* };
* }
*
* ⁣@app.onQuery('getUser')
* async getUser() {
* throw new AssertionError({
* message: 'This is an assertion Error',
* });
* }
*
* async handler(event, context) {
* return app.resolve(event, context, {
* scope: this, // bind decorated methods to the class instance
* });
* }
* }
*
* const lambda = new Lambda();
* export const handler = lambda.handler.bind(lambda);
* ```
*
* @param error - The error class to handle.
* @param handler - The handler function to be called when the error is caught.
*/
exceptionHandler<T extends Error>(error: ErrorClass<T> | ErrorClass<T>[], handler: ExceptionHandler<T>): void;
exceptionHandler<T extends Error>(error: ErrorClass<T> | ErrorClass<T>[]): MethodDecorator;
}
export { Router };
//# sourceMappingURL=Router.d.ts.map
import { getStringFromEnv, isDevMode, } from '@aws-lambda-powertools/commons/utils/env';
import { ExceptionHandlerRegistry } from './ExceptionHandlerRegistry.js';
import { RouteHandlerRegistry } from './RouteHandlerRegistry.js';

@@ -16,2 +17,6 @@ /**

/**
* A map of registered exception handlers for handling errors in GraphQL resolvers.
*/
exceptionHandlerRegistry;
/**
* A logger instance to be used for logging debug, warning, and error messages.

@@ -42,2 +47,5 @@ *

});
this.exceptionHandlerRegistry = new ExceptionHandlerRegistry({
logger: this.logger,
});
this.isDev = isDevMode();

@@ -171,3 +179,19 @@ }

}
exceptionHandler(error, handler) {
if (typeof handler === 'function') {
this.exceptionHandlerRegistry.register({
error,
handler: handler,
});
return;
}
return (_target, _propertyKey, descriptor) => {
this.exceptionHandlerRegistry.register({
error,
handler: descriptor?.value,
});
return descriptor;
};
}
}
export { Router };

@@ -1,3 +0,34 @@

import type { APIGatewayProxyEvent } from 'aws-lambda';
import type { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import type { HandlerResponse } from '../types/rest.js';
/**
* Converts an API Gateway proxy event to a Web API Request object.
*
* @param event - The API Gateway proxy event
* @returns A Web API Request object
*/
export declare const proxyEventToWebRequest: (event: APIGatewayProxyEvent) => Request;
/**
* Converts a Web API Response object to an API Gateway proxy result.
*
* @param response - The Web API Response object
* @returns An API Gateway proxy result
*/
export declare const webResponseToProxyResult: (response: Response) => Promise<APIGatewayProxyResult>;
/**
* Converts a handler response to a Web API Response object.
* Handles APIGatewayProxyResult, Response objects, and plain objects.
*
* @param response - The handler response (APIGatewayProxyResult, Response, or plain object)
* @param headers - Optional headers to be included in the response
* @returns A Web API Response object
*/
export declare const handlerResultToWebResponse: (response: HandlerResponse, resHeaders?: Headers) => Response;
/**
* Converts a handler response to an API Gateway proxy result.
* Handles APIGatewayProxyResult, Response objects, and plain objects.
*
* @param response - The handler response (APIGatewayProxyResult, Response, or plain object)
* @returns An API Gateway proxy result
*/
export declare const handlerResultToProxyResult: (response: HandlerResponse) => Promise<APIGatewayProxyResult>;
//# sourceMappingURL=converters.d.ts.map

@@ -0,1 +1,9 @@

import { isAPIGatewayProxyResult } from './utils.js';
/**
* Creates a request body from API Gateway event body, handling base64 decoding if needed.
*
* @param body - The raw body from the API Gateway event
* @param isBase64Encoded - Whether the body is base64 encoded
* @returns The decoded body string or null
*/
const createBody = (body, isBase64Encoded) => {

@@ -9,16 +17,26 @@ if (body === null)

};
/**
* Converts an API Gateway proxy event to a Web API Request object.
*
* @param event - The API Gateway proxy event
* @returns A Web API Request object
*/
export const proxyEventToWebRequest = (event) => {
const { httpMethod, path, domainName } = event.requestContext;
const { httpMethod, path } = event;
const { domainName } = event.requestContext;
const headers = new Headers();
for (const [name, value] of Object.entries(event.headers ?? {})) {
if (value != null)
headers.append(name, value);
headers.set(name, value);
}
for (const [name, values] of Object.entries(event.multiValueHeaders ?? {})) {
for (const value of values ?? []) {
headers.append(name, value);
const headerValue = headers.get(name);
if (!headerValue?.includes(value)) {
headers.append(name, value);
}
}
}
const hostname = headers.get('Host') ?? domainName;
const protocol = headers.get('X-Forwarded-Proto') ?? 'http';
const protocol = headers.get('X-Forwarded-Proto') ?? 'https';
const url = new URL(path, `${protocol}://${hostname}/`);

@@ -40,1 +58,83 @@ for (const [name, value] of Object.entries(event.queryStringParameters ?? {})) {

};
/**
* Converts a Web API Response object to an API Gateway proxy result.
*
* @param response - The Web API Response object
* @returns An API Gateway proxy result
*/
export const webResponseToProxyResult = async (response) => {
const headers = {};
const multiValueHeaders = {};
for (const [key, value] of response.headers.entries()) {
const values = value.split(',').map((v) => v.trimStart());
if (values.length > 1) {
multiValueHeaders[key] = values;
}
else {
headers[key] = value;
}
}
const result = {
statusCode: response.status,
headers,
body: await response.text(),
isBase64Encoded: false,
};
if (Object.keys(multiValueHeaders).length > 0) {
result.multiValueHeaders = multiValueHeaders;
}
return result;
};
/**
* Converts a handler response to a Web API Response object.
* Handles APIGatewayProxyResult, Response objects, and plain objects.
*
* @param response - The handler response (APIGatewayProxyResult, Response, or plain object)
* @param headers - Optional headers to be included in the response
* @returns A Web API Response object
*/
export const handlerResultToWebResponse = (response, resHeaders) => {
if (response instanceof Response) {
return response;
}
const headers = new Headers(resHeaders);
headers.set('Content-Type', 'application/json');
if (isAPIGatewayProxyResult(response)) {
for (const [key, value] of Object.entries(response.headers ?? {})) {
if (value != null) {
headers.set(key, String(value));
}
}
for (const [key, values] of Object.entries(response.multiValueHeaders ?? {})) {
for (const value of values ?? []) {
headers.append(key, String(value));
}
}
return new Response(response.body, {
status: response.statusCode,
headers,
});
}
return Response.json(response, { headers });
};
/**
* Converts a handler response to an API Gateway proxy result.
* Handles APIGatewayProxyResult, Response objects, and plain objects.
*
* @param response - The handler response (APIGatewayProxyResult, Response, or plain object)
* @returns An API Gateway proxy result
*/
export const handlerResultToProxyResult = async (response) => {
if (isAPIGatewayProxyResult(response)) {
return response;
}
if (response instanceof Response) {
return await webResponseToProxyResult(response);
}
return {
statusCode: 200,
body: JSON.stringify(response),
headers: { 'content-type': 'application/json' },
isBase64Encoded: false,
};
};

@@ -1,2 +0,2 @@

import type { HttpMethod, Path, RouteHandler } from '../types/rest.js';
import type { HttpMethod, Middleware, Path, RouteHandler } from '../types/rest.js';
declare class Route {

@@ -7,5 +7,6 @@ readonly id: string;

readonly handler: RouteHandler;
constructor(method: HttpMethod, path: Path, handler: RouteHandler);
readonly middleware: Middleware[];
constructor(method: HttpMethod, path: Path, handler: RouteHandler, middleware?: Middleware[]);
}
export { Route };
//# sourceMappingURL=Route.d.ts.map

@@ -6,3 +6,4 @@ class Route {

handler;
constructor(method, path, handler) {
middleware;
constructor(method, path, handler, middleware = []) {
this.id = `${method}:${path}`;

@@ -12,4 +13,5 @@ this.method = method;

this.handler = handler;
this.middleware = middleware;
}
}
export { Route };

@@ -1,2 +0,2 @@

import type { HttpMethod, Path, RouteHandlerOptions, RouteRegistryOptions } from '../types/rest.js';
import type { HttpMethod, Path, RestRouteHandlerOptions, RouteRegistryOptions } from '../types/rest.js';
import type { Route } from './Route.js';

@@ -35,5 +35,5 @@ declare class RouteHandlerRegistry {

*/
resolve(method: HttpMethod, path: Path): RouteHandlerOptions | null;
resolve(method: HttpMethod, path: Path): RestRouteHandlerOptions | null;
}
export { RouteHandlerRegistry };
//# sourceMappingURL=RouteHandlerRegistry.d.ts.map

@@ -135,2 +135,3 @@ import { ParameterValidationError } from './errors.js';

params: {},
middleware: staticRoute.middleware,
};

@@ -153,2 +154,3 @@ }

rawParams: params,
middleware: route.middleware,
};

@@ -155,0 +157,0 @@ }

@@ -1,3 +0,3 @@

import type { APIGatewayProxyEvent } from 'aws-lambda';
import type { CompiledRoute, Path, ValidationResult } from '../types/rest.js';
import type { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import type { CompiledRoute, HttpMethod, Middleware, Path, ValidationResult } from '../types/rest.js';
export declare function compilePath(path: Path): CompiledRoute;

@@ -14,2 +14,47 @@ export declare function validatePathPattern(path: Path): ValidationResult;

export declare const isAPIGatewayProxyEvent: (event: unknown) => event is APIGatewayProxyEvent;
export declare const isHttpMethod: (method: string) => method is HttpMethod;
/**
* Type guard to check if the provided result is an API Gateway Proxy result.
*
* We use this function to ensure that the result is an object and has the
* required properties without adding a dependency.
*
* @param result - The result to check
*/
export declare const isAPIGatewayProxyResult: (result: unknown) => result is APIGatewayProxyResult;
/**
* Composes multiple middleware functions into a single middleware function.
*
* Middleware functions are executed in order, with each middleware having the ability
* to call `next()` to proceed to the next middleware in the chain. The composed middleware
* follows the onion model where middleware executes in order before `next()` and in
* reverse order after `next()`.
*
* @param middleware - Array of middleware functions to compose
* @returns A single middleware function that executes all provided middleware in sequence
*
* @example
* ```typescript
* const middleware1: Middleware = async (params, options, next) => {
* console.log('middleware1 start');
* await next();
* console.log('middleware1 end');
* };
*
* const middleware2: Middleware = async (params, options, next) => {
* console.log('middleware2 start');
* await next();
* console.log('middleware2 end');
* };
*
* const composed: Middleware = composeMiddleware([middleware1, middleware2]);
* // Execution order:
* // middleware1 start
* // -> middleware2 start
* // -> handler
* // -> middleware2 end
* // -> middleware1 end
* ```
*/
export declare const composeMiddleware: (middleware: Middleware[]) => Middleware;
//# sourceMappingURL=utils.d.ts.map
import { isRecord, isString } from '@aws-lambda-powertools/commons/typeutils';
import { PARAM_PATTERN, SAFE_CHARS, UNSAFE_CHARS } from './constants.js';
import { HttpVerbs, PARAM_PATTERN, SAFE_CHARS, UNSAFE_CHARS, } from './constants.js';
export function compilePath(path) {

@@ -50,6 +50,94 @@ const paramNames = [];

isString(event.resource) &&
isRecord(event.headers) &&
(event.headers == null || isRecord(event.headers)) &&
(event.multiValueHeaders == null || isRecord(event.multiValueHeaders)) &&
isRecord(event.requestContext) &&
typeof event.isBase64Encoded === 'boolean' &&
(event.body === null || isString(event.body)));
(event.body === null || isString(event.body)) &&
(event.pathParameters === null || isRecord(event.pathParameters)) &&
(event.queryStringParameters === null ||
isRecord(event.queryStringParameters)) &&
(event.multiValueQueryStringParameters === null ||
isRecord(event.multiValueQueryStringParameters)) &&
(event.stageVariables === null || isRecord(event.stageVariables)));
};
export const isHttpMethod = (method) => {
return Object.keys(HttpVerbs).includes(method);
};
/**
* Type guard to check if the provided result is an API Gateway Proxy result.
*
* We use this function to ensure that the result is an object and has the
* required properties without adding a dependency.
*
* @param result - The result to check
*/
export const isAPIGatewayProxyResult = (result) => {
if (!isRecord(result))
return false;
return (typeof result.statusCode === 'number' &&
isString(result.body) &&
(result.headers === undefined || isRecord(result.headers)) &&
(result.multiValueHeaders === undefined ||
isRecord(result.multiValueHeaders)) &&
(result.isBase64Encoded === undefined ||
typeof result.isBase64Encoded === 'boolean'));
};
/**
* Composes multiple middleware functions into a single middleware function.
*
* Middleware functions are executed in order, with each middleware having the ability
* to call `next()` to proceed to the next middleware in the chain. The composed middleware
* follows the onion model where middleware executes in order before `next()` and in
* reverse order after `next()`.
*
* @param middleware - Array of middleware functions to compose
* @returns A single middleware function that executes all provided middleware in sequence
*
* @example
* ```typescript
* const middleware1: Middleware = async (params, options, next) => {
* console.log('middleware1 start');
* await next();
* console.log('middleware1 end');
* };
*
* const middleware2: Middleware = async (params, options, next) => {
* console.log('middleware2 start');
* await next();
* console.log('middleware2 end');
* };
*
* const composed: Middleware = composeMiddleware([middleware1, middleware2]);
* // Execution order:
* // middleware1 start
* // -> middleware2 start
* // -> handler
* // -> middleware2 end
* // -> middleware1 end
* ```
*/
export const composeMiddleware = (middleware) => {
return async (params, reqCtx, next) => {
let index = -1;
let result;
const dispatch = async (i) => {
if (i <= index)
throw new Error('next() called multiple times');
index = i;
if (i === middleware.length) {
const nextResult = await next();
if (nextResult !== undefined) {
result = nextResult;
}
return;
}
const middlewareFn = middleware[i];
const middlewareResult = await middlewareFn(params, reqCtx, () => dispatch(i + 1));
if (middlewareResult !== undefined) {
result = middlewareResult;
}
};
await dispatch(0);
return result;
};
};

@@ -110,3 +110,33 @@ import type { GenericLogger } from '@aws-lambda-powertools/commons/types';

});
export type { RouteHandlerRegistryOptions, RouteHandlerOptions, GraphQlRouterOptions, GraphQlRouteOptions, GraphQlBatchRouteOptions, ResolverHandler, BatchResolverHandler, BatchResolverHandlerFn, BatchResolverAggregateHandlerFn, };
type ExceptionSyncHandlerFn<T extends Error> = (error: T) => unknown;
type ExceptionHandlerFn<T extends Error> = (error: T) => Promise<unknown>;
type ExceptionHandler<T extends Error = Error> = ExceptionSyncHandlerFn<T> | ExceptionHandlerFn<T>;
type ErrorClass<T extends Error> = new (...args: any[]) => T;
/**
* Options for handling exceptions in the event handler.
*
* @template T - The type of error that extends the base Error class
*/
type ExceptionHandlerOptions<T extends Error = Error> = {
/**
* The error class to handle (must be Error or a subclass)
*/
error: ErrorClass<T> | ErrorClass<T>[];
/**
* The handler function to be called when the error is caught
*/
handler: ExceptionHandler<T>;
};
/**
* Options for the {@link ExceptionHandlerRegistry | `ExceptionHandlerRegistry`} class
*/
type ExceptionHandlerRegistryOptions = {
/**
* A logger instance to be used for logging debug, warning, and error messages.
*
* When no logger is provided, we'll only log warnings and errors using the global `console` object.
*/
logger: Pick<GenericLogger, 'debug' | 'warn' | 'error'>;
};
export type { RouteHandlerRegistryOptions, RouteHandlerOptions, GraphQlRouterOptions, GraphQlRouteOptions, GraphQlBatchRouteOptions, ResolverHandler, BatchResolverHandler, BatchResolverHandlerFn, BatchResolverAggregateHandlerFn, ExceptionHandler, ErrorClass, ExceptionHandlerOptions, ExceptionHandlerRegistryOptions, };
//# sourceMappingURL=appsync-graphql.d.ts.map

@@ -5,2 +5,3 @@ export type { AppSyncEventsEvent, AppSyncEventsPublishEvent, AppSyncEventsSubscribeEvent, OnPublishAggregateOutput, OnPublishAggregatePayload, OnPublishEventPayload, OnPublishOutput, RouteOptions, RouterOptions, } from './appsync-events.js';

export type { Anything, ResolveOptions, } from './common.js';
export type { ErrorHandler, ErrorResolveOptions, ErrorResponse, HandlerResponse, HttpMethod, HttpStatusCode, Middleware, Path, RequestContext, RestRouteHandlerOptions, RestRouteOptions, RestRouterOptions, RouteHandler, } from './rest.js';
//# sourceMappingURL=index.d.ts.map

@@ -11,9 +11,10 @@ import type { GenericLogger, JSONObject } from '@aws-lambda-powertools/commons/types';

};
type RequestOptions = {
type RequestContext = {
request: Request;
event: APIGatewayProxyEvent;
context: Context;
res: Response;
};
type ErrorResolveOptions = RequestOptions & ResolveOptions;
type ErrorHandler<T extends Error = Error> = (error: T, options?: RequestOptions) => Promise<ErrorResponse>;
type ErrorResolveOptions = RequestContext & ResolveOptions;
type ErrorHandler<T extends Error = Error> = (error: T, reqCtx: RequestContext) => Promise<ErrorResponse>;
interface ErrorConstructor<T extends Error = Error> {

@@ -24,5 +25,5 @@ new (...args: any[]): T;

/**
* Options for the {@link BaseRouter} class
* Options for the {@link Router} class
*/
type RouterOptions = {
type RestRouterOptions = {
/**

@@ -42,15 +43,20 @@ * A logger instance to be used for logging debug, warning, and error messages.

type DynamicRoute = Route & CompiledRoute;
type RouteHandler<TParams = Record<string, unknown>, TReturn = Response | JSONObject> = (args: TParams, options?: RequestOptions) => Promise<TReturn>;
type HandlerResponse = Response | JSONObject;
type RouteHandler<TParams = Record<string, unknown>, TReturn = HandlerResponse> = (args: TParams, reqCtx: RequestContext) => Promise<TReturn>;
type HttpMethod = keyof typeof HttpVerbs;
type HttpStatusCode = (typeof HttpErrorCodes)[keyof typeof HttpErrorCodes];
type Path = `/${string}`;
type RouteHandlerOptions = {
type RestRouteHandlerOptions = {
handler: RouteHandler;
params: Record<string, string>;
rawParams: Record<string, string>;
middleware: Middleware[];
};
type RouteOptions = {
type RestRouteOptions = {
method: HttpMethod | HttpMethod[];
path: Path;
middleware?: Middleware[];
};
type NextFunction = () => Promise<HandlerResponse | void>;
type Middleware = (params: Record<string, string>, reqCtx: RequestContext, next: NextFunction) => Promise<void | HandlerResponse>;
type RouteRegistryOptions = {

@@ -76,3 +82,3 @@ /**

};
export type { CompiledRoute, DynamicRoute, ErrorResponse, ErrorConstructor, ErrorHandlerRegistryOptions, ErrorHandler, ErrorResolveOptions, HttpStatusCode, HttpMethod, Path, RequestOptions, RouterOptions, RouteHandler, RouteOptions, RouteHandlerOptions, RouteRegistryOptions, ValidationResult, };
export type { CompiledRoute, DynamicRoute, ErrorResponse, ErrorConstructor, ErrorHandlerRegistryOptions, ErrorHandler, ErrorResolveOptions, HandlerResponse, HttpStatusCode, HttpMethod, Middleware, Path, RequestContext, RestRouterOptions, RouteHandler, RestRouteOptions, RestRouteHandlerOptions, RouteRegistryOptions, ValidationResult, };
//# sourceMappingURL=rest.d.ts.map
{
"name": "@aws-lambda-powertools/event-handler",
"version": "2.25.2",
"version": "2.26.0",
"description": "Lightweight routing to reduce boilerplate for API Gateway REST/HTTP API, ALB, Lambda Function URLs, and AppSync.",

@@ -32,3 +32,3 @@ "author": {

"dependencies": {
"@aws-lambda-powertools/commons": "2.25.2"
"@aws-lambda-powertools/commons": "2.26.0"
},

@@ -79,2 +79,12 @@ "files": [

}
},
"./experimental-rest": {
"require": {
"types": "./lib/cjs/rest/index.d.ts",
"default": "./lib/cjs/rest/index.js"
},
"import": {
"types": "./lib/esm/rest/index.d.ts",
"default": "./lib/esm/rest/index.js"
}
}

@@ -99,2 +109,6 @@ },

"./lib/esm/types/index.d.ts"
],
"experimental-rest": [
"./lib/cjs/rest/index.d.ts",
"./lib/esm/rest/index.d.ts"
]

@@ -101,0 +115,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet