From 5d38256979ea8158bf3b686412e911542869b72a 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 +- .../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 | 14 +- .../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 | 8 +- layers/tests/unit/layer-publisher.test.ts | 2 +- package-lock.json | 42 +-- packages/batch/package.json | 1 + .../helpers/populateEnvironmentVariables.ts | 2 +- packages/commons/src/version.ts | 2 +- packages/idempotency/package.json | 1 + packages/logger/package.json | 1 + .../formatter/PowertoolsLogFormatter.test.ts | 273 +++++++----------- 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 + 45 files changed, 216 insertions(+), 241 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/actions/cached-node-modules/action.yml b/.github/actions/cached-node-modules/action.yml index 008c852792..988c447f12 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' build: description: 'Whether to build the packages or not' default: 'true' @@ -15,6 +15,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 7571608960..7ff88d2644 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 a1d60e3012..4162f35cf8 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 6b845abe20..0629e251fa 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: [16, 18] + version: [16, 18, 20] fail-fast: false steps: - name: Checkout code @@ -45,8 +45,8 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: 18 - cache: 'npm' + node-version: 20 + cache: "npm" - name: Setup dependencies uses: ./.github/actions/cached-node-modules - name: Run linting @@ -63,8 +63,8 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: 18 - cache: 'npm' + node-version: 20 + cache: "npm" - name: Setup dependencies uses: ./.github/actions/cached-node-modules - name: Run linting @@ -81,8 +81,8 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: 18 - cache: 'npm' + node-version: 20 + cache: "npm" - name: Setup dependencies uses: ./.github/actions/cached-node-modules - name: Run linting 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 3db702a2df..1dd1ddc972 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: [16, 18] + version: [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 b83c7a2754..9bf38b2e5d 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 bac610ef79..bb15b248c7 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" } } \ No newline at end of file diff --git a/layers/src/layer-publisher-stack.ts b/layers/src/layer-publisher-stack.ts index 01148546db..775d42b6d6 100644 --- a/layers/src/layer-publisher-stack.ts +++ b/layers/src/layer-publisher-stack.ts @@ -36,14 +36,18 @@ 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_16_X, Runtime.NODEJS_18_X], + compatibleRuntimes: [ + 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 // ...(![ 'eu-south-2', 'eu-central-2', 'ap-southeast-4' ].includes(Stack.of(this).region) ? { compatibleArchitectures: [Architecture.X86_64] } : {}), 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 98b90788bd..bec61bc0f5 100644 --- a/layers/tests/unit/layer-publisher.test.ts +++ b/layers/tests/unit/layer-publisher.test.ts @@ -25,7 +25,7 @@ describe('Class: LayerPublisherStack', () => { // Assess template.resourceCountIs('AWS::Lambda::LayerVersion', 1); template.hasResourceProperties('AWS::Lambda::LayerVersion', { - CompatibleRuntimes: ['nodejs16.x', 'nodejs18.x'], + CompatibleRuntimes: ['nodejs16.x', 'nodejs18.x', 'nodejs20.x'], LicenseInfo: 'MIT-0', /* CompatibleArchitectures: [ 'x86_64', diff --git a/package-lock.json b/package-lock.json index 5dee3f7184..82d7bd7018 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", @@ -162,7 +162,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": { @@ -196,9 +196,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", @@ -211,9 +211,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" } @@ -5455,9 +5455,9 @@ } }, "node_modules/aws-cdk": { - "version": "2.98.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.98.0.tgz", - "integrity": "sha512-K8WCstCTmJo7dOwzAfUxhWmRYs9FmtFMpKh0OkEOs7iJ1HsNvAOz2LUURkVMqINXgfhmqqjgK6PQxI4AfgOdGA==", + "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" }, @@ -5469,9 +5469,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.98.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.98.0.tgz", - "integrity": "sha512-6APM6zVTCi59L/8lPX47DINlCD9ZG7OEQ28pD/ftmHZ8qC7AlBWwWqOfuSL+DyEbJBLcw3AZ2MLM1AMJPO+sVg==", + "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", @@ -5485,7 +5485,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", @@ -5494,7 +5494,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" @@ -5695,7 +5695,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/punycode": { - "version": "2.3.0", + "version": "2.3.1", "inBundle": true, "license": "MIT", "engines": { @@ -5780,7 +5780,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/universalify": { - "version": "2.0.0", + "version": "2.0.1", "inBundle": true, "license": "MIT", "engines": { @@ -16744,10 +16744,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 5b8870117c..69c37bd479 100644 --- a/packages/batch/package.json +++ b/packages/batch/package.json @@ -15,6 +15,7 @@ "jest": "jest --detectOpenHandles --verbose", "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:cjs": "tsc --build tsconfig.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json", 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 a29bcabeed..b58140e330 100644 --- a/packages/idempotency/package.json +++ b/packages/idempotency/package.json @@ -15,6 +15,7 @@ "jest": "jest --detectOpenHandles --verbose", "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:cjs": "tsc --build tsconfig.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json", diff --git a/packages/logger/package.json b/packages/logger/package.json index fe5484d35e..a21ec2cb31 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -15,6 +15,7 @@ "jest": "jest --detectOpenHandles --verbose", "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:cjs": "tsc --build tsconfig.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json", diff --git a/packages/logger/tests/unit/formatter/PowertoolsLogFormatter.test.ts b/packages/logger/tests/unit/formatter/PowertoolsLogFormatter.test.ts index 3a97c9637b..50f64b9854 100644 --- a/packages/logger/tests/unit/formatter/PowertoolsLogFormatter.test.ts +++ b/packages/logger/tests/unit/formatter/PowertoolsLogFormatter.test.ts @@ -3,7 +3,7 @@ * * @group unit/logger/logFormatter */ -import { AssertionError, strictEqual } from 'node:assert'; +import { AssertionError } from 'node:assert'; import { PowertoolsLogFormatter } from '../../../src/formatter/PowertoolsLogFormatter.js'; import { LogItem } from '../../../src/index.js'; import type { UnformattedAttributes } from '../../../src/types/Logger.js'; @@ -108,205 +108,154 @@ describe('Class: PowertoolsLogFormatter', () => { test('when an error of type Error is passed, it returns an object with expected structure and values', () => { // Prepare const formatter = new PowertoolsLogFormatter(); - 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( - /PowertoolsLogFormatter.test.ts:\d+$/ - ), - message: 'Ouch!', - name: 'Error', - stack: expect.stringMatching( - /PowertoolsLogFormatter.test.ts:\d+:\d+/ - ), - }); - } - 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 PowertoolsLogFormatter(); - 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( - /PowertoolsLogFormatter.test.ts:\d+$/ - ), - message: 'doesNotExist is not defined', - name: 'ReferenceError', - stack: expect.stringMatching( - /PowertoolsLogFormatter.test.ts:\d+:\d+/ - ), - }); - } - 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 PowertoolsLogFormatter(); - 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(/PowertoolsLogFormatter.test.ts:\d+/), - message: expect.stringMatching( - /Expected values to be strictly equal/ - ), - name: 'AssertionError', - stack: expect.stringMatching( - /PowertoolsLogFormatter.test.ts:\d+:\d+/ - ), - }); - } - 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 PowertoolsLogFormatter(); - 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(/PowertoolsLogFormatter.test.ts:\d+/), - message: 'The argument must be between 10 and 20', - name: 'RangeError', - stack: expect.stringMatching( - /PowertoolsLogFormatter.test.ts:\d+:\d+/ - ), - }); - } + // 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 PowertoolsLogFormatter(); - 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 PowertoolsLogFormatter(); - 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(/PowertoolsLogFormatter.test.ts:\d+/), - message: 'Unexpected identifier', - name: 'SyntaxError', - stack: expect.stringMatching( - /PowertoolsLogFormatter.test.ts:\d+:\d+/ - ), - }); - } - 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 PowertoolsLogFormatter(); - 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(/PowertoolsLogFormatter.test.ts:\d+/), - message: expect.stringMatching(/Cannot read propert/), - name: 'TypeError', - stack: expect.stringMatching( - /PowertoolsLogFormatter.test.ts:\d+:\d+/ - ), - }); - } - 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 PowertoolsLogFormatter(); - 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(/PowertoolsLogFormatter.test.ts:\d+/), - message: 'URI malformed', - name: 'URIError', - stack: expect.stringMatching( - /PowertoolsLogFormatter.test.ts:\d+:\d+/ - ), - }); - } - 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 db6b884e26..f518064590 100644 --- a/packages/metrics/package.json +++ b/packages/metrics/package.json @@ -15,6 +15,7 @@ "jest": "jest --detectOpenHandles --verbose", "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:cjs": "tsc --build tsconfig.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json", diff --git a/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts b/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts index bdaa6b750d..5bf1a38809 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.js'; +import { getMetrics, sortDimensions } from '../helpers/metricsUtils.js'; import { MetricsTestNodejsFunction } from '../helpers/resources.js'; 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 6cb286c708..8211d6c882 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.js'; +import { getMetrics, sortDimensions } from '../helpers/metricsUtils.js'; import { MetricsTestNodejsFunction } from '../helpers/resources.js'; 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 0984c8a6bc..859c551266 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/types'; @@ -64,4 +67,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 6d7e23b2d0..db0e36f7b2 100644 --- a/packages/parameters/package.json +++ b/packages/parameters/package.json @@ -15,6 +15,7 @@ "jest": "jest --detectOpenHandles --verbose", "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:cjs": "tsc --build tsconfig.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json", diff --git a/packages/testing/package.json b/packages/testing/package.json index 3673a834f0..ff9bb5d720 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -94,10 +94,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 66b7bb2466..0699c4efb4 100644 --- a/packages/testing/src/constants.ts +++ b/packages/testing/src/constants.ts @@ -3,14 +3,15 @@ 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. */ const TEST_RUNTIMES = { 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 5078a0b598..5e5874ae0b 100644 --- a/packages/tracer/package.json +++ b/packages/tracer/package.json @@ -15,6 +15,7 @@ "jest": "jest --detectOpenHandles --verbose", "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:cjs": "tsc --build tsconfig.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json",