Skip to content

Commit

Permalink
docs(parser): add utility readme (#2360)
Browse files Browse the repository at this point in the history
* init parser package

* add init config

* feat(logger): Support for external observability providers (#1511)

* Updated formatAttributes for additional parameters and LogItem return type

* Updated the unit tests to pass with new formatter

* Updated Powertool named objects to Powertools

* Updated tests to match new naming consistency

* Updated for tests for new naming consistency

* Updated formatter for new design decisions

* Update Logger for ephemeral attributes

* Update bringYourOwnFormatter documentation to match new formatter

---------

Co-authored-by: erikayao93 <[email protected]>

* chore(logger): PowertoolsLogFormatter docstring and variable naming update (#1585)

* Updated formatAttributes for additional parameters and LogItem return type

* Updated the unit tests to pass with new formatter

* Updated Powertool named objects to Powertools

* Updated tests to match new naming consistency

* Updated for tests for new naming consistency

* Updated formatter for new design decisions

* Update Logger for ephemeral attributes

* Update bringYourOwnFormatter documentation to match new formatter

* Fixed incorrect return type, renamed variable for consistency

* feat(logger): Support for external observability providers (#1511)

* Updated formatAttributes for additional parameters and LogItem return type

* Updated the unit tests to pass with new formatter

* Updated Powertool named objects to Powertools

* Updated tests to match new naming consistency

* Updated for tests for new naming consistency

* Updated formatter for new design decisions

* Update Logger for ephemeral attributes

* Update bringYourOwnFormatter documentation to match new formatter

---------

Co-authored-by: erikayao93 <[email protected]>

* chore(logger): PowertoolsLogFormatter docstring and variable naming update (#1585)

* Updated formatAttributes for additional parameters and LogItem return type

* Updated the unit tests to pass with new formatter

* Updated Powertool named objects to Powertools

* Updated tests to match new naming consistency

* Updated for tests for new naming consistency

* Updated formatter for new design decisions

* Update Logger for ephemeral attributes

* Update bringYourOwnFormatter documentation to match new formatter

* Fixed incorrect return type, renamed variable for consistency

* chore(maintenance): bump dependencies & drop nodejs14x (#1687)

* chore: update release script to mark all utilities as alpha

* chore: restore version to ease conflicts

* chore: release version change

* chore: release version change

* chore(maintenance): remove `createLogger` and `createTracer` helpers (#1722)

* chore(maintenance): bump dependencies & drop nodejs14x (#1687)

* chore: add pre-release script

* chore: restore deps

* chore: added v2 shim

* chore(maintenance): remove logger and tracer helper function

* chore: remove imports

* chore: fix deps & versions

* tests: moved unit tests

* tests: move logger tests

* chore: added v2 shim

* chore: added v2 shim

* feat(logger): add esmodule support (#1734)

* feat(logger): add esm build output

* fix(Logger): Remove barrel files update references

* test(Logger): update jest/ts-jest to use ESM

* chore(Logger): remove unused lodash.merge

* fix(logger): reinstate lodash.merge

* chore(logger): revert TS assertion

* chore(logger): revert format changes

* chore(logger): update postbuild to remove incremental tsbuildinfo files

* fix(logger): correct reference to types output

* feat(logging): add middleware export

* chore(logger): replace postbuild script with echo statement

* feat(logger): add typesVersions property and barrel files to /types

* chore(logger): file not used, can be added back if needed

* chore(logger): add space back to README

* chore(logger): revert space in README

* feat(commons): add esmodule support (#1735)

* chore(logger): adapt logger to commons exports

* feat(commons): add esmodule support

* chore: address sonar findings

* chore(commons): exported version

* chore: fixed imports in examples

* chore(parameters): fixed imports

* chore(metrics): fixed imports

* chore(tracer): fixed imports

* chore(idempotency): fixed imports

* chore(commons): test coverage

* chore(batch): fix imports

* feat(parameters): add esmodule support (#1736)

* feat(batch): add esmodule support (#1737)

* feat(internal): add esmodule support (#1738)

* feat(testing): add esmodule support

* chore(all): update imports

* feat(metrics): add esmodule support (#1739)

* feat(tracer): add esmodule support (#1741)

* feat(tracer): add esmodule support

* chore(docs): update imports

* feat(idempotency): add esmodule support  (#1743)

* feat(idempotency): add esmodule support

* chore(metrics): fix import

* chore(ci): v2 release line

* chore(ci): fix alpha versioning pre-release

* docs(maintenance): add processes tab (#1747)

* docs(maintenance): update mkdocs to support tabs

* chore(ci): add parallel test npm script

* chore(ci): add jest command

* docs(maintenance): add testing page to navbar

* docs(maintenance): add contributing info

* chore: update roadmap

* chore: update release drafter workflow to allow for manual trigger

* fix formatting

* docs: maintainers handbook

* chore: link to new location

* fix links

* Update docs/maintainers.md

Co-authored-by: Alexander Schueren <[email protected]>

---------

Co-authored-by: Alexander Schueren <[email protected]>

* chore(tracer): update warning to better format segment name (#1750)

* chore(tracer): update warning in Tracer to better format segment name

* chore: linting

* chore(internal): remove outdated notice files (#1752)

* chore(maintenance): set `removeComments` to` false` in `tsconfig.json` (#1754)

* chore(docs): add invisible unicode char to decorator docs (#1755)

* chore: remove extra comma

* chore(docs): upgrade doc intro

* chore(ci): add workflow to publish v2 docs on merge (#1756)

* chore(docs): upgrade doc intro

* chore(ci): remove mike commands

* chore(ci): upgrade mkdocs

* feat(logger): align sampling debug logs feature implementation with the other runtimes (#1744)

* test(logger): remove logsSampled field, add default sampleRateValue

* test(logger): add tests for sampling debug logs feature

* feat(logger): change implementation to make sampling decision at per-function level

* refactor(logger): remove redundant createLogger method

* refactor(logger): remove getSampleRateValue method

* test(logger): improve tests

* refactor(logger): return createLogger() back with the detailed comment of the method importance

* test(logger): add constructor/custom config/env var priority tests for sampling rate feature, improve description

* refactor(logger): address review comments

* feat(logger): add refreshSampleRateCalculation method and tests

* test(logger): adjust end-to-end tests

* chore(logger): refactor types and interfaces (#1758)

* chore(logger): refactor types and interfaces

* chore: grouped type files

* chore: fix code smell

* chore: fix ci

* chore: fix ci

* chore(maintenance): bump Middy v4 & run tests (#1760)

* chore(parameters): fix esm bundling

* chore(parameters): refactor provider constructor to init client as needed (#1757)

* chore(parameters): refactor provider constructor to init client as needed

* chore(parameters): moved client instrumentation up in baseprovider

* chore(parameters): fix code smells

* chore(parameters): fix code smells

* chore(parameters): change declare client param

* chore(commons): update Powertools UA middleware detection (#1762)

* chore(commons): fix double ua detection

* chore(commons): fix unit test

* chore(layers) widen version check in e2e

* chore(maintenance): enable `isolatedModules` and isolate cache (#1765)

* chore(layers) widen version check in e2e

* chore(maintenance): enable isolatedModules

* chore: remove redundant comments from tsconfig

* chore: changed path of tsbuild cache

* fix: idempotency types

* chore(idempotency): refactor aws sdk init logic (#1768)

* build(tracer): bump aws-xray-sdk-core to latest

* build(maintenance): bump aws sdk dev dependencies

* chore(logger): set default UTC timezone (#1775)

* chore(parameters): add export types

* chore(logger): set default utc timezone

* chore(logger): pass down envvarsservice to log formatter

* 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]>

* feat(parser): add schema envelopes (#1815)

* first envelope

* add abstract class

* add tests

* add more tests

* fix tests

* add envelopes

* add middy parser

* minor schema changes

* add more envelopes and tests, refactored utils to autocomplete event files

* simplified check

* remove middleware from this branch

* refactored from class to function envelopes

* removed parser tests, should be in another branch

* add parser to pre push

* consistent naming

* feat(parser): implement middy parser middleware (#1823)

* add middy middleware

* add type to imports

* remove schema type, stick with unkown

* feat(parser): implement parser decorator (#1831)

* feat(parser): add types for built-in schemas (#1838)

* add types for built-in schemas

* fixed imports

* only use top level schema

* chore(parser): add parser subpath exports to package.json (#2179)

* add exports and type version to package json, including index.js

* use index.js as import for coverage

* use package lock from main

* fix envelope path and add types to exports

* use explicit exports instead of *

* import type

* make export types explicit

* adjust imports in tests for coverage, removed unused exports

* remove duplicate imports

* feat(parser): implement `safeParse` option (#2244)

* first draft on safeParse with major refactoring

* add safeParse

* fixed sns tests

* bump coverage

* remove throw error and return ParsedResult

* remove one level to reduce complexity score

* make static methods readonly

* simplified cryptic  ternary operation into something readble

* Update packages/parser/src/parserDecorator.ts

Co-authored-by: Andrea Amorosi <[email protected]>

* merged

* simplify export

* add invisible character for decorator rendering

* fix docs and tests

* Update packages/parser/src/parserDecorator.ts

Co-authored-by: Andrea Amorosi <[email protected]>

* add comment with description

* remove context

* remove unintentional safeParse export

* add examples to parse standalone function

---------

Co-authored-by: Andrea Amorosi <[email protected]>

* refresh package lock after merge

* docs(parser): add docs for parser utility (#1835)

* WIP: parser

* fix test imports

* remove unnecessary exports

* add custom validation

* remove unnecessary export

* add warning

* remove duplicate imports

* add types and error handlig

* remove comment from annotations

* minor changes

* revert merge changes

* merged package-lock

* Update docs/utilities/parser.md

Co-authored-by: Andrea Amorosi <[email protected]>

* Update docs/utilities/parser.md

Co-authored-by: Andrea Amorosi <[email protected]>

* adjust imports to new implementation

* add safeParse

* fixed line highlight

* typo

* revert index.md, add private scope to snippets packagef

* Update docs/utilities/parser.md

Co-authored-by: Andrea Amorosi <[email protected]>

* add parser to main, fixed zod install command

* fix callout indent

* fix tooltip

---------

Co-authored-by: Andrea Amorosi <[email protected]>

* feat(parser): add custom parse error (#2339)

* chore: remove rebase leftovers

* docs(parser): add utility readme

---------

Co-authored-by: Alexander Melnyk <[email protected]>
Co-authored-by: Alexander Melnyk <[email protected]>
Co-authored-by: Erika Yao <[email protected]>
Co-authored-by: erikayao93 <[email protected]>
Co-authored-by: Ant Stanley <[email protected]>
Co-authored-by: Sergei Cherniaev <[email protected]>
  • Loading branch information
7 people authored Apr 15, 2024
1 parent 9bf9ac8 commit 4f526ec
Show file tree
Hide file tree
Showing 196 changed files with 9,652 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .github/scripts/release_patch_package_json.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,4 @@ const betaPackages = [];
} catch (err) {
throw err;
}
})();
})();
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ tmp

# TS build files
tsconfig.tsbuildinfo
.tsbuildinfo
.tsbuildinfo
3 changes: 2 additions & 1 deletion .husky/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ npm t \
-w packages/metrics \
-w packages/tracer \
-w packages/idempotency \
-w packages/parameters
-w packages/parameters \
-w packages/parser
3 changes: 1 addition & 2 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
src
tests
jest.config.js
tsconfig.json
.vscode
.github
Expand All @@ -13,7 +12,7 @@ coverage
tslint.json
tsconfig.json
MakeFile
jest.config.js
jest.config.cjs
.npmignore
.eslintignore
.huskyrc.js
Expand Down
6 changes: 3 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ You can use Powertools for AWS Lambda (TypeScript) by installing it with your fa
| **[Parameters (AppConfig)](./utilities/parameters.md#install)** | **`npm i @aws-lambda-powertools/parameters @aws-sdk/client-appconfigdata`**{.copyMe}:clipboard: | |
| **[Parser](./utilities/parser.md#install)** | **`npm i @aws-lambda-powertools/parser zod@~3`**{.copyMe}:clipboard: | |


=== "Lambda Layer"

You can add our layer both in the [AWS Lambda Console _(under `Layers`)_](https://eu-west-1.console.aws.amazon.com/lambda/home#/add/layer){target="_blank"}, or via your favorite infrastructure as code framework with the ARN value.
Expand Down Expand Up @@ -325,11 +324,12 @@ Core utilities such as Tracing, Logging, and Metrics will be available across al
| [Parameters](./utilities/parameters.md) | High-level functions to retrieve one or more parameters from AWS SSM Parameter Store, AWS Secrets Manager, AWS AppConfig, and Amazon DynamoDB |
| [Idempotency](./utilities/idempotency.md) | Class method decorator, Middy middleware, and function wrapper to make your Lambda functions idempotent and prevent duplicate execution based on payload content. |
| [Batch Processing](./utilities/batch.md) | Utility to handle partial failures when processing batches from Amazon SQS, Amazon Kinesis Data Streams, and Amazon DynamoDB Streams. |
| [Parser](./utilities/parser.md) | Utility to parse and validate AWS Lambda event payloads using Zod, a TypeScript-first schema declaration and validation library. |

## Environment variables

???+ info
Explicit parameters take precedence over environment variables
Explicit parameters take precedence over environment variables

| Environment variable | Description | Utility | Default |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ------------------- |
Expand Down Expand Up @@ -438,4 +438,4 @@ These are our core principles to guide our decision making.
- __Keep it lean__. Additional dependencies are carefully considered for security and ease of maintenance, and prevent negatively impacting startup time.
- __We strive for backwards compatibility__. New features and changes should keep backwards compatibility. If a breaking change cannot be avoided, the deprecation and migration process should be clearly defined.
- __We work backwards from the community__. We aim to strike a balance of what would work best for 80% of customers. Emerging practices are considered and discussed via Requests for Comment (RFCs)
- __Progressive__. Utilities are designed to be incrementally adoptable for customers at any stage of their Serverless journey. They follow language idioms and their community’s common practices.
- __Progressive__. Utilities are designed to be incrementally adoptable for customers at any stage of their Serverless journey. They follow language idioms and their community’s common practices.
4 changes: 3 additions & 1 deletion docs/snippets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@
"@aws-sdk/client-secrets-manager": "^3.554.0",
"@aws-sdk/client-ssm": "^3.554.0",
"@aws-sdk/util-dynamodb": "^3.554.0",
"@middy/core": "^4.7.0",
"aws-sdk": "^2.1598.0",
"aws-sdk-client-mock": "^4.0.0",
"aws-sdk-client-mock-jest": "^4.0.0",
"axios": "^1.6.8",
"hashi-vault-js": "^0.4.14"
"hashi-vault-js": "^0.4.14",
"zod": "^3.22.4"
}
}
35 changes: 35 additions & 0 deletions docs/snippets/parser/decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Context } from 'aws-lambda';
import type { LambdaInterface } from '@aws-lambda-powertools/commons/types';
import { parser } from '@aws-lambda-powertools/parser';
import { z } from 'zod';
import { Logger } from '@aws-lambda-powertools/logger';

const logger = new Logger();

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(
z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
})
),
optionalField: z.string().optional(),
});

type Order = z.infer<typeof orderSchema>;

class Lambda implements LambdaInterface {
@parser({ schema: orderSchema })
public async handler(event: Order, _context: Context): Promise<void> {
// event is now typed as Order
for (const item of event.items) {
logger.info('Processing item', { item });
}
}
}

const myFunction = new Lambda();
export const handler = myFunction.handler.bind(myFunction);
36 changes: 36 additions & 0 deletions docs/snippets/parser/envelopeDecorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Context } from 'aws-lambda';
import type { LambdaInterface } from '@aws-lambda-powertools/commons/types';
import { parser } from '@aws-lambda-powertools/parser';
import { z } from 'zod';
import { EventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { Logger } from '@aws-lambda-powertools/logger';

const logger = new Logger();

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(
z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
})
),
optionalField: z.string().optional(),
});

type Order = z.infer<typeof orderSchema>;

class Lambda implements LambdaInterface {
@parser({ schema: orderSchema, envelope: EventBridgeEnvelope }) // (1)!
public async handler(event: Order, _context: Context): Promise<void> {
// event is now typed as Order
for (const item of event.items) {
logger.info('Processing item', item); // (2)!
}
}
}

const myFunction = new Lambda();
export const handler = myFunction.handler.bind(myFunction);
37 changes: 37 additions & 0 deletions docs/snippets/parser/envelopeMiddy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { Context } from 'aws-lambda';
import { parser } from '@aws-lambda-powertools/parser/middleware';
import { z } from 'zod';
import middy from '@middy/core';
import { EventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { Logger } from '@aws-lambda-powertools/logger';

const logger = new Logger();

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(
z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
})
),
optionalField: z.string().optional(),
});

type Order = z.infer<typeof orderSchema>;

const lambdaHandler = async (
event: Order,
_context: Context
): Promise<void> => {
for (const item of event.items) {
// item is parsed as OrderItem
logger.info('Processing item', { item });
}
};

export const handler = middy(lambdaHandler).use(
parser({ schema: orderSchema, envelope: EventBridgeEnvelope })
);
21 changes: 21 additions & 0 deletions docs/snippets/parser/examplePayload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": "0",
"id": "6a7e8feb-b491-4cf7-a9f1-bf3703467718",
"detail-type": "OrderPurchased",
"source": "OrderService",
"account": "111122223333",
"time": "2020-10-22T18:43:48Z",
"region": "us-west-1",
"resources": ["some_additional"],
"detail": {
"id": 10876546789,
"description": "My order",
"items": [
{
"id": 1015938732,
"quantity": 1,
"description": "item xpto"
}
]
}
}
40 changes: 40 additions & 0 deletions docs/snippets/parser/extend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { Context } from 'aws-lambda';
import type { LambdaInterface } from '@aws-lambda-powertools/commons/types';
import { parser } from '@aws-lambda-powertools/parser';
import { z } from 'zod';
import { EventBridgeSchema } from '@aws-lambda-powertools/parser/schemas';
import { Logger } from '@aws-lambda-powertools/logger';

const logger = new Logger();

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(
z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
})
),
optionalField: z.string().optional(),
});

const orderEventSchema = EventBridgeSchema.extend({
detail: orderSchema, // (1)!
});

type OrderEvent = z.infer<typeof orderEventSchema>;

class Lambda implements LambdaInterface {
@parser({ schema: orderEventSchema }) // (2)!
public async handler(event: OrderEvent, _context: Context): Promise<void> {
for (const item of event.detail.items) {
// process OrderItem
logger.info('Processing item', { item }); // (3)!
}
}
}

const myFunction = new Lambda();
export const handler = myFunction.handler.bind(myFunction);
33 changes: 33 additions & 0 deletions docs/snippets/parser/manual.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { Context } from 'aws-lambda';
import { z } from 'zod';
import { EventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { EventBridgeSchema } from '@aws-lambda-powertools/parser/schemas';
import type { EventBridgeEvent } from '@aws-lambda-powertools/parser/types';
import { Logger } from '@aws-lambda-powertools/logger';

const logger = new Logger();

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(
z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
})
),
optionalField: z.string().optional(),
});
type Order = z.infer<typeof orderSchema>;

export const handler = async (
event: EventBridgeEvent,
_context: Context
): Promise<void> => {
const parsedEvent = EventBridgeSchema.parse(event); // (1)!
logger.info('Parsed event', parsedEvent);

const orders: Order = EventBridgeEnvelope.parse(event, orderSchema); // (2)!
logger.info('Parsed orders', orders);
};
35 changes: 35 additions & 0 deletions docs/snippets/parser/manualSafeParse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Context } from 'aws-lambda';
import { z } from 'zod';
import { EventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { EventBridgeSchema } from '@aws-lambda-powertools/parser/schemas';
import type { EventBridgeEvent } from '@aws-lambda-powertools/parser/types';
import { Logger } from '@aws-lambda-powertools/logger';

const logger = new Logger();

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(
z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
})
),
optionalField: z.string().optional(),
});

export const handler = async (
event: EventBridgeEvent,
_context: Context
): Promise<void> => {
const parsedEvent = EventBridgeSchema.safeParse(event); // (1)!
parsedEvent.success
? logger.info('Event parsed successfully', parsedEvent.data)
: logger.error('Event parsing failed', parsedEvent.error);
const parsedEvenlope = EventBridgeEnvelope.safeParse(event, orderSchema); // (2)!
parsedEvenlope.success
? logger.info('Event envelope parsed successfully', parsedEvenlope.data)
: logger.error('Event envelope parsing failed', parsedEvenlope.error);
};
36 changes: 36 additions & 0 deletions docs/snippets/parser/middy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Context } from 'aws-lambda';
import { parser } from '@aws-lambda-powertools/parser/middleware';
import { z } from 'zod';
import middy from '@middy/core';
import { Logger } from '@aws-lambda-powertools/logger';

const logger = new Logger();

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(
z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
})
),
optionalField: z.string().optional(),
});

type Order = z.infer<typeof orderSchema>;

const lambdaHandler = async (
event: Order,
_context: Context
): Promise<void> => {
for (const item of event.items) {
// item is parsed as OrderItem
logger.info('Processing item', { item });
}
};

export const handler = middy(lambdaHandler).use(
parser({ schema: orderSchema })
);
21 changes: 21 additions & 0 deletions docs/snippets/parser/refine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { z } from 'zod';

const orderItemSchema = z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
});

export const orderSchema = z
.object({
id: z.number().positive(),
description: z.string(),
items: z.array(orderItemSchema).refine((items) => items.length > 0, {
message: 'Order must have at least one item', // (1)!
}),
optionalField: z.string().optional(),
})
.refine((order) => order.id > 100 && order.items.length > 100, {
message:
'All orders with more than 100 items must have an id greater than 100', // (2)!
});
Loading

0 comments on commit 4f526ec

Please sign in to comment.