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 65dc112dba..071a30e01b 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 e1401b638d..f9033f03d3 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 c9fbf5216c..819d2f3d5a 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 d86c8d7b10..42d5db19e7 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 32ee9c0902..122e3844da 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 f590a624b1..0c20a1686a 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 c67d0e58db..acb4a606e7 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 9eaace6133..3de8a449ff 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 dfd274e6bd..9009f542cf 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 88da081792..babf9cb2da 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 38c85edcf7..4c2a2b6d55 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 a77793ecc5..9de2256827 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -lts/hydrogen +lts/iron diff --git a/docs/contributing/setup.md b/docs/contributing/setup.md index 6960bfcf88..d105488b24 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 6412297499..0184b095b0 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 1cc37a50ba..59f38cc6da 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 a3804b742d..549571dc6e 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 29f3f8a109..6fb06a94c4 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 c95dea07b7..dfa9e3fd1e 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 032b354a74..3de5232790 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 65b91507eb..08dcf89d38 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 8a07d5dc3c..526ce48156 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 010ecc89ca..ccd2078aee 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 4856f2b0e6..bedd2f6b5e 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 b1a5b009be..65852c06ca 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 c2b844376e..df89ef8a62 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 76653f05af..42bb17e335 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 b7cfa0d9ed..a7aeb12b4d 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 3f19a4c5d3..39d440f21f 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 363539203f..81f7b0d053 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 6ef6c19fda..f9d37afc31 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 a365c34f3d..9f7ff98f70 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 ecda462c43..d331df2749 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 ed956b0c1b..79280525ae 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 cb0b37f295..9dc602e5f0 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 c42c660c40..7f338fc57f 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 03f72769cd..46de4c9ae5 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 87293d0eb3..ec740e0f03 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 e16627d1ec..de72147494 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 02e1e2a303..9176ce8d8d 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 86dd8990f6..4995ca9ae6 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 332636210e..a0ab289392 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 b22861ab16..b984cffd54 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 5254b474cb..674efa370f 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 f9a4957858..90555da286 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 04e33c5c47..be988626cc 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 e29fbe0132..4cc07ea909 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 8cdc8b6982..d536ba7748 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",