From 6b9b1bcb9baf4b3d8e0e5ec6709594aca09bb033 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Tue, 14 Nov 2023 11:36:32 +0100 Subject: [PATCH] feat(maintenance): add support for nodejs20.x runtime (#1790) * feat(maintenance): support nodejs20.x runtime * tests(metrics): fix object ordering in tests * build(testing): bump cdk * build(maintenance): revert aws-cdk-lib to support nodejs14 * tests(maintenance): set runtime with family * chore(docs): patch runtime in cdk * chore(docs): patch runtime in cdk * chore(maintenance): increment version in commons ahead of release --- .devcontainer/Dockerfile | 5 +- .devcontainer/devcontainer.json | 5 +- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + .../actions/cached-node-modules/action.yml | 5 +- .github/workflows/make-release.yml | 2 +- .github/workflows/make-v2-release.yml | 2 +- .github/workflows/publish_layer.yml | 2 +- .github/workflows/reusable-publish-docs.yml | 2 +- ...sable-run-linting-check-and-unit-tests.yml | 8 +- .../workflows/reusable_deploy_layer_stack.yml | 2 +- .github/workflows/run-e2e-tests.yml | 6 +- .nvmrc | 2 +- docs/contributing/setup.md | 4 +- docs/contributing/testing.md | 2 +- docs/core/logger.md | 2 +- docs/core/metrics.md | 2 +- docs/core/tracer.md | 2 +- .../batch/templates/sam/dynamodb.yaml | 2 +- .../snippets/batch/templates/sam/kinesis.yaml | 2 +- docs/snippets/batch/templates/sam/sqs.yaml | 2 +- .../idempotency/templates/tableCdk.ts | 2 +- .../idempotency/templates/tableSam.yaml | 2 +- .../idempotency/templates/tableTerraform.tf | 2 +- docs/utilities/idempotency.md | 2 +- docs/utilities/parameters.md | 2 +- examples/cdk/package.json | 4 +- examples/cdk/src/example-stack.ts | 4 +- examples/sam/template.yaml | 2 +- layers/package.json | 2 +- layers/src/layer-publisher-stack.ts | 3 +- layers/tests/unit/layer-publisher.test.ts | 7 +- package-lock.json | 42 +-- packages/batch/package.json | 1 + .../helpers/populateEnvironmentVariables.ts | 2 +- packages/commons/src/version.ts | 2 +- packages/idempotency/package.json | 1 + .../tests/e2e/idempotentDecorator.test.ts | 7 - packages/logger/package.json | 1 + .../formatter/PowertoolLogFormatter.test.ts | 283 +++++++----------- packages/metrics/package.json | 1 + .../e2e/basicFeatures.decorators.test.ts | 10 +- .../tests/e2e/basicFeatures.manual.test.ts | 6 +- .../metrics/tests/helpers/metricsUtils.ts | 10 +- packages/parameters/package.json | 1 + packages/testing/package.json | 4 +- packages/testing/src/constants.ts | 5 +- packages/tracer/package.json | 1 + 47 files changed, 215 insertions(+), 254 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 65dc112db..071a30e01 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,12 +1,15 @@ # See here for image contents: https://github.com/microsoft/vscode-dev-containers/blob/v0.212.0/containers/javascript-node/.devcontainer/base.Dockerfile # [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster -ARG VARIANT="18-bullseye" +ARG VARIANT="20-bullseye" FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT} # This section to install additional OS packages. RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y install --no-install-recommends bash-completion +# Install fnm to manage Node.js versions +RUN curl -fsSL https://fnm.vercel.app/install | bash -s + RUN wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip \ && unzip aws-sam-cli-linux-x86_64.zip -d sam-installation \ && sudo ./sam-installation/install \ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e1401b638..f9033f03d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,7 @@ // Append -bullseye or -buster to pin to an OS version. // Use -bullseye variants on local arm64/Apple Silicon. "args": { - "VARIANT": "18-bullseye" + "VARIANT": "20-bullseye" } }, "customizations": { @@ -16,8 +16,7 @@ "extensions": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", - "firsttris.vscode-jest-runner", - "amazonwebservices.aws-toolkit-vscode" + "firsttris.vscode-jest-runner" ], "vscode": { "git.enableCommitSigning": true diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c9fbf5216..819d2f3d5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -67,6 +67,7 @@ body: attributes: label: AWS Lambda function runtime options: + - 20.x - 18.x - 16.x - 14.x diff --git a/.github/actions/cached-node-modules/action.yml b/.github/actions/cached-node-modules/action.yml index d86c8d7b1..42d5db19e 100644 --- a/.github/actions/cached-node-modules/action.yml +++ b/.github/actions/cached-node-modules/action.yml @@ -1,9 +1,9 @@ name: 'Cached Node Modules' description: 'A simple action to cache node_modules or install them if they are not cached' inputs: - nodeVersion: # id of input + nodeVersion: # id of input description: 'Node.js version to use in the cache key' - default: '18' + default: '20' outputs: cache-hit: description: "Whether the cache was hit or not" @@ -12,6 +12,7 @@ runs: using: "composite" steps: - name: Install npm + # We need to keep this npm version until we drop Node.js 16 support because Node.js 16 doesn't support npm 10 run: npm i -g npm@next-9 shell: bash - name: Cache node modules diff --git a/.github/workflows/make-release.yml b/.github/workflows/make-release.yml index 32ee9c090..122e3844d 100644 --- a/.github/workflows/make-release.yml +++ b/.github/workflows/make-release.yml @@ -26,7 +26,7 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: "18" + node-version: "20" cache: "npm" - name: Setup auth tokens run: | diff --git a/.github/workflows/make-v2-release.yml b/.github/workflows/make-v2-release.yml index f590a624b..0c20a1686 100644 --- a/.github/workflows/make-v2-release.yml +++ b/.github/workflows/make-v2-release.yml @@ -21,7 +21,7 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: '18' + node-version: '20' cache: 'npm' - name: Setup auth tokens run: | diff --git a/.github/workflows/publish_layer.yml b/.github/workflows/publish_layer.yml index c67d0e58d..acb4a606e 100644 --- a/.github/workflows/publish_layer.yml +++ b/.github/workflows/publish_layer.yml @@ -39,7 +39,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: "18" + node-version: "20" - name: Setup dependencies uses: ./.github/actions/cached-node-modules - name: CDK build diff --git a/.github/workflows/reusable-publish-docs.yml b/.github/workflows/reusable-publish-docs.yml index 9eaace613..3de8a449f 100644 --- a/.github/workflows/reusable-publish-docs.yml +++ b/.github/workflows/reusable-publish-docs.yml @@ -47,7 +47,7 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: "18" + node-version: "20" cache: "npm" - name: Setup dependencies uses: ./.github/actions/cached-node-modules diff --git a/.github/workflows/reusable-run-linting-check-and-unit-tests.yml b/.github/workflows/reusable-run-linting-check-and-unit-tests.yml index dfd274e6b..9009f542c 100644 --- a/.github/workflows/reusable-run-linting-check-and-unit-tests.yml +++ b/.github/workflows/reusable-run-linting-check-and-unit-tests.yml @@ -10,7 +10,7 @@ jobs: NODE_ENV: dev strategy: matrix: - version: [14, 16, 18] + version: [14, 16, 18, 20] fail-fast: false steps: - name: Checkout code @@ -45,7 +45,7 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: 18 + node-version: 20 cache: "npm" - name: Setup dependencies uses: ./.github/actions/cached-node-modules @@ -63,7 +63,7 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: 18 + node-version: 20 cache: "npm" - name: Setup dependencies uses: ./.github/actions/cached-node-modules @@ -81,7 +81,7 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: 18 + node-version: 20 cache: "npm" - name: Setup dependencies uses: ./.github/actions/cached-node-modules diff --git a/.github/workflows/reusable_deploy_layer_stack.yml b/.github/workflows/reusable_deploy_layer_stack.yml index 88da08179..babf9cb2d 100644 --- a/.github/workflows/reusable_deploy_layer_stack.yml +++ b/.github/workflows/reusable_deploy_layer_stack.yml @@ -71,7 +71,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: "18" + node-version: "20" - name: Setup dependencies uses: ./.github/actions/cached-node-modules - name: Download artifact diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index 38c85edcf..4c2a2b6d5 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -28,7 +28,7 @@ jobs: packages/parameters, packages/idempotency, ] - version: [14, 16, 18] + version: [14, 16, 18, 20] arch: [x86_64, arm64] fail-fast: false steps: @@ -53,11 +53,11 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: ${{ matrix.version }} + node-version: '20' - name: Setup dependencies uses: ./.github/actions/cached-node-modules with: - nodeVersion: ${{ matrix.version }} + nodeVersion: '20' - name: Setup AWS credentials uses: aws-actions/configure-aws-credentials@04b98b3f9e85f563fb061be8751a0352327246b0 # v3.0.1 with: diff --git a/.nvmrc b/.nvmrc index a77793ecc..9de225682 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -lts/hydrogen +lts/iron diff --git a/docs/contributing/setup.md b/docs/contributing/setup.md index 6960bfcf8..d105488b2 100644 --- a/docs/contributing/setup.md +++ b/docs/contributing/setup.md @@ -23,8 +23,8 @@ graph LR Unless you're using the pre-configured Cloud environment, you'll need the following installed: * [GitHub account](https://github.com/join){target="_blank" rel="nofollow"}. You'll need to be able to fork, clone, and contribute via pull request. -* [Node.js 18.x](https://nodejs.org/download/release/latest-v18.x/){target="_blank" rel="nofollow"}. The repository contains an `.nvmrc` file, so if you use tools like [nvm](https://github.com/nvm-sh/nvm#nvmrc), [fnm](https://github.com/Schniz/fnm) you can switch version quickly. -* [npm 9.x](https://www.npmjs.com/). We use it to install dependencies and manage the workspaces. +* [Node.js 20.x](https://nodejs.org/download/release/latest-v20.x/){target="_blank" rel="nofollow"}. The repository contains an `.nvmrc` file, so if you use tools like [nvm](https://github.com/nvm-sh/nvm#nvmrc), [fnm](https://github.com/Schniz/fnm) you can switch version quickly. +* [npm 10.x](https://www.npmjs.com/). We use it to install dependencies and manage the workspaces. * [Docker](https://docs.docker.com/engine/install/){target="_blank" rel="nofollow"}. We use it to run documentation, and non-JavaScript tooling. * [Fork the repository](https://github.com/aws-powertools/powertools-lambda-typescript/fork). You'll work against your fork of this repository. diff --git a/docs/contributing/testing.md b/docs/contributing/testing.md index 641229749..0184b095b 100644 --- a/docs/contributing/testing.md +++ b/docs/contributing/testing.md @@ -84,7 +84,7 @@ To run integration tests you'll need to set up an AWS account and obtain credent * `npm test:e2e -ws` to run all the integration tests for all the modules sequentially * `test:e2e:parallel` to run all the integration tests for all the modules in parallel * `npm test:e2e -w packages/metrics` to run all the integration tests for the `metrics` module -* `npm run test:e2e:nodejs18x -w packages/metrics` to run all the integration tests for the `metrics` module using the `nodejs18x` runtime +* `npm run test:e2e:nodejs20x -w packages/metrics` to run all the integration tests for the `metrics` module using the `nodejs20x` runtime The tests will deploy the necessary AWS resources using AWS CDK, and will run the Lambda functions using the AWS SDK. After that, the tests will verify the Lambda functions behave as expected by checking logs, metrics, traces, and other resources as needed. Finally, the tests will destroy all the AWS resources created at the beginning. diff --git a/docs/core/logger.md b/docs/core/logger.md index 1cc37a50b..59f38cc6d 100644 --- a/docs/core/logger.md +++ b/docs/core/logger.md @@ -68,7 +68,7 @@ These settings will be used across all logs emitted: ShoppingCartApiFunction: Type: AWS::Serverless::Function Properties: - Runtime: nodejs18.x + Runtime: nodejs20.x Environment: Variables: LOG_LEVEL: WARN diff --git a/docs/core/metrics.md b/docs/core/metrics.md index a3804b742..549571dc6 100644 --- a/docs/core/metrics.md +++ b/docs/core/metrics.md @@ -88,7 +88,7 @@ The `Metrics` utility is instantiated outside of the Lambda handler. In doing th HelloWorldFunction: Type: AWS::Serverless::Function Properties: - Runtime: nodejs16.x + Runtime: nodejs20.x Environment: Variables: POWERTOOLS_SERVICE_NAME: orders diff --git a/docs/core/tracer.md b/docs/core/tracer.md index 29f3f8a10..6fb06a94c 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -74,7 +74,7 @@ The `Tracer` utility is instantiated outside of the Lambda handler. In doing thi HelloWorldFunction: Type: AWS::Serverless::Function Properties: - Runtime: nodejs18.x + Runtime: nodejs20.x Tracing: Active Environment: Variables: diff --git a/docs/snippets/batch/templates/sam/dynamodb.yaml b/docs/snippets/batch/templates/sam/dynamodb.yaml index c95dea07b..dfa9e3fd1 100644 --- a/docs/snippets/batch/templates/sam/dynamodb.yaml +++ b/docs/snippets/batch/templates/sam/dynamodb.yaml @@ -6,7 +6,7 @@ Globals: Function: Timeout: 5 MemorySize: 256 - Runtime: nodejs18.x + Runtime: nodejs20.x Tracing: Active Environment: Variables: diff --git a/docs/snippets/batch/templates/sam/kinesis.yaml b/docs/snippets/batch/templates/sam/kinesis.yaml index 032b354a7..3de523279 100644 --- a/docs/snippets/batch/templates/sam/kinesis.yaml +++ b/docs/snippets/batch/templates/sam/kinesis.yaml @@ -6,7 +6,7 @@ Globals: Function: Timeout: 5 MemorySize: 256 - Runtime: nodejs18.x + Runtime: nodejs20.x Tracing: Active Environment: Variables: diff --git a/docs/snippets/batch/templates/sam/sqs.yaml b/docs/snippets/batch/templates/sam/sqs.yaml index 65b91507e..08dcf89d3 100644 --- a/docs/snippets/batch/templates/sam/sqs.yaml +++ b/docs/snippets/batch/templates/sam/sqs.yaml @@ -6,7 +6,7 @@ Globals: Function: Timeout: 5 MemorySize: 256 - Runtime: nodejs18.x + Runtime: nodejs20.x Tracing: Active Environment: Variables: diff --git a/docs/snippets/idempotency/templates/tableCdk.ts b/docs/snippets/idempotency/templates/tableCdk.ts index 8a07d5dc3..526ce4815 100644 --- a/docs/snippets/idempotency/templates/tableCdk.ts +++ b/docs/snippets/idempotency/templates/tableCdk.ts @@ -18,7 +18,7 @@ export class IdempotencyStack extends Stack { }); const fnHandler = new NodejsFunction(this, 'helloWorldFunction', { - runtime: Runtime.NODEJS_18_X, + runtime: Runtime.NODEJS_20_X, handler: 'handler', entry: 'src/index.ts', environment: { diff --git a/docs/snippets/idempotency/templates/tableSam.yaml b/docs/snippets/idempotency/templates/tableSam.yaml index 010ecc89c..ccd2078ae 100644 --- a/docs/snippets/idempotency/templates/tableSam.yaml +++ b/docs/snippets/idempotency/templates/tableSam.yaml @@ -17,7 +17,7 @@ Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: - Runtime: python3.11 + Runtime: nodejs20.x Handler: app.py Policies: - Statement: diff --git a/docs/snippets/idempotency/templates/tableTerraform.tf b/docs/snippets/idempotency/templates/tableTerraform.tf index 4856f2b0e..bedd2f6b5 100644 --- a/docs/snippets/idempotency/templates/tableTerraform.tf +++ b/docs/snippets/idempotency/templates/tableTerraform.tf @@ -28,7 +28,7 @@ resource "aws_dynamodb_table" "IdempotencyTable" { resource "aws_lambda_function" "IdempotencyFunction" { function_name = "IdempotencyFunction" role = aws_iam_role.IdempotencyFunctionRole.arn - runtime = "nodejs18.x" + runtime = "nodejs20.x" handler = "index.handler" filename = "lambda.zip" } diff --git a/docs/utilities/idempotency.md b/docs/utilities/idempotency.md index b1a5b009b..65852c06c 100644 --- a/docs/utilities/idempotency.md +++ b/docs/utilities/idempotency.md @@ -60,7 +60,7 @@ While we support Amazon DynamoDB as a persistance layer out of the box, you need ???+ note - This utility supports **[AWS SDK for JavaScript v3](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/){target="_blank"} only**. If you are using the `nodejs18.x` runtime, the AWS SDK for JavaScript v3 is already installed and you can install only the utility. + This utility supports **[AWS SDK for JavaScript v3](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/){target="_blank"} only**. If you are using the `nodejs18.x` runtime or newer, the AWS SDK for JavaScript v3 is already installed and you can install only the utility. ### IAM Permissions diff --git a/docs/utilities/parameters.md b/docs/utilities/parameters.md index c2b844376..df89ef8a6 100644 --- a/docs/utilities/parameters.md +++ b/docs/utilities/parameters.md @@ -44,7 +44,7 @@ Depending on the provider you want to use, install the library and the correspon ``` ???+ tip - If you are using the `nodejs18.x` runtime, the AWS SDK for JavaScript v3 is already installed and you can install the utility only. + If you are using the `nodejs18.x` runtime or newer, the AWS SDK for JavaScript v3 is already installed and you can install the utility only. ### IAM Permissions diff --git a/examples/cdk/package.json b/examples/cdk/package.json index 76653f05a..42bb17e33 100644 --- a/examples/cdk/package.json +++ b/examples/cdk/package.json @@ -35,7 +35,7 @@ "@types/aws-lambda": "^8.10.121", "@types/jest": "^29.5.4", "@types/node": "20.6.1", - "aws-cdk": "^2.96.1", + "aws-cdk": "^2.107.0", "esbuild": "^0.19.3", "jest": "^29.7.0", "ts-jest": "^29.1.1", @@ -44,7 +44,7 @@ }, "dependencies": { "@middy/core": "^3.6.2", - "aws-cdk-lib": "^2.96.1", + "aws-cdk-lib": "^2.107.0", "constructs": "^10.2.70", "phin": "^3.7.0", "source-map-support": "^0.5.21" diff --git a/examples/cdk/src/example-stack.ts b/examples/cdk/src/example-stack.ts index b7cfa0d9e..a7aeb12b4 100644 --- a/examples/cdk/src/example-stack.ts +++ b/examples/cdk/src/example-stack.ts @@ -11,7 +11,7 @@ import { StringParameter } from 'aws-cdk-lib/aws-ssm'; import { Construct } from 'constructs'; const commonProps: Partial = { - runtime: Runtime.NODEJS_18_X, + runtime: Runtime.NODEJS_20_X, tracing: Tracing.ACTIVE, timeout: Duration.seconds(30), logRetention: RetentionDays.ONE_DAY, @@ -112,7 +112,7 @@ class UuidApi extends Construct { super(scope, id); const uuidFn = new NodejsFunction(this, 'UuidFn', { - runtime: Runtime.NODEJS_18_X, + runtime: Runtime.NODEJS_20_X, entry: './functions/uuid.ts', }); diff --git a/examples/sam/template.yaml b/examples/sam/template.yaml index 3f19a4c5d..39d440f21 100644 --- a/examples/sam/template.yaml +++ b/examples/sam/template.yaml @@ -31,7 +31,7 @@ Parameters: # https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy-globals.html Globals: Function: - Runtime: nodejs18.x + Runtime: nodejs20.x Architectures: - x86_64 MemorySize: 128 diff --git a/layers/package.json b/layers/package.json index 363539203..81f7b0d05 100644 --- a/layers/package.json +++ b/layers/package.json @@ -40,7 +40,7 @@ }, "dependencies": { "aws-cdk": "^2.96.1", - "aws-cdk-lib": "^2.96.1", + "aws-cdk-lib": "^2.107.0", "esbuild": "^0.19.3" } } diff --git a/layers/src/layer-publisher-stack.ts b/layers/src/layer-publisher-stack.ts index 6ef6c19fd..f9d37afc3 100644 --- a/layers/src/layer-publisher-stack.ts +++ b/layers/src/layer-publisher-stack.ts @@ -40,6 +40,7 @@ export class LayerPublisherStack extends Stack { Runtime.NODEJS_14_X, Runtime.NODEJS_16_X, Runtime.NODEJS_18_X, + Runtime.NODEJS_20_X, ], license: 'MIT-0', // This is needed because the following regions do not support the compatibleArchitectures property #1400 @@ -47,7 +48,7 @@ export class LayerPublisherStack extends Stack { code: Code.fromAsset(resolve(__dirname), { bundling: { // This is here only because is required by CDK, however it is not used since the bundling is done locally - image: Runtime.NODEJS_18_X.bundlingImage, + image: Runtime.NODEJS_20_X.bundlingImage, // We need to run a command to generate a random UUID to force the bundling to run every time command: [`echo "${randomUUID()}"`], local: { diff --git a/layers/tests/unit/layer-publisher.test.ts b/layers/tests/unit/layer-publisher.test.ts index a365c34f3..9f7ff98f7 100644 --- a/layers/tests/unit/layer-publisher.test.ts +++ b/layers/tests/unit/layer-publisher.test.ts @@ -25,7 +25,12 @@ describe('Class: LayerPublisherStack', () => { // Assess template.resourceCountIs('AWS::Lambda::LayerVersion', 1); template.hasResourceProperties('AWS::Lambda::LayerVersion', { - CompatibleRuntimes: ['nodejs14.x', 'nodejs16.x', 'nodejs18.x'], + CompatibleRuntimes: [ + 'nodejs14.x', + 'nodejs16.x', + 'nodejs18.x', + 'nodejs20.x', + ], LicenseInfo: 'MIT-0', /* CompatibleArchitectures: [ 'x86_64', diff --git a/package-lock.json b/package-lock.json index ecda462c4..d331df274 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,7 +76,7 @@ "license": "MIT-0", "dependencies": { "@middy/core": "^3.6.2", - "aws-cdk-lib": "^2.96.1", + "aws-cdk-lib": "^2.107.0", "constructs": "^10.2.70", "phin": "^3.7.0", "source-map-support": "^0.5.21" @@ -95,7 +95,7 @@ "@types/aws-lambda": "^8.10.121", "@types/jest": "^29.5.4", "@types/node": "20.6.1", - "aws-cdk": "^2.96.1", + "aws-cdk": "^2.107.0", "esbuild": "^0.19.3", "jest": "^29.7.0", "ts-jest": "^29.1.1", @@ -146,7 +146,7 @@ "license": "MIT-0", "dependencies": { "aws-cdk": "^2.96.1", - "aws-cdk-lib": "^2.96.1", + "aws-cdk-lib": "^2.107.0", "esbuild": "^0.19.3" }, "bin": { @@ -180,9 +180,9 @@ } }, "node_modules/@aws-cdk/asset-awscli-v1": { - "version": "2.2.200", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.200.tgz", - "integrity": "sha512-Kf5J8DfJK4wZFWT2Myca0lhwke7LwHcHBo+4TvWOGJrFVVKVuuiLCkzPPRBQQVDj0Vtn2NBokZAz8pfMpAqAKg==" + "version": "2.2.201", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.201.tgz", + "integrity": "sha512-INZqcwDinNaIdb5CtW3ez5s943nX5stGBQS6VOP2JDlOFP81hM3fds/9NDknipqfUkZM43dx+HgVvkXYXXARCQ==" }, "node_modules/@aws-cdk/asset-kubectl-v20": { "version": "2.1.2", @@ -195,9 +195,9 @@ "integrity": "sha512-DDt4SLdLOwWCjGtltH4VCST7hpOI5DzieuhGZsBpZ+AgJdSI2GCjklCXm0GCTwJG/SolkL5dtQXyUKgg9luBDg==" }, "node_modules/@aws-cdk/cli-lib-alpha": { - "version": "2.96.1-alpha.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cli-lib-alpha/-/cli-lib-alpha-2.96.1-alpha.0.tgz", - "integrity": "sha512-KRPG90986E+TbC9VDHR01R5SUct+aM5CEal8fLEn5hYg79Rp8Haaa96OwPaX/aiZdo+sM0v4fCaLICxG5/QZPg==", + "version": "2.107.0-alpha.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cli-lib-alpha/-/cli-lib-alpha-2.107.0-alpha.0.tgz", + "integrity": "sha512-pgG0wdtW73Y83+8/HwsBdFEjtjOegVHDecFx41mTGhtjHO2NdgoZUX4ab4vm/YNOHIW6zOKFNzGFLi5Q5PfVHA==", "engines": { "node": ">= 14.15.0" } @@ -6007,9 +6007,9 @@ } }, "node_modules/aws-cdk": { - "version": "2.96.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.96.1.tgz", - "integrity": "sha512-dCMriGZj2w6/B5+bu45knQM9QmPpDoUMiGCzsxALsOJVu/Fr5QwvmHxRBTc48uaVAOlYN2qQsAcG5H6TXtBJhg==", + "version": "2.107.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.107.0.tgz", + "integrity": "sha512-Hu0KaTpIO8Zuz/qZqn1FXT0xqO/hSjmimgt0mMYkkjsHYzt4xkfFarjes2X4a5PhYv8hSWml1ClfcmW6yEOAzA==", "bin": { "cdk": "bin/cdk" }, @@ -6021,9 +6021,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.96.1", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.96.1.tgz", - "integrity": "sha512-7jo7btYghU0OCx9BUi/CmEL967Udc3PNm45uBxn6P2ipvhuYSLkJj0toNiln8uPmMKdTzZPH2r22kX+7N9NzQw==", + "version": "2.107.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.107.0.tgz", + "integrity": "sha512-eLyTTxthuxpOAN/RdmP0lKenpscwSFatMhEEqcxVd94ikeUUG3od3QQalpCDf5ohNYhJL6JMwhSVmMEtDJMGNQ==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -6037,7 +6037,7 @@ "yaml" ], "dependencies": { - "@aws-cdk/asset-awscli-v1": "^2.2.200", + "@aws-cdk/asset-awscli-v1": "^2.2.201", "@aws-cdk/asset-kubectl-v20": "^2.1.2", "@aws-cdk/asset-node-proxy-agent-v6": "^2.0.1", "@balena/dockerignore": "^1.0.2", @@ -6046,7 +6046,7 @@ "ignore": "^5.2.4", "jsonschema": "^1.4.1", "minimatch": "^3.1.2", - "punycode": "^2.3.0", + "punycode": "^2.3.1", "semver": "^7.5.4", "table": "^6.8.1", "yaml": "1.10.2" @@ -6247,7 +6247,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/punycode": { - "version": "2.3.0", + "version": "2.3.1", "inBundle": true, "license": "MIT", "engines": { @@ -6332,7 +6332,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/universalify": { - "version": "2.0.0", + "version": "2.0.1", "inBundle": true, "license": "MIT", "engines": { @@ -17917,10 +17917,10 @@ "version": "1.14.2", "license": "MIT-0", "dependencies": { - "@aws-cdk/cli-lib-alpha": "^2.96.1-alpha.0", + "@aws-cdk/cli-lib-alpha": "^2.107.0-alpha.0", "@aws-sdk/client-lambda": "^3.438.0", "@smithy/util-utf8": "^2.0.0", - "aws-cdk-lib": "^2.96.1", + "aws-cdk-lib": "^2.107.0", "esbuild": "^0.19.3" } }, diff --git a/packages/batch/package.json b/packages/batch/package.json index ed956b0c1..79280525a 100644 --- a/packages/batch/package.json +++ b/packages/batch/package.json @@ -16,6 +16,7 @@ "test:e2e:nodejs14x": "echo 'Not Implemented'", "test:e2e:nodejs16x": "echo 'Not Implemented'", "test:e2e:nodejs18x": "echo 'Not Implemented'", + "test:e2e:nodejs20x": "echo 'Not Implemented'", "test:e2e": "echo 'Not Implemented'", "watch": "jest --watch", "build": "tsc --build --force", diff --git a/packages/batch/tests/helpers/populateEnvironmentVariables.ts b/packages/batch/tests/helpers/populateEnvironmentVariables.ts index cb0b37f29..9dc602e5f 100644 --- a/packages/batch/tests/helpers/populateEnvironmentVariables.ts +++ b/packages/batch/tests/helpers/populateEnvironmentVariables.ts @@ -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 = 'nodejs18.x'; +process.env.AWS_EXECUTION_ENV = 'nodejs20.x'; process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE = '128'; if ( process.env.AWS_REGION === undefined && diff --git a/packages/commons/src/version.ts b/packages/commons/src/version.ts index c42c660c4..7f338fc57 100644 --- a/packages/commons/src/version.ts +++ b/packages/commons/src/version.ts @@ -1,2 +1,2 @@ // this file is auto generated, do not modify -export const PT_VERSION = '1.13.1'; +export const PT_VERSION = '1.15.0'; diff --git a/packages/idempotency/package.json b/packages/idempotency/package.json index 03f72769c..46de4c9ae 100644 --- a/packages/idempotency/package.json +++ b/packages/idempotency/package.json @@ -16,6 +16,7 @@ "test:e2e:nodejs14x": "RUNTIME=nodejs14x jest --group=e2e", "test:e2e:nodejs16x": "RUNTIME=nodejs16x jest --group=e2e", "test:e2e:nodejs18x": "RUNTIME=nodejs18x jest --group=e2e", + "test:e2e:nodejs20x": "RUNTIME=nodejs20x jest --group=e2e", "test:e2e": "jest --group=e2e", "watch": "jest --watch", "build": "tsc --build --force", diff --git a/packages/idempotency/tests/e2e/idempotentDecorator.test.ts b/packages/idempotency/tests/e2e/idempotentDecorator.test.ts index 87293d0eb..ec740e0f0 100644 --- a/packages/idempotency/tests/e2e/idempotentDecorator.test.ts +++ b/packages/idempotency/tests/e2e/idempotentDecorator.test.ts @@ -14,7 +14,6 @@ import { ScanCommand } from '@aws-sdk/lib-dynamodb'; import { createHash } from 'node:crypto'; import { invokeFunction, - isValidRuntimeKey, TestInvocationLogs, TestStack, } from '@aws-lambda-powertools/testing-utils'; @@ -23,12 +22,6 @@ import { join } from 'node:path'; import { Duration } from 'aws-cdk-lib'; import { AttributeType } from 'aws-cdk-lib/aws-dynamodb'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; - -if (!isValidRuntimeKey(runtime)) { - throw new Error(`Invalid runtime key value: ${runtime}`); -} - const dynamoDBClient = new DynamoDBClient({}); describe('Idempotency e2e test decorator, default settings', () => { diff --git a/packages/logger/package.json b/packages/logger/package.json index e16627d1e..de7214749 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -16,6 +16,7 @@ "test:e2e:nodejs14x": "RUNTIME=nodejs14x jest --group=e2e", "test:e2e:nodejs16x": "RUNTIME=nodejs16x jest --group=e2e", "test:e2e:nodejs18x": "RUNTIME=nodejs18x jest --group=e2e", + "test:e2e:nodejs20x": "RUNTIME=nodejs20x jest --group=e2e", "test:e2e": "jest --group=e2e", "watch": "jest --watch --group=unit", "build": "tsc --build --force", diff --git a/packages/logger/tests/unit/formatter/PowertoolLogFormatter.test.ts b/packages/logger/tests/unit/formatter/PowertoolLogFormatter.test.ts index 02e1e2a30..9176ce8d8 100644 --- a/packages/logger/tests/unit/formatter/PowertoolLogFormatter.test.ts +++ b/packages/logger/tests/unit/formatter/PowertoolLogFormatter.test.ts @@ -3,7 +3,7 @@ * * @group unit/logger/all */ -import { AssertionError, strictEqual } from 'assert'; +import { AssertionError } from 'node:assert'; import { PowertoolLogFormatter } from '../../../src/formatter'; import { UnformattedAttributes } from '../../../src/types'; @@ -97,215 +97,154 @@ describe('Class: PowertoolLogFormatter', () => { test('when an error of type Error is passed, it returns an object with expected structure and values', () => { // Prepare const formatter = new PowertoolLogFormatter(); - const shouldThrow = (): void => { - throw new Error('Ouch!'); - }; - - // Act - try { - shouldThrow(); - } catch (error) { - // Assess - expect(error).toBeInstanceOf(Error); - const formattedError = formatter.formatError(error); - expect(formattedError).toEqual({ - location: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+$/ - ), - message: 'Ouch!', - name: 'Error', - stack: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ - ), - }); - } - expect(shouldThrow).toThrowError(expect.any(Error)); + // Act & Assess + const formattedError = formatter.formatError(new Error('Ouch!')); + expect(formattedError).toEqual({ + location: expect.stringMatching( + /PowertoolLogFormatter.test.ts:[0-9]+$/ + ), + message: 'Ouch!', + name: 'Error', + stack: expect.stringMatching( + /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ + ), + }); }); test('when an error of type ReferenceError is passed, it returns an object with expected structure and values', () => { // Prepare const formatter = new PowertoolLogFormatter(); - const shouldThrow = (): void => { - // This is a reference error purposely to test the formatter - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - doesNotExist; - }; - // Act - try { - shouldThrow(); - } catch (error) { - // Assess - expect(error).toBeInstanceOf(Error); - const formattedReferenceError = formatter.formatError(error); - expect(formattedReferenceError).toEqual({ - location: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+$/ - ), - message: 'doesNotExist is not defined', - name: 'ReferenceError', - stack: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ - ), - }); - } - - expect(shouldThrow).toThrowError(expect.any(ReferenceError)); + // Act & Assess + const formattedReferenceError = formatter.formatError( + new ReferenceError('doesNotExist is not defined') + ); + expect(formattedReferenceError).toEqual({ + location: expect.stringMatching( + /PowertoolLogFormatter.test.ts:[0-9]+$/ + ), + message: 'doesNotExist is not defined', + name: 'ReferenceError', + stack: expect.stringMatching( + /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ + ), + }); }); test('when an error of type AssertionError is passed, it returns an object with expected structure and values', () => { // Prepare const formatter = new PowertoolLogFormatter(); - const shouldThrow = (): void => { - strictEqual(1, 2); - }; - - // Act - try { - shouldThrow(); - } catch (error) { - // Assess - expect(error).toBeInstanceOf(AssertionError); - const formattedAssertionError = formatter.formatError( - error - ); - expect(formattedAssertionError).toEqual({ - location: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+/ - ), - message: expect.stringMatching( - /Expected values to be strictly equal/ - ), - name: 'AssertionError', - stack: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ - ), - }); - } - expect(shouldThrow).toThrowError(expect.any(AssertionError)); + // Act & Assess + const formattedAssertionError = formatter.formatError( + new AssertionError({ + message: 'Expected values to be strictly equal', + actual: 1, + expected: 2, + operator: 'strictEqual', + }) + ); + expect(formattedAssertionError).toEqual({ + location: expect.stringMatching( + /(node:)*internal\/assert\/assertion_error(.js)*:[0-9]+$/ + ), + message: expect.stringMatching(/Expected values to be strictly equal/), + name: 'AssertionError', + stack: expect.stringMatching( + /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ + ), + }); }); test('when an error of type RangeError is passed, it returns an object with expected structure and values', () => { // Prepare const formatter = new PowertoolLogFormatter(); - const shouldThrow = (): void => { - throw new RangeError('The argument must be between 10 and 20'); - }; - // Act - try { - shouldThrow(); - } catch (error) { - // Assess - expect(error).toBeInstanceOf(RangeError); - const formattedRangeError = formatter.formatError(error); - expect(formattedRangeError).toEqual({ - location: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+/ - ), - message: 'The argument must be between 10 and 20', - name: 'RangeError', - stack: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ - ), - }); - } + // Act & Assess + const formattedRangeError = formatter.formatError( + new RangeError('The argument must be between 10 and 20') + ); + expect(formattedRangeError).toEqual({ + location: expect.stringMatching(/PowertoolLogFormatter.test.ts:[0-9]+/), + message: 'The argument must be between 10 and 20', + name: 'RangeError', + stack: expect.stringMatching( + /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ + ), + }); + }); + + test('when an error of type ReferenceError is passed, it returns an object with expected structure and values', () => { + // Prepare + const formatter = new PowertoolLogFormatter(); - expect(shouldThrow).toThrowError(expect.any(RangeError)); + // Act & Assess + const formattedError = formatter.formatError( + new ReferenceError('foo is not defined') + ); + expect(formattedError).toEqual({ + location: expect.stringMatching(/PowertoolLogFormatter.test.ts:[0-9]+/), + message: 'foo is not defined', + name: 'ReferenceError', + stack: expect.stringMatching( + /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ + ), + }); }); test('when an error of type SyntaxError is passed, it returns an object with expected structure and values', () => { // Prepare const formatter = new PowertoolLogFormatter(); - const shouldThrow = (): void => { - eval('foo bar'); - }; - // Act - try { - shouldThrow(); - } catch (error) { - // Assess - expect(error).toBeInstanceOf(SyntaxError); - const formattedSyntaxError = formatter.formatError(error); - expect(formattedSyntaxError).toEqual({ - location: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+/ - ), - message: 'Unexpected identifier', - name: 'SyntaxError', - stack: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ - ), - }); - } - - expect(shouldThrow).toThrowError(expect.any(SyntaxError)); + // Act & Assess + const formattedSyntaxError = formatter.formatError( + new SyntaxError(`Unexpected identifier 'bar'`) + ); + expect(formattedSyntaxError).toEqual({ + location: expect.stringMatching(/PowertoolLogFormatter.test.ts:[0-9]+/), + message: `Unexpected identifier 'bar'`, + name: 'SyntaxError', + stack: expect.stringMatching( + /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ + ), + }); }); test('when an error of type TypeError is passed, it returns an object with expected structure and values', () => { // Prepare const formatter = new PowertoolLogFormatter(); - const shouldThrow = (): void => { - // This is a reference error purposely to test the formatter - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - null.foo(); - }; - - // Act - try { - shouldThrow(); - } catch (error) { - // TODO: review message content assertion (see Issue #304) - // Assess - expect(error).toBeInstanceOf(Error); - const formattedTypeError = formatter.formatError(error); - expect(formattedTypeError).toEqual({ - location: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+/ - ), - message: expect.stringMatching(/Cannot read propert/), - name: 'TypeError', - stack: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ - ), - }); - } - expect(shouldThrow).toThrowError(expect.any(TypeError)); + // Act & Assess + const formattedTypeError = formatter.formatError( + new TypeError(`Cannot read property 'foo' of null`) + ); + expect(formattedTypeError).toEqual({ + location: expect.stringMatching(/PowertoolLogFormatter.test.ts:[0-9]+/), + message: expect.stringMatching(/Cannot read propert/), + name: 'TypeError', + stack: expect.stringMatching( + /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ + ), + }); }); test('when an error of type URIError is passed, it returns an object with expected structure and values', () => { // Prepare const formatter = new PowertoolLogFormatter(); - const shouldThrow = (): void => { - decodeURIComponent('%'); - }; - // Act - try { - shouldThrow(); - } catch (error) { - // Assess - expect(error).toBeInstanceOf(URIError); - const formattedURIError = formatter.formatError(error); - expect(formattedURIError).toEqual({ - location: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+/ - ), - message: 'URI malformed', - name: 'URIError', - stack: expect.stringMatching( - /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ - ), - }); - } - - expect(shouldThrow).toThrowError(expect.any(URIError)); + // Act & Assess + const formattedURIError = formatter.formatError( + new URIError('URI malformed') + ); + expect(formattedURIError).toEqual({ + location: expect.stringMatching(/PowertoolLogFormatter.test.ts:[0-9]+/), + message: 'URI malformed', + name: 'URIError', + stack: expect.stringMatching( + /PowertoolLogFormatter.test.ts:[0-9]+:[0-9]+/ + ), + }); }); test('when an error with cause of type Error is formatted, the cause key is included and formatted', () => { diff --git a/packages/metrics/package.json b/packages/metrics/package.json index 86dd8990f..4995ca9ae 100644 --- a/packages/metrics/package.json +++ b/packages/metrics/package.json @@ -16,6 +16,7 @@ "test:e2e:nodejs14x": "RUNTIME=nodejs14x jest --group=e2e", "test:e2e:nodejs16x": "RUNTIME=nodejs16x jest --group=e2e", "test:e2e:nodejs18x": "RUNTIME=nodejs18x jest --group=e2e", + "test:e2e:nodejs20x": "RUNTIME=nodejs20x jest --group=e2e", "test:e2e": "jest --group=e2e", "watch": "jest --group=unit --watch ", "build": "tsc --build --force", diff --git a/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts b/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts index 332636210..a0ab28939 100644 --- a/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts +++ b/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts @@ -12,7 +12,7 @@ import { GetMetricStatisticsCommand, } from '@aws-sdk/client-cloudwatch'; import { join } from 'node:path'; -import { getMetrics } from '../helpers/metricsUtils'; +import { getMetrics, sortDimensions } from '../helpers/metricsUtils'; import { MetricsTestNodejsFunction } from '../helpers/resources'; import { commonEnvironmentVars, @@ -98,7 +98,9 @@ describe(`Metrics E2E tests, basic features decorator usage`, () => { expect(coldStartMetrics.Metrics?.length).toBe(1); const coldStartMetric = coldStartMetrics.Metrics?.[0]; - expect(coldStartMetric?.Dimensions).toStrictEqual(expectedDimensions); + expect(sortDimensions(coldStartMetric?.Dimensions)).toStrictEqual( + sortDimensions(expectedDimensions) + ); // Check coldstart metric value const adjustedStartTime = new Date(startTime.getTime() - ONE_MINUTE); @@ -167,7 +169,9 @@ describe(`Metrics E2E tests, basic features decorator usage`, () => { Value: expectedExtraDimension.MyExtraDimension, }, ]; - expect(metric?.Dimensions).toStrictEqual(expectedDimensions); + expect(sortDimensions(metric?.Dimensions)).toStrictEqual( + sortDimensions(expectedDimensions) + ); // Check coldstart metric value const adjustedStartTime = new Date( diff --git a/packages/metrics/tests/e2e/basicFeatures.manual.test.ts b/packages/metrics/tests/e2e/basicFeatures.manual.test.ts index b22861ab1..b984cffd5 100644 --- a/packages/metrics/tests/e2e/basicFeatures.manual.test.ts +++ b/packages/metrics/tests/e2e/basicFeatures.manual.test.ts @@ -12,7 +12,7 @@ import { GetMetricStatisticsCommand, } from '@aws-sdk/client-cloudwatch'; import { join } from 'node:path'; -import { getMetrics } from '../helpers/metricsUtils'; +import { getMetrics, sortDimensions } from '../helpers/metricsUtils'; import { MetricsTestNodejsFunction } from '../helpers/resources'; import { commonEnvironmentVars, @@ -156,7 +156,9 @@ describe(`Metrics E2E tests, manual usage`, () => { Value: expectedExtraDimension.MyExtraDimension, }, ]; - expect(metric?.Dimensions).toStrictEqual(expectedDimensions); + expect(sortDimensions(metric?.Dimensions)).toStrictEqual( + sortDimensions(expectedDimensions) + ); // Check coldstart metric value const adjustedStartTime = new Date( diff --git a/packages/metrics/tests/helpers/metricsUtils.ts b/packages/metrics/tests/helpers/metricsUtils.ts index 5254b474c..674efa370 100644 --- a/packages/metrics/tests/helpers/metricsUtils.ts +++ b/packages/metrics/tests/helpers/metricsUtils.ts @@ -5,7 +5,10 @@ import { CloudWatchClient, ListMetricsCommand, } from '@aws-sdk/client-cloudwatch'; -import type { ListMetricsCommandOutput } from '@aws-sdk/client-cloudwatch'; +import type { + Dimension, + ListMetricsCommandOutput, +} from '@aws-sdk/client-cloudwatch'; import type { Context, Handler } from 'aws-lambda'; import type { LambdaInterface } from '@aws-lambda-powertools/commons'; @@ -66,4 +69,7 @@ const setupDecoratorLambdaHandler = ( return handler; }; -export { getMetrics, setupDecoratorLambdaHandler }; +const sortDimensions = (dimensions?: Dimension[]): Dimension[] | undefined => + dimensions?.sort((a, b) => (a.Name || '').localeCompare(b?.Name || '')); + +export { getMetrics, setupDecoratorLambdaHandler, sortDimensions }; diff --git a/packages/parameters/package.json b/packages/parameters/package.json index f9a495785..90555da28 100644 --- a/packages/parameters/package.json +++ b/packages/parameters/package.json @@ -16,6 +16,7 @@ "test:e2e:nodejs14x": "RUNTIME=nodejs14x jest --group=e2e", "test:e2e:nodejs16x": "RUNTIME=nodejs16x jest --group=e2e", "test:e2e:nodejs18x": "RUNTIME=nodejs18x jest --group=e2e", + "test:e2e:nodejs20x": "RUNTIME=nodejs20x jest --group=e2e", "test:e2e": "jest --group=e2e", "watch": "jest --watch", "build": "tsc --build --force", diff --git a/packages/testing/package.json b/packages/testing/package.json index 04e33c5c4..be988626c 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -44,10 +44,10 @@ }, "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/packages/testing#readme", "dependencies": { - "@aws-cdk/cli-lib-alpha": "^2.96.1-alpha.0", + "@aws-cdk/cli-lib-alpha": "^2.107.0-alpha.0", "@aws-sdk/client-lambda": "^3.438.0", "@smithy/util-utf8": "^2.0.0", - "aws-cdk-lib": "^2.96.1", + "aws-cdk-lib": "^2.107.0", "esbuild": "^0.19.3" } } diff --git a/packages/testing/src/constants.ts b/packages/testing/src/constants.ts index e29fbe013..4cc07ea90 100644 --- a/packages/testing/src/constants.ts +++ b/packages/testing/src/constants.ts @@ -3,7 +3,7 @@ import { Runtime, Architecture } from 'aws-cdk-lib/aws-lambda'; /** * The default AWS Lambda runtime to use when none is provided. */ -const defaultRuntime = 'nodejs18x'; +const defaultRuntime = 'nodejs20x'; /** * The AWS Lambda runtimes that are supported by the project. @@ -11,7 +11,8 @@ const defaultRuntime = 'nodejs18x'; const TEST_RUNTIMES = { nodejs14x: Runtime.NODEJS_14_X, nodejs16x: Runtime.NODEJS_16_X, - [defaultRuntime]: Runtime.NODEJS_18_X, + nodejs18x: Runtime.NODEJS_18_X, + [defaultRuntime]: Runtime.NODEJS_20_X, } as const; /** diff --git a/packages/tracer/package.json b/packages/tracer/package.json index 8cdc8b698..d536ba774 100644 --- a/packages/tracer/package.json +++ b/packages/tracer/package.json @@ -16,6 +16,7 @@ "test:e2e:nodejs14x": "RUNTIME=nodejs14x jest --group=e2e", "test:e2e:nodejs16x": "RUNTIME=nodejs16x jest --group=e2e", "test:e2e:nodejs18x": "RUNTIME=nodejs18x jest --group=e2e", + "test:e2e:nodejs20x": "RUNTIME=nodejs20x jest --group=e2e", "test:e2e": "jest --group=e2e", "watch": "jest --watch", "build": "tsc --build --force",