UNPKG

@energica-city/shared-amplify-utils

Version:

Shared utilities for AWS Amplify projects

268 lines 9.84 kB
import type { Context, APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'; import type { Middleware, MiddlewareChain } from '../middlewareChain'; import type { AmplifyOutputs, AmplifyModelType, QueryFactoryResult } from '../../queries/types'; import type * as yup from 'yup'; /** * AWS API Gateway REST event type alias * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html} */ export type RestEvent = APIGatewayProxyEvent; /** * AWS API Gateway REST response type alias * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html} */ export type RestResponse = APIGatewayProxyResult; /** * Standard return type for REST handlers */ export type RestHandlerReturn = RestResponse; /** * Type alias for model instances using QueryFactory results * @template T - Model name as string * @template Types - Record of model types */ export type RestModelInstance<T extends string = string, Types extends Record<T, AmplifyModelType> = Record<T, AmplifyModelType>> = QueryFactoryResult<T, Types>; /** * Base input interface for REST operations containing AWS Lambda event and context */ export interface RestBaseInput { /** AWS API Gateway REST event */ event: RestEvent; /** AWS Lambda execution context */ context: Context; } /** * Enhanced REST input with initialized Amplify model instances * * This interface extends the base input with type-safe model access. * Models are initialized by the RestModelInitializer middleware. * * @template TTypes - Record mapping model names to their Amplify types * * @example * ```typescript * // Define your model types * type MyModels = { * User: UserType; * Post: PostType; * }; * * // Use in handler * const handler = async (input: RestInputWithModels<MyModels>) => { * const user = await input.models.User.create({ input: userData }); * return createSuccessResponse(user); * }; * ``` */ export interface RestInputWithModels<TTypes extends Record<string, AmplifyModelType> = Record<string, AmplifyModelType>> extends RestBaseInput { /** Initialized model instances for database operations */ models?: { [K in keyof TTypes]: QueryFactoryResult<K & string, TTypes>; }; } /** * Interface for storing validated data using symbol keys * * This interface allows storing arbitrary data using symbols as keys, * preventing naming conflicts with standard event properties. * * @see Symbol-based storage in RestRequestValidator */ export interface ValidatedDataStorage { /** Symbol-keyed storage for validated data */ [key: symbol]: unknown; } /** * REST input enhanced with validation data storage capabilities * * This interface extends RestInputWithModels to support storing validated * request data (body, query, path, headers) using symbol keys for safe access. * * @template TTypes - Record mapping model names to their Amplify types * * @example * ```typescript * const handler = async (input: RestInputWithValidation<MyModels>) => { * // Access validated, type-safe data * const userData = getValidatedBody<UserCreateInput>(input); * const queryParams = getValidatedQuery<PaginationParams>(input); * * const user = await input.models.User.create({ input: userData }); * return createSuccessResponse(user); * }; * ``` */ export interface RestInputWithValidation<TTypes extends Record<string, AmplifyModelType> = Record<string, AmplifyModelType>> extends RestInputWithModels<TTypes> { /** Event enhanced with validated data storage */ event: RestEvent & ValidatedDataStorage; } /** * Type alias for REST middleware chain with model typing * @template TTypes - Record mapping model names to their Amplify types * @template TReturn - Return type of the final handler (defaults to RestHandlerReturn) */ export type RestMiddlewareChain<TTypes extends Record<string, AmplifyModelType> = Record<string, AmplifyModelType>, TReturn = RestHandlerReturn> = MiddlewareChain<RestInputWithModels<TTypes>, TReturn>; /** * Type alias for individual REST middleware functions * @template TTypes - Record mapping model names to their Amplify types * @template TReturn - Return type of the middleware (defaults to RestHandlerReturn) */ export type RestMiddleware<TTypes extends Record<string, AmplifyModelType> = Record<string, AmplifyModelType>, TReturn = RestHandlerReturn> = Middleware<RestInputWithModels<TTypes>, TReturn>; /** * Configuration interface for REST model initializer middleware * * @template TSchema - Amplify schema type with models property * @template TTypes - Record mapping model names to their Amplify types * * @example * ```typescript * const config: RestModelInitializerConfig<MySchema, MyTypes> = { * schema: myAmplifySchema, * amplifyOutputs: myAmplifyOutputs, * entities: ['User', 'Post'], // Optional: only initialize specific models * timeout: 10000 // Optional: custom timeout * }; * ``` */ export interface RestModelInitializerConfig<TSchema extends { models: Record<string, unknown>; }, TTypes extends Record<string, AmplifyModelType>> { /** Amplify schema containing model definitions */ schema: TSchema; /** Amplify outputs configuration */ amplifyOutputs: AmplifyOutputs; /** Optional: specific entities to initialize (defaults to all) */ entities?: (keyof TTypes & string)[]; /** Optional: client key for Amplify client (defaults to 'default') */ clientKey?: string; /** Optional: initialization timeout in milliseconds (defaults to 5000) */ timeout?: number; } /** * Configuration interface for REST request logger middleware * * @example * ```typescript * // Development configuration * const devConfig: RestRequestLoggerConfig = { * logEvent: true, * logResponse: true, * logRequestBody: true, * logLevel: 'debug' * }; * * // Production configuration * const prodConfig: RestRequestLoggerConfig = { * logEvent: true, * logResponse: false, * excludeEventFields: ['authorization', 'password'], * logLevel: 'info' * }; * ``` */ export interface RestRequestLoggerConfig { /** Whether to log incoming requests (defaults to true) */ logEvent?: boolean; /** Whether to log outgoing responses (defaults to true) */ logResponse?: boolean; /** Whether to include timing information (defaults to true) */ logTiming?: boolean; /** Maximum depth for object serialization (defaults to 3) */ maxDepth?: number; /** Event fields to exclude from logs (e.g., sensitive data) */ excludeEventFields?: string[]; /** Response fields to exclude from logs (e.g., tokens) */ excludeResponseFields?: string[]; /** Default context to include in all logs */ defaultContext?: Record<string, unknown>; /** Log level for request/response messages (defaults to 'info') */ logLevel?: 'debug' | 'info' | 'warn' | 'error'; /** Whether to include request body in logs (defaults to false) */ logRequestBody?: boolean; /** Whether to force structured logging mode (defaults to true) */ forceStructuredLogging?: boolean; } /** * Configuration interface for REST error handler middleware * * @example * ```typescript * // Development configuration * const devConfig: RestErrorHandlerConfig = { * includeStackTrace: true, * defaultContext: { service: 'my-api', version: '1.0.0' } * }; * * // Production configuration * const prodConfig: RestErrorHandlerConfig = { * includeStackTrace: false, * forceStructuredLogging: true * }; * ``` */ export interface RestErrorHandlerConfig { /** Whether to include stack traces in error responses (defaults to development mode) */ includeStackTrace?: boolean; /** Default context to include in error logs */ defaultContext?: Record<string, unknown>; /** Whether to force structured logging mode (defaults to true) */ forceStructuredLogging?: boolean; } /** * Configuration interface for REST request validation middleware * * Supports validation of request body, query parameters, path parameters, and headers * using Yup schemas for type-safe validation. * * @example * ```typescript * const validationConfig: RestRequestValidationConfig = { * body: yup.object({ * name: yup.string().required(), * email: yup.string().email().required(), * age: yup.number().min(18).required() * }), * query: yup.object({ * page: yup.number().min(1).default(1), * limit: yup.number().min(1).max(100).default(10) * }), * headers: yup.object({ * authorization: yup.string().required() * }) * }; * ``` */ export interface RestRequestValidationConfig { /** Optional: Yup schema for request body validation */ body?: yup.Schema<unknown>; /** Optional: Yup schema for query parameters validation */ query?: yup.Schema<Record<string, unknown>>; /** Optional: Yup schema for path parameters validation */ path?: yup.Schema<Record<string, string>>; /** Optional: Yup schema for headers validation */ headers?: yup.Schema<Record<string, string>>; } /** * Interface describing validation error details * * Used for providing structured information about validation failures * in error responses and logs. */ export interface ValidationErrorDetail { /** Name of the field that failed validation */ field: string; /** Validation error message */ message: string; /** The value that failed validation */ value: unknown; /** Type of validation that failed */ type: string; } /** * Default type constraint for model types * * Used as a default generic parameter throughout the REST middleware system * when specific model types are not provided. */ export type DefaultModelTypes = Record<string, AmplifyModelType>; //# sourceMappingURL=types.d.ts.map