Skip to content

Commit 20cde95

Browse files
am29ddreamorosi
andauthored
feat(parser): add built-in schemas (#1788)
* add dynamodb schema * add alb * add parser to v2 build * fix test * add alb * add built-in schema * add more tests for schemas * remove index export * add cloudwatch with base64 zlip transform * add throw test case * formatting * add kafka schema * restructured tests * add vpc lattice and lattice v2 * s3 event notification should extend eventbridge * s3 sqs should extend from sqs * simplify cloudwatch extract from string * keep message as string, instead of empty object * fix detail type of eb and field names * remove duplicated entries * fix homepage URL in readme * improved test coverage * key and value are always present * cleanup unnecessary definitions, widen peerDep version req * Update packages/parser/src/schemas/cloudwatch.ts Co-authored-by: Andrea Amorosi <[email protected]> * clean up events, some fields are imaginary * fix api gw * fix broken IP addresses in examples * add more tests to api gw * fix apigw2 add more tests * add optional scopes to apigwv2 * add optional field back to api gw, stricter methods for vpc lattice * add test for messageId refinement * remove redundant entry * fix sqs * add dmarcPolicy for ses * added tests * moved cw function from kinesis, fix imports * add parser to build step in ci * use any safely here * removed console logs * name, add datetime to strings * narrow string to datetime * refine to url * imports, remove try/catch * add .js extension to imports * moved comment, fixed path * rename event filename to fix events --------- Co-authored-by: Andrea Amorosi <[email protected]>
1 parent f54e1b5 commit 20cde95

File tree

137 files changed

+4951
-27
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+4951
-27
lines changed

.github/actions/cached-node-modules/action.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@ runs:
4444
npm run build -w packages/parameters & \
4545
npm run build -w packages/idempotency & \
4646
npm run build -w packages/batch & \
47+
npm run build -w packages/parser & \
4748
npm run build -w packages/testing
4849
shell: bash

.github/workflows/reusable-run-linting-check-and-unit-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ jobs:
2525
with:
2626
nodeVersion: ${{ matrix.version }}
2727
- name: Run linting
28-
run: npm run lint -w packages/commons -w packages/logger -w packages/tracer -w packages/metrics -w packages/parameters -w packages/idempotency -w packages/batch
28+
run: npm run lint -w packages/commons -w packages/logger -w packages/tracer -w packages/metrics -w packages/parameters -w packages/idempotency -w packages/batch -w packages/parser
2929
- name: Run unit tests
30-
run: npm t -w packages/commons -w packages/logger -w packages/tracer -w packages/metrics -w packages/parameters -w packages/idempotency -w packages/batch
30+
run: npm t -w packages/commons -w packages/logger -w packages/tracer -w packages/metrics -w packages/parameters -w packages/idempotency -w packages/batch -w packages/parser
3131
check-examples:
3232
runs-on: ubuntu-latest
3333
env:

.npmignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
src
22
tests
3-
jest.config.js
3+
jest.config.cjs
44
tsconfig.json
55
.vscode
66
.github
@@ -13,7 +13,6 @@ coverage
1313
tslint.json
1414
tsconfig.json
1515
MakeFile
16-
jest.config.js
1716
.npmignore
1817
.eslintignore
1918
.huskyrc.js

docs/snippets/idempotency/samples/makeIdempotentJmes.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@
2727
},
2828
"body": "{\"user\":\"xyz\",\"productId\":\"123456789\"}",
2929
"isBase64Encoded": false
30-
}
30+
}

docs/snippets/idempotency/samples/workingWIthIdempotencyRequiredKeyError.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
"name": "foo",
55
"productId": 10000
66
}
7-
}
7+
}

docs/snippets/idempotency/samples/workingWIthIdempotencyRequiredKeySuccess.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
"name": "Foo"
55
},
66
"productId": 10000
7-
}
7+
}

docs/snippets/idempotency/samples/workingWithBatch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@
2323
"awsRegion": "us-east-2"
2424
}
2525
]
26-
}
26+
}

package-lock.json

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/parser/jest.config.js renamed to packages/parser/jest.config.cjs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,20 @@ module.exports = {
55
},
66
runner: 'groups',
77
preset: 'ts-jest',
8+
moduleNameMapper: {
9+
'^(\\.{1,2}/.*)\\.js$': '$1',
10+
},
811
transform: {
9-
'^.+\\.ts?$': 'ts-jest',
12+
'^.+\\.ts?$': ['ts-jest', {tsconfig: './tests/tsconfig.json'}],
13+
1014
},
1115
moduleFileExtensions: ['js', 'ts'],
1216
collectCoverageFrom: ['**/src/**/*.ts', '!**/node_modules/**'],
1317
testMatch: ['**/?(*.)+(spec|test).ts'],
1418
roots: ['<rootDir>/src', '<rootDir>/tests'],
1519
testPathIgnorePatterns: ['/node_modules/'],
1620
testEnvironment: 'node',
17-
coveragePathIgnorePatterns: ['/node_modules/', '/types/'],
21+
coveragePathIgnorePatterns: ['/node_modules/', '/types'],
1822
coverageThreshold: {
1923
global: {
2024
statements: 100,
@@ -24,5 +28,4 @@ module.exports = {
2428
},
2529
},
2630
coverageReporters: ['json-summary', 'text', 'lcov'],
27-
setupFiles: ['<rootDir>/tests/helpers/populateEnvironmentVariables.ts'],
2831
};

packages/parser/package.json

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,45 @@
22
"name": "@aws-lambda-powertools/parser",
33
"version": "0.0.0",
44
"description": "The parser package for the Powertools for AWS Lambda (TypeScript) library.",
5+
"author": {
6+
"name": "Amazon Web Services",
7+
"url": "https://aws.amazon.com"
8+
},
9+
"publishConfig": {
10+
"access": "restricted"
11+
},
512
"scripts": {
613
"test": "npm run test:unit",
714
"test:unit": "jest --group=unit --detectOpenHandles --coverage --verbose",
15+
"jest": "jest --detectOpenHandles --coverage --verbose",
816
"watch": "jest --watch",
9-
"build": "tsc --build --force",
17+
"build:cjs": "tsc --build tsconfig.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json",
18+
"build:esm": "tsc --build tsconfig.esm.json && echo '{ \"type\": \"module\" }' > lib/esm/package.json",
19+
"build": "npm run build:esm & npm run build:cjs",
1020
"lint": "eslint --ext .ts,.js --no-error-on-unmatched-pattern .",
1121
"lint-fix": "eslint --fix --ext .ts,.js --no-error-on-unmatched-pattern .",
12-
"prebuild": "rimraf ./lib",
1322
"prepack": "node ../../.github/scripts/release_patch_package_json.js ."
1423
},
15-
"author": {
16-
"name": "Amazon Web Services",
17-
"url": "https://aws.amazon.com"
18-
},
1924
"lint-staged": {
2025
"*.{js,ts}": "npm run lint-fix"
2126
},
22-
"homepage": "https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/packages/batch#readme",
27+
"homepage": "https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/packages/parser#readme",
2328
"license": "MIT-0",
24-
"main": "./lib/index.js",
25-
"types": "./lib/index.d.ts",
29+
"type": "module",
30+
"exports": {
31+
".": {
32+
"require": {
33+
"types": "./lib/cjs/index.d.ts",
34+
"default": "./lib/cjs/index.js"
35+
},
36+
"import": {
37+
"types": "./lib/esm/index.d.ts",
38+
"default": "./lib/esm/index.js"
39+
}
40+
}
41+
},
42+
"main": "./lib/cjs/index.js",
43+
"types": "./lib/cjs/index.d.ts",
2644
"files": [
2745
"lib"
2846
],
@@ -42,10 +60,8 @@
4260
"serverless",
4361
"nodejs"
4462
],
45-
"publishConfig": {
46-
"access": "restricted"
47-
},
48-
"devDependencies": {
49-
"zod": "^3.22.2"
63+
64+
"peerDependencies": {
65+
"zod": ">=3.x"
5066
}
51-
}
67+
}
File renamed without changes.

packages/parser/src/schemas/alb.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { z } from 'zod';
2+
3+
const AlbSchema = z.object({
4+
httpMethod: z.string(),
5+
path: z.string(),
6+
body: z.string(),
7+
isBase64Encoded: z.boolean(),
8+
headers: z.record(z.string(), z.string()).optional(),
9+
queryStringParameters: z.record(z.string(), z.string()).optional(),
10+
requestContext: z.object({
11+
elb: z.object({
12+
targetGroupArn: z.string(),
13+
}),
14+
}),
15+
});
16+
17+
const AlbMultiValueHeadersSchema = AlbSchema.extend({
18+
multiValueHeaders: z.record(z.string(), z.array(z.string())),
19+
multiValueQueryStringParameters: z.record(z.string(), z.array(z.string())),
20+
});
21+
22+
export { AlbSchema, AlbMultiValueHeadersSchema };

packages/parser/src/schemas/apigw.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { z } from 'zod';
2+
3+
const APIGatewayCert = z.object({
4+
clientCertPem: z.string(),
5+
subjectDN: z.string(),
6+
issuerDN: z.string(),
7+
serialNumber: z.string(),
8+
validity: z.object({
9+
notBefore: z.string(),
10+
notAfter: z.string(),
11+
}),
12+
});
13+
14+
const APIGatewayEventIdentity = z.object({
15+
accessKey: z.string().nullish(),
16+
accountId: z.string().nullish(),
17+
apiKey: z.string().nullish(),
18+
apiKeyId: z.string().nullish(),
19+
caller: z.string().nullish(),
20+
cognitoAuthenticationProvider: z.string().nullish(),
21+
cognitoAuthenticationType: z.string().nullish(),
22+
cognitoIdentityId: z.string().nullish(),
23+
cognitoIdentityPoolId: z.string().nullish(),
24+
principalOrgId: z.string().nullish(),
25+
sourceIp: z.string().ip().optional(),
26+
user: z.string().nullish(),
27+
userAgent: z.string().nullish(),
28+
userArn: z.string().nullish(),
29+
clientCert: APIGatewayCert.nullish(),
30+
});
31+
32+
const APIGatewayEventRequestContext = z
33+
.object({
34+
accountId: z.string(),
35+
apiId: z.string(),
36+
authorizer: z
37+
.object({
38+
claims: z.record(z.string(), z.any()).nullish(),
39+
scopes: z.array(z.string()).nullish(),
40+
})
41+
.nullish(),
42+
stage: z.string(),
43+
protocol: z.string(),
44+
identity: APIGatewayEventIdentity,
45+
requestId: z.string(),
46+
requestTime: z.string(),
47+
requestTimeEpoch: z.number(),
48+
resourceId: z.string().nullish(),
49+
resourcePath: z.string(),
50+
domainName: z.string().nullish(),
51+
domainPrefix: z.string().nullish(),
52+
extendedRequestId: z.string().nullish(),
53+
httpMethod: z.enum([
54+
'GET',
55+
'POST',
56+
'PUT',
57+
'PATCH',
58+
'DELETE',
59+
'HEAD',
60+
'OPTIONS',
61+
]),
62+
path: z.string(),
63+
connectedAt: z.number().nullish(),
64+
connectionId: z.string().nullish(),
65+
eventType: z.enum(['CONNECT', 'MESSAGE', 'DISCONNECT']).nullish(),
66+
messageDirection: z.string().nullish(),
67+
messageId: z.string().nullish(),
68+
routeKey: z.string().nullish(),
69+
operationName: z.string().nullish(),
70+
})
71+
.refine(
72+
(input) => {
73+
return (
74+
!input.messageId || (input.messageId && input.eventType === 'MESSAGE')
75+
);
76+
},
77+
{
78+
message: 'messageId is available only when `eventType` is MESSAGE',
79+
}
80+
);
81+
82+
const APIGatewayProxyEventSchema = z.object({
83+
version: z.string().optional(),
84+
authorizationToken: z.string().optional(),
85+
identitySource: z.string().optional(),
86+
methodArn: z.string().optional(),
87+
type: z.enum(['TOKEN', 'REQUEST']).optional(),
88+
resource: z.string(),
89+
path: z.string(),
90+
httpMethod: z.enum([
91+
'GET',
92+
'POST',
93+
'PUT',
94+
'PATCH',
95+
'DELETE',
96+
'HEAD',
97+
'OPTIONS',
98+
]),
99+
headers: z.record(z.string()).optional(),
100+
queryStringParameters: z.record(z.string()).optional(),
101+
multiValueHeaders: z.record(z.array(z.string())).optional(),
102+
multiValueQueryStringParameters: z.record(z.array(z.string())).optional(),
103+
requestContext: APIGatewayEventRequestContext,
104+
pathParameters: z.record(z.string()).optional().nullish(),
105+
stageVariables: z.record(z.string()).optional().nullish(),
106+
isBase64Encoded: z.boolean().optional(),
107+
body: z.string().optional(),
108+
});
109+
110+
export { APIGatewayProxyEventSchema, APIGatewayCert };

0 commit comments

Comments
 (0)