diff --git a/layers/bin/layers.ts b/layers/bin/layers.ts index be4605b3e3..e4c5148311 100644 --- a/layers/bin/layers.ts +++ b/layers/bin/layers.ts @@ -1,8 +1,8 @@ #!/usr/bin/env node import 'source-map-support/register'; import { App } from 'aws-cdk-lib'; -import { LayerPublisherStack } from '../src/layer-publisher-stack'; import { CanaryStack } from 'layers/src/canary-stack'; +import { LayerPublisherStack } from '../src/layer-publisher-stack'; const SSM_PARAM_LAYER_ARN = '/layers/powertools-layer-arn'; diff --git a/layers/cdk.json b/layers/cdk.json index 4ca6aac30e..d01ddd44bc 100644 --- a/layers/cdk.json +++ b/layers/cdk.json @@ -1,9 +1,7 @@ { "app": "npx ts-node --prefer-ts-exts bin/layers.ts", "watch": { - "include": [ - "**" - ], + "include": ["**"], "exclude": [ "README.md", "cdk*.json", @@ -24,9 +22,6 @@ "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true, "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, - "@aws-cdk/core:target-partitions": [ - "aws", - "aws-cn" - ] + "@aws-cdk/core:target-partitions": ["aws", "aws-cn"] } } diff --git a/layers/package.json b/layers/package.json index 748686d6da..1a76536d03 100644 --- a/layers/package.json +++ b/layers/package.json @@ -12,8 +12,8 @@ "jest": "jest --detectOpenHandles", "cdk": "cdk", "package": "echo 'Not applicable'", - "lint": "eslint --ext .ts,.js --no-error-on-unmatched-pattern .", - "lint-fix": "eslint --fix --ext .ts,.js --fix --no-error-on-unmatched-pattern .", + "lint": "biome lint .", + "lint:fix": "biome check --write .", "test:unit": "jest --group=unit", "test:e2e": "jest --group=e2e", "createLayerFolder": "cdk synth --context BuildFromLocal=true" diff --git a/layers/src/canary-stack.ts b/layers/src/canary-stack.ts index 645c9c40c9..9ee3a4031b 100644 --- a/layers/src/canary-stack.ts +++ b/layers/src/canary-stack.ts @@ -1,13 +1,13 @@ -import { CustomResource, Duration, Stack, StackProps } from 'aws-cdk-lib'; -import { Construct } from 'constructs'; -import { LayerVersion, Runtime, Tracing } from 'aws-cdk-lib/aws-lambda'; -import { RetentionDays } from 'aws-cdk-lib/aws-logs'; import { randomUUID } from 'node:crypto'; -import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam'; -import { Provider } from 'aws-cdk-lib/custom-resources'; -import { StringParameter } from 'aws-cdk-lib/aws-ssm'; import path from 'node:path'; +import { CustomResource, Duration, Stack, type StackProps } from 'aws-cdk-lib'; +import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam'; +import { LayerVersion, Runtime, Tracing } from 'aws-cdk-lib/aws-lambda'; import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; +import { RetentionDays } from 'aws-cdk-lib/aws-logs'; +import { StringParameter } from 'aws-cdk-lib/aws-ssm'; +import { Provider } from 'aws-cdk-lib/custom-resources'; +import type { Construct } from 'constructs'; export interface CanaryStackProps extends StackProps { readonly layerName: string; diff --git a/layers/src/layer-publisher-stack.ts b/layers/src/layer-publisher-stack.ts index 71da06737c..74ea60cc67 100644 --- a/layers/src/layer-publisher-stack.ts +++ b/layers/src/layer-publisher-stack.ts @@ -1,4 +1,7 @@ -import { CfnOutput, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib'; +import { execSync } from 'node:child_process'; +import { randomUUID } from 'node:crypto'; +import { join, resolve, sep } from 'node:path'; +import { CfnOutput, RemovalPolicy, Stack, type StackProps } from 'aws-cdk-lib'; import { CfnLayerVersionPermission, Code, @@ -6,10 +9,7 @@ import { Runtime, } from 'aws-cdk-lib/aws-lambda'; import { StringParameter } from 'aws-cdk-lib/aws-ssm'; -import { Construct } from 'constructs'; -import { execSync } from 'node:child_process'; -import { randomUUID } from 'node:crypto'; -import { join, resolve, sep } from 'node:path'; +import type { Construct } from 'constructs'; export interface LayerPublisherStackProps extends StackProps { readonly layerName?: string; @@ -217,7 +217,7 @@ export class LayerPublisherStack extends Stack { new CfnOutput(this, 'LatestLayerArn', { value: this.lambdaLayerVersion.layerVersionArn, - exportName: props?.layerName ?? `LambdaPowerToolsForTypeScriptLayerARN`, + exportName: props?.layerName ?? 'LambdaPowerToolsForTypeScriptLayerARN', }); } } diff --git a/layers/tests/e2e/layerPublisher.class.test.functionCode.ts b/layers/tests/e2e/layerPublisher.class.test.functionCode.ts index b95eeafea9..a58bcbde9d 100644 --- a/layers/tests/e2e/layerPublisher.class.test.functionCode.ts +++ b/layers/tests/e2e/layerPublisher.class.test.functionCode.ts @@ -1,18 +1,18 @@ -import { join } from 'node:path'; import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { BatchProcessor, EventType } from '@aws-lambda-powertools/batch'; +import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb'; import { Logger } from '@aws-lambda-powertools/logger'; import { Metrics } from '@aws-lambda-powertools/metrics'; -import { Tracer } from '@aws-lambda-powertools/tracer'; -import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb'; -import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; -import { BatchProcessor, EventType } from '@aws-lambda-powertools/batch'; -import { SSMProvider } from '@aws-lambda-powertools/parameters/ssm'; -import { SecretsProvider } from '@aws-lambda-powertools/parameters/secrets'; import { AppConfigProvider } from '@aws-lambda-powertools/parameters/appconfig'; import { DynamoDBProvider } from '@aws-lambda-powertools/parameters/dynamodb'; -import { SSMClient } from '@aws-sdk/client-ssm'; -import { SecretsManagerClient } from '@aws-sdk/client-secrets-manager'; +import { SecretsProvider } from '@aws-lambda-powertools/parameters/secrets'; +import { SSMProvider } from '@aws-lambda-powertools/parameters/ssm'; +import { Tracer } from '@aws-lambda-powertools/tracer'; import { AppConfigDataClient } from '@aws-sdk/client-appconfigdata'; +import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; +import { SecretsManagerClient } from '@aws-sdk/client-secrets-manager'; +import { SSMClient } from '@aws-sdk/client-ssm'; const logger = new Logger({ logLevel: 'DEBUG', @@ -91,7 +91,7 @@ export const handler = async (): Promise => { 'batch', ]) { const moduleVersion = await getVersionFromModule(moduleName); - if (moduleVersion != expectedVersion) { + if (moduleVersion !== expectedVersion) { throw new Error( `Package version mismatch (${moduleName}): ${moduleVersion} != ${expectedVersion}` ); diff --git a/layers/tests/e2e/layerPublisher.test.ts b/layers/tests/e2e/layerPublisher.test.ts index a00f2cb742..56d7441397 100644 --- a/layers/tests/e2e/layerPublisher.test.ts +++ b/layers/tests/e2e/layerPublisher.test.ts @@ -3,23 +3,23 @@ * * @group e2e/layers/all */ -import { App } from 'aws-cdk-lib'; -import { LayerVersion } from 'aws-cdk-lib/aws-lambda'; -import { LayerPublisherStack } from '../../src/layer-publisher-stack'; +import { join } from 'node:path'; import { - TestStack, TestInvocationLogs, - invokeFunctionOnce, + TestStack, generateTestUniqueName, + invokeFunctionOnce, } from '@aws-lambda-powertools/testing-utils'; import { TestNodejsFunction } from '@aws-lambda-powertools/testing-utils/resources/lambda'; +import { App } from 'aws-cdk-lib'; +import { LayerVersion } from 'aws-cdk-lib/aws-lambda'; +import packageJson from '../../package.json'; +import { LayerPublisherStack } from '../../src/layer-publisher-stack'; import { RESOURCE_NAME_PREFIX, SETUP_TIMEOUT, TEARDOWN_TIMEOUT, } from './constants'; -import { join } from 'node:path'; -import packageJson from '../../package.json'; jest.spyOn(console, 'log').mockImplementation(); @@ -39,7 +39,7 @@ function assertLogs( * * The lambda function is invoked once and the logs are collected. The goal of the test is to verify that the layer creation and usage works as expected. */ -describe(`Layers E2E tests`, () => { +describe('Layers E2E tests', () => { const testStack = new TestStack({ stackNameProps: { stackNamePrefix: RESOURCE_NAME_PREFIX, @@ -96,7 +96,7 @@ describe(`Layers E2E tests`, () => { ); // Add a lambda function for each output format to the test stack - cases.forEach((outputFormat) => { + for (const outputFormat of cases) { new TestNodejsFunction( testStack, { @@ -120,7 +120,7 @@ describe(`Layers E2E tests`, () => { ...(outputFormat === 'ESM' && { outputFormat: 'ESM' }), } ); - }); + } // Deploy the test stack await testStack.deploy(); @@ -141,20 +141,19 @@ describe(`Layers E2E tests`, () => { describe.each(cases)( 'utilities tests for %s output format', (outputFormat) => { - let invocationLogs: TestInvocationLogs; - beforeAll(() => { + it('should have no errors in the logs, which indicates the pacakges version matches the expected one', () => { const maybeInvocationLogs = invocationLogsMap.get(outputFormat); assertLogs(maybeInvocationLogs); - invocationLogs = maybeInvocationLogs; - }); - - it('should have no errors in the logs, which indicates the pacakges version matches the expected one', () => { + const invocationLogs = maybeInvocationLogs; const logs = invocationLogs.getFunctionLogs('ERROR'); expect(logs.length).toBe(0); }); it('should have one warning related to missing Metrics namespace', () => { + const maybeInvocationLogs = invocationLogsMap.get(outputFormat); + assertLogs(maybeInvocationLogs); + const invocationLogs = maybeInvocationLogs; const logs = invocationLogs.getFunctionLogs('WARN'); expect(logs.length).toBe(1); @@ -162,7 +161,11 @@ describe(`Layers E2E tests`, () => { }); it('should have one info log related to coldstart metric', () => { + const maybeInvocationLogs = invocationLogsMap.get(outputFormat); + assertLogs(maybeInvocationLogs); + const invocationLogs = maybeInvocationLogs; const logs = invocationLogs.getFunctionLogs(); + const emfLogEntry = logs.find((log) => log.match( /{"_aws":{"Timestamp":\d+,"CloudWatchMetrics":\[\{"Namespace":"\S+","Dimensions":\[\["service"\]\],"Metrics":\[\{"Name":"ColdStart","Unit":"Count"\}\]\}\]},"service":"\S+","ColdStart":1}/ @@ -173,6 +176,9 @@ describe(`Layers E2E tests`, () => { }); it('should have one debug log with tracer subsegment info', () => { + const maybeInvocationLogs = invocationLogsMap.get(outputFormat); + assertLogs(maybeInvocationLogs); + const invocationLogs = maybeInvocationLogs; const logs = invocationLogs.getFunctionLogs('DEBUG'); expect(logs.length).toBe(1); diff --git a/layers/tests/tsconfig.json b/layers/tests/tsconfig.json index a07fdb8a65..0bbd7e9af9 100644 --- a/layers/tests/tsconfig.json +++ b/layers/tests/tsconfig.json @@ -1,12 +1,8 @@ { - "extends": "../tsconfig.json", - "compilerOptions": { - "rootDir": "../", - "noEmit": true - }, - "include": [ - "../src/**/*", - "../package.json", - "./**/*", - ] -} \ No newline at end of file + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../", + "noEmit": true + }, + "include": ["../src/**/*", "../package.json", "./**/*"] +} diff --git a/layers/tsconfig.json b/layers/tsconfig.json index 4acbde11be..5194193adc 100644 --- a/layers/tsconfig.json +++ b/layers/tsconfig.json @@ -1,12 +1,9 @@ { - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "./lib", - "rootDir": "./", - "resolveJsonModule": true - }, - "include": [ - "./src/**/*", - "./bin/**/*" - ], -} \ No newline at end of file + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "./lib", + "rootDir": "./", + "resolveJsonModule": true + }, + "include": ["./src/**/*", "./bin/**/*"] +}