Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ body:
options:
- 24.x
- 22.x
- 20.x
validations:
required: true
- type: dropdown
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/quality_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
NODE_ENV: dev
strategy:
matrix:
version: [20, 22, 24]
version: [22, 24]
workspace: [
"packages/batch",
"packages/commons",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
NODE_ENV: dev
strategy:
matrix:
version: [20, 22, 24]
version: [22, 24]
workspace: [
"packages/batch",
"packages/commons",
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
packages/batch,
layers,
]
version: [20, 22, 24]
version: [22, 24]
arch: [x86_64, arm64]
fail-fast: false
steps:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- markdownlint-disable MD013 -->
# Powertools for AWS Lambda (TypeScript)

![NodeSupport](https://img.shields.io/static/v1?label=node&message=%2020|%2022&style=flat&logo=nodedotjs)
![NodeSupport](https://img.shields.io/static/v1?label=node&message=%2022|%2024&style=flat&logo=nodedotjs)
![GitHub Release](https://img.shields.io/github/v/release/aws-powertools/powertools-lambda-typescript?style=flat)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=aws-powertools_powertools-lambda-typescript&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=aws-powertools_powertools-lambda-typescript)
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=aws-powertools_powertools-lambda-typescript&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=aws-powertools_powertools-lambda-typescript)
Expand Down
1 change: 0 additions & 1 deletion docs/getting-started/lambda-layers.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ Change `{aws::region}` to your AWS region, e.g. `eu-west-1`, and run the followi
"CreatedDate": "2025-04-08T07:38:30.424+0000",
"Version": 24,
"CompatibleRuntimes": [
"nodejs20.x",
"nodejs22.x",
"nodejs24.x"
],
Expand Down
4 changes: 2 additions & 2 deletions docs/versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ Most AWS SDKs have underlying dependencies, such as language runtimes, AWS Lambd

The following terms are used to classify underlying third party dependencies:

* [**AWS Lambda Runtime**](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html): Examples include `nodejs20.x`, `python3.12`, etc.
* **Language Runtime**: Examples include Python 3.12, NodeJS 20, Java 17, .NET Core, etc.
* [**AWS Lambda Runtime**](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html): Examples include `nodejs22.x`, `python3.12`, etc.
* **Language Runtime**: Examples include Python 3.12, NodeJS 22, Java 17, .NET Core, etc.
* **Third party Library**: Examples include Pydantic, AWS X-Ray SDK, AWS Encryption SDK, Middy.js, etc.

Powertools for AWS Lambda follows the [AWS Lambda Runtime deprecation policy cycle](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtime-support-policy), when it comes to Language Runtime. This means we will stop supporting their respective deprecated Language Runtime _(e.g., `nodejs20.x`)_ without increasing the major SDK version.
Expand Down
4 changes: 2 additions & 2 deletions examples/app/cdk/function-with-logstream-construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type BindTableProps = {
*
* The function is created with the following properties:
* - `handler` set to `handler`
* - `runtime` set to `Runtime.NODEJS_20_X`
* - `runtime` set to `Runtime.NODEJS_22_X`
* - `tracing` set to `Tracing.ACTIVE`
* - `architecture` set to `Architecture.ARM_64`
* - `timeout` set to `Duration.seconds(30)`
Expand All @@ -60,7 +60,7 @@ export class FunctionWithLogGroup extends NodejsFunction {
super(scope, id, {
...props,
handler: 'handler',
runtime: Runtime.NODEJS_20_X,
runtime: Runtime.NODEJS_22_X,
tracing: Tracing.ACTIVE,
architecture: Architecture.ARM_64,
timeout: Duration.seconds(30),
Expand Down
2 changes: 1 addition & 1 deletion examples/snippets/commons/testingMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('function: getMetadata', async () => {
vi.stubEnv('AWS_LAMBDA_METADATA_API', '127.0.0.1:1234');
vi.stubEnv('AWS_LAMBDA_METADATA_TOKEN', 'test-token');

const payload = { runtime: 'nodejs20.x' };
const payload = { runtime: 'nodejs22.x' };
fetchMock.mockResolvedValue({
ok: true,
json: vi.fn().mockResolvedValue(payload),
Expand Down
2 changes: 1 addition & 1 deletion examples/snippets/idempotency/templates/tableCdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class IdempotencyStack extends Stack {
});

const fnHandler = new NodejsFunction(this, 'helloWorldFunction', {
runtime: Runtime.NODEJS_20_X,
runtime: Runtime.NODEJS_22_X,
handler: 'handler',
entry: 'src/index.ts',
environment: {
Expand Down
2 changes: 1 addition & 1 deletion examples/snippets/idempotency/templates/tableTerraform.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ resource "aws_dynamodb_table" "IdempotencyTable" {
resource "aws_lambda_function" "IdempotencyFunction" {
function_name = "IdempotencyFunction"
role = aws_iam_role.IdempotencyFunctionRole.arn
runtime = "nodejs20.x"
runtime = "nodejs22.x"
handler = "index.handler"
filename = "lambda.zip"
}
Expand Down
1 change: 0 additions & 1 deletion layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"test:unit": "vitest --run tests/unit",
"test:unit:coverage": "echo 'Not Implemented'",
"test:unit:types": "echo 'Not Implemented'",
"test:e2e:nodejs20x": "echo 'Not Implemented'",
"test:e2e:nodejs22x": "echo 'Not Implemented'",
"test:e2e:nodejs24x": "echo 'Not Implemented'",
"test:e2e": "vitest --run tests/e2e",
Expand Down
2 changes: 1 addition & 1 deletion layers/src/canary-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class CanaryStack extends Stack {
'../tests/e2e/layerPublisher.class.test.functionCode.ts'
),
handler: 'handler',
runtime: Runtime.NODEJS_20_X,
runtime: Runtime.NODEJS_22_X,
functionName: `canary-${suffix}`,
timeout: Duration.seconds(30),
bundling: {
Expand Down
6 changes: 1 addition & 5 deletions layers/src/layer-publisher-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@ export class LayerPublisherStack extends Stack {
this.lambdaLayerVersion = new LayerVersion(this, 'LambdaPowertoolsLayer', {
layerVersionName: props?.layerName,
description: `Powertools for AWS Lambda (TypeScript) version ${powertoolsPackageVersion}`,
compatibleRuntimes: [
Runtime.NODEJS_20_X,
Runtime.NODEJS_22_X,
Runtime.NODEJS_24_X,
],
compatibleRuntimes: [Runtime.NODEJS_22_X, Runtime.NODEJS_24_X],
license: 'MIT-0',
compatibleArchitectures: [Architecture.ARM_64, Architecture.X86_64],
code: Code.fromAsset(resolve(__dirname), {
Expand Down
2 changes: 1 addition & 1 deletion layers/tests/unit/layer-publisher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('Class: LayerPublisherStack', () => {
// Assess
template.resourceCountIs('AWS::Lambda::LayerVersion', 1);
template.hasResourceProperties('AWS::Lambda::LayerVersion', {
CompatibleRuntimes: ['nodejs20.x', 'nodejs22.x', 'nodejs24.x'],
CompatibleRuntimes: ['nodejs22.x', 'nodejs24.x'],
LicenseInfo: 'MIT-0',
/* CompatibleArchitectures: [
'x86_64',
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,6 @@
"*.md": "markdownlint-cli2 --fix"
},
"engines": {
"node": ">=20"
"node": ">=22"
}
}
1 change: 0 additions & 1 deletion packages/batch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"test:unit": "vitest --run",
"test:unit:coverage": "vitest --run tests/unit --coverage.enabled --coverage.thresholds.100 --coverage.include='src/**'",
"test:unit:types": "echo 'Not Implemented'",
"test:e2e:nodejs20x": "RUNTIME=nodejs20x vitest --run tests/e2e",
"test:e2e:nodejs22x": "RUNTIME=nodejs22x vitest --run tests/e2e",
"test:e2e:nodejs24x": "RUNTIME=nodejs24x vitest --run tests/e2e",
"test:e2e": "vitest --run tests/e2e",
Expand Down
2 changes: 1 addition & 1 deletion packages/commons/src/awsSdkUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const isSdkClient = (client: unknown): client is SdkClient =>
* The middleware will append the provided feature name and the current version of
* the Powertools for AWS Lambda library to the user agent string.
*
* @example "PT/Tracer/2.1.0 PTEnv/nodejs20x"
* @example "PT/Tracer/2.1.0 PTEnv/nodejs22x"
*
* @param feature The feature name to be added to the user agent
*
Expand Down
1 change: 0 additions & 1 deletion packages/event-handler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"test:unit": "vitest --run tests/unit",
"test:unit:coverage": "vitest --run tests/unit --coverage.enabled --coverage.thresholds.100 --coverage.include='src/**'",
"test:unit:types": "vitest --typecheck --run tests/types",
"test:e2e:nodejs20x": "RUNTIME=nodejs20x vitest run tests/e2e",
"test:e2e:nodejs22x": "RUNTIME=nodejs22x vitest run tests/e2e",
"test:e2e:nodejs24x": "RUNTIME=nodejs24x vitest run tests/e2e",
"test:e2e": "vitest run tests/e2e",
Expand Down
1 change: 0 additions & 1 deletion packages/idempotency/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"test:unit:coverage": "vitest --run tests/unit --coverage.enabled --coverage.thresholds.100 --coverage.include='src/**'",
"test:unit:types": "echo 'Not Implemented'",
"test:unit:watch": "vitest tests/unit",
"test:e2e:nodejs20x": "RUNTIME=nodejs20x vitest --run tests/e2e",
"test:e2e:nodejs22x": "RUNTIME=nodejs22x vitest --run tests/e2e",
"test:e2e:nodejs24x": "RUNTIME=nodejs24x vitest --run tests/e2e",
"test:e2e": "vitest --run tests/e2e",
Expand Down
140 changes: 68 additions & 72 deletions packages/idempotency/tests/e2e/durableIdempotent.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createHash } from 'node:crypto';
import { join } from 'node:path';
import {
getRuntimeKey,
invokeFunction,
TestStack,
} from '@aws-lambda-powertools/testing-utils';
Expand All @@ -12,85 +11,82 @@ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
import { IdempotencyTestNodejsFunctionAndDynamoTable } from '../helpers/resources.js';
import { RESOURCE_NAME_PREFIX } from './constants.js';

describe.skipIf(getRuntimeKey() === 'nodejs20x')(
'Idempotency E2E tests, durable functions',
() => {
const testStack = new TestStack({
stackNameProps: {
stackNamePrefix: RESOURCE_NAME_PREFIX,
testName: 'durable',
},
});
describe('Idempotency E2E tests, durable functions', () => {
const testStack = new TestStack({
stackNameProps: {
stackNamePrefix: RESOURCE_NAME_PREFIX,
testName: 'durable',
},
});

// Location of the lambda function code
const lambdaFunctionCodeFilePath = join(
__dirname,
'durableIdempotent.FunctionCode.ts'
);
// Location of the lambda function code
const lambdaFunctionCodeFilePath = join(
__dirname,
'durableIdempotent.FunctionCode.ts'
);

let functionNameDurable: string;
let tableNameDurable: string;
new IdempotencyTestNodejsFunctionAndDynamoTable(
testStack,
{
function: {
entry: lambdaFunctionCodeFilePath,
handler: 'handlerDurable',
durableConfig: {
executionTimeout: Duration.minutes(5),
retentionPeriod: Duration.days(1),
},
let functionNameDurable: string;
let tableNameDurable: string;
new IdempotencyTestNodejsFunctionAndDynamoTable(
testStack,
{
function: {
entry: lambdaFunctionCodeFilePath,
handler: 'handlerDurable',
durableConfig: {
executionTimeout: Duration.minutes(5),
retentionPeriod: Duration.days(1),
},
},
{
nameSuffix: 'durable',
}
);

const ddb = new DynamoDBClient({});
},
{
nameSuffix: 'durable',
}
);

beforeAll(async () => {
// Deploy the stack
await testStack.deploy();
const ddb = new DynamoDBClient({});

// Get the actual function names from the stack outputs
functionNameDurable = testStack.findAndGetStackOutputValue('durableFn');
tableNameDurable = testStack.findAndGetStackOutputValue('durableTable');
});
beforeAll(async () => {
// Deploy the stack
await testStack.deploy();

it('calls an idempotent durable function and always returns the same result when called multiple times', async () => {
// Prepare
const payload = {
foo: 'bar',
};
const payloadHash = createHash('md5')
.update(JSON.stringify(payload))
.digest('base64');
// Get the actual function names from the stack outputs
functionNameDurable = testStack.findAndGetStackOutputValue('durableFn');
tableNameDurable = testStack.findAndGetStackOutputValue('durableTable');
});

// Act
await invokeFunction({
functionName: `${functionNameDurable}:$LATEST`,
times: 2,
invocationMode: 'SEQUENTIAL',
payload,
});
it('calls an idempotent durable function and always returns the same result when called multiple times', async () => {
// Prepare
const payload = {
foo: 'bar',
};
const payloadHash = createHash('md5')
.update(JSON.stringify(payload))
.digest('base64');

// Assess
const idempotencyRecords = await ddb.send(
new ScanCommand({
TableName: tableNameDurable,
})
);
expect(idempotencyRecords.Items?.length).toEqual(1);
expect(idempotencyRecords.Items?.[0].id).toEqual(
`${functionNameDurable}#${payloadHash}`
);
// Act
await invokeFunction({
functionName: `${functionNameDurable}:$LATEST`,
times: 2,
invocationMode: 'SEQUENTIAL',
payload,
});

afterAll(async () => {
if (!process.env.DISABLE_TEARDOWN) {
await testStack.destroy();
}
});
}
);
// Assess
const idempotencyRecords = await ddb.send(
new ScanCommand({
TableName: tableNameDurable,
})
);
expect(idempotencyRecords.Items?.length).toEqual(1);
expect(idempotencyRecords.Items?.[0].id).toEqual(
`${functionNameDurable}#${payloadHash}`
);
});

afterAll(async () => {
if (!process.env.DISABLE_TEARDOWN) {
await testStack.destroy();
}
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Reserved variables
process.env._X_AMZN_TRACE_ID = '1-abcdef12-3456abcdef123456abcdef12';
process.env.AWS_LAMBDA_FUNCTION_NAME = 'my-lambda-function';
process.env.AWS_EXECUTION_ENV = 'nodejs20.x';
process.env.AWS_EXECUTION_ENV = 'nodejs22.x';
process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE = '128';
if (
process.env.AWS_REGION === undefined &&
Expand Down
1 change: 0 additions & 1 deletion packages/kafka/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"test:unit": "vitest --run",
"test:unit:coverage": "vitest --run tests/unit --coverage.enabled --coverage.thresholds.100 --coverage.include='src/**'",
"test:unit:types": "echo 'Not Implemented'",
"test:e2e:nodejs20x": "echo \"Not implemented\"",
"test:e2e:nodejs22x": "echo \"Not implemented\"",
"test:e2e:nodejs24x": "echo \"Not implemented\"",
"test:e2e": "echo \"Not implemented\"",
Expand Down
1 change: 0 additions & 1 deletion packages/logger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"test:unit:coverage": "vitest --run tests/unit --coverage.enabled --coverage.thresholds.100 --coverage.include='src/**'",
"test:unit:types": "echo 'Not Implemented'",
"test:unit:watch": "vitest tests/unit",
"test:e2e:nodejs20x": "RUNTIME=nodejs20x vitest --run tests/e2e",
"test:e2e:nodejs22x": "RUNTIME=nodejs22x vitest --run tests/e2e",
"test:e2e:nodejs24x": "RUNTIME=nodejs24x vitest --run tests/e2e",
"test:e2e": "vitest --run tests/e2e",
Expand Down
1 change: 0 additions & 1 deletion packages/metrics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"test:unit:coverage": "vitest --run tests/unit --coverage.enabled --coverage.thresholds.100 --coverage.include='src/**'",
"test:unit:types": "echo 'Not Implemented'",
"test:unit:watch": "vitest tests/unit",
"test:e2e:nodejs20x": "RUNTIME=nodejs20x vitest --run tests/e2e",
"test:e2e:nodejs22x": "RUNTIME=nodejs22x vitest --run tests/e2e",
"test:e2e:nodejs24x": "RUNTIME=nodejs24x vitest --run tests/e2e",
"test:e2e": "vitest --run tests/e2e",
Expand Down
1 change: 0 additions & 1 deletion packages/parameters/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"test:unit:coverage": "vitest --run tests/unit --coverage.enabled --coverage.thresholds.100 --coverage.include='src/**'",
"test:unit:types": "vitest --run tests/types --typecheck",
"test:unit:watch": "vitest tests/unit",
"test:e2e:nodejs20x": "RUNTIME=nodejs20x vitest --run tests/e2e",
"test:e2e:nodejs22x": "RUNTIME=nodejs22x vitest --run tests/e2e",
"test:e2e:nodejs24x": "RUNTIME=nodejs24x vitest --run tests/e2e",
"test:e2e": "vitest --run tests/e2e",
Expand Down
Loading
Loading