Skip to content

feat(parser): add built-in schemas #1788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 51 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
aa66d8c
add dynamodb schema
am29d Oct 31, 2023
64c3eb1
add alb
am29d Oct 31, 2023
c5127f9
merged feat/v2
am29d Oct 31, 2023
f0464ab
add parser to v2 build
am29d Nov 2, 2023
f353c7f
fix test
am29d Nov 2, 2023
4a66dec
add alb
am29d Nov 2, 2023
633ce9a
Merge branch 'feat/v2' into feat/praser/built-in-schemas
am29d Nov 3, 2023
6078cb0
add built-in schema
am29d Nov 10, 2023
5bcab2e
add more tests for schemas
am29d Nov 10, 2023
0e9db61
remove index export
am29d Nov 10, 2023
fefe01a
merged target
am29d Nov 13, 2023
c06989b
add cloudwatch with base64 zlip transform
am29d Nov 13, 2023
a4d3852
add throw test case
am29d Nov 13, 2023
7a2a203
formatting
am29d Nov 13, 2023
689ef45
add kafka schema
am29d Nov 13, 2023
7e0dd71
restructured tests
am29d Nov 13, 2023
067fd82
add vpc lattice and lattice v2
am29d Nov 14, 2023
04fd892
s3 event notification should extend eventbridge
am29d Nov 14, 2023
694f389
s3 sqs should extend from sqs
am29d Nov 14, 2023
1408bb9
simplify cloudwatch extract from string
am29d Nov 14, 2023
60b139b
keep message as string, instead of empty object
am29d Nov 14, 2023
1fdac46
fix detail type of eb and field names
am29d Nov 14, 2023
f6d09d2
remove duplicated entries
am29d Nov 14, 2023
3f8f4bb
fix homepage URL in readme
am29d Nov 14, 2023
ccb51e1
improved test coverage
am29d Nov 14, 2023
208a66f
key and value are always present
am29d Nov 14, 2023
d8919d3
cleanup unnecessary definitions, widen peerDep version req
am29d Nov 14, 2023
8eefbe8
Update packages/parser/src/schemas/cloudwatch.ts
am29d Nov 15, 2023
eceea76
clean up events, some fields are imaginary
am29d Nov 15, 2023
f67a8e1
fix api gw
am29d Nov 15, 2023
955d277
fix broken IP addresses in examples
am29d Nov 15, 2023
f165302
add more tests to api gw
am29d Nov 15, 2023
06d5467
fix apigw2 add more tests
am29d Nov 15, 2023
1af893a
add optional scopes to apigwv2
am29d Nov 15, 2023
a9cfa6a
add optional field back to api gw, stricter methods for vpc lattice
am29d Nov 15, 2023
2d671d0
add test for messageId refinement
am29d Nov 15, 2023
7cdcc0b
remove redundant entry
am29d Nov 15, 2023
dd39001
fix sqs
am29d Nov 15, 2023
bd0cefe
add dmarcPolicy for ses
am29d Nov 15, 2023
7b33250
added tests
am29d Nov 15, 2023
51219a8
moved cw function from kinesis, fix imports
am29d Nov 17, 2023
bbf5ac3
add parser to build step in ci
am29d Nov 17, 2023
d8a040f
use any safely here
am29d Nov 17, 2023
254ebd7
removed console logs
am29d Nov 17, 2023
e0dcf23
name, add datetime to strings
am29d Nov 17, 2023
0b6d570
narrow string to datetime
am29d Nov 17, 2023
f453246
refine to url
am29d Nov 17, 2023
455b329
imports, remove try/catch
am29d Nov 17, 2023
228217e
add .js extension to imports
am29d Nov 17, 2023
e330e51
moved comment, fixed path
am29d Nov 17, 2023
8ce4af6
rename event filename to fix events
am29d Nov 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions packages/parser/src/schemas/cloudwatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ const CloudWatchLogsDecodeSchema = z.object({
logEvents: z.array(CloudWatchLogEventSchema),
});

function decompressRecordToJSON(
const decompressRecordToJSON = (
data: string
): z.infer<typeof CloudWatchLogsDecodeSchema> {
): z.infer<typeof CloudWatchLogsDecodeSchema> => {
try {
console.debug('Decoding data', data);
const uncompressed = gunzipSync(Buffer.from(data, 'base64')).toString(
Expand All @@ -30,16 +30,23 @@ function decompressRecordToJSON(
console.debug('Failed to gunzip data', e);
throw e;
}
}
};

const CloudWatchLogsSchema = z.object({
awslogs: z.object({
data: z.string().transform((data) => decompressRecordToJSON(data)),
}),
});

const extractCloudWatchLogFromEvent = (
data: string
): z.infer<typeof CloudWatchLogsDecodeSchema> => {
return decompressRecordToJSON(data);
};

export {
CloudWatchLogsSchema,
CloudWatchLogsDecodeSchema,
decompressRecordToJSON,
extractCloudWatchLogFromEvent,
};
12 changes: 1 addition & 11 deletions packages/parser/src/schemas/kinesis.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import { z } from 'zod';
import {
CloudWatchLogsDecodeSchema,
decompressRecordToJSON,
} from './cloudwatch.js';

const KinesisDataStreamRecordPayload = z.object({
kinesisSchemaVersion: z.string(),
Expand All @@ -26,10 +22,4 @@ const KinesisDataStreamSchema = z.object({
Records: z.array(KinesisDataStreamRecord),
});

const extractCloudWatchLogFromEvent = (
data: string
): z.infer<typeof CloudWatchLogsDecodeSchema> => {
return decompressRecordToJSON(data);
};

export { KinesisDataStreamSchema, extractCloudWatchLogFromEvent };
export { KinesisDataStreamSchema };
13 changes: 8 additions & 5 deletions packages/parser/src/schemas/s3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ const S3Message = z.object({
configurationId: z.string(),
object: z.object({
key: z.string(),
size: z.number(),
eTag: z.string(),
size: z.number().optional(),
urlDecodedKey: z.string().optional(),
eTag: z.string().optional(),
sequencer: z.string(),
versionId: z.optional(z.string()),
}),
Expand Down Expand Up @@ -118,7 +119,9 @@ const S3ObjectSessionContext = z.object({
}),
attributes: z.object({
creationDate: z.string(),
mfaAuthenticated: z.string(),
mfaAuthenticated: z
.union([z.boolean(), z.literal('true'), z.literal('false')])
.transform((value) => value === true || value === 'true'),
}),
});

Expand All @@ -129,13 +132,13 @@ const S3ObjectUserIdentity = z.object({
userName: z.string().optional(),
principalId: z.string(),
arn: z.string(),
sessionContext: S3ObjectSessionContext,
sessionContext: S3ObjectSessionContext.optional(),
});

const S3ObjectLambdaEventSchema = z.object({
xAmzRequestId: z.string(),
getObjectContext: S3ObjectContext,
configurationId: S3ObjectConfiguration,
configuration: S3ObjectConfiguration,
userRequest: S3ObjectUserRequest,
userIdentity: S3ObjectUserIdentity,
protocolVersion: z.string(),
Expand Down
4 changes: 1 addition & 3 deletions packages/parser/tests/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"resolveJsonModule": true,
"rootDir": "../",
"noEmit": true
},
"include": [
"../src/**/*",
"./**/*.*",
"./**/*.json",
"./**/*.*"
]
}
11 changes: 8 additions & 3 deletions packages/parser/tests/unit/schema/alb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,25 @@ import {
AlbSchema,
AlbMultiValueHeadersSchema,
} from '../../../src/schemas/alb';
import albEvent from '../../events/albEvent.json';
import albEventPathTrailingSlash from '../../events/albEventPathTrailingSlash.json';
import albMultiValueHeadersEvent from '../../events/albMultiValueHeadersEvent.json';
import { loadExampleEvent } from './utils';

describe('ALB ', () => {
it('should parse alb event', () => {
const albEvent = loadExampleEvent('albEvent.json');
expect(AlbSchema.parse(albEvent)).toEqual(albEvent);
});
it('should parse alb event path trailing slash', () => {
const albEventPathTrailingSlash = loadExampleEvent(
'albEventPathTrailingSlash.json'
);
expect(AlbSchema.parse(albEventPathTrailingSlash)).toEqual(
albEventPathTrailingSlash
);
});
it('should parse alb event with multi value headers event', () => {
const albMultiValueHeadersEvent = loadExampleEvent(
'albMultiValueHeadersEvent.json'
);
expect(AlbMultiValueHeadersSchema.parse(albMultiValueHeadersEvent)).toEqual(
albMultiValueHeadersEvent
);
Expand Down
31 changes: 23 additions & 8 deletions packages/parser/tests/unit/schema/apigw.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,67 @@
* @group unit/parser/schema/
*/
import { APIGatewayProxyEventSchema } from '../../../src/schemas/apigw';
import apiGatewayProxyEvent from '../../events/apiGatewayProxyEvent.json';
import apiGatewayAuthorizerRequestEvent from '../../events/apiGatewayAuthorizerRequestEvent.json';
import apiGatewaySchemaMiddlewareInvalidEvent from '../../events/apiGatewaySchemaMiddlewareInvalidEvent.json';
import apiGatewaySchemaMiddlewareValidEvent from '../../events/apiGatewaySchemaMiddlewareValidEvent.json';
import apiGatewayProxyEvent_noVersionAuth from '../../events/apiGatewayProxyEvent_noVersionAuth.json';
import apiGatewayProxyEventAnotherPath from '../../events/apiGatewayProxyEventAnotherPath.json';
import apiGatewayProxyEventPathTrailingSlash from '../../events/apiGatewayProxyEventPathTrailingSlash.json';
import apiGatewayProxyOtherEvent from '../../events/apiGatewayProxyOtherEvent.json';
import { loadExampleEvent } from './utils';

describe('APIGateway ', () => {
it('should parse api gateway event', () => {
const apiGatewayProxyEvent = loadExampleEvent('apiGatewayProxyEvent.json');
expect(APIGatewayProxyEventSchema.parse(apiGatewayProxyEvent)).toEqual(
apiGatewayProxyEvent
);
});
it('should parse api gateway authorizer request event', () => {
const apiGatewayAuthorizerRequestEvent = loadExampleEvent(
'apiGatewayAuthorizerRequestEvent.json'
);
expect(
APIGatewayProxyEventSchema.parse(apiGatewayAuthorizerRequestEvent)
).toEqual(apiGatewayAuthorizerRequestEvent);
});
it('should parse schema middleware invalid event', () => {
const apiGatewaySchemaMiddlewareInvalidEvent = loadExampleEvent(
'apiGatewaySchemaMiddlewareInvalidEvent.json'
);
expect(
APIGatewayProxyEventSchema.parse(apiGatewaySchemaMiddlewareInvalidEvent)
).toEqual(apiGatewaySchemaMiddlewareInvalidEvent);
});
it('should parse schema middleware valid event', () => {
const apiGatewaySchemaMiddlewareValidEvent = loadExampleEvent(
'apiGatewaySchemaMiddlewareValidEvent.json'
);
expect(
APIGatewayProxyEventSchema.parse(apiGatewaySchemaMiddlewareValidEvent)
).toEqual(apiGatewaySchemaMiddlewareValidEvent);
});
it('should parse proxy event with no version auth', () => {
const apiGatewayProxyEvent_noVersionAuth = loadExampleEvent(
'apiGatewayProxyEvent_noVersionAuth.json'
);
expect(
APIGatewayProxyEventSchema.parse(apiGatewayProxyEvent_noVersionAuth)
).toEqual(apiGatewayProxyEvent_noVersionAuth);
});
it('should parse proxy event with another path', () => {
const apiGatewayProxyEventAnotherPath = loadExampleEvent(
'apiGatewayProxyEventAnotherPath.json'
);
expect(
APIGatewayProxyEventSchema.parse(apiGatewayProxyEventAnotherPath)
).toEqual(apiGatewayProxyEventAnotherPath);
});
it('should parse proxy event with path trailing slash', () => {
const apiGatewayProxyEventPathTrailingSlash = loadExampleEvent(
'apiGatewayProxyEventPathTrailingSlash.json'
);
expect(
APIGatewayProxyEventSchema.parse(apiGatewayProxyEventPathTrailingSlash)
).toEqual(apiGatewayProxyEventPathTrailingSlash);
});
it('should parse other proxy event', () => {
const apiGatewayProxyOtherEvent = loadExampleEvent(
'apiGatewayProxyOtherEvent.json'
);
expect(APIGatewayProxyEventSchema.parse(apiGatewayProxyOtherEvent)).toEqual(
apiGatewayProxyOtherEvent
);
Expand Down
29 changes: 22 additions & 7 deletions packages/parser/tests/unit/schema/apigwv2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,63 @@
* @group unit/parser/schema/
*/
import { APIGatewayProxyEventV2Schema } from '../../../src/schemas/apigwv2';
import apiGatewayProxyV2Event from '../../events/apiGatewayProxyV2Event.json';
import apiGatewayProxyV2Event_GET from '../../events/apiGatewayProxyV2Event_GET.json';
import apiGatewayProxyV2EventPathTrailingSlash from '../../events/apiGatewayProxyV2EventPathTrailingSlash.json';
import apiGatewayProxyV2IamEvent from '../../events/apiGatewayProxyV2IamEvent.json';
import apiGatewayProxyV2LambdaAuthorizerEvent from '../../events/apiGatewayProxyV2LambdaAuthorizerEvent.json';
import apiGatewayProxyV2OtherGetEvent from '../../events/apiGatewayProxyV2OtherGetEvent.json';
import apiGatewayProxyV2SchemaMiddlewareValidEvent from '../../events/apiGatewayProxyV2SchemaMiddlewareValidEvent.json';
import { loadExampleEvent } from './utils';

describe('API GW v2 ', () => {
it('should parse api gateway v2 event', () => {
const apiGatewayProxyV2Event = loadExampleEvent(
'apiGatewayProxyV2Event.json'
);
expect(APIGatewayProxyEventV2Schema.parse(apiGatewayProxyV2Event)).toEqual(
apiGatewayProxyV2Event
);
});
it('should parse api gateway v2 event with GET method', () => {
const apiGatewayProxyV2Event_GET = loadExampleEvent(
'apiGatewayProxyV2Event_GET.json'
);
expect(
APIGatewayProxyEventV2Schema.parse(apiGatewayProxyV2Event_GET)
).toEqual(apiGatewayProxyV2Event_GET);
});
it('should parse api gateway v2 event with path trailing slash', () => {
const apiGatewayProxyV2EventPathTrailingSlash = loadExampleEvent(
'apiGatewayProxyV2EventPathTrailingSlash.json'
);
expect(
APIGatewayProxyEventV2Schema.parse(
apiGatewayProxyV2EventPathTrailingSlash
)
).toEqual(apiGatewayProxyV2EventPathTrailingSlash);
});
it('should parse api gateway v2 event with iam', () => {
const apiGatewayProxyV2IamEvent = loadExampleEvent(
'apiGatewayProxyV2IamEvent.json'
);
expect(
APIGatewayProxyEventV2Schema.parse(apiGatewayProxyV2IamEvent)
).toEqual(apiGatewayProxyV2IamEvent);
});
it('should parse api gateway v2 event with lambda authorizer', () => {
const apiGatewayProxyV2LambdaAuthorizerEvent = loadExampleEvent(
'apiGatewayProxyV2LambdaAuthorizerEvent.json'
);
expect(
APIGatewayProxyEventV2Schema.parse(apiGatewayProxyV2LambdaAuthorizerEvent)
).toEqual(apiGatewayProxyV2LambdaAuthorizerEvent);
});
it('should parse api gateway v2 event with other get event', () => {
const apiGatewayProxyV2OtherGetEvent = loadExampleEvent(
'apiGatewayProxyV2OtherGetEvent.json'
);
expect(
APIGatewayProxyEventV2Schema.parse(apiGatewayProxyV2OtherGetEvent)
).toEqual(apiGatewayProxyV2OtherGetEvent);
});
it('should parse api gateway v2 event with schema middleware', () => {
const apiGatewayProxyV2SchemaMiddlewareValidEvent = loadExampleEvent(
'apiGatewayProxyV2SchemaMiddlewareValidEvent.json'
);
expect(
APIGatewayProxyEventV2Schema.parse(
apiGatewayProxyV2SchemaMiddlewareValidEvent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import {
CloudFormationCustomResourceUpdateSchema,
CloudFormationCustomResourceDeleteSchema,
} from '../../../src/schemas/cloudformation-custom-resource';
import cloudFormationCustomResourceCreateEvent from '../../events/cloudformationCustomResourceCreate.json';
import cloudFormationCustomResourceUpdateEvent from '../../events/cloudformationCustomResourceUpdate.json';
import cloudFormationCustomResourceDeleteEvent from '../../events/cloudformationCustomResourceDelete.json';
import { loadExampleEvent } from './utils';

describe('CloudFormationCustomResource ', () => {
it('should parse create event', () => {
const cloudFormationCustomResourceCreateEvent = loadExampleEvent(
'cloudFormationCustomResourceCreateEvent.json'
);
console.log(CloudFormationCustomResourceCreateSchema.shape);
expect(
CloudFormationCustomResourceCreateSchema.parse(
Expand All @@ -22,13 +23,19 @@ describe('CloudFormationCustomResource ', () => {
).toEqual(cloudFormationCustomResourceCreateEvent);
});
it('should parse update event', () => {
const cloudFormationCustomResourceUpdateEvent = loadExampleEvent(
'cloudFormationCustomResourceUpdateEvent.json'
);
expect(
CloudFormationCustomResourceUpdateSchema.parse(
cloudFormationCustomResourceUpdateEvent
)
).toEqual(cloudFormationCustomResourceUpdateEvent);
});
it('should parse delete event', () => {
const cloudFormationCustomResourceDeleteEvent = loadExampleEvent(
'cloudFormationCustomResourceDeleteEvent.json'
);
expect(
CloudFormationCustomResourceDeleteSchema.parse(
cloudFormationCustomResourceDeleteEvent
Expand Down
3 changes: 2 additions & 1 deletion packages/parser/tests/unit/schema/cloudwatch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
* @group unit/parser/schema/
*/
import { CloudWatchLogsSchema } from '../../../src/schemas/cloudwatch';
import cloudWatchLogEvent from '../../events/cloudWatchLogEvent.json';
import { loadExampleEvent } from './utils';

describe('CloudWatchLogs ', () => {
it('should parse cloudwatch logs event', () => {
const cloudWatchLogEvent = loadExampleEvent('cloudWatchLogEvent.json');
const parsed = CloudWatchLogsSchema.parse(cloudWatchLogEvent);
expect(parsed.awslogs.data).toBeDefined();
expect(parsed.awslogs.data?.logEvents[0]).toEqual({
Expand Down
7 changes: 4 additions & 3 deletions packages/parser/tests/unit/schema/dynamodb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
* @group unit/parser/schema/
*/
import { DynamoDBStreamSchema } from '../../../src/schemas/dynamodb';
import dynamodbStreamEvent from '../../events/dynamoStreamEvent.json';
import { loadExampleEvent } from './utils';

describe('DynamoDB ', () => {
const dynamoStreamEvent = loadExampleEvent('dynamoStreamEvent.json');
it('should parse a stream of records', () => {
expect(DynamoDBStreamSchema.parse(dynamodbStreamEvent)).toEqual(
dynamodbStreamEvent
expect(DynamoDBStreamSchema.parse(dynamoStreamEvent)).toEqual(
dynamoStreamEvent
);
});
});
3 changes: 2 additions & 1 deletion packages/parser/tests/unit/schema/eventbridge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
*/

import { EventBridgeSchema } from '../../../src/schemas/eventbridge';
import eventBridgeEvent from '../../events/eventBridgeEvent.json';
import { loadExampleEvent } from './utils';

describe('EventBridge ', () => {
it('should parse eventbridge event', () => {
const eventBridgeEvent = loadExampleEvent('eventBridgeEvent.json');
expect(EventBridgeSchema.parse(eventBridgeEvent)).toEqual(eventBridgeEvent);
});
});
Loading