diff --git a/.github/workflows/pr_lint_and_test.yml b/.github/workflows/pr_lint_and_test.yml index df1cd9dd3b..7341f07d95 100644 --- a/.github/workflows/pr_lint_and_test.yml +++ b/.github/workflows/pr_lint_and_test.yml @@ -7,12 +7,16 @@ jobs: runs-on: ubuntu-latest env: NODE_ENV: dev + strategy: + matrix: + version: [12, 14, 16] + fail-fast: false steps: - uses: actions/checkout@v3 - - name: "Use NodeJS 16" + - name: "Use NodeJS" uses: actions/setup-node@v3 with: - node-version: '16' + node-version: ${{ matrix.version }} - name: Install npm@8.x run: npm i -g npm@next-8 - name: "Setup npm" diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index b6420d71f0..7b17f76092 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -49,13 +49,14 @@ jobs: matrix: package: [logger, metrics, tracer] version: [12, 14, 16] + fail-fast: false steps: - name: "Checkout" uses: actions/checkout@v3 - - name: "Use NodeJS 16" + - name: "Use NodeJS" uses: actions/setup-node@v3 with: - node-version: 16 + node-version: ${{ matrix.version }} - name: "Install npm@8.x" run: npm i -g npm@next-8 - name: "Install monorepo packages" diff --git a/examples/cdk/tsconfig.json b/examples/cdk/tsconfig.json index 3d8421df47..ce59f26c4a 100644 --- a/examples/cdk/tsconfig.json +++ b/examples/cdk/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "outDir": "lib", @@ -22,7 +22,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, -"lib": [ "es2020" ], +"lib": [ "es2019" ], "types": [ "jest", "node" diff --git a/examples/lambda-functions/tsconfig.json b/examples/lambda-functions/tsconfig.json index 6fe6024ff3..b253fc49a1 100644 --- a/examples/lambda-functions/tsconfig.json +++ b/examples/lambda-functions/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -21,7 +21,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "node" ] diff --git a/examples/sam/src/tsconfig.json b/examples/sam/src/tsconfig.json index 6fe6024ff3..b253fc49a1 100644 --- a/examples/sam/src/tsconfig.json +++ b/examples/sam/src/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -21,7 +21,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "node" ] diff --git a/examples/sam/tsconfig.json b/examples/sam/tsconfig.json index 6fe6024ff3..b253fc49a1 100644 --- a/examples/sam/tsconfig.json +++ b/examples/sam/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -21,7 +21,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "node" ] diff --git a/package-lock.json b/package-lock.json index 8868345202..e36f0711fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "@types/aws-lambda": "^8.10.72", "@types/jest": "^27.4.0", "@types/node": "^17.0.8", + "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^5.12.1", "@typescript-eslint/parser": "^5.12.1", "archiver": "^5.3.0", @@ -48,7 +49,8 @@ "ts-node": "^10.0.0", "typedoc": "^0.22.11", "typedoc-plugin-missing-exports": "^0.22.6", - "typescript": "^4.1.3" + "typescript": "^4.1.3", + "uuid": "^8.3.2" }, "engines": { "node": ">=12" @@ -373,15 +375,6 @@ "node": ">=12.0.0" } }, - "node_modules/@aws-sdk/client-dynamodb/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@aws-sdk/client-sso": { "version": "3.58.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.58.0.tgz", @@ -736,15 +729,6 @@ "node": ">= 12.0.0" } }, - "node_modules/@aws-sdk/middleware-retry/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@aws-sdk/middleware-sdk-sts": { "version": "3.58.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.58.0.tgz", @@ -3997,6 +3981,12 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true + }, "node_modules/@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -4963,6 +4953,16 @@ "node": ">= 10.0.0" } }, + "node_modules/aws-sdk/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -13474,6 +13474,16 @@ "node": ">=0.8" } }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -14337,6 +14347,16 @@ "node": ">=8" } }, + "node_modules/temp-write/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -14926,13 +14946,12 @@ } }, "node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "bin": { - "uuid": "bin/uuid" + "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache": { @@ -15849,14 +15868,6 @@ "@aws-sdk/util-waiter": "3.55.0", "tslib": "^2.3.1", "uuid": "^8.3.2" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - } } }, "@aws-sdk/client-sso": { @@ -16157,14 +16168,6 @@ "@aws-sdk/util-middleware": "3.55.0", "tslib": "^2.3.1", "uuid": "^8.3.2" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - } } }, "@aws-sdk/middleware-sdk-sts": { @@ -18829,6 +18832,12 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true + }, "@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -19505,6 +19514,14 @@ "url": "0.10.3", "uuid": "3.3.2", "xml2js": "0.4.19" + }, + "dependencies": { + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + } } }, "aws-sign2": { @@ -26190,6 +26207,12 @@ "psl": "^1.1.28", "punycode": "^2.1.1" } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true } } }, @@ -26838,6 +26861,14 @@ "make-dir": "^3.0.0", "temp-dir": "^1.0.0", "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "terminal-link": { @@ -27280,9 +27311,9 @@ } }, "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, "v8-compile-cache": { diff --git a/package.json b/package.json index 2e7676dfad..d7a987463b 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "@types/aws-lambda": "^8.10.72", "@types/jest": "^27.4.0", "@types/node": "^17.0.8", + "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^5.12.1", "@typescript-eslint/parser": "^5.12.1", "archiver": "^5.3.0", @@ -78,7 +79,8 @@ "ts-node": "^10.0.0", "typedoc": "^0.22.11", "typedoc-plugin-missing-exports": "^0.22.6", - "typescript": "^4.1.3" + "typescript": "^4.1.3", + "uuid": "^8.3.2" }, "files": [ "lib/**/*" diff --git a/packages/commons/tsconfig-dev.json b/packages/commons/tsconfig-dev.json index 802f18e8f9..7743a7b77d 100644 --- a/packages/commons/tsconfig-dev.json +++ b/packages/commons/tsconfig-dev.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -23,7 +23,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "jest", "node" diff --git a/packages/commons/tsconfig.json b/packages/commons/tsconfig.json index cbd9922f32..19330d4c1b 100644 --- a/packages/commons/tsconfig.json +++ b/packages/commons/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -23,7 +23,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "jest", "node" diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index e26fdfac27..f83e0d3b8f 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -252,12 +252,16 @@ class Logger extends Utility implements ClassThatLogs { */ public injectLambdaContext(): HandlerMethodDecorator { return (target, _propertyKey, descriptor) => { - const originalMethod = descriptor.value; + /** + * The descriptor.value is the method this decorator decorates, it cannot be undefined. + */ + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const originalMethod = descriptor.value!; descriptor.value = (event, context, callback) => { this.addContext(context); - return originalMethod?.apply(target, [ event, context, callback ]); + return originalMethod.apply(target, [ event, context, callback ]); }; }; } @@ -446,11 +450,11 @@ class Logger extends Utility implements ClassThatLogs { * @returns {number} */ private getSampleRateValue(): number { - if (!this.powertoolLogData?.sampleRateValue) { + if (!this.powertoolLogData.sampleRateValue) { this.setSampleRateValue(); } - return this.powertoolLogData?.sampleRateValue; + return this.powertoolLogData.sampleRateValue; } /** diff --git a/packages/logger/tests/e2e/basicFeatures.middy.test.ts b/packages/logger/tests/e2e/basicFeatures.middy.test.ts index ab36645acd..2595b92ec6 100644 --- a/packages/logger/tests/e2e/basicFeatures.middy.test.ts +++ b/packages/logger/tests/e2e/basicFeatures.middy.test.ts @@ -8,9 +8,9 @@ */ import path from 'path'; -import { randomUUID } from 'crypto'; import { App, Stack } from 'aws-cdk-lib'; import { APIGatewayAuthorizerResult } from 'aws-lambda'; +import { v4 } from 'uuid'; import { createStackWithLambdaFunction, generateUniqueName, @@ -35,7 +35,7 @@ if (!isValidRuntimeKey(runtime)) { const LEVEL = InvocationLogs.LEVEL; -const uuid = randomUUID(); +const uuid = v4(); const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'BasicFeatures-Middy'); const functionName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'BasicFeatures-Middy'); const lambdaFunctionCodeFile = 'basicFeatures.middy.test.FunctionCode.ts'; diff --git a/packages/logger/tests/e2e/childLogger.manual.test.ts b/packages/logger/tests/e2e/childLogger.manual.test.ts index b8bc59c47d..325f9cf4ad 100644 --- a/packages/logger/tests/e2e/childLogger.manual.test.ts +++ b/packages/logger/tests/e2e/childLogger.manual.test.ts @@ -8,8 +8,8 @@ */ import path from 'path'; -import { randomUUID } from 'crypto'; import { App, Stack } from 'aws-cdk-lib'; +import { v4 } from 'uuid'; import { createStackWithLambdaFunction, generateUniqueName, @@ -34,7 +34,7 @@ if (!isValidRuntimeKey(runtime)) { const LEVEL = InvocationLogs.LEVEL; -const uuid = randomUUID(); +const uuid = v4(); const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'ChildLogger-Manual'); const functionName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'ChildLogger-Manual'); const lambdaFunctionCodeFile = 'childLogger.manual.test.FunctionCode.ts'; diff --git a/packages/logger/tests/e2e/sampleRate.decorator.test.ts b/packages/logger/tests/e2e/sampleRate.decorator.test.ts index 038d61b4b5..1b349b8579 100644 --- a/packages/logger/tests/e2e/sampleRate.decorator.test.ts +++ b/packages/logger/tests/e2e/sampleRate.decorator.test.ts @@ -8,8 +8,8 @@ */ import path from 'path'; -import { randomUUID } from 'crypto'; import { App, Stack } from 'aws-cdk-lib'; +import { v4 } from 'uuid'; import { createStackWithLambdaFunction, generateUniqueName, @@ -34,7 +34,7 @@ if (!isValidRuntimeKey(runtime)) { const LEVEL = InvocationLogs.LEVEL; -const uuid = randomUUID(); +const uuid = v4(); const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'SampleRate-Decorator'); const functionName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'SampleRate-Decorator'); const lambdaFunctionCodeFile = 'sampleRate.decorator.test.FunctionCode.ts'; diff --git a/packages/logger/tsconfig-dev.json b/packages/logger/tsconfig-dev.json index 4ea999b37f..7c6046c8bc 100644 --- a/packages/logger/tsconfig-dev.json +++ b/packages/logger/tsconfig-dev.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -22,7 +22,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "jest", "node" diff --git a/packages/logger/tsconfig.es.json b/packages/logger/tsconfig.es.json index 4ea999b37f..7c6046c8bc 100644 --- a/packages/logger/tsconfig.es.json +++ b/packages/logger/tsconfig.es.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -22,7 +22,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "jest", "node" diff --git a/packages/logger/tsconfig.json b/packages/logger/tsconfig.json index 20da6e39a9..3d7d8b8b05 100644 --- a/packages/logger/tsconfig.json +++ b/packages/logger/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "outDir": "lib", @@ -22,7 +22,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "jest", "node" diff --git a/packages/metrics/src/Metrics.ts b/packages/metrics/src/Metrics.ts index 36aad90687..aba0e0d865 100644 --- a/packages/metrics/src/Metrics.ts +++ b/packages/metrics/src/Metrics.ts @@ -237,7 +237,11 @@ class Metrics extends Utility implements MetricsInterface { } return (target, _propertyKey, descriptor) => { - const originalMethod = descriptor.value; + /** + * The descriptor.value is the method this decorator decorates, it cannot be undefined. + */ + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const originalMethod = descriptor.value!; descriptor.value = ( async (event: unknown, context: Context, callback: Callback): Promise => { this.functionName = context.functionName; @@ -245,7 +249,7 @@ class Metrics extends Utility implements MetricsInterface { let result: unknown; try { - result = await originalMethod?.apply(target, [ event, context, callback ]); + result = await originalMethod.apply(target, [ event, context, callback ]); } catch (error) { throw error; } finally { diff --git a/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts b/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts index 5d53d812d5..bf7afa1bdb 100644 --- a/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts +++ b/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts @@ -8,10 +8,10 @@ */ import path from 'path'; -import { randomUUID } from 'crypto'; import { Tracing } from 'aws-cdk-lib/aws-lambda'; import { App, Stack } from 'aws-cdk-lib'; import * as AWS from 'aws-sdk'; +import { v4 } from 'uuid'; import { generateUniqueName, isValidRuntimeKey, @@ -35,7 +35,7 @@ if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); } -const uuid = randomUUID(); +const uuid = v4(); const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'decorator'); const functionName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'decorator'); const lambdaFunctionCodeFile = 'basicFeatures.decorator.test.functionCode.ts'; diff --git a/packages/metrics/tests/e2e/basicFeatures.manual.test.ts b/packages/metrics/tests/e2e/basicFeatures.manual.test.ts index f0ebecfdfc..6a43fb665f 100644 --- a/packages/metrics/tests/e2e/basicFeatures.manual.test.ts +++ b/packages/metrics/tests/e2e/basicFeatures.manual.test.ts @@ -8,10 +8,10 @@ */ import path from 'path'; -import { randomUUID } from 'crypto'; import { Tracing } from 'aws-cdk-lib/aws-lambda'; import { App, Stack } from 'aws-cdk-lib'; import * as AWS from 'aws-sdk'; +import { v4 } from 'uuid'; import { generateUniqueName, isValidRuntimeKey, @@ -35,7 +35,7 @@ if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); } -const uuid = randomUUID(); +const uuid = v4(); const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'manual'); const functionName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'manual'); const lambdaFunctionCodeFile = 'basicFeatures.manual.test.functionCode.ts'; diff --git a/packages/metrics/tsconfig.es.json b/packages/metrics/tsconfig.es.json index d28abaa6d5..65215a1c76 100644 --- a/packages/metrics/tsconfig.es.json +++ b/packages/metrics/tsconfig.es.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -23,7 +23,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "jest", "node" diff --git a/packages/metrics/tsconfig.json b/packages/metrics/tsconfig.json index 582618277f..23252b808b 100644 --- a/packages/metrics/tsconfig.json +++ b/packages/metrics/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -24,7 +24,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "jest", "node" diff --git a/packages/tracer/src/Tracer.ts b/packages/tracer/src/Tracer.ts index b25d940777..ba554f72ae 100644 --- a/packages/tracer/src/Tracer.ts +++ b/packages/tracer/src/Tracer.ts @@ -123,7 +123,8 @@ class Tracer extends Utility implements TracerInterface { private customConfigService?: ConfigServiceInterface; - private envVarsService?: EnvironmentVariablesService; + // envVarsService is always initialized in the constructor in setOptions() + private envVarsService!: EnvironmentVariablesService; private serviceName?: string; @@ -340,11 +341,15 @@ class Tracer extends Utility implements TracerInterface { */ public captureLambdaHandler(): HandlerMethodDecorator { return (target, _propertyKey, descriptor) => { - const originalMethod = descriptor.value; + /** + * The descriptor.value is the method this decorator decorates, it cannot be undefined. + */ + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const originalMethod = descriptor.value!; descriptor.value = ((event, context, callback) => { if (!this.isTracingEnabled()) { - return originalMethod?.apply(target, [ event, context, callback ]); + return originalMethod.apply(target, [ event, context, callback ]); } return this.provider.captureAsyncFunc(`## ${process.env._HANDLER}`, async subsegment => { @@ -352,7 +357,7 @@ class Tracer extends Utility implements TracerInterface { this.addServiceNameAnnotation(); let result: unknown; try { - result = await originalMethod?.apply(target, [ event, context, callback ]); + result = await originalMethod.apply(target, [ event, context, callback ]); this.addResponseAsMetadata(result, process.env._HANDLER); } catch (error) { this.addErrorAsMetadata(error as Error); @@ -407,17 +412,19 @@ class Tracer extends Utility implements TracerInterface { */ public captureMethod(): MethodDecorator { return (target, _propertyKey, descriptor) => { - const originalMethod = descriptor.value; + // The descriptor.value is the method this decorator decorates, it cannot be undefined. + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const originalMethod = descriptor.value!; descriptor.value = (...args: unknown[]) => { if (!this.isTracingEnabled()) { - return originalMethod?.apply(target, [...args]); + return originalMethod.apply(target, [...args]); } return this.provider.captureAsyncFunc(`### ${originalMethod.name}`, async subsegment => { let result; try { - result = await originalMethod?.apply(this, [...args]); + result = await originalMethod.apply(this, [...args]); this.addResponseAsMetadata(result, originalMethod.name); } catch (error) { this.addErrorAsMetadata(error as Error); @@ -509,7 +516,7 @@ class Tracer extends Utility implements TracerInterface { return; } - document?.addAnnotation(key, value); + document.addAnnotation(key, value); } /** @@ -544,7 +551,7 @@ class Tracer extends Utility implements TracerInterface { } namespace = namespace || this.serviceName; - document?.addMetadata(key, value, namespace); + document.addMetadata(key, value, namespace); } /** @@ -588,7 +595,7 @@ class Tracer extends Utility implements TracerInterface { * Used internally during initialization. */ private getEnvVarsService(): EnvironmentVariablesService { - return this.envVarsService; + return this.envVarsService; } /** @@ -596,7 +603,7 @@ class Tracer extends Utility implements TracerInterface { * Used internally during initialization. */ private isLambdaExecutionEnv(): boolean { - return this.getEnvVarsService()?.getAwsExecutionEnv() !== ''; + return this.getEnvVarsService().getAwsExecutionEnv() !== ''; } /** @@ -604,7 +611,7 @@ class Tracer extends Utility implements TracerInterface { * Used internally during initialization. */ private isLambdaSamCli(): boolean { - return this.getEnvVarsService()?.getSamLocal() !== ''; + return this.getEnvVarsService().getSamLocal() !== ''; } /** @@ -629,7 +636,7 @@ class Tracer extends Utility implements TracerInterface { return; } - const envVarsValue = this.getEnvVarsService()?.getTracingCaptureError(); + const envVarsValue = this.getEnvVarsService().getTracingCaptureError(); if (envVarsValue.toLowerCase() === 'false') { this.captureError = false; @@ -662,7 +669,7 @@ class Tracer extends Utility implements TracerInterface { return; } - const envVarsValue = this.getEnvVarsService()?.getCaptureHTTPsRequests(); + const envVarsValue = this.getEnvVarsService().getCaptureHTTPsRequests(); if (envVarsValue.toLowerCase() === 'false') { this.captureHTTPsRequests = false; @@ -682,7 +689,7 @@ class Tracer extends Utility implements TracerInterface { return; } - const envVarsValue = this.getEnvVarsService()?.getTracingCaptureResponse(); + const envVarsValue = this.getEnvVarsService().getTracingCaptureResponse(); if (envVarsValue.toLowerCase() === 'false') { this.captureResponse = false; @@ -753,7 +760,7 @@ class Tracer extends Utility implements TracerInterface { return; } - const envVarsValue = this.getEnvVarsService()?.getServiceName(); + const envVarsValue = this.getEnvVarsService().getServiceName(); if (envVarsValue !== undefined && Tracer.isValidServiceName(envVarsValue)) { this.serviceName = envVarsValue; @@ -781,7 +788,7 @@ class Tracer extends Utility implements TracerInterface { return; } - const envVarsValue = this.getEnvVarsService()?.getTracingEnabled(); + const envVarsValue = this.getEnvVarsService().getTracingEnabled(); if (envVarsValue.toLowerCase() === 'false') { this.tracingEnabled = false; diff --git a/packages/tracer/src/middleware/middy.ts b/packages/tracer/src/middleware/middy.ts index 2114a80533..bac2490177 100644 --- a/packages/tracer/src/middleware/middy.ts +++ b/packages/tracer/src/middleware/middy.ts @@ -37,7 +37,7 @@ const captureLambdaHandler = (target: Tracer): middy.MiddlewareObj => { const close = (): void => { const subsegment = target.getSegment(); - subsegment?.close(); + subsegment.close(); target.setSegment(lambdaSegment as Segment); }; diff --git a/packages/tracer/tests/e2e/allFeatures.decorator.test.ts b/packages/tracer/tests/e2e/allFeatures.decorator.test.ts index 535a9660e1..5c2272f18a 100644 --- a/packages/tracer/tests/e2e/allFeatures.decorator.test.ts +++ b/packages/tracer/tests/e2e/allFeatures.decorator.test.ts @@ -4,11 +4,11 @@ * @group e2e/tracer/decorator */ -import { randomUUID } from 'crypto'; import path from 'path'; import { Table, AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb'; import { App, Stack, RemovalPolicy } from 'aws-cdk-lib'; import * as AWS from 'aws-sdk'; +import { v4 } from 'uuid'; import { deployStack, destroyStack } from '../../../commons/tests/utils/cdk-cli'; import { getTraces, @@ -54,27 +54,27 @@ if (!isValidRuntimeKey(runtime)) { * Each stack must use a unique `serviceName` as it's used to for retrieving the trace. * Using the same one will result in traces from different test cases mixing up. */ -const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, randomUUID(), runtime, 'AllFeatures-Decorator'); +const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, v4(), runtime, 'AllFeatures-Decorator'); const lambdaFunctionCodeFile = 'allFeatures.decorator.test.functionCode.ts'; let startTime: Date; /** * Function #1 is with all flags enabled. */ -const uuidFunction1 = randomUUID(); +const uuidFunction1 = v4(); const functionNameWithAllFlagsEnabled = generateUniqueName(RESOURCE_NAME_PREFIX, uuidFunction1, runtime, 'AllFeatures-Decoratory-AllFlagsEnabled'); const serviceNameWithAllFlagsEnabled = functionNameWithAllFlagsEnabled; /** * Function #2 doesn't capture error or response */ -const uuidFunction2 = randomUUID(); +const uuidFunction2 = v4(); const functionNameWithNoCaptureErrorOrResponse = generateUniqueName(RESOURCE_NAME_PREFIX, uuidFunction2, runtime, 'AllFeatures-Decorator-NoCaptureErrorOrResponse'); const serviceNameWithNoCaptureErrorOrResponse = functionNameWithNoCaptureErrorOrResponse; /** * Function #3 disables tracer */ -const uuidFunction3 = randomUUID(); +const uuidFunction3 = v4(); const functionNameWithTracerDisabled = generateUniqueName(RESOURCE_NAME_PREFIX, uuidFunction3, runtime, 'AllFeatures-Decorator-TracerDisabled'); const serviceNameWithTracerDisabled = functionNameWithNoCaptureErrorOrResponse; diff --git a/packages/tracer/tests/e2e/allFeatures.manual.test.ts b/packages/tracer/tests/e2e/allFeatures.manual.test.ts index de8920f55b..ed97abb3ad 100644 --- a/packages/tracer/tests/e2e/allFeatures.manual.test.ts +++ b/packages/tracer/tests/e2e/allFeatures.manual.test.ts @@ -4,11 +4,11 @@ * @group e2e/tracer/manual */ -import { randomUUID } from 'crypto'; import path from 'path'; import { Table, AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb'; import { App, Stack, RemovalPolicy } from 'aws-cdk-lib'; import * as AWS from 'aws-sdk'; +import { v4 } from 'uuid'; import { deployStack, destroyStack } from '../../../commons/tests/utils/cdk-cli'; import { getTraces, @@ -47,7 +47,7 @@ if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); } -const uuid = randomUUID(); +const uuid = v4(); const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'AllFeatures-Manual'); const functionName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'AllFeatures-Manual'); const lambdaFunctionCodeFile = 'allFeatures.manual.test.functionCode.ts'; diff --git a/packages/tracer/tests/e2e/allFeatures.middy.test.ts b/packages/tracer/tests/e2e/allFeatures.middy.test.ts index 8cb26b84b6..2f4b7cf931 100644 --- a/packages/tracer/tests/e2e/allFeatures.middy.test.ts +++ b/packages/tracer/tests/e2e/allFeatures.middy.test.ts @@ -4,11 +4,11 @@ * @group e2e/tracer/middy */ -import { randomUUID } from 'crypto'; import path from 'path'; import { Table, AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb'; import { App, Stack, RemovalPolicy } from 'aws-cdk-lib'; import * as AWS from 'aws-sdk'; +import { v4 } from 'uuid'; import { deployStack, destroyStack } from '../../../commons/tests/utils/cdk-cli'; import { getTraces, @@ -54,27 +54,27 @@ if (!isValidRuntimeKey(runtime)) { * Each stack must use a unique `serviceName` as it's used to for retrieving the trace. * Using the same one will result in traces from different test cases mixing up. */ -const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, randomUUID(), runtime, 'AllFeatures-Middy'); +const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, v4(), runtime, 'AllFeatures-Middy'); const lambdaFunctionCodeFile = 'allFeatures.middy.test.functionCode.ts'; let startTime: Date; /** * Function #1 is with all flags enabled. */ -const uuidFunction1 = randomUUID(); +const uuidFunction1 = v4(); const functionNameWithAllFlagsEnabled = generateUniqueName(RESOURCE_NAME_PREFIX, uuidFunction1, runtime, 'AllFeatures-Middy-AllFlagsEnabled'); const serviceNameWithAllFlagsEnabled = functionNameWithAllFlagsEnabled; /** * Function #2 doesn't capture error or response */ -const uuidFunction2 = randomUUID(); +const uuidFunction2 = v4(); const functionNameWithNoCaptureErrorOrResponse = generateUniqueName(RESOURCE_NAME_PREFIX, uuidFunction2, runtime, 'AllFeatures-Middy-NoCaptureErrorOrResponse'); const serviceNameWithNoCaptureErrorOrResponse = functionNameWithNoCaptureErrorOrResponse; /** * Function #3 disables tracer */ -const uuidFunction3 = randomUUID(); +const uuidFunction3 = v4(); const functionNameWithTracerDisabled = generateUniqueName(RESOURCE_NAME_PREFIX, uuidFunction3, runtime, 'AllFeatures-Middy-TracerDisabled'); const serviceNameWithTracerDisabled = functionNameWithNoCaptureErrorOrResponse; diff --git a/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts b/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts index 96f4de7abc..21cd44840c 100644 --- a/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts +++ b/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts @@ -4,11 +4,11 @@ * @group e2e/tracer/decorator-async-handler */ -import { randomUUID } from 'crypto'; import path from 'path'; import { Table, AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb'; import { App, Stack, RemovalPolicy } from 'aws-cdk-lib'; import * as AWS from 'aws-sdk'; +import { v4 } from 'uuid'; import { deployStack, destroyStack } from '../../../commons/tests/utils/cdk-cli'; import { getTraces, @@ -46,11 +46,11 @@ if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); } -const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, randomUUID(), runtime, 'AllFeatures-Decorator'); +const stackName = generateUniqueName(RESOURCE_NAME_PREFIX, v4(), runtime, 'AllFeatures-Decorator'); const lambdaFunctionCodeFile = 'asyncHandler.decorator.test.functionCode.ts'; let startTime: Date; -const uuid = randomUUID(); +const uuid = v4(); const functionName = generateUniqueName(RESOURCE_NAME_PREFIX, uuid, runtime, 'AllFeatures-Decoratory-AllFlagsEnabled'); const serviceName = functionName; diff --git a/packages/tracer/tests/unit/Tracer.test.ts b/packages/tracer/tests/unit/Tracer.test.ts index 377ff13136..fb34bfb71f 100644 --- a/packages/tracer/tests/unit/Tracer.test.ts +++ b/packages/tracer/tests/unit/Tracer.test.ts @@ -8,11 +8,22 @@ import { Tracer } from '../../src'; import { Callback, Context, Handler } from 'aws-lambda/handler'; import { Segment, setContextMissingStrategy, Subsegment } from 'aws-xray-sdk-core'; import { DynamoDB } from 'aws-sdk'; +import { ProviderServiceInterface } from '../../src/provider'; interface LambdaInterface { handler: Handler } +type CaptureAsyncFuncMock = jest.SpyInstance unknown, parent?: Segment | Subsegment]>; +const createCaptureAsyncFuncMock = function(provider: ProviderServiceInterface): CaptureAsyncFuncMock { + return jest.spyOn(provider, 'captureAsyncFunc') + .mockImplementation((methodName, callBackFn) => { + const subsegment = new Subsegment(`### ${methodName}`); + jest.spyOn(subsegment, 'flush').mockImplementation(() => null); + callBackFn(subsegment); + }); +}; + jest.spyOn(console, 'debug').mockImplementation(() => null); jest.spyOn(console, 'warn').mockImplementation(() => null); jest.spyOn(console, 'error').mockImplementation(() => null); @@ -579,7 +590,7 @@ describe('Class: Tracer', () => { describe('Method: captureLambdaHandler', () => { test('when used as decorator while tracing is disabled, it does nothing', async () => { - + // Prepare const tracer: Tracer = new Tracer({ enabled: false }); jest.spyOn(tracer.provider, 'getSegment').mockImplementation(() => new Segment('facade', process.env._X_AMZN_TRACE_ID || null)); @@ -763,7 +774,7 @@ describe('Class: Tracer', () => { .mockImplementationOnce(() => newSubsegmentFirstInvocation) .mockImplementation(() => newSubsegmentSecondInvocation); setContextMissingStrategy(() => null); - const captureAsyncFuncSpy = jest.spyOn(tracer.provider, 'captureAsyncFunc'); + const captureAsyncFuncSpy = createCaptureAsyncFuncMock(tracer.provider); const putAnnotationSpy = jest.spyOn(tracer, 'putAnnotation'); class Lambda implements LambdaInterface { @@ -814,7 +825,7 @@ describe('Class: Tracer', () => { jest.spyOn(tracer.provider, 'getSegment') .mockImplementation(() => newSubsegment); setContextMissingStrategy(() => null); - const captureAsyncFuncSpy = jest.spyOn(tracer.provider, 'captureAsyncFunc'); + const captureAsyncFuncSpy = createCaptureAsyncFuncMock(tracer.provider); class Lambda implements LambdaInterface { @tracer.captureLambdaHandler() @@ -930,7 +941,7 @@ describe('Class: Tracer', () => { jest.spyOn(tracer.provider, 'getSegment') .mockImplementation(() => newSubsegment); setContextMissingStrategy(() => null); - const captureAsyncFuncSpy = jest.spyOn(tracer.provider, 'captureAsyncFunc'); + const captureAsyncFuncSpy = createCaptureAsyncFuncMock(tracer.provider); const addErrorSpy = jest.spyOn(newSubsegment, 'addError'); class Lambda implements LambdaInterface { diff --git a/packages/tracer/tsconfig.es.json b/packages/tracer/tsconfig.es.json index 802f18e8f9..7743a7b77d 100644 --- a/packages/tracer/tsconfig.es.json +++ b/packages/tracer/tsconfig.es.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -23,7 +23,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "jest", "node" diff --git a/packages/tracer/tsconfig.json b/packages/tracer/tsconfig.json index 8b93f8c299..c3cb48b6fb 100644 --- a/packages/tracer/tsconfig.json +++ b/packages/tracer/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "experimentalDecorators": true, "noImplicitAny": true, - "target": "ES2020", + "target": "ES2019", "module": "commonjs", "declaration": true, "declarationMap": true, @@ -24,7 +24,7 @@ "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority" }, - "lib": [ "es2020" ], + "lib": [ "es2019" ], "types": [ "jest", "node"