diff --git a/jest.config.js b/jest.config.js index bfe10956..34f40f44 100644 --- a/jest.config.js +++ b/jest.config.js @@ -9,6 +9,6 @@ module.exports = { testEnvironment: "/testEnvironment.js", clearMocks: true, collectCoverageFrom: ["src/**/*.ts"], - testRegex: "(src\\/).*(\\.spec\\.ts)$", - testPathIgnorePatterns: ["\\.snap$", "/node_modules/", "snapshot_tests/"], + testRegex: String.raw`(src[\/]).*(\.spec\.ts)$`, + testPathIgnorePatterns: [String.raw`\.snap$`, "/node_modules/", "snapshot_tests/"], }; diff --git a/jest.integration.config.js b/jest.integration.config.js index 1acc8f6b..57784b4e 100644 --- a/jest.integration.config.js +++ b/jest.integration.config.js @@ -9,5 +9,5 @@ module.exports = { testEnvironment: "/testEnvironment.js", clearMocks: true, collectCoverageFrom: ["src/**/*.ts"], - testRegex: ["(snapshot_tests\\/).*(\\.spec\\.ts)$"], + testRegex: [String.raw`(snapshot_tests[\/]).*(\.spec\.ts)$`], }; diff --git a/package.json b/package.json index 05988f89..b1f1d213 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,9 @@ ] }, "dependencies": { + "@aws-sdk/client-cloudformation": "^3.137.0", + "@aws-sdk/client-cloudwatch-logs": "^3.137.0", + "@aws-sdk/client-lambda": "^3.137.0", "@datadog/datadog-ci-base": "^5.16.1", "simple-git": "^3.36.0" }, diff --git a/src/aws-sdk-request.spec.ts b/src/aws-sdk-request.spec.ts new file mode 100644 index 00000000..ca1372e1 --- /dev/null +++ b/src/aws-sdk-request.spec.ts @@ -0,0 +1,102 @@ +import Aws from "serverless/plugins/aws/provider/awsProvider"; +import { + cloudFormationDescribeStacks, + cloudWatchLogsDescribeSubscriptionFilters, + lambdaGetFunction, +} from "./aws-sdk-request"; + +const lambdaSend = jest.fn(); +const logsSend = jest.fn(); +const cfnSend = jest.fn(); + +const LambdaClient = jest.fn().mockImplementation(() => ({ send: lambdaSend })); +const CloudWatchLogsClient = jest.fn().mockImplementation(() => ({ send: logsSend })); +const CloudFormationClient = jest.fn().mockImplementation(() => ({ send: cfnSend })); + +jest.mock("@aws-sdk/client-lambda", () => ({ + LambdaClient, + GetFunctionCommand: jest.fn().mockImplementation((input) => ({ input })), +})); +jest.mock("@aws-sdk/client-cloudwatch-logs", () => ({ + CloudWatchLogsClient, + DescribeSubscriptionFiltersCommand: jest.fn().mockImplementation((input) => ({ input })), +})); +jest.mock("@aws-sdk/client-cloudformation", () => ({ + CloudFormationClient, + DescribeStacksCommand: jest.fn().mockImplementation((input) => ({ input })), +})); + +/** Serverless Framework style provider: exposes request(), no getAwsSdkV3Config(). */ +function legacyAwsMock(requestImpl: jest.Mock): Aws { + return { request: requestImpl } as unknown as Aws; +} + +/** osls v4 style provider: exposes getAwsSdkV3Config(), request() throws. */ +function oslsV4AwsMock(config: Record = { region: "us-east-1" }): Aws { + return { + getAwsSdkV3Config: jest.fn().mockResolvedValue(config), + request: jest.fn().mockRejectedValue(new Error("AWS_SDK_V2_SURFACE_REMOVED")), + } as unknown as Aws; +} + +describe("aws-sdk-request dual path", () => { + describe("Serverless Framework (legacy provider.request path)", () => { + it("lambdaGetFunction calls provider.request", async () => { + const request = jest.fn().mockResolvedValue(undefined); + await lambdaGetFunction(legacyAwsMock(request), "my-forwarder"); + expect(request).toHaveBeenCalledWith("Lambda", "getFunction", { FunctionName: "my-forwarder" }); + expect(LambdaClient).not.toHaveBeenCalled(); + }); + + it("cloudWatchLogsDescribeSubscriptionFilters returns filters from provider.request", async () => { + const filters = [{ filterName: "dd" }]; + const request = jest.fn().mockResolvedValue({ subscriptionFilters: filters }); + const result = await cloudWatchLogsDescribeSubscriptionFilters(legacyAwsMock(request), "/aws/lambda/foo"); + expect(request).toHaveBeenCalledWith("CloudWatchLogs", "describeSubscriptionFilters", { + logGroupName: "/aws/lambda/foo", + }); + expect(result).toBe(filters); + }); + + it("cloudFormationDescribeStacks calls provider.request with region option", async () => { + const output = { Stacks: [{ StackId: "abc" }] }; + const request = jest.fn().mockResolvedValue(output); + const result = await cloudFormationDescribeStacks(legacyAwsMock(request), "my-stack", "eu-west-1"); + expect(request).toHaveBeenCalledWith( + "CloudFormation", + "describeStacks", + { StackName: "my-stack" }, + { region: "eu-west-1" }, + ); + expect(result).toBe(output); + }); + }); + + describe("osls v4 (AWS SDK v3 client path)", () => { + it("lambdaGetFunction constructs a LambdaClient and sends GetFunctionCommand", async () => { + lambdaSend.mockResolvedValue({}); + const aws = oslsV4AwsMock(); + await lambdaGetFunction(aws, "my-forwarder"); + expect((aws as any).getAwsSdkV3Config).toHaveBeenCalled(); + expect(LambdaClient).toHaveBeenCalledWith({ region: "us-east-1" }); + expect(lambdaSend).toHaveBeenCalledWith({ input: { FunctionName: "my-forwarder" } }); + }); + + it("cloudWatchLogsDescribeSubscriptionFilters returns [] when SDK response omits filters", async () => { + logsSend.mockResolvedValue({}); + const result = await cloudWatchLogsDescribeSubscriptionFilters(oslsV4AwsMock(), "/aws/lambda/foo"); + expect(CloudWatchLogsClient).toHaveBeenCalled(); + expect(logsSend).toHaveBeenCalledWith({ input: { logGroupName: "/aws/lambda/foo" } }); + expect(result).toEqual([]); + }); + + it("cloudFormationDescribeStacks passes the region to getAwsSdkV3Config and sends the command", async () => { + cfnSend.mockResolvedValue({ Stacks: [{ StackId: "abc" }] }); + const aws = oslsV4AwsMock({ region: "eu-west-1" }); + const result = await cloudFormationDescribeStacks(aws, "my-stack", "eu-west-1"); + expect((aws as any).getAwsSdkV3Config).toHaveBeenCalledWith({ region: "eu-west-1" }); + expect(cfnSend).toHaveBeenCalledWith({ input: { StackName: "my-stack" } }); + expect(result).toEqual({ Stacks: [{ StackId: "abc" }] }); + }); + }); +}); diff --git a/src/aws-sdk-request.ts b/src/aws-sdk-request.ts new file mode 100644 index 00000000..13ac7a29 --- /dev/null +++ b/src/aws-sdk-request.ts @@ -0,0 +1,67 @@ +import Aws from "serverless/plugins/aws/provider/awsProvider"; + +/** + * osls v4 removed the AWS SDK v2 surface from the AWS provider: calling + * `provider.request()`, `provider.sdk` or `provider.getCredentials()` now throws + * an error with code `AWS_SDK_V2_SURFACE_REMOVED`. Instead osls v4 exposes + * `provider.getAwsSdkV3Config()`, which returns osls-resolved client + * configuration (region, credentials, retry/proxy/CA settings) so plugins can + * build their own AWS SDK v3 clients. + * + * The Serverless Framework (1.x–4.x) still supports `provider.request()` and + * does not expose `getAwsSdkV3Config()`. To stay compatible with both we detect + * `getAwsSdkV3Config()` at runtime: when present (osls v4) we construct an AWS + * SDK v3 client, otherwise we fall back to the still-supported + * `provider.request()`. The SDK v3 client packages are loaded lazily so they + * are only required when the osls v4 code path actually runs. + * + * See https://github.com/oss-serverless/osls/blob/4.x/docs/guides/upgrading-to-v4.md#aws-sdk-v2-removed-plugin-authors + */ + +interface AwsSdkV3ClientConfig { + region?: string; + [key: string]: unknown; +} + +// `getAwsSdkV3Config` is not part of @types/serverless yet, so extend the type. +type AwsProviderWithSdkV3 = Aws & { + getAwsSdkV3Config(options?: { region?: string }): Promise; +}; + +function supportsAwsSdkV3(aws: Aws): aws is AwsProviderWithSdkV3 { + return typeof (aws as Partial).getAwsSdkV3Config === "function"; +} + +/** Calls Lambda GetFunction. Rejects if the function does not exist. */ +export async function lambdaGetFunction(aws: Aws, functionName: string): Promise { + if (supportsAwsSdkV3(aws)) { + const { LambdaClient, GetFunctionCommand } = await import("@aws-sdk/client-lambda"); + const client = new LambdaClient(await aws.getAwsSdkV3Config()); + await client.send(new GetFunctionCommand({ FunctionName: functionName })); + return; + } + await aws.request("Lambda", "getFunction", { FunctionName: functionName }); +} + +/** Calls CloudWatchLogs DescribeSubscriptionFilters for a log group. */ +export async function cloudWatchLogsDescribeSubscriptionFilters(aws: Aws, logGroupName: string): Promise { + if (supportsAwsSdkV3(aws)) { + const { CloudWatchLogsClient, DescribeSubscriptionFiltersCommand } = + await import("@aws-sdk/client-cloudwatch-logs"); + const client = new CloudWatchLogsClient(await aws.getAwsSdkV3Config()); + const output = await client.send(new DescribeSubscriptionFiltersCommand({ logGroupName })); + return output.subscriptionFilters ?? []; + } + const result = await aws.request("CloudWatchLogs", "describeSubscriptionFilters", { logGroupName }); + return result.subscriptionFilters; +} + +/** Calls CloudFormation DescribeStacks for a stack in the given region. */ +export async function cloudFormationDescribeStacks(aws: Aws, stackName: string, region: string): Promise { + if (supportsAwsSdkV3(aws)) { + const { CloudFormationClient, DescribeStacksCommand } = await import("@aws-sdk/client-cloudformation"); + const client = new CloudFormationClient(await aws.getAwsSdkV3Config({ region })); + return client.send(new DescribeStacksCommand({ StackName: stackName })); + } + return aws.request("CloudFormation", "describeStacks", { StackName: stackName }, { region }); +} diff --git a/src/forwarder.ts b/src/forwarder.ts index 7c702677..4c88742a 100644 --- a/src/forwarder.ts +++ b/src/forwarder.ts @@ -2,6 +2,7 @@ import Service from "serverless/classes/Service"; import { FunctionInfo } from "./layer"; import { version } from "../package.json"; import Aws = require("serverless/plugins/aws/provider/awsProvider"); +import { cloudWatchLogsDescribeSubscriptionFilters, lambdaGetFunction } from "./aws-sdk-request"; const logGroupKey = "AWS::Logs::LogGroup"; const logGroupSubscriptionKey = "AWS::Logs::SubscriptionFilter"; @@ -38,10 +39,6 @@ interface SubscriptionFilter { logGroupName: string; roleArn: string; } -interface DescribeSubscriptionFiltersResponse { - subscriptionFilters: SubscriptionFilter[]; -} - type SubLogsConfig = | boolean | { @@ -115,7 +112,7 @@ function isLogGroup(value: unknown): value is LogGroupResource { */ async function validateForwarderArn(aws: Aws, functionArn: CloudFormationObjectArn | string): Promise { try { - await aws.request("Lambda", "getFunction", { FunctionName: functionArn }); + await lambdaGetFunction(aws, functionArn as string); } catch (err) { throw new DatadogForwarderNotFoundError(`Could not perform GetFunction on ${functionArn}.`); } @@ -293,14 +290,7 @@ export async function canSubscribeLogGroup(aws: Aws, logGroupName: string, expec export async function describeSubscriptionFilters(aws: Aws, logGroupName: string): Promise { try { - const result: DescribeSubscriptionFiltersResponse = await aws.request( - "CloudWatchLogs", - "describeSubscriptionFilters", - { - logGroupName, - }, - ); - return result.subscriptionFilters; + return await cloudWatchLogsDescribeSubscriptionFilters(aws, logGroupName); } catch (err) { // An error will occur if the log group doesn't exist, so we swallow this and return an empty list. return []; diff --git a/src/monitor-api-requests.ts b/src/monitor-api-requests.ts index 4c7374b2..b2fc9399 100644 --- a/src/monitor-api-requests.ts +++ b/src/monitor-api-requests.ts @@ -1,5 +1,6 @@ import * as Serverless from "serverless"; import { MonitorParams, ServerlessMonitor, replaceCriticalThreshold } from "./monitors"; +import { cloudFormationDescribeStacks } from "./aws-sdk-request"; export class InvalidAuthenticationError extends Error { constructor(message: string) { @@ -127,18 +128,11 @@ export async function searchMonitors( } export async function getCloudFormationStackId(serverless: Serverless): Promise { - const stackName = serverless.getProvider("aws").naming.getStackName(); - const describeStackOutput = await serverless - .getProvider("aws") - .request( - "CloudFormation", - "describeStacks", - { StackName: stackName }, - { region: serverless.getProvider("aws").getRegion() }, - ) - .catch(() => { - // Ignore any request exceptions, fail silently and skip output logging - }); + const aws = serverless.getProvider("aws"); + const stackName = aws.naming.getStackName(); + const describeStackOutput = await cloudFormationDescribeStacks(aws, stackName, aws.getRegion()).catch(() => { + // Ignore any request exceptions, fail silently and skip output logging + }); const cloudFormationStackId: string = describeStackOutput ? describeStackOutput.Stacks[0].StackId : ""; return cloudFormationStackId; } diff --git a/src/output.ts b/src/output.ts index c0395ccf..dbeaf506 100644 --- a/src/output.ts +++ b/src/output.ts @@ -1,5 +1,6 @@ import * as Serverless from "serverless"; import { FunctionInfo } from "./layer"; +import { cloudFormationDescribeStacks } from "./aws-sdk-request"; const yellowFont = "\x1b[33m"; const orangeFont = "\x1b[38;2;255;165;0m"; @@ -41,18 +42,11 @@ export async function printOutputs( service: string, env: string, ): Promise { - const stackName = serverless.getProvider("aws").naming.getStackName(); - const describeStackOutput = await serverless - .getProvider("aws") - .request( - "CloudFormation", - "describeStacks", - { StackName: stackName }, - { region: serverless.getProvider("aws").getRegion() }, - ) - .catch(() => { - // Ignore any request exceptions, fail silently and skip output logging - }); + const aws = serverless.getProvider("aws"); + const stackName = aws.naming.getStackName(); + const describeStackOutput = await cloudFormationDescribeStacks(aws, stackName, aws.getRegion()).catch(() => { + // Ignore any request exceptions, fail silently and skip output logging + }); if (describeStackOutput === undefined) { return; } diff --git a/yarn.lock b/yarn.lock index 3c4aecc7..56d5ff67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -155,6 +155,38 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-cloudwatch-logs@npm:^3.137.0": + version: 3.1085.0 + resolution: "@aws-sdk/client-cloudwatch-logs@npm:3.1085.0" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/credential-provider-node": "npm:^3.972.66" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/fetch-http-handler": "npm:^5.6.4" + "@smithy/node-http-handler": "npm:^4.9.4" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/b99f7d0796f061d1a04f6b29d062cccc01bda52ae445d1e801fbee1784fbbea884a6a503c13f6c97b38b79d5aabf9c7f062b4d1884298432f5e5b98755ae8d2b + languageName: node + linkType: hard + +"@aws-sdk/client-lambda@npm:^3.137.0": + version: 3.1085.0 + resolution: "@aws-sdk/client-lambda@npm:3.1085.0" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/credential-provider-node": "npm:^3.972.66" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/fetch-http-handler": "npm:^5.6.4" + "@smithy/node-http-handler": "npm:^4.9.4" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/b88c97642ac9869ff0d91ed39f4c303407c143031eb9342c201d234d260ef4880643fdebe148a90a018ac0c4306149fb3752db7ca2ebd5d624a3cb7a6377187b + languageName: node + linkType: hard + "@aws-sdk/client-s3@npm:^3.137.0": version: 3.1036.0 resolution: "@aws-sdk/client-s3@npm:3.1036.0" @@ -288,6 +320,22 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/core@npm:^3.975.1": + version: 3.975.1 + resolution: "@aws-sdk/core@npm:3.975.1" + dependencies: + "@aws-sdk/types": "npm:^3.974.0" + "@aws-sdk/xml-builder": "npm:^3.972.34" + "@aws/lambda-invoke-store": "npm:^0.3.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/signature-v4": "npm:^5.6.3" + "@smithy/types": "npm:^4.16.0" + bowser: "npm:^2.11.0" + tslib: "npm:^2.6.2" + checksum: 10c0/76eca6a578e112e7de0aacf7b9e57c4ecdce23966bf50a4d55fdc9e835ea17e811f8075cc4d1263dd009ef84e96795011bf297ae173d339a36fba70e74cfb946 + languageName: node + linkType: hard + "@aws-sdk/crc64-nvme@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/crc64-nvme@npm:3.972.7" @@ -311,6 +359,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-env@npm:^3.972.57": + version: 3.972.57 + resolution: "@aws-sdk/credential-provider-env@npm:3.972.57" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/91568f2539a495f67e16bc89481172a9a94dee8321ee460b23f7b34136091b4a6596b8d33aded9975b098a9e2ed1ff4eb2c16cc3c86d0fa7d6da6818b3812ede + languageName: node + linkType: hard + "@aws-sdk/credential-provider-http@npm:^3.972.33": version: 3.972.33 resolution: "@aws-sdk/credential-provider-http@npm:3.972.33" @@ -329,6 +390,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-http@npm:^3.972.59": + version: 3.972.59 + resolution: "@aws-sdk/credential-provider-http@npm:3.972.59" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/fetch-http-handler": "npm:^5.6.4" + "@smithy/node-http-handler": "npm:^4.9.4" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/9d52d19e51a4c55ac4bb8b311a6a0ba621ee9c86b2c6f3f94c4968d41c877173938b4d16a79f8100ce31c6a1812a9ca98de9e38b3ba436abd266076769bdc3b2 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-imds@npm:^3.81.0": version: 3.370.0 resolution: "@aws-sdk/credential-provider-imds@npm:3.370.0" @@ -364,6 +440,27 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-ini@npm:^3.973.1": + version: 3.973.1 + resolution: "@aws-sdk/credential-provider-ini@npm:3.973.1" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/credential-provider-env": "npm:^3.972.57" + "@aws-sdk/credential-provider-http": "npm:^3.972.59" + "@aws-sdk/credential-provider-login": "npm:^3.972.63" + "@aws-sdk/credential-provider-process": "npm:^3.972.57" + "@aws-sdk/credential-provider-sso": "npm:^3.973.1" + "@aws-sdk/credential-provider-web-identity": "npm:^3.972.63" + "@aws-sdk/nested-clients": "npm:^3.997.31" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/credential-provider-imds": "npm:^4.4.7" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/ef6f07adee2c7c3e01b27b81076ffcf9ee2fcb8a2e2752c6839d3d4df6b47272d19a8472d061779377eb2bc36779d262abae9e6dfab32763eae188e655427f9d + languageName: node + linkType: hard + "@aws-sdk/credential-provider-login@npm:^3.972.35": version: 3.972.35 resolution: "@aws-sdk/credential-provider-login@npm:3.972.35" @@ -380,6 +477,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-login@npm:^3.972.63": + version: 3.972.63 + resolution: "@aws-sdk/credential-provider-login@npm:3.972.63" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/nested-clients": "npm:^3.997.31" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/3e00d427c7fb0fdc0374100f4ebf38971220251b72c3e0e223ad37c11168e21db8439a865c26584eb10c21c8a7d465646fd9a0161723ee1a9e8d79b044456b8a + languageName: node + linkType: hard + "@aws-sdk/credential-provider-node@npm:^3.972.36": version: 3.972.36 resolution: "@aws-sdk/credential-provider-node@npm:3.972.36" @@ -400,6 +511,25 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-node@npm:^3.972.66": + version: 3.972.66 + resolution: "@aws-sdk/credential-provider-node@npm:3.972.66" + dependencies: + "@aws-sdk/credential-provider-env": "npm:^3.972.57" + "@aws-sdk/credential-provider-http": "npm:^3.972.59" + "@aws-sdk/credential-provider-ini": "npm:^3.973.1" + "@aws-sdk/credential-provider-process": "npm:^3.972.57" + "@aws-sdk/credential-provider-sso": "npm:^3.973.1" + "@aws-sdk/credential-provider-web-identity": "npm:^3.972.63" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/credential-provider-imds": "npm:^4.4.7" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/8d407f2a3f1ee549e60980a2064f104ec97bf4d137d9c22c9142a44639052d69b9a56d90d26c2d639ebb20909d9111534e3b0e888ccaa6fc6176e69e7cdb5b07 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-process@npm:^3.80.0, @aws-sdk/credential-provider-process@npm:^3.972.31": version: 3.972.31 resolution: "@aws-sdk/credential-provider-process@npm:3.972.31" @@ -414,6 +544,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-process@npm:^3.972.57": + version: 3.972.57 + resolution: "@aws-sdk/credential-provider-process@npm:3.972.57" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/9bb9cb3257c5a9d646c17c60013a6cbf95da5f0a6a7c05e75a83674e15e0847ccdfb439fb3bc7ec2943e7bc4fe380c97ab6ca728099be48a6ac7206b3b826713 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-sso@npm:^3.100.0, @aws-sdk/credential-provider-sso@npm:^3.972.35": version: 3.972.35 resolution: "@aws-sdk/credential-provider-sso@npm:3.972.35" @@ -430,6 +573,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-sso@npm:^3.973.1": + version: 3.973.1 + resolution: "@aws-sdk/credential-provider-sso@npm:3.973.1" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/nested-clients": "npm:^3.997.31" + "@aws-sdk/token-providers": "npm:3.1083.0" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/737987f91936aec720550dd0098b109e1b6993b638525e7f2c7b5740c75d94c6a8960ab59afdb279261d344aea35a01b1fc35e3b9be5762ce098011d4c5de5ac + languageName: node + linkType: hard + "@aws-sdk/credential-provider-web-identity@npm:^3.78.0, @aws-sdk/credential-provider-web-identity@npm:^3.972.35": version: 3.972.35 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.35" @@ -445,6 +603,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-web-identity@npm:^3.972.63": + version: 3.972.63 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.63" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/nested-clients": "npm:^3.997.31" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/f8d6abdc141cab07c0efb75e6fe50f1543fa750daed92d43cfc597ce8e2c97c01820fd7cfedf27498208fac811fa17bb06a0ef8eb8c4ae8cbdbc674f76631040 + languageName: node + linkType: hard + "@aws-sdk/middleware-bucket-endpoint@npm:^3.972.10": version: 3.972.10 resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.972.10" @@ -637,6 +809,22 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/nested-clients@npm:^3.997.31": + version: 3.997.31 + resolution: "@aws-sdk/nested-clients@npm:3.997.31" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/signature-v4-multi-region": "npm:^3.996.39" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/fetch-http-handler": "npm:^5.6.4" + "@smithy/node-http-handler": "npm:^4.9.4" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/123aa96668b5b0b70d1c9555fed441662716aef3b0f3fab80200e5652423f4ec09025b286ae5288f861c64a2a9089e86279d96358d69a61206c9feb99c7892bf + languageName: node + linkType: hard + "@aws-sdk/node-config-provider@npm:3.370.0": version: 3.370.0 resolution: "@aws-sdk/node-config-provider@npm:3.370.0" @@ -706,6 +894,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/signature-v4-multi-region@npm:^3.996.39": + version: 3.996.39 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.996.39" + dependencies: + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/signature-v4": "npm:^5.6.3" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/3bee44dff6fcd668917aabbbff299f298175565a7850a3dbd9cb5545c379ea56ba4b0cc76182d27913ea1d2a508d8e98bbfa226d8a91d4669f7fb380b66bde2d + languageName: node + linkType: hard + "@aws-sdk/token-providers@npm:3.1036.0": version: 3.1036.0 resolution: "@aws-sdk/token-providers@npm:3.1036.0" @@ -721,6 +921,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/token-providers@npm:3.1083.0": + version: 3.1083.0 + resolution: "@aws-sdk/token-providers@npm:3.1083.0" + dependencies: + "@aws-sdk/core": "npm:^3.975.1" + "@aws-sdk/nested-clients": "npm:^3.997.31" + "@aws-sdk/types": "npm:^3.974.0" + "@smithy/core": "npm:^3.29.2" + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/9ccd9da9b4c3351c8b9f3f3ba1d2de0ab56fbaae84d0e3c77f2bb9f4b8ad18949af302058f80dd5f2c7b8f052bb34c80b04846a844e15bc0a337faa416188777 + languageName: node + linkType: hard + "@aws-sdk/types@npm:3.370.0": version: 3.370.0 resolution: "@aws-sdk/types@npm:3.370.0" @@ -741,6 +955,16 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/types@npm:^3.974.0": + version: 3.974.0 + resolution: "@aws-sdk/types@npm:3.974.0" + dependencies: + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/9e0ed5a75b60613c954431ffa249ccc8a2d03f59afb6ed52ec3eb16ddb71b707a1a7165518e3f25e345c09fc50dcebb4fb84d08a0a050a246bfe9feb76509bc9 + languageName: node + linkType: hard + "@aws-sdk/url-parser@npm:3.370.0": version: 3.370.0 resolution: "@aws-sdk/url-parser@npm:3.370.0" @@ -825,6 +1049,16 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/xml-builder@npm:^3.972.34": + version: 3.972.34 + resolution: "@aws-sdk/xml-builder@npm:3.972.34" + dependencies: + "@smithy/types": "npm:^4.16.0" + tslib: "npm:^2.6.2" + checksum: 10c0/a04c804d75ae9935ce086d9ff3ea2f03a67633b25180cb82f861bdec3fe10d2f45e59bd6541ee1b1558bc0c6429d688bc19ea256878ebac1bcde1a6d0bb06f8b + languageName: node + linkType: hard + "@aws/lambda-invoke-store@npm:^0.2.2": version: 0.2.4 resolution: "@aws/lambda-invoke-store@npm:0.2.4" @@ -832,6 +1066,13 @@ __metadata: languageName: node linkType: hard +"@aws/lambda-invoke-store@npm:^0.3.0": + version: 0.3.0 + resolution: "@aws/lambda-invoke-store@npm:0.3.0" + checksum: 10c0/b4a2e6b3b5397bc606053e64270d26dc5c886336f88a98cad587b1592eec17058f8fb172f1827a9f0e591f3595cf8f01575c8c9b36cde38c06456f8a65204046 + languageName: node + linkType: hard + "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.27.1, @babel/code-frame@npm:^7.29.7": version: 7.29.7 resolution: "@babel/code-frame@npm:7.29.7" @@ -2024,6 +2265,16 @@ __metadata: languageName: node linkType: hard +"@smithy/core@npm:^3.29.2, @smithy/core@npm:^3.29.3": + version: 3.29.3 + resolution: "@smithy/core@npm:3.29.3" + dependencies: + "@smithy/types": "npm:^4.16.1" + tslib: "npm:^2.6.2" + checksum: 10c0/530322e1b4eeaf89c64c0e57385714f8e2dc53adeae7cfad56fa957dfa5f67755a0d875f3a15c67f01ecccef83cc51a3b854f6c35987606626e5c11901f2de94 + languageName: node + linkType: hard + "@smithy/credential-provider-imds@npm:^4.2.14": version: 4.2.14 resolution: "@smithy/credential-provider-imds@npm:4.2.14" @@ -2037,6 +2288,17 @@ __metadata: languageName: node linkType: hard +"@smithy/credential-provider-imds@npm:^4.4.7": + version: 4.4.8 + resolution: "@smithy/credential-provider-imds@npm:4.4.8" + dependencies: + "@smithy/core": "npm:^3.29.3" + "@smithy/types": "npm:^4.16.1" + tslib: "npm:^2.6.2" + checksum: 10c0/55cbe1dc8160194b715d98c33582e7303b26dca7e682db67a283cf6fb46acba5454d3ece1065e955e5bf1b31d87318dae87574c8d356f3464b89e8c1069cfad0 + languageName: node + linkType: hard + "@smithy/eventstream-codec@npm:^4.2.14": version: 4.2.14 resolution: "@smithy/eventstream-codec@npm:4.2.14" @@ -2105,6 +2367,17 @@ __metadata: languageName: node linkType: hard +"@smithy/fetch-http-handler@npm:^5.6.4": + version: 5.6.5 + resolution: "@smithy/fetch-http-handler@npm:5.6.5" + dependencies: + "@smithy/core": "npm:^3.29.3" + "@smithy/types": "npm:^4.16.1" + tslib: "npm:^2.6.2" + checksum: 10c0/91c75e5d701659b22c36338d1002c5282f409ff88eccee40f8d85172708ca7869a468b942f38df85a5888c93b50041920b57fd8d67517dc9ec18d60ec4143f14 + languageName: node + linkType: hard + "@smithy/hash-blob-browser@npm:^4.2.15": version: 4.2.15 resolution: "@smithy/hash-blob-browser@npm:4.2.15" @@ -2270,6 +2543,17 @@ __metadata: languageName: node linkType: hard +"@smithy/node-http-handler@npm:^4.9.4": + version: 4.9.5 + resolution: "@smithy/node-http-handler@npm:4.9.5" + dependencies: + "@smithy/core": "npm:^3.29.3" + "@smithy/types": "npm:^4.16.1" + tslib: "npm:^2.6.2" + checksum: 10c0/2ea8f79b4774902759169f3b402c4e6a9cdf49981064f7551d6278dea7fe63e485c0e9a11b091467614f22ebd0ee691457ef604a752753c54b70e14fd068a2e7 + languageName: node + linkType: hard + "@smithy/property-provider@npm:^1.0.1": version: 1.2.0 resolution: "@smithy/property-provider@npm:1.2.0" @@ -2356,6 +2640,17 @@ __metadata: languageName: node linkType: hard +"@smithy/signature-v4@npm:^5.6.3": + version: 5.6.4 + resolution: "@smithy/signature-v4@npm:5.6.4" + dependencies: + "@smithy/core": "npm:^3.29.3" + "@smithy/types": "npm:^4.16.1" + tslib: "npm:^2.6.2" + checksum: 10c0/de1ed09b7d68e5d16025f2d21da6461f0a07bb962b0cf9cabbb9fa2b11c5ca229b57f5f3e3dc7bd8e11c79afaf73d7625d22911c748ddb959b2ad98360348470 + languageName: node + linkType: hard + "@smithy/smithy-client@npm:^4.12.13": version: 4.12.13 resolution: "@smithy/smithy-client@npm:4.12.13" @@ -2389,6 +2684,15 @@ __metadata: languageName: node linkType: hard +"@smithy/types@npm:^4.16.0, @smithy/types@npm:^4.16.1": + version: 4.16.1 + resolution: "@smithy/types@npm:4.16.1" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10c0/e024d9d148deca7bd21d032a9316db109bbe7cf256ffbb8d3981655b9f4f7695c08ec9b87f5a8cf1442e783ba26cb27e4f09603c5bfa3ba1e526c41b1b3e94d2 + languageName: node + linkType: hard + "@smithy/url-parser@npm:^4.2.14": version: 4.2.14 resolution: "@smithy/url-parser@npm:4.2.14" @@ -7726,6 +8030,9 @@ __metadata: version: 0.0.0-use.local resolution: "serverless-plugin-datadog@workspace:." dependencies: + "@aws-sdk/client-cloudformation": "npm:^3.137.0" + "@aws-sdk/client-cloudwatch-logs": "npm:^3.137.0" + "@aws-sdk/client-lambda": "npm:^3.137.0" "@datadog/datadog-ci-base": "npm:^5.16.1" "@types/jest": "npm:^30.0.0" "@types/mock-fs": "npm:4.13.4"