@energica-city/shared-amplify-utils
Version:
Shared utilities for AWS Amplify projects
268 lines • 9.84 kB
TypeScript
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