diff --git a/package-lock.json b/package-lock.json index 6c2c21d9c0..1ef8019ed9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,6 +47,7 @@ "ts-node": "^10.9.2", "typedoc": "^0.25.13", "typedoc-plugin-missing-exports": "^2.3.0", + "typedoc-plugin-zod": "^1.1.2", "typescript": "^5.4.5" }, "engines": { @@ -17869,6 +17870,15 @@ "typedoc": "0.24.x || 0.25.x" } }, + "node_modules/typedoc-plugin-zod": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/typedoc-plugin-zod/-/typedoc-plugin-zod-1.1.2.tgz", + "integrity": "sha512-jsmuYg1xsGjwKdhKN4tgRYORnbKpU7v5B1ZpsazMH5lUsI6ZLxBqAY5iiZ06oz/01gHOsAdhpABgWD97MOjKQA==", + "dev": true, + "peerDependencies": { + "typedoc": "0.23.x || 0.24.x || 0.25.x" + } + }, "node_modules/typescript": { "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", diff --git a/package.json b/package.json index 1b28d47c1f..5208489464 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "ts-node": "^10.9.2", "typedoc": "^0.25.13", "typedoc-plugin-missing-exports": "^2.3.0", + "typedoc-plugin-zod": "^1.1.2", "typescript": "^5.4.5" }, "lint-staged": { diff --git a/packages/parser/src/errors.ts b/packages/parser/src/errors.ts index 8e03bce5e9..2806b2d4cd 100644 --- a/packages/parser/src/errors.ts +++ b/packages/parser/src/errors.ts @@ -1,5 +1,6 @@ /** - * Error thrown when a parsing error occurs. The cause of the error is included in the message, if possible. + * Custom parsing error that wraps any erros thrown during schema or envelope parsing. + * The cause of the error is included in the message, if possible. */ class ParseError extends Error { /** diff --git a/packages/parser/src/parserDecorator.ts b/packages/parser/src/parserDecorator.ts index 0572d3a22e..2fdf93ed19 100644 --- a/packages/parser/src/parserDecorator.ts +++ b/packages/parser/src/parserDecorator.ts @@ -22,7 +22,7 @@ import type { ParserOptions, ParsedResult } from './types/index.js'; * * class Lambda implements LambdaInterface { * - * ⁣@parser({ envelope: SqsEnvelope, schema: OrderSchema }) + * @parser({ envelope: SqsEnvelope, schema: OrderSchema }) * public async handler(event: Order, _context: Context): Promise { * // sqs event is parsed and the payload is extracted and parsed * // apply business logic to your Order event @@ -53,7 +53,7 @@ import type { ParserOptions, ParsedResult } from './types/index.js'; * * class Lambda implements LambdaInterface { * - * ⁣git@parser({ envelope: SqsEnvelope, schema: OrderSchema, safeParse: true }) + * @parser({ envelope: SqsEnvelope, schema: OrderSchema, safeParse: true }) * public async handler(event: ParsedResult, _context: unknown): Promise { * if (event.success) { * // event.data is the parsed event object of type Order diff --git a/packages/parser/src/schemas/alb.ts b/packages/parser/src/schemas/alb.ts index 54d5de4fed..4afa283de2 100644 --- a/packages/parser/src/schemas/alb.ts +++ b/packages/parser/src/schemas/alb.ts @@ -1,5 +1,42 @@ import { z } from 'zod'; +/** + * Zod schema for Application load balancer event + * + * @example + * ```json + * { + * "requestContext": { + * "elb": { + * "targetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/my-target-group/6d0ecf831eec9f09" + * } + * }, + * "httpMethod": "GET", + * "path": "/", + * "queryStringParameters": { + * parameters + * }, + * "headers": { + * "accept": "text/html,application/xhtml+xml", + * "accept-language": "en-US,en;q=0.8", + * "content-type": "text/plain", + * "cookie": "cookies", + * "host": "lambda-846800462-us-east-2.elb.amazonaws.com", + * "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6)", + * "x-amzn-trace-id": "Root=1-5bdb40ca-556d8b0c50dc66f0511bf520", + * "x-forwarded-for": "72.21.198.66", + * "x-forwarded-port": "443", + * "x-forwarded-proto": "https" + * }, + * "isBase64Encoded": false, + * "body": "request_body" + * } + * ``` + * + * @see {@link types.ALBEvent | ALBEvent} + * @see {@link https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html} + * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/services-alb.html} + */ const AlbSchema = z.object({ httpMethod: z.string(), path: z.string(), @@ -14,6 +51,24 @@ const AlbSchema = z.object({ }), }); +/** + * Zod schema for Application load balancer event with multi-value headers + * + * @example + * ```json + * { + * "multiValueHeaders": { + * "Set-cookie": [ + * "cookie-name=cookie-value;Domain=myweb.com;Secure;HttpOnly", + * "cookie-name=cookie-value;Expires=May 8, 2019" + * ], + * "Content-Type": [ + * "application/json" + * ] + * } + * } + * ``` + */ const AlbMultiValueHeadersSchema = AlbSchema.extend({ multiValueHeaders: z.record(z.string(), z.array(z.string())), multiValueQueryStringParameters: z.record(z.string(), z.array(z.string())), diff --git a/packages/parser/src/schemas/apigw.ts b/packages/parser/src/schemas/apigw.ts index b31255ab49..53558736f2 100644 --- a/packages/parser/src/schemas/apigw.ts +++ b/packages/parser/src/schemas/apigw.ts @@ -147,6 +147,7 @@ const APIGatewayEventRequestContext = z * "apiId": "abcdef123" * } * ``` + * @see {@link types.APIGatewayProxyEvent | APIGatewayProxyEvent} * * @see {@link https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html} */ diff --git a/packages/parser/src/schemas/cloudformation-custom-resource.ts b/packages/parser/src/schemas/cloudformation-custom-resource.ts index 84369dbdae..cb18cad58c 100644 --- a/packages/parser/src/schemas/cloudformation-custom-resource.ts +++ b/packages/parser/src/schemas/cloudformation-custom-resource.ts @@ -10,6 +10,28 @@ const CloudFormationCustomResourceBaseSchema = z.object({ ResourceProperties: z.record(z.any()), }); +/** + * Zod schema for CloudFormation Custom Resource event with RequestType = 'Create' + * + * @example + * ```json + * { + * "RequestType": "Create", + * "ServiceToken": "arn:aws:lambda:us-east-1:xxx:function:xxxx-CrbuiltinfunctionidProvi-2vKAalSppmKe", + * "ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/7F%7Cb1f50fdfc25f3b", + * "StackId": "arn:aws:cloudformation:us-east-1:xxxx:stack/xxxx/271845b0-f2e8-11ed-90ac-0eeb25b8ae21", + * "RequestId": "xxxxx-d2a0-4dfb-ab1f-xxxxxx", + * "LogicalResourceId": "xxxxxxxxx", + * "ResourceType": "Custom::MyType", + * "ResourceProperties": { + * "ServiceToken": "arn:aws:lambda:us-east-1:xxxxx:function:xxxxx", + * "MyProps": "ss" + * } + * } + * ``` + * @see {@link types.CloudFormationCustomResourceCreateEvent | CloudFormationCustomResourceCreateEvent} + * @see {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-requesttypes-create.html} + */ const CloudFormationCustomResourceCreateSchema = CloudFormationCustomResourceBaseSchema.merge( z.object({ @@ -17,6 +39,28 @@ const CloudFormationCustomResourceCreateSchema = }) ); +/** + * Zod schema for CloudFormation Custom Resource event with RequestType = 'Delete' + * + * @example + * ```json + * { + * "RequestType": "Delete", + * "ServiceToken": "arn:aws:lambda:us-east-1:xxx:function:xxxx-CrbuiltinfunctionidProvi-2vKAalSppmKe", + * "ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/7F%7Cb1f50fdfc25f3b", + * "StackId": "arn:aws:cloudformation:us-east-1:xxxx:stack/xxxx/271845b0-f2e8-11ed-90ac-0eeb25b8ae21", + * "RequestId": "xxxxx-d2a0-4dfb-ab1f-xxxxxx", + * "LogicalResourceId": "xxxxxxxxx", + * "ResourceType": "Custom::MyType", + * "ResourceProperties": { + * "ServiceToken": "arn:aws:lambda:us-east-1:xxxxx:function:xxxxx", + * "MyProps": "ss" + * } + * } + * ``` + * @see {@link types.CloudFormationCustomResourceDeleteEvent | CloudFormationCustomResourceDeleteEvent} + * @see {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-requesttypes-delete.html} + */ const CloudFormationCustomResourceDeleteSchema = CloudFormationCustomResourceBaseSchema.merge( z.object({ @@ -24,6 +68,32 @@ const CloudFormationCustomResourceDeleteSchema = }) ); +/** + * Zod schema for CloudFormation Custom Resource event with RequestType = 'Update' + * + * @example + * ```json + * { + * "RequestType": "Update", + * "ServiceToken": "arn:aws:lambda:us-east-1:xxx:function:xxxx-CrbuiltinfunctionidProvi-2vKAalSppmKe", + * "ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/7F%7Cb1f50fdfc25f3b", + * "StackId": "arn:aws:cloudformation:us-east-1:xxxx:stack/xxxx/271845b0-f2e8-11ed-90ac-0eeb25b8ae21", + * "RequestId": "xxxxx-d2a0-4dfb-ab1f-xxxxxx", + * "LogicalResourceId": "xxxxxxxxx", + * "ResourceType": "Custom::MyType", + * "ResourceProperties": { + * "ServiceToken": "arn:aws:lambda:us-east-1:xxxxx:function:xxxxx", + * "MyProps": "new" + * }, + * "OldResourceProperties": { + * "ServiceToken": "arn:aws:lambda:us-east-1:xxxxx:function:xxxxx-xxxx-xxx", + * "MyProps": "old" + * } + * } + * ``` + * @see {@link types.CloudFormationCustomResourceUpdateEvent | CloudFormationCustomResourceUpdateEvent} + * @see {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-requesttypes-update.html} + */ const CloudFormationCustomResourceUpdateSchema = CloudFormationCustomResourceBaseSchema.merge( z.object({ diff --git a/packages/parser/src/schemas/cloudwatch.ts b/packages/parser/src/schemas/cloudwatch.ts index 2694507b04..941ea6330e 100644 --- a/packages/parser/src/schemas/cloudwatch.ts +++ b/packages/parser/src/schemas/cloudwatch.ts @@ -24,6 +24,52 @@ const decompressRecordToJSON = ( return CloudWatchLogsDecodeSchema.parse(JSON.parse(uncompressed)); }; +/** + * Zod schema for CloudWatch Logs. + * + * @example + * ```json + * { + * "awslogs": { + * "data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwWQRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpLwivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQDQiMdxRQEAAA==" + * } + * } + * ``` + * The `data` field compressed JSON string, once transformed the payload will look like: + * + * @example + * ```json + * { + * "owner": "123456789012", + * "logGroup": "CloudTrail", + * "logStream": "123456789012_CloudTrail_us-east-1", + * "subscriptionFilters": [ + * "Destination" + * ], + * "messageType": "DATA_MESSAGE", + * "logEvents": [ + * { + * "id": "31953106606966983378809025079804211143289615424298221568", + * "timestamp": 1432826855000, + * "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" + * }, + * { + * "id": "31953106606966983378809025079804211143289615424298221569", + * "timestamp": 1432826855000, + * "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" + * }, + * { + * "id": "31953106606966983378809025079804211143289615424298221570", + * "timestamp": 1432826855000, + * "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" + * } + * ] + * } + * ``` + * + * @see {@link types.CloudWatchLogsEvent | CloudWatchLogsEvent} + * @see {@link https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#LambdaFunctionExample} + */ const CloudWatchLogsSchema = z.object({ awslogs: z.object({ data: z.string().transform((data) => decompressRecordToJSON(data)), diff --git a/packages/parser/src/schemas/dynamodb.ts b/packages/parser/src/schemas/dynamodb.ts index 011ff85f8a..e33b003535 100644 --- a/packages/parser/src/schemas/dynamodb.ts +++ b/packages/parser/src/schemas/dynamodb.ts @@ -31,6 +31,81 @@ const DynamoDBStreamRecord = z.object({ userIdentity: UserIdentity.optional(), }); +/** + * Zod schema for Amazon DynamoDB Stream event. + * + * @example + * ```json + * { + * "Records": [ + * { + * "eventID": "1", + * "eventVersion": "1.0", + * "dynamodb": { + * "ApproximateCreationDateTime": 1693997155.0, + * "Keys": { + * "Id": { + * "N": "101" + * } + * }, + * "NewImage": { + * "Message": { + * "S": "New item!" + * }, + * "Id": { + * "N": "101" + * } + * }, + * "StreamViewType": "NEW_AND_OLD_IMAGES", + * "SequenceNumber": "111", + * "SizeBytes": 26 + * }, + * "awsRegion": "us-west-2", + * "eventName": "INSERT", + * "eventSourceARN": "eventsource_arn", + * "eventSource": "aws:dynamodb" + * }, + * { + * "eventID": "2", + * "eventVersion": "1.0", + * "dynamodb": { + * "OldImage": { + * "Message": { + * "S": "New item!" + * }, + * "Id": { + * "N": "101" + * } + * }, + * "SequenceNumber": "222", + * "Keys": { + * "Id": { + * "N": "101" + * } + * }, + * "SizeBytes": 59, + * "NewImage": { + * "Message": { + * "S": "This item has changed" + * }, + * "Id": { + * "N": "101" + * } + * }, + * "StreamViewType": "NEW_AND_OLD_IMAGES" + * }, + * "awsRegion": "us-west-2", + * "eventName": "MODIFY", + * "eventSourceARN": "source_arn", + * "eventSource": "aws:dynamodb" + * } + * ] + * } + * ``` + * + * @see {@link types.DynamoDBStreamEvent | DynamoDBStreamEvent} + * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html} + */ const DynamoDBStreamSchema = z.object({ Records: z.array(DynamoDBStreamRecord), }); diff --git a/packages/parser/src/schemas/eventbridge.ts b/packages/parser/src/schemas/eventbridge.ts index 9c509e5c03..82b3a48674 100644 --- a/packages/parser/src/schemas/eventbridge.ts +++ b/packages/parser/src/schemas/eventbridge.ts @@ -1,5 +1,32 @@ import { z } from 'zod'; +/** + * Zod schema for EventBridge event + * + * @example + * ```json + * { + * "version": "0", + * "id": "6a7e8feb-b491-4cf7-a9f1-bf3703467718", + * "detail-type": "EC2 Instance State-change Notification", + * "source": "aws.ec2", + * "account": "111122223333", + * "time": "2017-12-22T18:43:48Z", + * "region": "us-west-1", + * "resources": [ + * "arn:aws:ec2:us-west-1:123456789012:instance/i-1234567890abcdef0" + * ], + * "detail": { + * "instance_id": "i-1234567890abcdef0", + * "state": "terminated" + * }, + * "replay-name": "replay_archive" + * } + * ``` + * + * @see {@link types.EventBridgeEvent | EventBridgeEvent} + * @see {@link https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-and-events.html} + */ const EventBridgeSchema = z.object({ version: z.string(), id: z.string(), diff --git a/packages/parser/src/schemas/kafka.ts b/packages/parser/src/schemas/kafka.ts index 08bd5d03ab..067346f123 100644 --- a/packages/parser/src/schemas/kafka.ts +++ b/packages/parser/src/schemas/kafka.ts @@ -32,10 +32,98 @@ const KafkaBaseEventSchema = z.object({ records: z.record(z.string(), z.array(KafkaRecordSchema)), }); +/** Zod schema for Kafka event from Self Managed Kafka + * + * @example + * ```json + * { + * "eventSource":"aws:SelfManagedKafka", + * "bootstrapServers":"b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092", + * "records":{ + * "mytopic-0":[ + * { + * "topic":"mytopic", + * "partition":0, + * "offset":15, + * "timestamp":1545084650987, + * "timestampType":"CREATE_TIME", + * "key":"cmVjb3JkS2V5", + * "value":"eyJrZXkiOiJ2YWx1ZSJ9", + * "headers":[ + * { + * "headerKey":[ + * 104, + * 101, + * 97, + * 100, + * 101, + * 114, + * 86, + * 97, + * 108, + * 117, + * 101 + * ] + * } + * ] + * } + * ] + * } + * } + * ``` + * + * @see {@link types.KafkaSelfManagedEvent | KafkaSelfManagedEvent} + * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/with-kafka.html} + */ const KafkaSelfManagedEventSchema = KafkaBaseEventSchema.extend({ eventSource: z.literal('aws:SelfManagedKafka'), }); +/** + * Zod schema for Kafka event from MSK + * + * @example + * ```json + * { + * "eventSource":"aws:kafka", + * "eventSourceArn":"arn:aws:kafka:us-east-1:0123456789019:cluster/SalesCluster/abcd1234-abcd-cafe-abab-9876543210ab-4", + * "bootstrapServers":"b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092", + * "records":{ + * "mytopic-0":[ + * { + * "topic":"mytopic", + * "partition":0, + * "offset":15, + * "timestamp":1545084650987, + * "timestampType":"CREATE_TIME", + * "key":"cmVjb3JkS2V5", + * "value":"eyJrZXkiOiJ2YWx1ZSJ9", + * "headers":[ + * { + * "headerKey":[ + * 104, + * 101, + * 97, + * 100, + * 101, + * 114, + * 86, + * 97, + * 108, + * 117, + * 101 + * ] + * } + * ] + * } + * ] + * } + * } + * ``` + * + * @see {@link types.KafkaMskEvent | KafkaMskEvent} + * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/with-msk.html} + */ const KafkaMskEventSchema = KafkaBaseEventSchema.extend({ eventSource: z.literal('aws:kafka'), eventSourceArn: z.string(), diff --git a/packages/parser/src/schemas/kinesis-firehose.ts b/packages/parser/src/schemas/kinesis-firehose.ts index e541cc3f65..57d7d5a2ae 100644 --- a/packages/parser/src/schemas/kinesis-firehose.ts +++ b/packages/parser/src/schemas/kinesis-firehose.ts @@ -40,10 +40,73 @@ const KinesisFirehoseSqsRecord = KinesisFireHoseRecordBase.extend({ }), }); +/** + * Zod schema for Kinesis Firehose events + * + * @example + * ```json + * { + * "invocationId": "2b4d1ad9-2f48-94bd-a088-767c317e994a", + * "sourceKinesisStreamArn": "arn:aws:kinesis:us-east-1:123456789012:stream/kinesis-source", + * "deliveryStreamArn": "arn:aws:firehose:us-east-2:123456789012:deliverystream/delivery-stream-name", + * "region": "us-east-2", + * "records": [ + * { + * "data": "SGVsbG8gV29ybGQ=", + * "recordId": "record1", + * "approximateArrivalTimestamp": 1664028820148, + * "kinesisRecordMetadata": { + * "shardId": "shardId-000000000000", + * "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c317a", + * "approximateArrivalTimestamp": 1664028820148, + * "sequenceNumber": "49546986683135544286507457936321625675700192471156785154", + * "subsequenceNumber": 0 + * } + * }, + * { + * "data": "eyJIZWxsbyI6ICJXb3JsZCJ9", + * "recordId": "record2", + * "approximateArrivalTimestamp": 1664028793294, + * "kinesisRecordMetadata": { + * "shardId": "shardId-000000000001", + * "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c318a", + * "approximateArrivalTimestamp": 1664028793294, + * "sequenceNumber": "49546986683135544286507457936321625675700192471156785155", + * "subsequenceNumber": 0 + * } + * } + * ] + * } + * ``` + * + * @see {@link types.KinesisFireHoseEvent | KinesisFireHoseEvent} + * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/services-kinesisfirehose.html} + */ const KinesisFirehoseSchema = KinesisFireHoseBaseSchema.extend({ records: z.array(KinesisFirehoseRecord), }); +/** + * Zod schema for Kinesis Firehose events with SQS records + * + * @example + * ```json + * { + * "invocationId": "556b67a3-48fc-4385-af49-e133aade9cb9", + * "deliveryStreamArn": "arn:aws:firehose:us-east-1:123456789012:deliverystream/PUT-S3-tdyyE", + * "region": "us-east-1", + * "records": [ + * { + * "recordId": "49640912821178817833517986466168945147170627572855734274000000", + * "approximateArrivalTimestamp": 1684864917398, + * "data": "eyJtZXNzYWdlSWQiOiI1YWI4MDdkNC01NjQ0LTRjNTUtOTdhMy00NzM5NjYzNWFjNzQiLCJyZWNlaXB0SGFuZGxlIjoiQVFFQndKbkt5ckhpZ1VNWmo2cllpZ0NneGxhUzNTTHkwYS4uLiIsImJvZHkiOiJUZXN0IG1lc3NhZ2UuIiwiYXR0cmlidXRlcyI6eyJBcHByb3hpbWF0ZVJlY2VpdmVDb3VudCI6IjEiLCJTZW50VGltZXN0YW1wIjoiMTY4NDg2NDg1MjQ5MSIsIlNlbmRlcklkIjoiQUlEQUlFTlFaSk9MTzIzWVZKNFZPIiwiQXBwcm94aW1hdGVGaXJzdFJlY2VpdmVUaW1lc3RhbXAiOiIxNjg0ODY0ODcyNDkxIn0sIm1lc3NhZ2VBdHRyaWJ1dGVzIjp7fSwibWQ1T2ZNZXNzYWdlQXR0cmlidXRlcyI6bnVsbCwibWQ1T2ZCb2R5IjoiYzhiNmJjNjBjOGI4YjNhOTA0ZTQ1YzFmYWJkZjUyM2QiLCJldmVudFNvdXJjZSI6ImF3czpzcXMiLCJldmVudFNvdXJjZUFSTiI6ImFybjphd3M6c3FzOnVzLWVhc3QtMToyMDA5ODQxMTIzODY6U05TIiwiYXdzUmVnaW9uIjoidXMtZWFzdC0xIn0K" + * } + * ] + * } + * ``` + * + * @see {@link types.KinesisFireHoseSqsEvent | KinesisFireHoseSqsEvent} + */ const KinesisFirehoseSqsSchema = KinesisFireHoseBaseSchema.extend({ records: z.array(KinesisFirehoseSqsRecord), }); diff --git a/packages/parser/src/schemas/kinesis.ts b/packages/parser/src/schemas/kinesis.ts index fbd734297e..041b378f6a 100644 --- a/packages/parser/src/schemas/kinesis.ts +++ b/packages/parser/src/schemas/kinesis.ts @@ -36,6 +36,52 @@ const KinesisDataStreamRecord = z.object({ kinesis: KinesisDataStreamRecordPayload, }); +/** + * Zod schema for Kinesis Data Stream event + * + * @example + * ```json + * { + * "Records": [ + * { + * "kinesis": { + * "kinesisSchemaVersion": "1.0", + * "partitionKey": "1", + * "sequenceNumber": "49590338271490256608559692538361571095921575989136588898", + * "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0Lg==", + * "approximateArrivalTimestamp": 1545084650.987 + * }, + * "eventSource": "aws:kinesis", + * "eventVersion": "1.0", + * "eventID": "shardId-000000000006:49590338271490256608559692538361571095921575989136588898", + * "eventName": "aws:kinesis:record", + * "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-role", + * "awsRegion": "us-east-2", + * "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream" + * }, + * { + * "kinesis": { + * "kinesisSchemaVersion": "1.0", + * "partitionKey": "1", + * "sequenceNumber": "49590338271490256608559692540925702759324208523137515618", + * "data": "VGhpcyBpcyBvbmx5IGEgdGVzdC4=", + * "approximateArrivalTimestamp": 1545084711.166 + * }, + * "eventSource": "aws:kinesis", + * "eventVersion": "1.0", + * "eventID": "shardId-000000000006:49590338271490256608559692540925702759324208523137515618", + * "eventName": "aws:kinesis:record", + * "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-role", + * "awsRegion": "us-east-2", + * "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream" + * } + * ] + * } + *``` + * @see {@link types.KinesisDataStreamEvent | KinesisDataStreamEvent} + * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/with-kinesis.html#services-kinesis-event-example} + * + */ const KinesisDataStreamSchema = z.object({ Records: z.array(KinesisDataStreamRecord), }); diff --git a/packages/parser/src/schemas/lambda.ts b/packages/parser/src/schemas/lambda.ts index e8e72be255..0530f56d67 100644 --- a/packages/parser/src/schemas/lambda.ts +++ b/packages/parser/src/schemas/lambda.ts @@ -1,13 +1,63 @@ import { APIGatewayProxyEventV2Schema } from './apigwv2.js'; /** - * Lambda Function URL follows the API Gateway HTTP APIs Payload Format Version 2.0. + * Zod schema for Lambda Function URL follows the API Gateway HTTP APIs Payload Format Version 2.0. * * Keys related to API Gateway features not available in Function URL use a sentinel value (e.g.`routeKey`, `stage`). - * Documentation: - * - https://docs.aws.amazon.com/lambda/latest/dg/urls-configuration.html - * - https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html#urls-payloads * + * @example + * ```json + * { + * "version": "2.0", + * "routeKey": "$default", + * "rawPath": "/", + * "rawQueryString": "", + * "headers": { + * "sec-fetch-mode": "navigate", + * "x-amzn-tls-version": "TLSv1.2", + * "sec-fetch-site": "cross-site", + * "accept-language": "pt-BR,pt;q=0.9", + * "x-forwarded-proto": "https", + * "x-forwarded-port": "443", + * "x-forwarded-for": "123.123.123.123", + * "sec-fetch-user": "?1", + * "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng;q=0.8,application/signed-exchange;v=b3;q=0.9", + * "x-amzn-tls-cipher-suite": "ECDHE-RSA-AES128-GCM-SHA256", + * "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"", + * "sec-ch-ua-mobile": "?0", + * "x-amzn-trace-id": "Root=1-62ecd163-5f302e550dcde3b12402207d", + * "sec-ch-ua-platform": "\"Linux\"", + * "host": ".lambda-url.us-east-1.on.aws", + * "upgrade-insecure-requests": "1", + * "cache-control": "max-age=0", + * "accept-encoding": "gzip, deflate, br", + * "sec-fetch-dest": "document", + * "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36" + * }, + * "requestContext": { + * "accountId": "anonymous", + * "apiId": "", + * "domainName": ".lambda-url.us-east-1.on.aws", + * "domainPrefix": "", + * "http": { + * "method": "GET", + * "path": "/", + * "protocol": "HTTP/1.1", + * "sourceIp": "123.123.123.123", + * "userAgent": "agent" + * }, + * "requestId": "id", + * "routeKey": "$default", + * "stage": "$default", + * "time": "05/Aug/2022:08:14:39 +0000", + * "timeEpoch": 1659687279885 + * }, + * "isBase64Encoded": false + * } + * ``` + * + * @see {@link types.LambdaFunctionUrlEvent | LambdaFunctionUrlEvent} + * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html#urls-payloads} */ const LambdaFunctionUrlSchema = APIGatewayProxyEventV2Schema.extend({}); diff --git a/packages/parser/src/schemas/s3.ts b/packages/parser/src/schemas/s3.ts index ccc8fca155..38729824b2 100644 --- a/packages/parser/src/schemas/s3.ts +++ b/packages/parser/src/schemas/s3.ts @@ -88,10 +88,95 @@ const S3EventNotificationEventBridgeDetailSchema = z.object({ 'destination-access-tier': z.string().optional(), }); +/** + * Zod schema for S3 -> EventBridge -> Lambda event notification. + * + * @example + * ```json + * { + * "version": "0", + * "id": "f5f1e65c-dc3a-93ca-6c1e-b1647eac7963", + * "detail-type": "Object Created", + * "source": "aws.s3", + * "account": "123456789012", + * "time": "2023-03-08T17:50:14Z", + * "region": "eu-west-1", + * "resources": [ + * "arn:aws:s3:::example-bucket" + * ], + * "detail": { + * "version": "0", + * "bucket": { + * "name": "example-bucket" + * }, + * "object": { + * "key": "IMG_m7fzo3.jpg", + * "size": 184662, + * "etag": "4e68adba0abe2dc8653dc3354e14c01d", + * "sequencer": "006408CAD69598B05E" + * }, + * "request-id": "57H08PA84AB1JZW0", + * "requester": "123456789012", + * "source-ip-address": "34.252.34.74", + * "reason": "PutObject" + * } + * } + * ``` + * + * @see {@link types.S3EventNotificationEventBridge | S3EventNotificationEventBridge } + * @see {@link https://docs.aws.amazon.com/AmazonS3/latest/userguide/ev-events.html#ev-events-list} + */ const S3EventNotificationEventBridgeSchema = EventBridgeSchema.extend({ detail: S3EventNotificationEventBridgeDetailSchema, }); +/** + * Zod schema for S3 event + * + * @example + * ```json + * { + * "Records": [ + * { + * "eventVersion": "2.1", + * "eventSource": "aws:s3", + * "awsRegion": "us-east-2", + * "eventTime": "2019-09-03T19:37:27.192Z", + * "eventName": "ObjectCreated:Put", + * "userIdentity": { + * "principalId": "AWS:AIDAINPONIXQXHT3IKHL2" + * }, + * "requestParameters": { + * "sourceIPAddress": "205.255.255.255" + * }, + * "responseElements": { + * "x-amz-request-id": "D82B88E5F771F645", + * "x-amz-id-2": "vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo=" + * }, + * "s3": { + * "s3SchemaVersion": "1.0", + * "configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1", + * "bucket": { + * "name": "lambda-artifacts-deafc19498e3f2df", + * "ownerIdentity": { + * "principalId": "A3I5XTEXAMAI3E" + * }, + * "arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df" + * }, + * "object": { + * "key": "b21b84d653bb07b05b1e6b33684dc11b", + * "size": 1305107, + * "eTag": "b21b84d653bb07b05b1e6b33684dc11b", + * "sequencer": "0C0F6F405D6ED209E1" + * } + * } + * } + * ] + * } + * ``` + * @see {@link types.S3Event | S3Event } + * @see {@link https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-content-structure.html} + */ const S3Schema = z.object({ Records: z.array(S3RecordSchema), }); @@ -100,6 +185,36 @@ const S3SqsEventNotificationRecordSchema = SqsRecordSchema.extend({ body: z.string(), }); +/** + * Zod schema for S3 -> SQS -> Lambda event notification. + * + * @example + * ```json + * { + * "Records": [ + * { + * "messageId": "ca3e7a89-c358-40e5-8aa0-5da01403c267", + * "receiptHandle": "AQEBE7XoI7IQRLF7SrpiW9W4BanmOWe8UtVDbv6/CEZYKf/OktSNIb4j689tQfR4k44V/LY20lZ5VpxYt2GTYCsSLKTcBalTJaRX9CKu/hVqy/23sSNiKxnP56D+VLSn+hU275+AP1h4pUL0d9gLdRB2haX8xiM+LcGfis5Jl8BBXtoxKRF60O87O9/NvCmmXLeqkJuexfyEZNyed0fFCRXFXSjbmThG0OIQgcrGI8glBRGPA8htns58VtXFsSaPYNoqP3p5n6+ewKKVLD0lfm+0DlnLKRa+mjvFBaSer9KK1ff+Aq6zJ6HynPwADj+aF70Hwimc2zImYe51SLEF/E2csYlMNZYI/2qXW0m9R7wJ/XDTV4g2+h+BMTxsKnJQ6NQd", + * "body": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-04-12T20:43:38.021Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"A1YQ72UWCM96UF\"},\"requestParameters\":{\"sourceIPAddress\":\"93.108.161.96\"},\"responseElements\":{\"x-amz-request-id\":\"YMSSR8BZJ2Y99K6P\",\"x-amz-id-2\":\"6ASrUfj5xpn859fIq+6FXflOex/SKl/rjfiMd7wRzMg/zkHKR22PDpnh7KD3uq//cuOTbdX4DInN5eIs+cR0dY1z2Mc5NDP/\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"SNS\",\"bucket\":{\"name\":\"xxx\",\"ownerIdentity\":{\"principalId\":\"A1YQ72UWCM96UF\"},\"arn\":\"arn:aws:s3:::xxx\"},\"object\":{\"key\":\"test.pdf\",\"size\":104681,\"eTag\":\"2e3ad1e983318bbd8e73b080e2997980\",\"versionId\":\"yd3d4HaWOT2zguDLvIQLU6ptDTwKBnQV\",\"sequencer\":\"00643717F9F8B85354\"}}}]}", + * "attributes": { + * "ApproximateReceiveCount": "1", + * "SentTimestamp": "1681332219270", + * "SenderId": "AIDAJHIPRHEMV73VRJEBU", + * "ApproximateFirstReceiveTimestamp": "1681332239270" + * }, + * "messageAttributes": { + * }, + * "md5OfBody": "16f4460f4477d8d693a5abe94fdbbd73", + * "eventSource": "aws:sqs", + * "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:SQS", + * "awsRegion": "us-east-1" + * } + * ] + * } + * ``` + * + * @see {@link types.S3SqsEventNotification | S3SqsEventNotification } + */ const S3SqsEventNotificationSchema = z.object({ Records: z.array(S3SqsEventNotificationRecordSchema), }); @@ -147,6 +262,46 @@ const S3ObjectUserIdentity = z.object({ sessionContext: S3ObjectSessionContext.optional(), }); +/** + * Zod schema for S3 IAM Access Point Lambda event notification. + * + * @example + * ```json + * { + * "xAmzRequestId": "1a5ed718-5f53-471d-b6fe-5cf62d88d02a", + * "getObjectContext": { + * "inputS3Url": "https://myap-123412341234.s3-accesspoint.us-east-1.amazonaws.com/s3.txt?X-Amz-Security-Token=...", + * "outputRoute": "io-iad-cell001", + * "outputToken": "..." + * }, + * "configuration": { + * "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:123412341234:accesspoint/myolap", + * "supportingAccessPointArn": "arn:aws:s3:us-east-1:123412341234:accesspoint/myap", + * "payload": "test" + * }, + * "userRequest": { + * "url": "/s3.txt", + * "headers": { + * "Host": "myolap-123412341234.s3-object-lambda.us-east-1.amazonaws.com", + * "Accept-Encoding": "identity", + * "X-Amz-Content-SHA256": "e3b0c44297fc1c149afbf4c8995fb92427ae41e4649b934ca495991b7852b855" + * } + * }, + * "userIdentity": { + * "type": "IAMUser", + * "principalId": "...", + * "arn": "arn:aws:iam::123412341234:user/myuser", + * "accountId": "123412341234", + * "accessKeyId": "...", + * "userName": "Alice" + * }, + * "protocolVersion": "1.00" + * } + * ``` + * + * @see {@link https://docs.aws.amazon.com/AmazonS3/latest/userguide/olap-event-context.html} + * @see {@link types.S3ObjectLambdaEvent | S3ObjectLambdaEvent } + */ const S3ObjectLambdaEventSchema = z.object({ xAmzRequestId: z.string(), getObjectContext: S3ObjectContext, diff --git a/packages/parser/src/schemas/ses.ts b/packages/parser/src/schemas/ses.ts index 254d3de255..c065f2e639 100644 --- a/packages/parser/src/schemas/ses.ts +++ b/packages/parser/src/schemas/ses.ts @@ -58,8 +58,119 @@ const SesRecordSchema = z.object({ ses: SesMessage, }); +/** + * Zod schema for SES events from AWS. + * + * @example + * ```json + * { + * "Records": [ + * { + * "eventVersion": "1.0", + * "ses": { + * "mail": { + * "commonHeaders": { + * "from": [ + * "Jane Doe " + * ], + * "to": [ + * "johndoe@example.com" + * ], + * "returnPath": "janedoe@example.com", + * "messageId": "<0123456789example.com>", + * "date": "Wed, 7 Oct 2015 12:34:56 -0700", + * "subject": "Test Subject" + * }, + * "source": "janedoe@example.com", + * "timestamp": "1970-01-01T00:00:00.000Z", + * "destination": [ + * "johndoe@example.com" + * ], + * "headers": [ + * { + * "name": "Return-Path", + * "value": "" + * }, + * { + * "name": "Received", + * "value": "from mailer.example.com (mailer.example.com [203.0.113.1]) by ..." + * }, + * { + * "name": "DKIM-Signature", + * "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=example; ..." + * }, + * { + * "name": "MIME-Version", + * "value": "1.0" + * }, + * { + * "name": "From", + * "value": "Jane Doe " + * }, + * { + * "name": "Date", + * "value": "Wed, 7 Oct 2015 12:34:56 -0700" + * }, + * { + * "name": "Message-ID", + * "value": "<0123456789example.com>" + * }, + * { + * "name": "Subject", + * "value": "Test Subject" + * }, + * { + * "name": "To", + * "value": "johndoe@example.com" + * }, + * { + * "name": "Content-Type", + * "value": "text/plain; charset=UTF-8" + * } + * ], + * "headersTruncated": false, + * "messageId": "o3vrnil0e2ic28tr" + * }, + * "receipt": { + * "recipients": [ + * "johndoe@example.com" + * ], + * "timestamp": "1970-01-01T00:00:00.000Z", + * "spamVerdict": { + * "status": "PASS" + * }, + * "dkimVerdict": { + * "status": "PASS" + * }, + * "dmarcPolicy": "reject", + * "processingTimeMillis": 574, + * "action": { + * "type": "Lambda", + * "invocationType": "Event", + * "functionArn": "arn:aws:lambda:us-west-2:012345678912:function:Example" + * }, + * "dmarcVerdict": { + * "status": "PASS" + * }, + * "spfVerdict": { + * "status": "PASS" + * }, + * "virusVerdict": { + * "status": "PASS" + * } + * } + * }, + * "eventSource": "aws:ses" + * } + * ] + * } + * ``` + * + * @see {@link types.SesEvent | SesEvent} + * @see {@link https://docs.aws.amazon.com/ses/latest/dg/receiving-email-notifications-examples.html} + */ const SesSchema = z.object({ Records: z.array(SesRecordSchema), }); -export { SesSchema, SesRecordSchema }; +export { SesSchema }; diff --git a/packages/parser/src/schemas/sns.ts b/packages/parser/src/schemas/sns.ts index 862306a66b..1e90a4b265 100644 --- a/packages/parser/src/schemas/sns.ts +++ b/packages/parser/src/schemas/sns.ts @@ -21,6 +21,35 @@ const SnsNotificationSchema = z.object({ Timestamp: z.string().datetime(), }); +/** + * Zod schema for SQS -> SNS event + * + * @example + * ```json + * { + * "Records": [ + * { + * "messageId": "79406a00-bf15-46ca-978c-22c3613fcb30", + * "receiptHandle": "AQEB3fkqlBqq239bMCAHIr5mZkxJYKtxsTTy1lMImmpY7zqpQdfcAE8zFiuRh7X5ciROy24taT2rRXfuJFN/yEUVcQ6d5CIOCEK4htmRJJOHIyGdZPAm2NUUG5nNn2aEzgfzVvrkPBsrCbr7XTzK5s6eUZNH/Nn9AJtHKHpzweRK34Bon9OU/mvyIT7EJbwHPsdhL14NrCp8pLWBiIhkaJkG2G6gPO89dwHtGVUARJL+zP70AuIu/f7QgmPtY2eeE4AVbcUT1qaIlSGHUXxoHq/VMHLd/c4zWl0EXQOo/90DbyCUMejTIKL7N15YfkHoQDHprvMiAr9S75cdMiNOduiHzZLg/qVcv4kxsksKLFMKjwlzmYuQYy2KslVGwoHMd4PD", + * "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"d88d4479-6ec0-54fe-b63f-1cf9df4bb16e\",\n \"TopicArn\" : \"arn:aws:sns:eu-west-1:231436140809:powertools265\",\n \"Message\" : \"{\\\"message\\\": \\\"hello world\\\", \\\"username\\\": \\\"lessa\\\"}\",\n \"Timestamp\" : \"2021-01-19T10:07:07.287Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"tEo2i6Lw6/Dr7Jdlulh0sXgnkF0idd3hqs8QZCorQpzkIWVOuu583NT0Gv0epuZD1Bo+tex6NgP5p6415yNVujGHJKnkrA9ztzXaVgFiol8rf8AFGQbmb7RsM9BqATQUJeg9nCTe0jksmWXmjxEFr8XKyyRuQBwSlRTngAvOw8jUnCe1vyYD5xPec1xpfOEGLi5BqSog+6tBtsry3oAtcENX8SV1tVuMpp6D+UrrU8xNT/5D70uRDppkPE3vq+t7rR0fVSdQRdUV9KmQD2bflA1Dyb2y37EzwJOMHDDQ82aOhj/JmPxvEAlV8RkZl6J0HIveraRy9wbNLbI7jpiOCw==\",\n \"SigningCertURL\" : \"https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem\",\n \"UnsubscribeURL\" : \"https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:231436140809:powertools265:15189ad7-870e-40e5-a7dd-a48898cd9f86\"\n}", + * "attributes": { + * "ApproximateReceiveCount": "1", + * "SentTimestamp": "1611050827340", + * "SenderId": "AIDAISMY7JYY5F7RTT6AO", + * "ApproximateFirstReceiveTimestamp": "1611050827344" + * }, + * "messageAttributes": {}, + * "md5OfBody": "8910bdaaf9a30a607f7891037d4af0b0", + * "eventSource": "aws:sqs", + * "eventSourceARN": "arn:aws:sqs:eu-west-1:231436140809:powertools265", + * "awsRegion": "eu-west-1" + * } + * ] + * } + * ``` + * + * @see {@link types.SnsSqsNotification | SnsSqsNotification} + */ const SnsSqsNotificationSchema = SnsNotificationSchema.extend({ UnsubscribeURL: z.string().optional(), SigningCertURL: z.string().url().optional(), @@ -36,14 +65,49 @@ const SnsRecordSchema = z.object({ Sns: SnsNotificationSchema, }); +/** + * Zod schema for SNS event + * + * @example + * ```json + * { + * "Records": [ + * { + * "EventVersion": "1.0", + * "EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:sns-la ...", + * "EventSource": "aws:sns", + * "Sns": { + * "SignatureVersion": "1", + * "Timestamp": "2019-01-02T12:45:07.000Z", + * "Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", + * "SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotification", + * "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", + * "Message": "Hello from SNS!", + * "MessageAttributes": { + * "Test": { + * "Type": "String", + * "Value": "TestString" + * }, + * "TestBinary": { + * "Type": "Binary", + * "Value": "TestBinary" + * } + * }, + * "Type": "Notification", + * "UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe", + * "TopicArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", + * "Subject": "TestInvoke" + * } + * } + * ] + * } + * ``` + * + * @see {@link types.SnsEvent | SnsEvent} + * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/with-sns.html#sns-sample-event} + */ const SnsSchema = z.object({ Records: z.array(SnsRecordSchema), }); -export { - SnsSchema, - SnsRecordSchema, - SnsNotificationSchema, - SnsMsgAttribute, - SnsSqsNotificationSchema, -}; +export { SnsSchema, SnsSqsNotificationSchema }; diff --git a/packages/parser/src/schemas/sqs.ts b/packages/parser/src/schemas/sqs.ts index 5484246e0d..c861a94dd3 100644 --- a/packages/parser/src/schemas/sqs.ts +++ b/packages/parser/src/schemas/sqs.ts @@ -36,13 +36,61 @@ const SqsRecordSchema = z.object({ awsRegion: z.string(), }); +/** + * Zod schema for SQS event + * + * @example + * ```json + * { + * "Records": [ + * { + * "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", + * "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + * "body": "Test message.", + * "attributes": { + * "ApproximateReceiveCount": "1", + * "SentTimestamp": "1545082649183", + * "SenderId": "AIDAIENQZJOLO23YVJ4VO", + * "ApproximateFirstReceiveTimestamp": "1545082649185" + * }, + * "messageAttributes": { + * "testAttr": { + * "stringValue": "100", + * "binaryValue": "base64Str", + * "dataType": "Number" + * } + * }, + * "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", + * "eventSource": "aws:sqs", + * "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", + * "awsRegion": "us-east-2" + * }, + * { + * "messageId": "2e1424d4-f796-459a-8184-9c92662be6da", + * "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", + * "body": "{\"message\": \"foo1\"}", + * "attributes": { + * "ApproximateReceiveCount": "1", + * "SentTimestamp": "1545082650636", + * "SenderId": "AIDAIENQZJOLO23YVJ4VO", + * "ApproximateFirstReceiveTimestamp": "1545082650649", + * "DeadLetterQueueSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue-dead" + * }, + * "messageAttributes": {}, + * "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", + * "eventSource": "aws:sqs", + * "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", + * "awsRegion": "us-east-2" + * } + * ] + * } + * ``` + * + * @see {@link types.SqsEvent | SqsEvent} + * @see {@link https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#example-standard-queue-message-event} + */ const SqsSchema = z.object({ Records: z.array(SqsRecordSchema), }); -export { - SqsSchema, - SqsRecordSchema, - SqsAttributesSchema, - SqsMsgAttributeSchema, -}; +export { SqsSchema, SqsRecordSchema }; diff --git a/packages/parser/src/schemas/vpc-lattice.ts b/packages/parser/src/schemas/vpc-lattice.ts index f8f266fa20..569caf2c93 100644 --- a/packages/parser/src/schemas/vpc-lattice.ts +++ b/packages/parser/src/schemas/vpc-lattice.ts @@ -1,5 +1,30 @@ import { z } from 'zod'; +/** + * Zod schema for VPC Lattice event + * + * @example + * ```json + * { + "raw_path": "/testpath", + * "method": "GET", + * "headers": { + * "user_agent": "curl/7.64.1", + * "x-forwarded-for": "10.213.229.10", + * "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", + * "accept": "*\/*", + * }, + * "query_string_parameters": { + * "order-id": "1" + * }, + * "body": "eyJ0ZXN0IjogImV2ZW50In0=", + * "is_base64_encoded": true + *} + * ``` + * + * @see {@link types.VpcLatticeEvent | VpcLatticeEvent} + * @see {@link https://docs.aws.amazon.com/vpc-lattice/latest/ug/lambda-functions.html#receive-event-from-service} + */ const VpcLatticeSchema = z.object({ method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']), raw_path: z.string(), diff --git a/packages/parser/src/schemas/vpc-latticev2.ts b/packages/parser/src/schemas/vpc-latticev2.ts index 1ef3fd671f..ef80f0a8e3 100644 --- a/packages/parser/src/schemas/vpc-latticev2.ts +++ b/packages/parser/src/schemas/vpc-latticev2.ts @@ -22,6 +22,45 @@ const VpcLatticeV2RequestContext = z.object({ identity: VpcLatticeV2RequestContextIdentity, }); +/** + * Zod schema for VpcLatticeV2 event + * + * @example + * ```json + * { + * "version": "2.0", + * "path": "/newpath", + * "method": "GET", + * "headers": { + * "user_agent": "curl/7.64.1", + * "x-forwarded-for": "10.213.229.10", + * "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", + * "accept": "*]/*" + * }, + * "queryStringParameters": { + * "order-id": "1" + * }, + * "body": "{\"message\": \"Hello from Lambda!\"}", + * "isBase64Encoded": false, + * "requestContext": { + * "serviceNetworkArn": "arn:aws:vpc-lattice:us-east-2:123456789012:servicenetwork/sn-0bf3f2882e9cc805a", + * "serviceArn": "arn:aws:vpc-lattice:us-east-2:123456789012:service/svc-0a40eebed65f8d69c", + * "targetGroupArn": "arn:aws:vpc-lattice:us-east-2:123456789012:targetgroup/tg-6d0ecf831eec9f09", + * "identity": { + * "sourceVpcArn": "arn:aws:ec2:region:123456789012:vpc/vpc-0b8276c84697e7339", + * "type": "AWS_IAM", + * "principal": "arn:aws:sts::123456789012:assumed-role/example-role/057d00f8b51257ba3c853a0f248943cf", + * "sessionName": "057d00f8b51257ba3c853a0f248943cf", + * "x509SanDns": "example.com" + * }, + * "region": "us-east-2", + * "timeEpoch": "1696331543569073" + * } + * } + * ``` + * @see {@link types.VpcLatticeEventV2 | VpcLatticeEventV2} + * @see {@link https://docs.aws.amazon.com/vpc-lattice/latest/ug/lambda-functions.html#receive-event-from-service} + */ const VpcLatticeV2Schema = z.object({ version: z.string(), path: z.string(), diff --git a/packages/parser/src/types/index.ts b/packages/parser/src/types/index.ts index 26052e60b6..33c9fadcd0 100644 --- a/packages/parser/src/types/index.ts +++ b/packages/parser/src/types/index.ts @@ -25,12 +25,11 @@ export type { KafkaSelfManagedEvent, KafkaMskEvent, KinesisDataStreamEvent, - KinesisDataStreamRecord, - KinesisDataStreamRecordPayload, KinesisFireHoseEvent, KinesisFireHoseSqsEvent, LambdaFunctionUrlEvent, SesEvent, + S3ObjectLambdaEvent, VpcLatticeEvent, VpcLatticeEventV2, } from './schema.js'; diff --git a/packages/parser/src/types/parser.ts b/packages/parser/src/types/parser.ts index c775a78d94..c3c6af7877 100644 --- a/packages/parser/src/types/parser.ts +++ b/packages/parser/src/types/parser.ts @@ -1,23 +1,35 @@ import type { ZodSchema, ZodError } from 'zod'; import type { Envelope } from './envelope.js'; +/** + * Options for the parser used in middy middleware and decorator + */ type ParserOptions = { schema: S; envelope?: Envelope; safeParse?: boolean; }; +/** + * A successful parsing result with the parsed data when using safeParse + */ type ParsedResultSuccess = { success: true; data: Output; }; +/** + * A failed parsing result with the error when using safeParse, contains the original event and the error. + */ type ParsedResultError = { success: false; error: ZodError | Error; originalEvent: Input; }; +/** + * The result of parsing an event using the safeParse, can either be a success or an error + */ type ParsedResult = | ParsedResultSuccess | ParsedResultError; diff --git a/packages/parser/src/types/schema.ts b/packages/parser/src/types/schema.ts index 6b18b57968..91574fe37b 100644 --- a/packages/parser/src/types/schema.ts +++ b/packages/parser/src/types/schema.ts @@ -1,45 +1,38 @@ -import { - KafkaSelfManagedEventSchema, - KafkaMskEventSchema, -} from '../schemas/kafka.js'; import { z } from 'zod'; import { - KinesisDataStreamRecord, - KinesisDataStreamRecordPayload, - KinesisDataStreamSchema, -} from '../schemas/kinesis.js'; -import { APIGatewayProxyEventSchema } from '../schemas/apigw.js'; -import { AlbSchema, AlbMultiValueHeadersSchema } from '../schemas/alb.js'; -import { APIGatewayProxyEventV2Schema } from '../schemas/apigwv2.js'; -import { DynamoDBStreamSchema } from '../schemas/dynamodb.js'; -import { SqsSchema } from '../schemas/sqs.js'; -import { + AlbSchema, + AlbMultiValueHeadersSchema, + APIGatewayProxyEventSchema, + APIGatewayProxyEventV2Schema, CloudFormationCustomResourceCreateSchema, CloudFormationCustomResourceDeleteSchema, CloudFormationCustomResourceUpdateSchema, -} from '../schemas/cloudformation-custom-resource.js'; -import { CloudWatchLogsSchema } from '../schemas/cloudwatch.js'; -import { EventBridgeSchema } from '../schemas/eventbridge.js'; -import { + CloudWatchLogsSchema, + DynamoDBStreamSchema, + EventBridgeSchema, + KafkaSelfManagedEventSchema, + KafkaMskEventSchema, + KinesisDataStreamSchema, KinesisFirehoseSchema, KinesisFirehoseSqsSchema, -} from '../schemas/kinesis-firehose.js'; -import { LambdaFunctionUrlSchema } from '../schemas/lambda.js'; -import { - S3EventNotificationEventBridgeSchema, + LambdaFunctionUrlSchema, S3Schema, + S3EventNotificationEventBridgeSchema, S3SqsEventNotificationSchema, -} from '../schemas/s3.js'; -import { SesSchema } from '../schemas/ses.js'; -import { SnsSchema } from '../schemas/sns.js'; -import { VpcLatticeSchema } from '../schemas/vpc-lattice.js'; -import { VpcLatticeV2Schema } from '../schemas/vpc-latticev2.js'; + SesSchema, + SnsSchema, + SqsSchema, + VpcLatticeSchema, + VpcLatticeV2Schema, + S3ObjectLambdaEventSchema, +} from '../schemas/index.js'; type ALBEvent = z.infer; type ALBMultiValueHeadersEvent = z.infer; type APIGatewayProxyEvent = z.infer; + type APIGatewayProxyEventV2 = z.infer; type CloudFormationCustomResourceCreateEvent = z.infer< @@ -80,6 +73,8 @@ type S3EventNotificationEventBridge = z.infer< type S3SqsEventNotification = z.infer; +type S3ObjectLambdaEvent = z.infer; + type SesEvent = z.infer; type SnsEvent = z.infer; @@ -104,14 +99,13 @@ export type { KafkaSelfManagedEvent, KafkaMskEvent, KinesisDataStreamEvent, - KinesisDataStreamRecord, - KinesisDataStreamRecordPayload, KinesisFireHoseEvent, KinesisFireHoseSqsEvent, LambdaFunctionUrlEvent, S3Event, S3EventNotificationEventBridge, S3SqsEventNotification, + S3ObjectLambdaEvent, SesEvent, SnsEvent, SqsEvent, diff --git a/packages/parser/tests/events/kinesisFirehoseKinesisEvent.json b/packages/parser/tests/events/kinesisFirehoseKinesisEvent.json index 6cdd8e8a5b..bfc2f34a2f 100644 --- a/packages/parser/tests/events/kinesisFirehoseKinesisEvent.json +++ b/packages/parser/tests/events/kinesisFirehoseKinesisEvent.json @@ -1,32 +1,32 @@ { - "invocationId": "2b4d1ad9-2f48-94bd-a088-767c317e994a", - "sourceKinesisStreamArn":"arn:aws:kinesis:us-east-1:123456789012:stream/kinesis-source", - "deliveryStreamArn": "arn:aws:firehose:us-east-2:123456789012:deliverystream/delivery-stream-name", - "region": "us-east-2", - "records": [ - { - "data": "SGVsbG8gV29ybGQ=", - "recordId": "record1", - "approximateArrivalTimestamp": 1664028820148, - "kinesisRecordMetadata": { - "shardId": "shardId-000000000000", - "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c317a", - "approximateArrivalTimestamp": 1664028820148, - "sequenceNumber": "49546986683135544286507457936321625675700192471156785154", - "subsequenceNumber": 0 - } - }, - { - "data": "eyJIZWxsbyI6ICJXb3JsZCJ9", - "recordId": "record2", - "approximateArrivalTimestamp": 1664028793294, - "kinesisRecordMetadata": { - "shardId": "shardId-000000000001", - "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c318a", - "approximateArrivalTimestamp": 1664028793294, - "sequenceNumber": "49546986683135544286507457936321625675700192471156785155", - "subsequenceNumber": 0 - } - } - ] + "invocationId": "2b4d1ad9-2f48-94bd-a088-767c317e994a", + "sourceKinesisStreamArn": "arn:aws:kinesis:us-east-1:123456789012:stream/kinesis-source", + "deliveryStreamArn": "arn:aws:firehose:us-east-2:123456789012:deliverystream/delivery-stream-name", + "region": "us-east-2", + "records": [ + { + "data": "SGVsbG8gV29ybGQ=", + "recordId": "record1", + "approximateArrivalTimestamp": 1664028820148, + "kinesisRecordMetadata": { + "shardId": "shardId-000000000000", + "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c317a", + "approximateArrivalTimestamp": 1664028820148, + "sequenceNumber": "49546986683135544286507457936321625675700192471156785154", + "subsequenceNumber": 0 + } + }, + { + "data": "eyJIZWxsbyI6ICJXb3JsZCJ9", + "recordId": "record2", + "approximateArrivalTimestamp": 1664028793294, + "kinesisRecordMetadata": { + "shardId": "shardId-000000000001", + "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c318a", + "approximateArrivalTimestamp": 1664028793294, + "sequenceNumber": "49546986683135544286507457936321625675700192471156785155", + "subsequenceNumber": 0 + } + } + ] } diff --git a/packages/parser/tests/events/kinesisFirehoseSQSEvent.json b/packages/parser/tests/events/kinesisFirehoseSQSEvent.json index bea267c420..a9e36f554d 100644 --- a/packages/parser/tests/events/kinesisFirehoseSQSEvent.json +++ b/packages/parser/tests/events/kinesisFirehoseSQSEvent.json @@ -1,12 +1,12 @@ { - "invocationId": "556b67a3-48fc-4385-af49-e133aade9cb9", - "deliveryStreamArn": "arn:aws:firehose:us-east-1:123456789012:deliverystream/PUT-S3-tdyyE", - "region": "us-east-1", - "records": [ + "invocationId": "556b67a3-48fc-4385-af49-e133aade9cb9", + "deliveryStreamArn": "arn:aws:firehose:us-east-1:123456789012:deliverystream/PUT-S3-tdyyE", + "region": "us-east-1", + "records": [ { "recordId": "49640912821178817833517986466168945147170627572855734274000000", "approximateArrivalTimestamp": 1684864917398, "data": "eyJtZXNzYWdlSWQiOiI1YWI4MDdkNC01NjQ0LTRjNTUtOTdhMy00NzM5NjYzNWFjNzQiLCJyZWNlaXB0SGFuZGxlIjoiQVFFQndKbkt5ckhpZ1VNWmo2cllpZ0NneGxhUzNTTHkwYS4uLiIsImJvZHkiOiJUZXN0IG1lc3NhZ2UuIiwiYXR0cmlidXRlcyI6eyJBcHByb3hpbWF0ZVJlY2VpdmVDb3VudCI6IjEiLCJTZW50VGltZXN0YW1wIjoiMTY4NDg2NDg1MjQ5MSIsIlNlbmRlcklkIjoiQUlEQUlFTlFaSk9MTzIzWVZKNFZPIiwiQXBwcm94aW1hdGVGaXJzdFJlY2VpdmVUaW1lc3RhbXAiOiIxNjg0ODY0ODcyNDkxIn0sIm1lc3NhZ2VBdHRyaWJ1dGVzIjp7fSwibWQ1T2ZNZXNzYWdlQXR0cmlidXRlcyI6bnVsbCwibWQ1T2ZCb2R5IjoiYzhiNmJjNjBjOGI4YjNhOTA0ZTQ1YzFmYWJkZjUyM2QiLCJldmVudFNvdXJjZSI6ImF3czpzcXMiLCJldmVudFNvdXJjZUFSTiI6ImFybjphd3M6c3FzOnVzLWVhc3QtMToyMDA5ODQxMTIzODY6U05TIiwiYXdzUmVnaW9uIjoidXMtZWFzdC0xIn0K" } - ] + ] } diff --git a/packages/parser/tests/events/lambdaFunctionUrlEvent.json b/packages/parser/tests/events/lambdaFunctionUrlEvent.json index da5c133e6f..116286bdc8 100644 --- a/packages/parser/tests/events/lambdaFunctionUrlEvent.json +++ b/packages/parser/tests/events/lambdaFunctionUrlEvent.json @@ -1,47 +1,47 @@ { - "version":"2.0", - "routeKey":"$default", - "rawPath":"/", - "rawQueryString":"", - "headers":{ - "sec-fetch-mode":"navigate", - "x-amzn-tls-version":"TLSv1.2", - "sec-fetch-site":"cross-site", - "accept-language":"pt-BR,pt;q=0.9", - "x-forwarded-proto":"https", - "x-forwarded-port":"443", - "x-forwarded-for":"123.123.123.123", - "sec-fetch-user":"?1", - "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", - "x-amzn-tls-cipher-suite":"ECDHE-RSA-AES128-GCM-SHA256", - "sec-ch-ua":"\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"", - "sec-ch-ua-mobile":"?0", - "x-amzn-trace-id":"Root=1-62ecd163-5f302e550dcde3b12402207d", - "sec-ch-ua-platform":"\"Linux\"", - "host":".lambda-url.us-east-1.on.aws", - "upgrade-insecure-requests":"1", - "cache-control":"max-age=0", - "accept-encoding":"gzip, deflate, br", - "sec-fetch-dest":"document", - "user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36" - }, - "requestContext":{ - "accountId":"anonymous", - "apiId":"", - "domainName":".lambda-url.us-east-1.on.aws", - "domainPrefix":"", - "http":{ - "method":"GET", - "path":"/", - "protocol":"HTTP/1.1", - "sourceIp":"123.123.123.123", - "userAgent":"agent" - }, - "requestId":"id", - "routeKey":"$default", - "stage":"$default", - "time":"05/Aug/2022:08:14:39 +0000", - "timeEpoch":1659687279885 - }, - "isBase64Encoded":false + "version": "2.0", + "routeKey": "$default", + "rawPath": "/", + "rawQueryString": "", + "headers": { + "sec-fetch-mode": "navigate", + "x-amzn-tls-version": "TLSv1.2", + "sec-fetch-site": "cross-site", + "accept-language": "pt-BR,pt;q=0.9", + "x-forwarded-proto": "https", + "x-forwarded-port": "443", + "x-forwarded-for": "123.123.123.123", + "sec-fetch-user": "?1", + "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", + "x-amzn-tls-cipher-suite": "ECDHE-RSA-AES128-GCM-SHA256", + "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"", + "sec-ch-ua-mobile": "?0", + "x-amzn-trace-id": "Root=1-62ecd163-5f302e550dcde3b12402207d", + "sec-ch-ua-platform": "\"Linux\"", + "host": ".lambda-url.us-east-1.on.aws", + "upgrade-insecure-requests": "1", + "cache-control": "max-age=0", + "accept-encoding": "gzip, deflate, br", + "sec-fetch-dest": "document", + "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36" + }, + "requestContext": { + "accountId": "anonymous", + "apiId": "", + "domainName": ".lambda-url.us-east-1.on.aws", + "domainPrefix": "", + "http": { + "method": "GET", + "path": "/", + "protocol": "HTTP/1.1", + "sourceIp": "123.123.123.123", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "05/Aug/2022:08:14:39 +0000", + "timeEpoch": 1659687279885 + }, + "isBase64Encoded": false } diff --git a/packages/parser/tests/events/s3EventBridgeNotificationObjectCreatedEvent.json b/packages/parser/tests/events/s3EventBridgeNotificationObjectCreatedEvent.json index 5cc8f2f402..6096ea8d77 100644 --- a/packages/parser/tests/events/s3EventBridgeNotificationObjectCreatedEvent.json +++ b/packages/parser/tests/events/s3EventBridgeNotificationObjectCreatedEvent.json @@ -1,28 +1,28 @@ { + "version": "0", + "id": "f5f1e65c-dc3a-93ca-6c1e-b1647eac7963", + "detail-type": "Object Created", + "source": "aws.s3", + "account": "123456789012", + "time": "2023-03-08T17:50:14Z", + "region": "eu-west-1", + "resources": [ + "arn:aws:s3:::example-bucket" + ], + "detail": { "version": "0", - "id": "f5f1e65c-dc3a-93ca-6c1e-b1647eac7963", - "detail-type": "Object Created", - "source": "aws.s3", - "account": "123456789012", - "time": "2023-03-08T17:50:14Z", - "region": "eu-west-1", - "resources": [ - "arn:aws:s3:::example-bucket" - ], - "detail": { - "version": "0", - "bucket": { - "name": "example-bucket" - }, - "object": { - "key": "IMG_m7fzo3.jpg", - "size": 184662, - "etag": "4e68adba0abe2dc8653dc3354e14c01d", - "sequencer": "006408CAD69598B05E" - }, - "request-id": "57H08PA84AB1JZW0", - "requester": "123456789012", - "source-ip-address": "34.252.34.74", - "reason": "PutObject" - } + "bucket": { + "name": "example-bucket" + }, + "object": { + "key": "IMG_m7fzo3.jpg", + "size": 184662, + "etag": "4e68adba0abe2dc8653dc3354e14c01d", + "sequencer": "006408CAD69598B05E" + }, + "request-id": "57H08PA84AB1JZW0", + "requester": "123456789012", + "source-ip-address": "34.252.34.74", + "reason": "PutObject" + } } \ No newline at end of file diff --git a/packages/parser/tests/events/s3SqsEvent.json b/packages/parser/tests/events/s3SqsEvent.json index 55863af12b..418bd050b2 100644 --- a/packages/parser/tests/events/s3SqsEvent.json +++ b/packages/parser/tests/events/s3SqsEvent.json @@ -1,22 +1,21 @@ { - "Records":[ - { - "messageId":"ca3e7a89-c358-40e5-8aa0-5da01403c267", - "receiptHandle":"AQEBE7XoI7IQRLF7SrpiW9W4BanmOWe8UtVDbv6/CEZYKf/OktSNIb4j689tQfR4k44V/LY20lZ5VpxYt2GTYCsSLKTcBalTJaRX9CKu/hVqy/23sSNiKxnP56D+VLSn+hU275+AP1h4pUL0d9gLdRB2haX8xiM+LcGfis5Jl8BBXtoxKRF60O87O9/NvCmmXLeqkJuexfyEZNyed0fFCRXFXSjbmThG0OIQgcrGI8glBRGPA8htns58VtXFsSaPYNoqP3p5n6+ewKKVLD0lfm+0DlnLKRa+mjvFBaSer9KK1ff+Aq6zJ6HynPwADj+aF70Hwimc2zImYe51SLEF/E2csYlMNZYI/2qXW0m9R7wJ/XDTV4g2+h+BMTxsKnJQ6NQd", - "body":"{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-04-12T20:43:38.021Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"A1YQ72UWCM96UF\"},\"requestParameters\":{\"sourceIPAddress\":\"93.108.161.96\"},\"responseElements\":{\"x-amz-request-id\":\"YMSSR8BZJ2Y99K6P\",\"x-amz-id-2\":\"6ASrUfj5xpn859fIq+6FXflOex/SKl/rjfiMd7wRzMg/zkHKR22PDpnh7KD3uq//cuOTbdX4DInN5eIs+cR0dY1z2Mc5NDP/\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"SNS\",\"bucket\":{\"name\":\"xxx\",\"ownerIdentity\":{\"principalId\":\"A1YQ72UWCM96UF\"},\"arn\":\"arn:aws:s3:::xxx\"},\"object\":{\"key\":\"test.pdf\",\"size\":104681,\"eTag\":\"2e3ad1e983318bbd8e73b080e2997980\",\"versionId\":\"yd3d4HaWOT2zguDLvIQLU6ptDTwKBnQV\",\"sequencer\":\"00643717F9F8B85354\"}}}]}", - "attributes":{ - "ApproximateReceiveCount":"1", - "SentTimestamp":"1681332219270", - "SenderId":"AIDAJHIPRHEMV73VRJEBU", - "ApproximateFirstReceiveTimestamp":"1681332239270" - }, - "messageAttributes":{ - - }, - "md5OfBody":"16f4460f4477d8d693a5abe94fdbbd73", - "eventSource":"aws:sqs", - "eventSourceARN":"arn:aws:sqs:us-east-1:123456789012:SQS", - "awsRegion":"us-east-1" - } - ] - } + "Records": [ + { + "messageId": "ca3e7a89-c358-40e5-8aa0-5da01403c267", + "receiptHandle": "AQEBE7XoI7IQRLF7SrpiW9W4BanmOWe8UtVDbv6/CEZYKf/OktSNIb4j689tQfR4k44V/LY20lZ5VpxYt2GTYCsSLKTcBalTJaRX9CKu/hVqy/23sSNiKxnP56D+VLSn+hU275+AP1h4pUL0d9gLdRB2haX8xiM+LcGfis5Jl8BBXtoxKRF60O87O9/NvCmmXLeqkJuexfyEZNyed0fFCRXFXSjbmThG0OIQgcrGI8glBRGPA8htns58VtXFsSaPYNoqP3p5n6+ewKKVLD0lfm+0DlnLKRa+mjvFBaSer9KK1ff+Aq6zJ6HynPwADj+aF70Hwimc2zImYe51SLEF/E2csYlMNZYI/2qXW0m9R7wJ/XDTV4g2+h+BMTxsKnJQ6NQd", + "body": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-04-12T20:43:38.021Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"A1YQ72UWCM96UF\"},\"requestParameters\":{\"sourceIPAddress\":\"93.108.161.96\"},\"responseElements\":{\"x-amz-request-id\":\"YMSSR8BZJ2Y99K6P\",\"x-amz-id-2\":\"6ASrUfj5xpn859fIq+6FXflOex/SKl/rjfiMd7wRzMg/zkHKR22PDpnh7KD3uq//cuOTbdX4DInN5eIs+cR0dY1z2Mc5NDP/\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"SNS\",\"bucket\":{\"name\":\"xxx\",\"ownerIdentity\":{\"principalId\":\"A1YQ72UWCM96UF\"},\"arn\":\"arn:aws:s3:::xxx\"},\"object\":{\"key\":\"test.pdf\",\"size\":104681,\"eTag\":\"2e3ad1e983318bbd8e73b080e2997980\",\"versionId\":\"yd3d4HaWOT2zguDLvIQLU6ptDTwKBnQV\",\"sequencer\":\"00643717F9F8B85354\"}}}]}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1681332219270", + "SenderId": "AIDAJHIPRHEMV73VRJEBU", + "ApproximateFirstReceiveTimestamp": "1681332239270" + }, + "messageAttributes": { + }, + "md5OfBody": "16f4460f4477d8d693a5abe94fdbbd73", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:SQS", + "awsRegion": "us-east-1" + } + ] +} diff --git a/packages/parser/tests/events/snsSqsEvent.json b/packages/parser/tests/events/snsSqsEvent.json index ee440fc296..9e4ce4eb1e 100644 --- a/packages/parser/tests/events/snsSqsEvent.json +++ b/packages/parser/tests/events/snsSqsEvent.json @@ -1,20 +1,20 @@ { - "Records": [ - { - "messageId": "79406a00-bf15-46ca-978c-22c3613fcb30", - "receiptHandle": "AQEB3fkqlBqq239bMCAHIr5mZkxJYKtxsTTy1lMImmpY7zqpQdfcAE8zFiuRh7X5ciROy24taT2rRXfuJFN/yEUVcQ6d5CIOCEK4htmRJJOHIyGdZPAm2NUUG5nNn2aEzgfzVvrkPBsrCbr7XTzK5s6eUZNH/Nn9AJtHKHpzweRK34Bon9OU/mvyIT7EJbwHPsdhL14NrCp8pLWBiIhkaJkG2G6gPO89dwHtGVUARJL+zP70AuIu/f7QgmPtY2eeE4AVbcUT1qaIlSGHUXxoHq/VMHLd/c4zWl0EXQOo/90DbyCUMejTIKL7N15YfkHoQDHprvMiAr9S75cdMiNOduiHzZLg/qVcv4kxsksKLFMKjwlzmYuQYy2KslVGwoHMd4PD", - "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"d88d4479-6ec0-54fe-b63f-1cf9df4bb16e\",\n \"TopicArn\" : \"arn:aws:sns:eu-west-1:231436140809:powertools265\",\n \"Message\" : \"{\\\"message\\\": \\\"hello world\\\", \\\"username\\\": \\\"lessa\\\"}\",\n \"Timestamp\" : \"2021-01-19T10:07:07.287Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"tEo2i6Lw6/Dr7Jdlulh0sXgnkF0idd3hqs8QZCorQpzkIWVOuu583NT0Gv0epuZD1Bo+tex6NgP5p6415yNVujGHJKnkrA9ztzXaVgFiol8rf8AFGQbmb7RsM9BqATQUJeg9nCTe0jksmWXmjxEFr8XKyyRuQBwSlRTngAvOw8jUnCe1vyYD5xPec1xpfOEGLi5BqSog+6tBtsry3oAtcENX8SV1tVuMpp6D+UrrU8xNT/5D70uRDppkPE3vq+t7rR0fVSdQRdUV9KmQD2bflA1Dyb2y37EzwJOMHDDQ82aOhj/JmPxvEAlV8RkZl6J0HIveraRy9wbNLbI7jpiOCw==\",\n \"SigningCertURL\" : \"https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem\",\n \"UnsubscribeURL\" : \"https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:231436140809:powertools265:15189ad7-870e-40e5-a7dd-a48898cd9f86\"\n}", - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1611050827340", - "SenderId": "AIDAISMY7JYY5F7RTT6AO", - "ApproximateFirstReceiveTimestamp": "1611050827344" - }, - "messageAttributes": {}, - "md5OfBody": "8910bdaaf9a30a607f7891037d4af0b0", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:eu-west-1:231436140809:powertools265", - "awsRegion": "eu-west-1" - } - ] + "Records": [ + { + "messageId": "79406a00-bf15-46ca-978c-22c3613fcb30", + "receiptHandle": "AQEB3fkqlBqq239bMCAHIr5mZkxJYKtxsTTy1lMImmpY7zqpQdfcAE8zFiuRh7X5ciROy24taT2rRXfuJFN/yEUVcQ6d5CIOCEK4htmRJJOHIyGdZPAm2NUUG5nNn2aEzgfzVvrkPBsrCbr7XTzK5s6eUZNH/Nn9AJtHKHpzweRK34Bon9OU/mvyIT7EJbwHPsdhL14NrCp8pLWBiIhkaJkG2G6gPO89dwHtGVUARJL+zP70AuIu/f7QgmPtY2eeE4AVbcUT1qaIlSGHUXxoHq/VMHLd/c4zWl0EXQOo/90DbyCUMejTIKL7N15YfkHoQDHprvMiAr9S75cdMiNOduiHzZLg/qVcv4kxsksKLFMKjwlzmYuQYy2KslVGwoHMd4PD", + "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"d88d4479-6ec0-54fe-b63f-1cf9df4bb16e\",\n \"TopicArn\" : \"arn:aws:sns:eu-west-1:231436140809:powertools265\",\n \"Message\" : \"{\\\"message\\\": \\\"hello world\\\", \\\"username\\\": \\\"lessa\\\"}\",\n \"Timestamp\" : \"2021-01-19T10:07:07.287Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"tEo2i6Lw6/Dr7Jdlulh0sXgnkF0idd3hqs8QZCorQpzkIWVOuu583NT0Gv0epuZD1Bo+tex6NgP5p6415yNVujGHJKnkrA9ztzXaVgFiol8rf8AFGQbmb7RsM9BqATQUJeg9nCTe0jksmWXmjxEFr8XKyyRuQBwSlRTngAvOw8jUnCe1vyYD5xPec1xpfOEGLi5BqSog+6tBtsry3oAtcENX8SV1tVuMpp6D+UrrU8xNT/5D70uRDppkPE3vq+t7rR0fVSdQRdUV9KmQD2bflA1Dyb2y37EzwJOMHDDQ82aOhj/JmPxvEAlV8RkZl6J0HIveraRy9wbNLbI7jpiOCw==\",\n \"SigningCertURL\" : \"https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem\",\n \"UnsubscribeURL\" : \"https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:231436140809:powertools265:15189ad7-870e-40e5-a7dd-a48898cd9f86\"\n}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1611050827340", + "SenderId": "AIDAISMY7JYY5F7RTT6AO", + "ApproximateFirstReceiveTimestamp": "1611050827344" + }, + "messageAttributes": {}, + "md5OfBody": "8910bdaaf9a30a607f7891037d4af0b0", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:eu-west-1:231436140809:powertools265", + "awsRegion": "eu-west-1" + } + ] } diff --git a/packages/parser/tests/events/vpcLatticeV2Event.json b/packages/parser/tests/events/vpcLatticeV2Event.json index fe10d83a3a..a1bd86f67b 100644 --- a/packages/parser/tests/events/vpcLatticeV2Event.json +++ b/packages/parser/tests/events/vpcLatticeV2Event.json @@ -1,30 +1,30 @@ { - "version": "2.0", - "path": "/newpath", - "method": "GET", - "headers": { - "user_agent": "curl/7.64.1", - "x-forwarded-for": "10.213.229.10", - "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", - "accept": "*/*" + "version": "2.0", + "path": "/newpath", + "method": "GET", + "headers": { + "user_agent": "curl/7.64.1", + "x-forwarded-for": "10.213.229.10", + "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", + "accept": "*/*" + }, + "queryStringParameters": { + "order-id": "1" + }, + "body": "{\"message\": \"Hello from Lambda!\"}", + "isBase64Encoded": false, + "requestContext": { + "serviceNetworkArn": "arn:aws:vpc-lattice:us-east-2:123456789012:servicenetwork/sn-0bf3f2882e9cc805a", + "serviceArn": "arn:aws:vpc-lattice:us-east-2:123456789012:service/svc-0a40eebed65f8d69c", + "targetGroupArn": "arn:aws:vpc-lattice:us-east-2:123456789012:targetgroup/tg-6d0ecf831eec9f09", + "identity": { + "sourceVpcArn": "arn:aws:ec2:region:123456789012:vpc/vpc-0b8276c84697e7339", + "type": "AWS_IAM", + "principal": "arn:aws:sts::123456789012:assumed-role/example-role/057d00f8b51257ba3c853a0f248943cf", + "sessionName": "057d00f8b51257ba3c853a0f248943cf", + "x509SanDns": "example.com" }, - "queryStringParameters": { - "order-id": "1" - }, - "body": "{\"message\": \"Hello from Lambda!\"}", - "isBase64Encoded": false, - "requestContext": { - "serviceNetworkArn": "arn:aws:vpc-lattice:us-east-2:123456789012:servicenetwork/sn-0bf3f2882e9cc805a", - "serviceArn": "arn:aws:vpc-lattice:us-east-2:123456789012:service/svc-0a40eebed65f8d69c", - "targetGroupArn": "arn:aws:vpc-lattice:us-east-2:123456789012:targetgroup/tg-6d0ecf831eec9f09", - "identity": { - "sourceVpcArn": "arn:aws:ec2:region:123456789012:vpc/vpc-0b8276c84697e7339", - "type" : "AWS_IAM", - "principal": "arn:aws:sts::123456789012:assumed-role/example-role/057d00f8b51257ba3c853a0f248943cf", - "sessionName": "057d00f8b51257ba3c853a0f248943cf", - "x509SanDns": "example.com" - }, - "region": "us-east-2", - "timeEpoch": "1696331543569073" - } + "region": "us-east-2", + "timeEpoch": "1696331543569073" + } } diff --git a/packages/parser/typedoc.json b/packages/parser/typedoc.json index ed0ca6fc47..51ddecfe5f 100644 --- a/packages/parser/typedoc.json +++ b/packages/parser/typedoc.json @@ -3,7 +3,11 @@ "../../typedoc.base.json" ], "entryPoints": [ - "./src/index.ts" + "./src/index.ts", + "./src/middleware/parser.ts", + "./src/types/index.ts", + "./src/envelopes/index.ts", + "./src/schemas/index.ts" ], "readme": "README.md" } \ No newline at end of file diff --git a/typedoc.json b/typedoc.json index daadd7bc2e..36bef91ee3 100644 --- a/typedoc.json +++ b/typedoc.json @@ -13,6 +13,7 @@ "layers", "examples/**" ], + "plugin": ["typedoc-plugin-zod"], "skipErrorChecking": true, "excludePrivate": true, "visibilityFilters": {