From c58112eb99bb7efcc87f8aa2e6836968e788a0a2 Mon Sep 17 00:00:00 2001 From: Steve Liu Date: Mon, 16 Dec 2024 14:47:20 -0800 Subject: [PATCH] feat: [.NET and JS Feature Parity] Support for new AWS Resources in JS SDK (#121) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *Description of changes:* Adding support for new AWS resources in JS SDK. Part of an ongoing project to increase the ADOT SDK support in Node and .NET. Changes in this PR support the exact same features as the Python version: https://github.com/aws-observability/aws-otel-python-instrumentation/pull/265 Manual Testing: Screenshot 2024-11-15 at 1 36 01 PM Screenshot 2024-11-15 at 2 07 05 PM Screenshot 2024-11-15 at 2 26 10 PM Screenshot 2024-11-18 at 9 47 33 AM Screenshot 2024-11-18 at 9 57 22 AM Screenshot 2024-11-18 at 10 00 34 AM Unit Tests for Instrumentation Patches and Metric Attribute Generators: image By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. --- .../package.json | 4 + .../src/aws-attribute-keys.ts | 9 + .../src/aws-metric-attribute-generator.ts | 77 +- .../src/patches/aws/services/bedrock.ts | 13 +- .../patches/aws/services/secretsmanager.ts | 43 + .../patches/aws/services/step-functions.ts | 36 + .../src/patches/instrumentation-patch.ts | 70 +- .../aws-metric-attribute-generator.test.ts | 37 + .../test/patches/aws/services/bedrock.test.ts | 5 +- .../aws/services/secretsmanager.test.ts | 100 ++ .../aws/services/step-functions.test.ts | 93 ++ .../patches/instrumentation-patch.test.ts | 177 ++- .../images/applications/mysql2/package.json | 2 +- package-lock.json | 1200 ++++++++++++++--- 14 files changed, 1641 insertions(+), 225 deletions(-) create mode 100644 aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/secretsmanager.ts create mode 100644 aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/step-functions.ts create mode 100644 aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/secretsmanager.test.ts create mode 100644 aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/step-functions.test.ts diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/package.json b/aws-distro-opentelemetry-node-autoinstrumentation/package.json index 4be5456..78412fa 100644 --- a/aws-distro-opentelemetry-node-autoinstrumentation/package.json +++ b/aws-distro-opentelemetry-node-autoinstrumentation/package.json @@ -73,7 +73,11 @@ "@aws-sdk/client-bedrock-agent-runtime": "3.632.0", "@aws-sdk/client-bedrock-runtime": "3.632.0", "@aws-sdk/client-kinesis": "3.632.0", + "@aws-sdk/client-lambda": "^3.632.0", "@aws-sdk/client-s3": "3.632.0", + "@aws-sdk/client-secrets-manager": "^3.632.0", + "@aws-sdk/client-sfn": "^3.632.0", + "@aws-sdk/client-sns": "^3.632.0", "@opentelemetry/contrib-test-utils": "0.41.0", "@types/mocha": "7.0.2", "@types/node": "18.6.5", diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-attribute-keys.ts b/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-attribute-keys.ts index e237827..46150b7 100644 --- a/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-attribute-keys.ts +++ b/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-attribute-keys.ts @@ -14,6 +14,7 @@ export const AWS_ATTRIBUTE_KEYS: { [key: string]: string } = { AWS_REMOTE_RESOURCE_IDENTIFIER: 'aws.remote.resource.identifier', AWS_SDK_DESCENDANT: 'aws.sdk.descendant', AWS_CONSUMER_PARENT_SPAN_KIND: 'aws.consumer.parent.span.kind', + AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER: 'aws.remote.resource.cfn.primary.identifier', AWS_REMOTE_TARGET: 'aws.remote.target', AWS_REMOTE_DB_USER: 'aws.remote.db.user', @@ -35,4 +36,12 @@ export const AWS_ATTRIBUTE_KEYS: { [key: string]: string } = { AWS_BEDROCK_KNOWLEDGE_BASE_ID: 'aws.bedrock.knowledge_base.id', AWS_BEDROCK_AGENT_ID: 'aws.bedrock.agent.id', AWS_BEDROCK_GUARDRAIL_ID: 'aws.bedrock.guardrail.id', + AWS_BEDROCK_GUARDRAIL_ARN: 'aws.bedrock.guardrail.arn', + AWS_SNS_TOPIC_ARN: 'aws.sns.topic.arn', + AWS_SECRETSMANAGER_SECRET_ARN: 'aws.secretsmanager.secret.arn', + AWS_STEPFUNCTIONS_STATEMACHINE_ARN: 'aws.stepfunctions.state_machine.arn', + AWS_STEPFUNCTIONS_ACTIVITY_ARN: 'aws.stepfunctions.activity.arn', + AWS_LAMBDA_FUNCTION_NAME: 'aws.lambda.function.name', + AWS_LAMBDA_RESOURCE_MAPPING_ID: 'aws.lambda.resource_mapping.id', + AWS_LAMBDA_FUNCTION_ARN: 'aws.lambda.function.arn', }; diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-metric-attribute-generator.ts b/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-metric-attribute-generator.ts index e58b600..ae318a3 100644 --- a/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-metric-attribute-generator.ts +++ b/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-metric-attribute-generator.ts @@ -55,6 +55,10 @@ const NORMALIZED_DYNAMO_DB_SERVICE_NAME: string = 'AWS::DynamoDB'; const NORMALIZED_KINESIS_SERVICE_NAME: string = 'AWS::Kinesis'; const NORMALIZED_S3_SERVICE_NAME: string = 'AWS::S3'; const NORMALIZED_SQS_SERVICE_NAME: string = 'AWS::SQS'; +const NORMALIZED_SNS_SERVICE_NAME: string = 'AWS::SNS'; +const NORMALIZED_SECRETSMANAGER_SERVICE_NAME = 'AWS::SecretsManager'; +const NORMALIZED_STEPFUNCTIONS_SERVICE_NAME = 'AWS::StepFunctions'; +const NORMALIZED_LAMBDA_SERVICE_NAME = 'AWS::Lambda'; const NORMALIZED_BEDROCK_SERVICE_NAME: string = 'AWS::Bedrock'; const NORMALIZED_BEDROCK_RUNTIME_SERVICE_NAME: string = 'AWS::BedrockRuntime'; @@ -330,6 +334,8 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator { BedrockAgent: NORMALIZED_BEDROCK_SERVICE_NAME, BedrockAgentRuntime: NORMALIZED_BEDROCK_SERVICE_NAME, BedrockRuntime: NORMALIZED_BEDROCK_RUNTIME_SERVICE_NAME, + SecretsManager: NORMALIZED_SECRETSMANAGER_SERVICE_NAME, + SFN: NORMALIZED_STEPFUNCTIONS_SERVICE_NAME, }; return awsSdkServiceMapping[serviceName] || 'AWS::' + serviceName; } @@ -350,6 +356,7 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator { private static setRemoteResourceTypeAndIdentifier(span: ReadableSpan, attributes: Attributes): void { let remoteResourceType: AttributeValue | undefined; let remoteResourceIdentifier: AttributeValue | undefined; + let cloudFormationIdentifier: AttributeValue | undefined; if (AwsSpanProcessingUtil.isAwsSDKSpan(span)) { const awsTableNames: AttributeValue | undefined = span.attributes[AWS_ATTRIBUTE_KEYS.AWS_DYNAMODB_TABLE_NAMES]; @@ -370,16 +377,56 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator { remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( span.attributes[AWS_ATTRIBUTE_KEYS.AWS_S3_BUCKET] ); + } else if (AwsSpanProcessingUtil.isKeyPresent(span, AWS_ATTRIBUTE_KEYS.AWS_SNS_TOPIC_ARN)) { + const snsArn = span.attributes[AWS_ATTRIBUTE_KEYS.AWS_SNS_TOPIC_ARN]; + + remoteResourceType = NORMALIZED_SNS_SERVICE_NAME + '::Topic'; + remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( + this.extractResourceNameFromArn(snsArn) + ); + cloudFormationIdentifier = AwsMetricAttributeGenerator.escapeDelimiters(snsArn); + } else if (AwsSpanProcessingUtil.isKeyPresent(span, AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN)) { + const secretsArn = span.attributes[AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN]; + + remoteResourceType = NORMALIZED_SECRETSMANAGER_SERVICE_NAME + '::Secret'; + remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( + this.extractResourceNameFromArn(secretsArn) + ); + cloudFormationIdentifier = AwsMetricAttributeGenerator.escapeDelimiters(secretsArn); + } else if (AwsSpanProcessingUtil.isKeyPresent(span, AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_STATEMACHINE_ARN)) { + const stateMachineArn = span.attributes[AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_STATEMACHINE_ARN]; + + remoteResourceType = NORMALIZED_STEPFUNCTIONS_SERVICE_NAME + '::StateMachine'; + remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( + this.extractResourceNameFromArn(stateMachineArn) + ); + cloudFormationIdentifier = AwsMetricAttributeGenerator.escapeDelimiters(stateMachineArn); + } else if (AwsSpanProcessingUtil.isKeyPresent(span, AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_ACTIVITY_ARN)) { + const activityArn = span.attributes[AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_ACTIVITY_ARN]; + + remoteResourceType = NORMALIZED_STEPFUNCTIONS_SERVICE_NAME + '::Activity'; + remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( + this.extractResourceNameFromArn(activityArn) + ); + cloudFormationIdentifier = AwsMetricAttributeGenerator.escapeDelimiters(activityArn); + } else if (AwsSpanProcessingUtil.isKeyPresent(span, AWS_ATTRIBUTE_KEYS.AWS_LAMBDA_RESOURCE_MAPPING_ID)) { + remoteResourceType = NORMALIZED_LAMBDA_SERVICE_NAME + '::EventSourceMapping'; + remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( + span.attributes[AWS_ATTRIBUTE_KEYS.AWS_LAMBDA_RESOURCE_MAPPING_ID] + ); } else if (AwsSpanProcessingUtil.isKeyPresent(span, AWS_ATTRIBUTE_KEYS.AWS_SQS_QUEUE_NAME)) { remoteResourceType = NORMALIZED_SQS_SERVICE_NAME + '::Queue'; remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( span.attributes[AWS_ATTRIBUTE_KEYS.AWS_SQS_QUEUE_NAME] ); } else if (AwsSpanProcessingUtil.isKeyPresent(span, AWS_ATTRIBUTE_KEYS.AWS_SQS_QUEUE_URL)) { - remoteResourceType = NORMALIZED_SQS_SERVICE_NAME + '::Queue'; - remoteResourceIdentifier = SqsUrlParser.getQueueName( - AwsMetricAttributeGenerator.escapeDelimiters(span.attributes[AWS_ATTRIBUTE_KEYS.AWS_SQS_QUEUE_URL]) + const sqsQueueUrl = AwsMetricAttributeGenerator.escapeDelimiters( + span.attributes[AWS_ATTRIBUTE_KEYS.AWS_SQS_QUEUE_URL] ); + + remoteResourceType = NORMALIZED_SQS_SERVICE_NAME + '::Queue'; + remoteResourceIdentifier = SqsUrlParser.getQueueName(sqsQueueUrl); + cloudFormationIdentifier = sqsQueueUrl; } else if (AwsSpanProcessingUtil.isKeyPresent(span, AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_AGENT_ID)) { remoteResourceType = NORMALIZED_BEDROCK_SERVICE_NAME + '::Agent'; remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( @@ -390,11 +437,17 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator { remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( span.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID] ); + cloudFormationIdentifier = `${AwsMetricAttributeGenerator.escapeDelimiters( + span.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID] + )}|${remoteResourceIdentifier}`; } else if (AwsSpanProcessingUtil.isKeyPresent(span, AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_GUARDRAIL_ID)) { remoteResourceType = NORMALIZED_BEDROCK_SERVICE_NAME + '::Guardrail'; remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( span.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_GUARDRAIL_ID] ); + cloudFormationIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( + span.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_GUARDRAIL_ARN] + ); } else if (AwsSpanProcessingUtil.isKeyPresent(span, AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID)) { remoteResourceType = NORMALIZED_BEDROCK_SERVICE_NAME + '::KnowledgeBase'; remoteResourceIdentifier = AwsMetricAttributeGenerator.escapeDelimiters( @@ -414,6 +467,14 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator { if (remoteResourceType !== undefined && remoteResourceIdentifier !== undefined) { attributes[AWS_ATTRIBUTE_KEYS.AWS_REMOTE_RESOURCE_TYPE] = remoteResourceType; attributes[AWS_ATTRIBUTE_KEYS.AWS_REMOTE_RESOURCE_IDENTIFIER] = remoteResourceIdentifier; + + if (AwsSpanProcessingUtil.isAwsSDKSpan(span)) { + if (cloudFormationIdentifier === undefined) { + cloudFormationIdentifier = remoteResourceIdentifier; + } + + attributes[AWS_ATTRIBUTE_KEYS.AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER] = cloudFormationIdentifier; + } } } @@ -532,6 +593,16 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator { return input.split('^').join('^^').split('|').join('^|'); } + // Extracts the name of the resource from an arn + private static extractResourceNameFromArn(attribute: AttributeValue | undefined): string | undefined { + if (typeof attribute === 'string' && attribute.startsWith('arn:aws:')) { + const split = attribute.split(':'); + return split[split.length - 1]; + } + + return undefined; + } + /** Span kind is needed for differentiating metrics in the EMF exporter */ private static setSpanKindForService(span: ReadableSpan, attributes: Attributes): void { let spanKind: string = SpanKind[span.kind]; diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/bedrock.ts b/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/bedrock.ts index 4f2736e..82da47a 100644 --- a/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/bedrock.ts +++ b/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/bedrock.ts @@ -15,6 +15,7 @@ const AGENT_ID: string = 'agentId'; const KNOWLEDGE_BASE_ID: string = 'knowledgeBaseId'; const DATA_SOURCE_ID: string = 'dataSourceId'; const GUARDRAIL_ID: string = 'guardrailId'; +const GUARDRAIL_ARN: string = 'guardrailArn'; const MODEL_ID: string = 'modelId'; const AWS_BEDROCK_SYSTEM: string = 'aws.bedrock'; @@ -60,6 +61,7 @@ const knowledgeBaseOperationAttributeKeyMapping = { }; const dataSourceOperationAttributeKeyMapping = { [AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID]: DATA_SOURCE_ID, + [AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]: KNOWLEDGE_BASE_ID, }; // This map allows us to get all relevant attribute key mappings for a given operation @@ -182,10 +184,15 @@ export class BedrockServiceExtension implements ServiceExtension { }; } responseHook(response: NormalizedResponse, span: Span, tracer: Tracer, config: AwsSdkInstrumentationConfig): void { - const guardrail_id = response.data[GUARDRAIL_ID]; + const guardrailId = response.data[GUARDRAIL_ID]; + const guardrailArn = response.data[GUARDRAIL_ARN]; + + if (guardrailId) { + span.setAttribute(AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_GUARDRAIL_ID, guardrailId); + } - if (guardrail_id) { - span.setAttribute(AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_GUARDRAIL_ID, guardrail_id); + if (guardrailArn) { + span.setAttribute(AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_GUARDRAIL_ARN, guardrailArn); } } } diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/secretsmanager.ts b/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/secretsmanager.ts new file mode 100644 index 0000000..bf78434 --- /dev/null +++ b/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/secretsmanager.ts @@ -0,0 +1,43 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { Attributes, Span, SpanKind, Tracer } from '@opentelemetry/api'; +import { + AwsSdkInstrumentationConfig, + NormalizedRequest, + NormalizedResponse, +} from '@opentelemetry/instrumentation-aws-sdk'; +import { AWS_ATTRIBUTE_KEYS } from '../../../aws-attribute-keys'; +import { RequestMetadata, ServiceExtension } from '../../../third-party/otel/aws/services/ServiceExtension'; + +export class SecretsManagerServiceExtension implements ServiceExtension { + requestPreSpanHook(request: NormalizedRequest, _config: AwsSdkInstrumentationConfig): RequestMetadata { + const secretId = request.commandInput?.SecretId; + + const spanKind: SpanKind = SpanKind.CLIENT; + let spanName: string | undefined; + + const spanAttributes: Attributes = {}; + + if (typeof secretId === 'string' && secretId.startsWith('arn:aws:secretsmanager:')) { + spanAttributes[AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN] = secretId; + } + + const isIncoming = false; + + return { + isIncoming, + spanAttributes, + spanKind, + spanName, + }; + } + + responseHook(response: NormalizedResponse, span: Span, tracer: Tracer, config: AwsSdkInstrumentationConfig): void { + const secretArn = response.data.ARN; + + if (secretArn) { + span.setAttribute(AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN, secretArn); + } + } +} diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/step-functions.ts b/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/step-functions.ts new file mode 100644 index 0000000..4271cb0 --- /dev/null +++ b/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/step-functions.ts @@ -0,0 +1,36 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { Attributes, SpanKind } from '@opentelemetry/api'; +import { AwsSdkInstrumentationConfig, NormalizedRequest } from '@opentelemetry/instrumentation-aws-sdk'; +import { AWS_ATTRIBUTE_KEYS } from '../../../aws-attribute-keys'; +import { RequestMetadata, ServiceExtension } from '../../../third-party/otel/aws/services/ServiceExtension'; + +export class StepFunctionsServiceExtension implements ServiceExtension { + requestPreSpanHook(request: NormalizedRequest, _config: AwsSdkInstrumentationConfig): RequestMetadata { + const stateMachineArn = request.commandInput?.stateMachineArn; + const activityArn = request.commandInput?.activityArn; + + const spanKind: SpanKind = SpanKind.CLIENT; + let spanName: string | undefined; + + const spanAttributes: Attributes = {}; + + if (stateMachineArn) { + spanAttributes[AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_STATEMACHINE_ARN] = stateMachineArn; + } + + if (activityArn) { + spanAttributes[AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_ACTIVITY_ARN] = activityArn; + } + + const isIncoming = false; + + return { + isIncoming, + spanAttributes, + spanKind, + spanName, + }; + } +} diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/instrumentation-patch.ts b/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/instrumentation-patch.ts index 1302bb7..74879b9 100644 --- a/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/instrumentation-patch.ts +++ b/aws-distro-opentelemetry-node-autoinstrumentation/src/patches/instrumentation-patch.ts @@ -25,9 +25,11 @@ import { } from './aws/services/bedrock'; import { KinesisServiceExtension } from './aws/services/kinesis'; import { S3ServiceExtension } from './aws/services/s3'; -import { AwsLambdaInstrumentationPatch } from './extended-instrumentations/aws-lambda'; +import { SecretsManagerServiceExtension } from './aws/services/secretsmanager'; +import { StepFunctionsServiceExtension } from './aws/services/step-functions'; import { InstrumentationConfigMap } from '@opentelemetry/auto-instrumentations-node'; import { AwsSdkInstrumentationExtended } from './extended-instrumentations/aws-sdk-instrumentation-extended'; +import { AwsLambdaInstrumentationPatch } from './extended-instrumentations/aws-lambda'; export const traceContextEnvironmentKey = '_X_AMZN_TRACE_ID'; const awsPropagator = new AWSXRayPropagator(); @@ -68,11 +70,15 @@ export function applyInstrumentationPatches( if (services) { services.set('S3', new S3ServiceExtension()); services.set('Kinesis', new KinesisServiceExtension()); + services.set('SecretsManager', new SecretsManagerServiceExtension()); + services.set('SFN', new StepFunctionsServiceExtension()); services.set('Bedrock', new BedrockServiceExtension()); services.set('BedrockAgent', new BedrockAgentServiceExtension()); services.set('BedrockAgentRuntime', new BedrockAgentRuntimeServiceExtension()); services.set('BedrockRuntime', new BedrockRuntimeServiceExtension()); patchSqsServiceExtension(services.get('SQS')); + patchSnsServiceExtension(services.get('SNS')); + patchLambdaServiceExtension(services.get('Lambda')); } } else if (instrumentation.instrumentationName === '@opentelemetry/instrumentation-aws-lambda') { diag.debug('Overriding aws lambda instrumentation'); @@ -154,3 +160,65 @@ function patchSqsServiceExtension(sqsServiceExtension: any): void { sqsServiceExtension.requestPreSpanHook = patchedRequestPreSpanHook; } } + +/* + * This patch extends the existing upstream extension for SNS. Extensions allow for custom logic for adding + * service-specific information to spans, such as attributes. Specifically, we are adding logic to add + * `aws.sns.topic.arn` attribute, to be used to generate RemoteTarget and achieve parity with the Java/Python instrumentation. + * + * + * @param snsServiceExtension SNS Service Extension obtained the service extension list from the AWS SDK OTel Instrumentation + */ +function patchSnsServiceExtension(snsServiceExtension: any): void { + if (snsServiceExtension) { + const requestPreSpanHook = snsServiceExtension.requestPreSpanHook; + snsServiceExtension._requestPreSpanHook = requestPreSpanHook; + + const patchedRequestPreSpanHook = ( + request: NormalizedRequest, + _config: AwsSdkInstrumentationConfig + ): RequestMetadata => { + const requestMetadata: RequestMetadata = snsServiceExtension._requestPreSpanHook(request, _config); + if (requestMetadata.spanAttributes) { + const topicArn = request.commandInput?.TopicArn; + if (topicArn) { + requestMetadata.spanAttributes[AWS_ATTRIBUTE_KEYS.AWS_SNS_TOPIC_ARN] = topicArn; + } + } + return requestMetadata; + }; + + snsServiceExtension.requestPreSpanHook = patchedRequestPreSpanHook; + } +} + +/* + * This patch extends the existing upstream extension for Lambda. Extensions allow for custom logic for adding + * service-specific information to spans, such as attributes. Specifically, we are adding logic to add + * `aws.lambda.resource_mapping.id` attribute, to be used to generate RemoteTarget and achieve parity with the Java/Python instrumentation. + * + * + * @param lambdaServiceExtension Lambda Service Extension obtained the service extension list from the AWS SDK OTel Instrumentation + */ +function patchLambdaServiceExtension(lambdaServiceExtension: any): void { + if (lambdaServiceExtension) { + const requestPreSpanHook = lambdaServiceExtension.requestPreSpanHook; + lambdaServiceExtension._requestPreSpanHook = requestPreSpanHook; + + const patchedRequestPreSpanHook = ( + request: NormalizedRequest, + _config: AwsSdkInstrumentationConfig + ): RequestMetadata => { + const requestMetadata: RequestMetadata = lambdaServiceExtension._requestPreSpanHook(request, _config); + if (requestMetadata.spanAttributes) { + const resourceMappingId = request.commandInput?.UUID; + if (resourceMappingId) { + requestMetadata.spanAttributes[AWS_ATTRIBUTE_KEYS.AWS_LAMBDA_RESOURCE_MAPPING_ID] = resourceMappingId; + } + } + return requestMetadata; + }; + + lambdaServiceExtension.requestPreSpanHook = patchedRequestPreSpanHook; + } +} diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/test/aws-metric-attribute-generator.test.ts b/aws-distro-opentelemetry-node-autoinstrumentation/test/aws-metric-attribute-generator.test.ts index e74eda3..0e0a7f2 100644 --- a/aws-distro-opentelemetry-node-autoinstrumentation/test/aws-metric-attribute-generator.test.ts +++ b/aws-distro-opentelemetry-node-autoinstrumentation/test/aws-metric-attribute-generator.test.ts @@ -761,6 +761,39 @@ describe('AwsMetricAttributeGeneratorTest', () => { validateRemoteResourceAttributes('AWS::Kinesis::Stream', 'AWS_KINESIS_STREAM_NAME'); mockAttribute(AWS_ATTRIBUTE_KEYS.AWS_KINESIS_STREAM_NAME, undefined); + // Validate behaviour of AWS_SNS_TOPIC_ARN attribute then remove it. + mockAttribute(AWS_ATTRIBUTE_KEYS.AWS_SNS_TOPIC_ARN, 'arn:aws:sns:us-east-1:123456789012:testTopic'); + validateRemoteResourceAttributes('AWS::SNS::Topic', 'testTopic'); + mockAttribute(AWS_ATTRIBUTE_KEYS.AWS_SNS_TOPIC_ARN, undefined); + + // Validate behaviour of AWS_SECRETSMANAGER_SECRET_ARN attributes then remove it. + mockAttribute( + AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN, + 'arn:aws:secretsmanager:us-east-1:123456789123:secret:testSecret' + ); + validateRemoteResourceAttributes('AWS::SecretsManager::Secret', 'testSecret'); + mockAttribute(AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN, undefined); + + // Validate behaviour of AWS_LAMBDA_RESOURCE_MAPPING_ID attribute then remove it. + mockAttribute(AWS_ATTRIBUTE_KEYS.AWS_LAMBDA_RESOURCE_MAPPING_ID, 'aws_lambda_resource_mapping_id'); + validateRemoteResourceAttributes('AWS::Lambda::EventSourceMapping', 'aws_lambda_resource_mapping_id'); + mockAttribute(AWS_ATTRIBUTE_KEYS.AWS_LAMBDA_RESOURCE_MAPPING_ID, undefined); + + // Validate behaviour of AWS_STEPFUNCTIONS_STATEMACHINE_ARN and AWS_STEPFUNCTIONS_ACTIVITY_ARN attributes then remove them. + mockAttribute( + AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_STATEMACHINE_ARN, + 'arn:aws:states:us-east-1:123456789123:stateMachine:testStateMachine' + ); + validateRemoteResourceAttributes('AWS::StepFunctions::StateMachine', 'testStateMachine'); + mockAttribute(AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_STATEMACHINE_ARN, undefined); + + mockAttribute( + AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_ACTIVITY_ARN, + 'arn:aws:states:us-east-1:123456789123:activity:testActivity' + ); + validateRemoteResourceAttributes('AWS::StepFunctions::Activity', 'testActivity'); + mockAttribute(AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_ACTIVITY_ARN, undefined); + // Validate behaviour of AWS_TABLE_NAMES attribute with one table name, then remove it. mockAttribute(AWS_ATTRIBUTE_KEYS.AWS_DYNAMODB_TABLE_NAMES, ['aws_table_name']); validateRemoteResourceAttributes('AWS::DynamoDB::Table', 'aws_table_name'); @@ -1167,6 +1200,10 @@ describe('AwsMetricAttributeGeneratorTest', () => { testAwsSdkServiceNormalization('Kinesis', 'AWS::Kinesis'); testAwsSdkServiceNormalization('S3', 'AWS::S3'); testAwsSdkServiceNormalization('SQS', 'AWS::SQS'); + testAwsSdkServiceNormalization('SNS', 'AWS::SNS'); + testAwsSdkServiceNormalization('Lambda', 'AWS::Lambda'); + testAwsSdkServiceNormalization('SecretsManager', 'AWS::SecretsManager'); + testAwsSdkServiceNormalization('SFN', 'AWS::StepFunctions'); testAwsSdkServiceNormalization('Bedrock', 'AWS::Bedrock'); testAwsSdkServiceNormalization('BedrockAgent', 'AWS::Bedrock'); testAwsSdkServiceNormalization('BedrockAgentRuntime', 'AWS::Bedrock'); diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/bedrock.test.ts b/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/bedrock.test.ts index b1516c6..f642e09 100644 --- a/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/bedrock.test.ts +++ b/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/bedrock.test.ts @@ -134,7 +134,7 @@ describe('BedrockAgent', () => { expect(getDataSourceSpans.length).toBe(1); const getDataSourceSpan = getDataSourceSpans[0]; expect(getDataSourceSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_AGENT_ID]).toBeUndefined(); - expect(getDataSourceSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]).toBeUndefined(); + expect(getDataSourceSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]).toBe(dummyKnowledgeBaseId); expect(getDataSourceSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID]).toBe(dummyDataSourceId); expect(getDataSourceSpan.kind).toBe(SpanKind.CLIENT); }); @@ -236,9 +236,11 @@ describe('Bedrock', () => { describe('GetGuardrail', () => { it('adds guardrailId to span', async () => { const dummyGuardrailIdentifier: string = 'ABCDEFGH'; + const guardrailArn: string = 'arn:aws:bedrock:us-east-1:123456789012:guardrail/abc123'; nock(`https://bedrock.${region}.amazonaws.com`).get(`/guardrails/${dummyGuardrailIdentifier}`).reply(200, { guardrailId: dummyGuardrailIdentifier, + guardrailArn: guardrailArn, }); await bedrock @@ -258,6 +260,7 @@ describe('Bedrock', () => { expect(getGuardrailSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]).toBeUndefined(); expect(getGuardrailSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID]).toBeUndefined(); expect(getGuardrailSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_GUARDRAIL_ID]).toBe(dummyGuardrailIdentifier); + expect(getGuardrailSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_GUARDRAIL_ARN]).toBe(guardrailArn); expect(getGuardrailSpan.kind).toBe(SpanKind.CLIENT); }); }); diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/secretsmanager.test.ts b/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/secretsmanager.test.ts new file mode 100644 index 0000000..7e84777 --- /dev/null +++ b/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/secretsmanager.test.ts @@ -0,0 +1,100 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { getTestSpans, registerInstrumentationTesting } from '@opentelemetry/contrib-test-utils'; +import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk'; +import { applyInstrumentationPatches } from './../../../../src/patches/instrumentation-patch'; + +const instrumentations: AwsInstrumentation[] = [new AwsInstrumentation()]; +applyInstrumentationPatches(instrumentations); +registerInstrumentationTesting(instrumentations[0]); + +import { SecretsManager } from '@aws-sdk/client-secrets-manager'; +import * as nock from 'nock'; + +import { SpanKind } from '@opentelemetry/api'; +import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; +import { expect } from 'expect'; +import { AWS_ATTRIBUTE_KEYS } from '../../../../src/aws-attribute-keys'; + +const region = 'us-east-1'; + +describe('SecretsManager', () => { + let secretsManager: SecretsManager; + beforeEach(() => { + secretsManager = new SecretsManager({ + region: region, + credentials: { + accessKeyId: 'abcde', + secretAccessKey: 'abcde', + }, + }); + }); + + describe('DescribeSecret', () => { + const testParams = [ + 'testId', + 'badarn:aws:secretsmanager:us-weast-1:123456789123:secret:testId123456', + 'arn:aws:secretsmanager:us-east-1:123456789123:secret:testId123456', + ]; + + testParams.forEach(secretId => { + it('should generate secret arn attribute only if secretId is an valid ARN', async () => { + nock(`https://secretsmanager.${region}.amazonaws.com/`).post('/').reply(200, 'null'); + + await secretsManager + .describeSecret({ + SecretId: secretId, + }) + .catch((err: any) => {}); + + const testSpans: ReadableSpan[] = getTestSpans(); + const getDescribeSecretSpans: ReadableSpan[] = testSpans.filter((s: ReadableSpan) => { + return s.name === 'SecretsManager.DescribeSecret'; + }); + + expect(getDescribeSecretSpans.length).toBe(1); + const describeSecretSpan = getDescribeSecretSpans[0]; + + if (secretId.startsWith('arn:aws:secretsmanager:')) { + expect(describeSecretSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN]).toBe(secretId); + } else { + expect(describeSecretSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN]).toBeUndefined(); + } + + expect(describeSecretSpan.kind).toBe(SpanKind.CLIENT); + }); + }); + }); + + describe('GetSecretValue', () => { + it('secret arn attribute should be populated from the response', async () => { + const secretIdArn = 'arn:aws:secretsmanager:us-east-1:123456789123:secret:testId123456'; + + nock(`https://secretsmanager.${region}.amazonaws.com/`).post('/').reply(200, { + ARN: secretIdArn, + Name: 'testId', + }); + + await secretsManager + .getSecretValue({ + SecretId: 'testSecret', + }) + .catch((err: any) => { + console.log(err); + }); + + const testSpans: ReadableSpan[] = getTestSpans(); + const getSecretValueSpans: ReadableSpan[] = testSpans.filter((s: ReadableSpan) => { + return s.name === 'SecretsManager.GetSecretValue'; + }); + + expect(getSecretValueSpans.length).toBe(1); + + const secretValueSpan = getSecretValueSpans[0]; + + expect(secretValueSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN]).toBe(secretIdArn); + expect(secretValueSpan.kind).toBe(SpanKind.CLIENT); + }); + }); +}); diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/step-functions.test.ts b/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/step-functions.test.ts new file mode 100644 index 0000000..8d9a5a5 --- /dev/null +++ b/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/step-functions.test.ts @@ -0,0 +1,93 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { getTestSpans, registerInstrumentationTesting } from '@opentelemetry/contrib-test-utils'; +import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk'; +import { applyInstrumentationPatches } from './../../../../src/patches/instrumentation-patch'; + +const instrumentations: AwsInstrumentation[] = [new AwsInstrumentation()]; +applyInstrumentationPatches(instrumentations); +registerInstrumentationTesting(instrumentations[0]); + +import { SFN } from '@aws-sdk/client-sfn'; +import * as nock from 'nock'; + +import { SpanKind } from '@opentelemetry/api'; +import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; +import { expect } from 'expect'; +import { AWS_ATTRIBUTE_KEYS } from '../../../../src/aws-attribute-keys'; + +const region = 'us-east-1'; + +describe('SFN', () => { + let sfn: SFN; + beforeEach(() => { + sfn = new SFN({ + region: region, + credentials: { + accessKeyId: 'abcde', + secretAccessKey: 'abcde', + }, + }); + }); + + describe('DescribeStateMachine', () => { + it('span has stateMachineArn in its attributes', async () => { + const stateMachineArn: string = 'arn:aws:states:us-east-1:123456789123:stateMachine:testStateMachine'; + + nock(`https://states.${region}.amazonaws.com/`).post('/').reply(200, 'null'); + + await sfn + .describeStateMachine({ + stateMachineArn: stateMachineArn, + }) + .catch((err: any) => { + console.log(err); + }); + + const testSpans: ReadableSpan[] = getTestSpans(); + const getStateMachineAttributeSpans: ReadableSpan[] = testSpans.filter((s: ReadableSpan) => { + return s.name === 'SFN.DescribeStateMachine'; + }); + + expect(getStateMachineAttributeSpans.length).toBe(1); + + const stateMachineAttributeSpan = getStateMachineAttributeSpans[0]; + + expect(AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_STATEMACHINE_ARN in stateMachineAttributeSpan.attributes).toBe(true); + expect(stateMachineAttributeSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_STATEMACHINE_ARN]).toBe( + stateMachineArn + ); + expect(stateMachineAttributeSpan.kind).toBe(SpanKind.CLIENT); + }); + }); + + describe('DescribeActivity', () => { + it('span has activityArn in its attributes', async () => { + const activityArn: string = 'arn:aws:states:us-east-1:123456789123:activity:testActivity'; + + nock(`https://states.${region}.amazonaws.com/`).post('/').reply(200, 'null'); + + await sfn + .describeActivity({ + activityArn: activityArn, + }) + .catch((err: any) => { + console.log(err); + }); + + const testSpans: ReadableSpan[] = getTestSpans(); + const getActivityAttributeSpans: ReadableSpan[] = testSpans.filter((s: ReadableSpan) => { + return s.name === 'SFN.DescribeActivity'; + }); + + expect(getActivityAttributeSpans.length).toBe(1); + + const activityAttributeSpan = getActivityAttributeSpans[0]; + + expect(AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_ACTIVITY_ARN in activityAttributeSpan.attributes).toBe(true); + expect(activityAttributeSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_ACTIVITY_ARN]).toBe(activityArn); + expect(activityAttributeSpan.kind).toBe(SpanKind.CLIENT); + }); + }); +}); diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/instrumentation-patch.test.ts b/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/instrumentation-patch.test.ts index 9c11b06..6a731f2 100644 --- a/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/instrumentation-patch.test.ts +++ b/aws-distro-opentelemetry-node-autoinstrumentation/test/patches/instrumentation-patch.test.ts @@ -32,10 +32,16 @@ import { AwsSdkInstrumentationExtended } from '../../src/patches/extended-instru const _STREAM_NAME: string = 'streamName'; const _BUCKET_NAME: string = 'bucketName'; const _QUEUE_NAME: string = 'queueName'; +const _ACTIVITY_ARN: string = 'arn:aws:states:us-east-1:123456789123:activity:testActivity'; +const _STATE_MACHINE_ARN: string = 'arn:aws:states:us-east-1:123456789123:stateMachine:testStateMachine'; +const _SECRETS_ARN: string = 'arn:aws:secretsmanager:us-east-1:123456789123:secret:testId123456'; +const _UUID: string = 'random-uuid'; +const _TOPIC_ARN: string = 'arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE'; const _QUEUE_URL: string = 'https://sqs.us-east-1.amazonaws.com/123412341234/queueName'; const _BEDROCK_AGENT_ID: string = 'agentId'; const _BEDROCK_DATASOURCE_ID: string = 'DataSourceId'; const _BEDROCK_GUARDRAIL_ID: string = 'GuardrailId'; +const _BEDROCK_GUARDRAIL_ARN: string = 'arn:aws:bedrock:us-east-1:123456789012:guardrail/abc123'; const _BEDROCK_KNOWLEDGEBASE_ID: string = 'KnowledgeBaseId'; const _GEN_AI_SYSTEM: string = 'aws.bedrock'; const _GEN_AI_REQUEST_MODEL: string = 'genAiReuqestModelId'; @@ -62,11 +68,18 @@ describe('InstrumentationPatchTest', () => { // Not from patching expect(services.has('SQS')).toBeTruthy(); expect(services.has('SNS')).toBeTruthy(); - expect(services.has('DynamoDB')).toBeTruthy(); expect(services.has('Lambda')).toBeTruthy(); + + expect(services.has('DynamoDB')).toBeTruthy(); // From patching but shouldn't be applied + expect(services.get('SecretsManager')).toBeFalsy(); + expect(services.get('SFN')).toBeFalsy(); expect(services.has('S3')).toBeFalsy(); expect(services.has('Kinesis')).toBeFalsy(); + expect(services.get('SNS')._requestPreSpanHook).toBeFalsy(); + expect(services.get('SNS').requestPreSpanHook).toBeTruthy(); + expect(services.get('Lambda')._requestPreSpanHook).toBeFalsy(); + expect(services.get('Lambda').requestPreSpanHook).toBeTruthy(); expect(services.get('SQS')._requestPreSpanHook).toBeFalsy(); expect(services.get('SQS').requestPreSpanHook).toBeTruthy(); expect(services.has('Bedrock')).toBeFalsy(); @@ -87,9 +100,16 @@ describe('InstrumentationPatchTest', () => { expect(services.has('SNS')).toBeTruthy(); expect(services.has('DynamoDB')).toBeTruthy(); expect(services.has('Lambda')).toBeTruthy(); + // From patching + expect(services.has('SecretsManager')).toBeTruthy(); + expect(services.has('SFN')).toBeTruthy(); expect(services.has('S3')).toBeTruthy(); expect(services.has('Kinesis')).toBeTruthy(); + expect(services.get('SNS')._requestPreSpanHook).toBeTruthy(); + expect(services.get('SNS').requestPreSpanHook).toBeTruthy(); + expect(services.get('Lambda')._requestPreSpanHook).toBeTruthy(); + expect(services.get('Lambda').requestPreSpanHook).toBeTruthy(); expect(services.get('SQS')._requestPreSpanHook).toBeTruthy(); expect(services.get('SQS').requestPreSpanHook).toBeTruthy(); expect(services.has('Bedrock')).toBeTruthy(); @@ -129,6 +149,36 @@ describe('InstrumentationPatchTest', () => { expect(sqsAttributes[AWS_ATTRIBUTE_KEYS.AWS_SQS_QUEUE_NAME]).toBeUndefined(); }); + it('SNS without patching', () => { + const unpatchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(UNPATCHED_INSTRUMENTATIONS); + const services: Map = extractServicesFromAwsSdkInstrumentation(unpatchedAwsSdkInstrumentation); + expect(() => doExtractSNSAttributes(services)).not.toThrow(); + + const snsAttributes = doExtractSNSAttributes(services); + expect(snsAttributes[AWS_ATTRIBUTE_KEYS.AWS_SNS_TOPIC_ARN]).toBeUndefined(); + }); + + it('Lambda without patching', () => { + const unpatchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(UNPATCHED_INSTRUMENTATIONS); + const services: Map = extractServicesFromAwsSdkInstrumentation(unpatchedAwsSdkInstrumentation); + expect(() => doExtractLambdaAttributes(services)).not.toThrow(); + + const lambdaAttributes: Attributes = doExtractLambdaAttributes(services); + expect(lambdaAttributes[AWS_ATTRIBUTE_KEYS.AWS_LAMBDA_RESOURCE_MAPPING_ID]).toBeUndefined(); + }); + + it('SFN without patching', () => { + const unpatchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(UNPATCHED_INSTRUMENTATIONS); + const services: Map = extractServicesFromAwsSdkInstrumentation(unpatchedAwsSdkInstrumentation); + expect(() => doExtractSFNAttributes(services)).toThrow(); + }); + + it('SecretsManager without patching', () => { + const unpatchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(UNPATCHED_INSTRUMENTATIONS); + const services: Map = extractServicesFromAwsSdkInstrumentation(unpatchedAwsSdkInstrumentation); + expect(() => doExtractSecretsManagerAttributes(services)).toThrow(); + }); + it('Bedrock without patching', () => { const unpatchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(UNPATCHED_INSTRUMENTATIONS); const services: Map = extractServicesFromAwsSdkInstrumentation(unpatchedAwsSdkInstrumentation); @@ -149,6 +199,14 @@ describe('InstrumentationPatchTest', () => { expect(kinesisAttributes[AWS_ATTRIBUTE_KEYS.AWS_KINESIS_STREAM_NAME]).toEqual(_STREAM_NAME); }); + it('SNS with patching', () => { + const patchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(PATCHED_INSTRUMENTATIONS); + const services: Map = extractServicesFromAwsSdkInstrumentation(patchedAwsSdkInstrumentation); + + const snsAttributes = doExtractSNSAttributes(services); + expect(snsAttributes[AWS_ATTRIBUTE_KEYS.AWS_SNS_TOPIC_ARN]).toBe(_TOPIC_ARN); + }); + it('SQS with patching', () => { const patchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(PATCHED_INSTRUMENTATIONS); const services: Map = extractServicesFromAwsSdkInstrumentation(patchedAwsSdkInstrumentation); @@ -165,6 +223,33 @@ describe('InstrumentationPatchTest', () => { expect(sqsAttributes[AWS_ATTRIBUTE_KEYS.AWS_SQS_QUEUE_NAME]).toEqual(_QUEUE_NAME); }); + it('Lambda with patching', () => { + const patchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(PATCHED_INSTRUMENTATIONS); + const services: Map = extractServicesFromAwsSdkInstrumentation(patchedAwsSdkInstrumentation); + const requestLambdaAttributes: Attributes = doExtractLambdaAttributes(services); + expect(requestLambdaAttributes[AWS_ATTRIBUTE_KEYS.AWS_LAMBDA_RESOURCE_MAPPING_ID]).toEqual(_UUID); + }); + + it('SFN with patching', () => { + const patchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(PATCHED_INSTRUMENTATIONS); + const services: Map = extractServicesFromAwsSdkInstrumentation(patchedAwsSdkInstrumentation); + const requestSFNAttributes: Attributes = doExtractSFNAttributes(services); + expect(requestSFNAttributes[AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_STATEMACHINE_ARN]).toEqual(_STATE_MACHINE_ARN); + expect(requestSFNAttributes[AWS_ATTRIBUTE_KEYS.AWS_STEPFUNCTIONS_ACTIVITY_ARN]).toEqual(_ACTIVITY_ARN); + }); + + it('SecretsManager with patching', () => { + const patchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(PATCHED_INSTRUMENTATIONS); + const services: Map = extractServicesFromAwsSdkInstrumentation(patchedAwsSdkInstrumentation); + const requestSecretsManagerAttributes: Attributes = doExtractSecretsManagerAttributes(services); + + expect(requestSecretsManagerAttributes[AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN]).toBe(_SECRETS_ARN); + + const responseHookSecretsManagerAttributes = doResponseHookSecretsManager(services); + + expect(responseHookSecretsManagerAttributes[AWS_ATTRIBUTE_KEYS.AWS_SECRETSMANAGER_SECRET_ARN]).toBe(_SECRETS_ARN); + }); + it('Bedrock with patching', () => { const patchedAwsSdkInstrumentation: AwsInstrumentation = extractAwsSdkInstrumentation(PATCHED_INSTRUMENTATIONS); const services: Map = extractServicesFromAwsSdkInstrumentation(patchedAwsSdkInstrumentation); @@ -172,8 +257,11 @@ describe('InstrumentationPatchTest', () => { // Expect no-op from attribute extraction in Bedrock expect(Object.entries(bedrockAttributes).length).toEqual(0); const bedrockAttributesAfterResponse: Attributes = doResponseHookBedrock(services, 'Bedrock'); - expect(Object.entries(bedrockAttributesAfterResponse).length).toBe(1); + expect(Object.entries(bedrockAttributesAfterResponse).length).toBe(2); expect(bedrockAttributesAfterResponse[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_GUARDRAIL_ID]).toEqual(_BEDROCK_GUARDRAIL_ID); + expect(bedrockAttributesAfterResponse[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_GUARDRAIL_ARN]).toEqual( + _BEDROCK_GUARDRAIL_ARN + ); }); it('Bedrock Agent with patching', () => { @@ -208,18 +296,25 @@ describe('InstrumentationPatchTest', () => { ListDataSources: { 'aws.bedrock.knowledge_base.id': _BEDROCK_KNOWLEDGEBASE_ID }, UpdateAgentKnowledgeBase: { 'aws.bedrock.knowledge_base.id': _BEDROCK_KNOWLEDGEBASE_ID }, DeleteDataSource: { 'aws.bedrock.data_source.id': _BEDROCK_DATASOURCE_ID }, - GetDataSource: { 'aws.bedrock.data_source.id': _BEDROCK_DATASOURCE_ID }, + GetDataSource: { + 'aws.bedrock.data_source.id': _BEDROCK_DATASOURCE_ID, + 'aws.bedrock.knowledge_base.id': _BEDROCK_KNOWLEDGEBASE_ID, + }, UpdateDataSource: { 'aws.bedrock.data_source.id': _BEDROCK_DATASOURCE_ID }, }; for (const [operation, attribute_tuple] of Object.entries(operation_to_expected_attribute)) { const bedrockAttributes: Attributes = doExtractBedrockAttributes(services, 'BedrockAgent', operation); - const [attribute_key, attribute_value] = Object.entries(attribute_tuple)[0]; - expect(Object.entries(bedrockAttributes).length).toBe(1); - expect(bedrockAttributes[attribute_key]).toEqual(attribute_value); + + for (const [attribute_key, attribute_value] of Object.entries(attribute_tuple)) { + expect(bedrockAttributes[attribute_key]).toEqual(attribute_value); + } + const bedrockAgentSuccessAttributes: Attributes = doResponseHookBedrock(services, 'BedrockAgent', operation); - expect(Object.entries(bedrockAgentSuccessAttributes).length).toBe(1); - expect(bedrockAgentSuccessAttributes[attribute_key]).toEqual(attribute_value); + + for (const [attribute_key, attribute_value] of Object.entries(attribute_tuple)) { + expect(bedrockAgentSuccessAttributes[attribute_key]).toEqual(attribute_value); + } } }); @@ -315,6 +410,55 @@ describe('InstrumentationPatchTest', () => { return doExtractAttributes(services, serviceName, params); } + function doExtractSNSAttributes(services: Map): Attributes { + const serviceName: string = 'SNS'; + const params: NormalizedRequest = { + serviceName: serviceName, + commandName: 'mockCommandName', + commandInput: { + TopicArn: _TOPIC_ARN, + }, + }; + return doExtractAttributes(services, serviceName, params); + } + + function doExtractLambdaAttributes(services: Map): Attributes { + const serviceName: string = 'Lambda'; + const params: NormalizedRequest = { + serviceName: serviceName, + commandName: 'mockCommandName', + commandInput: { + UUID: _UUID, + }, + }; + return doExtractAttributes(services, serviceName, params); + } + + function doExtractSFNAttributes(services: Map): Attributes { + const serviceName: string = 'SFN'; + const params: NormalizedRequest = { + serviceName: serviceName, + commandName: 'mockCommandName', + commandInput: { + stateMachineArn: _STATE_MACHINE_ARN, + activityArn: _ACTIVITY_ARN, + }, + }; + return doExtractAttributes(services, serviceName, params); + } + + function doExtractSecretsManagerAttributes(services: Map): Attributes { + const serviceName: string = 'SecretsManager'; + const params: NormalizedRequest = { + serviceName: serviceName, + commandName: 'mockCommandName', + commandInput: { + SecretId: _SECRETS_ARN, + }, + }; + return doExtractAttributes(services, serviceName, params); + } + function doExtractBedrockAttributes( services: Map, serviceName: string, @@ -347,6 +491,22 @@ describe('InstrumentationPatchTest', () => { return requestMetadata.spanAttributes || {}; } + function doResponseHookSecretsManager(services: Map): Attributes { + const results: Partial = { + data: { + ARN: _SECRETS_ARN, + }, + + request: { + commandInput: {}, + commandName: 'dummy_operation', + serviceName: 'SecretsManager', + }, + }; + + return doResponseHook(services, 'SecretsManager', results as NormalizedResponse); + } + function doResponseHookBedrock( services: Map, serviceName: string, @@ -358,6 +518,7 @@ describe('InstrumentationPatchTest', () => { dataSourceId: _BEDROCK_DATASOURCE_ID, knowledgeBaseId: _BEDROCK_KNOWLEDGEBASE_ID, guardrailId: _BEDROCK_GUARDRAIL_ID, + guardrailArn: _BEDROCK_GUARDRAIL_ARN, modelId: _GEN_AI_REQUEST_MODEL, }, request: { diff --git a/contract-tests/images/applications/mysql2/package.json b/contract-tests/images/applications/mysql2/package.json index 0c1fe64..5a18ef9 100644 --- a/contract-tests/images/applications/mysql2/package.json +++ b/contract-tests/images/applications/mysql2/package.json @@ -12,4 +12,4 @@ "dependencies": { "mysql2": "3.11.4" } -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 97ce276..7d8f801 100644 --- a/package-lock.json +++ b/package-lock.json @@ -62,7 +62,11 @@ "@aws-sdk/client-bedrock-agent-runtime": "3.632.0", "@aws-sdk/client-bedrock-runtime": "3.632.0", "@aws-sdk/client-kinesis": "3.632.0", + "@aws-sdk/client-lambda": "^3.632.0", "@aws-sdk/client-s3": "3.632.0", + "@aws-sdk/client-secrets-manager": "^3.632.0", + "@aws-sdk/client-sfn": "^3.632.0", + "@aws-sdk/client-sns": "^3.632.0", "@opentelemetry/contrib-test-utils": "0.41.0", "@types/mocha": "7.0.2", "@types/node": "18.6.5", @@ -613,48 +617,782 @@ "node": ">=16.0.0" } }, + "node_modules/@aws-sdk/client-lambda": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.699.0.tgz", + "integrity": "sha512-K9TGvQB8hkjwNhfWSfYllUpttqxTcd78ShSRCIhlcwzzsmQphET10xEb0Tm1k8sqriSQ+CiVOFSkX78gqoHzBg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/client-sts": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/eventstream-serde-browser": "^3.0.13", + "@smithy/eventstream-serde-config-resolver": "^3.0.10", + "@smithy/eventstream-serde-node": "^3.0.12", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-stream": "^3.3.1", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.1.9", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/client-sso": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz", + "integrity": "sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.699.0.tgz", + "integrity": "sha512-u8a1GorY5D1l+4FQAf4XBUC1T10/t7neuwT21r0ymrtMFSK2a9QqVHKMoLkvavAwyhJnARSBM9/UQC797PFOFw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.699.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/client-sts": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.699.0.tgz", + "integrity": "sha512-++lsn4x2YXsZPIzFVwv3fSUVM55ZT0WRFmPeNilYIhZClxHLmVAWKH4I55cY9ry60/aTKYjzOXkWwyBKGsGvQg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/core": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.696.0.tgz", + "integrity": "sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/core": "^2.5.3", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.7", + "@smithy/signature-v4": "^4.2.2", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-middleware": "^3.0.10", + "fast-xml-parser": "4.4.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-env": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz", + "integrity": "sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-http": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz", + "integrity": "sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-stream": "^3.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.699.0.tgz", + "integrity": "sha512-dXmCqjJnKmG37Q+nLjPVu22mNkrGHY8hYoOt3Jo9R2zr5MYV7s/NHsCHr+7E+BZ+tfZYLRPeB1wkpTeHiEcdRw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.699.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.699.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.699.0.tgz", + "integrity": "sha512-MmEmNDo1bBtTgRmdNfdQksXu4uXe66s0p1hi1YPrn1h59Q605eq/xiWbGL6/3KdkViH6eGUuABeV2ODld86ylg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-ini": "3.699.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.699.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-process": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz", + "integrity": "sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.699.0.tgz", + "integrity": "sha512-Ekp2cZG4pl9D8+uKWm4qO1xcm8/MeiI8f+dnlZm8aQzizeC+aXYy9GyoclSf6daK8KfRPiRfM7ZHBBL5dAfdMA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.696.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/token-providers": "3.699.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz", + "integrity": "sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.696.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/middleware-host-header": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz", + "integrity": "sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/middleware-logger": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz", + "integrity": "sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz", + "integrity": "sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz", + "integrity": "sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@smithy/core": "^2.5.3", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/region-config-resolver": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz", + "integrity": "sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/token-providers": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.699.0.tgz", + "integrity": "sha512-kuiEW9DWs7fNos/SM+y58HCPhcIzm1nEZLhe2/7/6+TvAYLuEWURYsbK48gzsxXlaJ2k/jGY3nIsA7RptbMOwA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sso-oidc": "^3.699.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/types": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.696.0.tgz", + "integrity": "sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/util-endpoints": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz", + "integrity": "sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "@smithy/util-endpoints": "^2.1.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz", + "integrity": "sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz", + "integrity": "sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/fetch-http-handler": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz", + "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, "node_modules/@aws-sdk/client-s3": { "version": "3.632.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.632.0.tgz", - "integrity": "sha512-GlhLo/t/E9w3EG3ZhFsSeSM3op2lfhc1LrLMXHFsmH1xIPkjIoxV+aHYIenuF7b/MGgMQDOjf07QeQNXfAr1gg==", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.632.0.tgz", + "integrity": "sha512-GlhLo/t/E9w3EG3ZhFsSeSM3op2lfhc1LrLMXHFsmH1xIPkjIoxV+aHYIenuF7b/MGgMQDOjf07QeQNXfAr1gg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha1-browser": "5.2.0", + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.632.0", + "@aws-sdk/client-sts": "3.632.0", + "@aws-sdk/core": "3.629.0", + "@aws-sdk/credential-provider-node": "3.632.0", + "@aws-sdk/middleware-bucket-endpoint": "3.620.0", + "@aws-sdk/middleware-expect-continue": "3.620.0", + "@aws-sdk/middleware-flexible-checksums": "3.620.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-location-constraint": "3.609.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-sdk-s3": "3.629.0", + "@aws-sdk/middleware-ssec": "3.609.0", + "@aws-sdk/middleware-user-agent": "3.632.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/signature-v4-multi-region": "3.629.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.632.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@aws-sdk/xml-builder": "3.609.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.2", + "@smithy/eventstream-serde-browser": "^3.0.6", + "@smithy/eventstream-serde-config-resolver": "^3.0.3", + "@smithy/eventstream-serde-node": "^3.0.5", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-blob-browser": "^3.1.2", + "@smithy/hash-node": "^3.0.3", + "@smithy/hash-stream-node": "^3.1.2", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/md5-js": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.14", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-stream": "^3.1.3", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager": { + "version": "3.632.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.632.0.tgz", + "integrity": "sha512-WsQhPHHK1yPfALcP1B7nBSGDzky6vFTUEXnUdfzb5Xy2cT+JTBTS6ChtQGqqOuGHDP/3t/9soqZ+L6rUCYBb/Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.632.0", + "@aws-sdk/client-sts": "3.632.0", + "@aws-sdk/core": "3.629.0", + "@aws-sdk/credential-provider-node": "3.632.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.632.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.632.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.2", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.14", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sfn": { + "version": "3.632.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sfn/-/client-sfn-3.632.0.tgz", + "integrity": "sha512-LPaMqALuArGX1Y5N3tHX4lNlZabsqgfGJZjwyLTHawqiGNDMlMqOUg4Dl0e2Ies8yvMjs//YXtMWz26x24cGkQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.632.0", + "@aws-sdk/client-sts": "3.632.0", + "@aws-sdk/core": "3.629.0", + "@aws-sdk/credential-provider-node": "3.632.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.632.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.632.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.2", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.14", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sns": { + "version": "3.632.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.632.0.tgz", + "integrity": "sha512-I8S0tFx26LL59/PiL4Reqna+LW7oIbRB+jygl4vrf4XIvpX5o4tmZmOmR0caYA+Cks3AomCi4cp+7WuwUpuATQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/client-sso-oidc": "3.632.0", "@aws-sdk/client-sts": "3.632.0", "@aws-sdk/core": "3.629.0", "@aws-sdk/credential-provider-node": "3.632.0", - "@aws-sdk/middleware-bucket-endpoint": "3.620.0", - "@aws-sdk/middleware-expect-continue": "3.620.0", - "@aws-sdk/middleware-flexible-checksums": "3.620.0", "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-location-constraint": "3.609.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-sdk-s3": "3.629.0", - "@aws-sdk/middleware-ssec": "3.609.0", "@aws-sdk/middleware-user-agent": "3.632.0", "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/signature-v4-multi-region": "3.629.0", "@aws-sdk/types": "3.609.0", "@aws-sdk/util-endpoints": "3.632.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", - "@aws-sdk/xml-builder": "3.609.0", "@smithy/config-resolver": "^3.0.5", "@smithy/core": "^2.3.2", - "@smithy/eventstream-serde-browser": "^3.0.6", - "@smithy/eventstream-serde-config-resolver": "^3.0.3", - "@smithy/eventstream-serde-node": "^3.0.5", "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-blob-browser": "^3.1.2", "@smithy/hash-node": "^3.0.3", - "@smithy/hash-stream-node": "^3.1.2", "@smithy/invalid-dependency": "^3.0.3", - "@smithy/md5-js": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", "@smithy/middleware-retry": "^3.0.14", @@ -674,9 +1412,7 @@ "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", - "@smithy/util-stream": "^3.1.3", "@smithy/util-utf8": "^3.0.0", - "@smithy/util-waiter": "^3.1.2", "tslib": "^2.6.2" }, "engines": { @@ -5544,12 +6280,13 @@ "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@smithy/abort-controller": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.4.tgz", - "integrity": "sha512-VupaALAQlXViW3/enTf/f5l5JZYSAxoJL7f0nanhNNKnww6DGCg1oYIuNP78KDugnkwthBO6iEcym16HhWV8RQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz", + "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5578,15 +6315,16 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.8.tgz", - "integrity": "sha512-Tv1obAC18XOd2OnDAjSWmmthzx6Pdeh63FbLin8MlPiuJ2ATpKkq0NcNOJFr0dO+JmZXnwu8FQxKJ3TKJ3Hulw==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.12.tgz", + "integrity": "sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^3.1.7", - "@smithy/types": "^3.4.2", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.6", + "@smithy/util-middleware": "^3.0.10", "tslib": "^2.6.2" }, "engines": { @@ -5594,19 +6332,18 @@ } }, "node_modules/@smithy/core": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.3.tgz", - "integrity": "sha512-4LTusLqFMRVQUfC3RNuTg6IzYTeJNpydRdTKq7J5wdEyIRQSu3rGIa3s80mgG2hhe6WOZl9IqTSo1pgbn6EHhA==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.4.tgz", + "integrity": "sha512-iFh2Ymn2sCziBRLPuOOxRPkuCx/2gBdXtBGuCUFLUe6bWYjKnhHyIPqGeNkLZ5Aco/5GjebRTBFiWID3sDbrKw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-endpoint": "^3.1.3", - "@smithy/middleware-retry": "^3.0.18", - "@smithy/middleware-serde": "^3.0.6", - "@smithy/protocol-http": "^4.1.3", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-middleware": "^3.0.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-stream": "^3.3.1", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -5615,15 +6352,16 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.3.tgz", - "integrity": "sha512-VoxMzSzdvkkjMJNE38yQgx4CfnmT+Z+5EUXkg4x7yag93eQkVQgZvN3XBSHC/ylfBbLbAtdu7flTCChX9I+mVg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz", + "integrity": "sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^3.1.7", - "@smithy/property-provider": "^3.1.6", - "@smithy/types": "^3.4.2", - "@smithy/url-parser": "^3.0.6", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.10", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", "tslib": "^2.6.2" }, "engines": { @@ -5631,25 +6369,27 @@ } }, "node_modules/@smithy/eventstream-codec": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.5.tgz", - "integrity": "sha512-6pu+PT2r+5ZnWEV3vLV1DzyrpJ0TmehQlniIDCSpZg6+Ji2SfOI38EqUyQ+O8lotVElCrfVc9chKtSMe9cmCZQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.9.tgz", + "integrity": "sha512-F574nX0hhlNOjBnP+noLtsPFqXnWh2L0+nZKCwcu7P7J8k+k+rdIDs+RMnrMwrzhUE4mwMgyN0cYnEn0G8yrnQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "@smithy/util-hex-encoding": "^3.0.0", "tslib": "^2.6.2" } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.9.tgz", - "integrity": "sha512-PiQLo6OQmZAotJweIcObL1H44gkvuJACKMNqpBBe5Rf2Ax1DOcGi/28+feZI7yTe1ERHlQQaGnm8sSkyDUgsMg==", + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.13.tgz", + "integrity": "sha512-Nee9m+97o9Qj6/XeLz2g2vANS2SZgAxV4rDBMKGHvFJHU/xz88x2RwCkwsvEwYjSX4BV1NG1JXmxEaDUzZTAtw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.8", - "@smithy/types": "^3.4.2", + "@smithy/eventstream-serde-universal": "^3.0.12", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5657,12 +6397,13 @@ } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.6.tgz", - "integrity": "sha512-iew15It+c7WfnVowWkt2a7cdPp533LFJnpjDQgfZQcxv2QiOcyEcea31mnrk5PVbgo0nNH3VbYGq7myw2q/F6A==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.10.tgz", + "integrity": "sha512-K1M0x7P7qbBUKB0UWIL5KOcyi6zqV5mPJoL0/o01HPJr0CSq3A9FYuJC6e11EX6hR8QTIR++DBiGrYveOu6trw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5670,13 +6411,14 @@ } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.8.tgz", - "integrity": "sha512-6m+wI+fT0na+6oao6UqALVA38fsScCpoG5UO/A8ZSyGLnPM2i4MS1cFUhpuALgvLMxfYoTCh7qSeJa0aG4IWpQ==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.12.tgz", + "integrity": "sha512-kiZymxXvZ4tnuYsPSMUHe+MMfc4FTeFWJIc0Q5wygJoUQM4rVHNghvd48y7ppuulNMbuYt95ah71pYc2+o4JOA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.8", - "@smithy/types": "^3.4.2", + "@smithy/eventstream-serde-universal": "^3.0.12", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5684,13 +6426,14 @@ } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.8.tgz", - "integrity": "sha512-09tqzIQ6e+7jLqGvRji1yJoDbL/zob0OFhq75edgStWErGLf16+yI5hRc/o9/YAybOhUZs/swpW2SPn892G5Gg==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.12.tgz", + "integrity": "sha512-1i8ifhLJrOZ+pEifTlF0EfZzMLUGQggYQ6WmZ4d5g77zEKf7oZ0kvh1yKWHPjofvOwqrkwRDVuxuYC8wVd662A==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-codec": "^3.1.5", - "@smithy/types": "^3.4.2", + "@smithy/eventstream-codec": "^3.1.9", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5724,12 +6467,13 @@ } }, "node_modules/@smithy/hash-node": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.6.tgz", - "integrity": "sha512-c/FHEdKK/7DU2z6ZE91L36ahyXWayR3B+FzELjnYq7wH5YqIseM24V+pWCS9kFn1Ln8OFGTf+pyYPiHZuX0s/Q==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.10.tgz", + "integrity": "sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -5754,12 +6498,13 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.6.tgz", - "integrity": "sha512-czM7Ioq3s8pIXht7oD+vmgy4Wfb4XavU/k/irO8NdXFFOx7YAlsCCcKOh/lJD1mJSYQqiR7NmpZ9JviryD/7AQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz", + "integrity": "sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" } }, @@ -5789,13 +6534,14 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.8.tgz", - "integrity": "sha512-VuyszlSO49WKh3H9/kIO2kf07VUwGV80QRiaDxUfP8P8UKlokz381ETJvwLhwuypBYhLymCYyNhB3fLAGBX2og==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz", + "integrity": "sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^4.1.3", - "@smithy/types": "^3.4.2", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5803,17 +6549,19 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.3.tgz", - "integrity": "sha512-KeM/OrK8MVFUsoJsmCN0MZMVPjKKLudn13xpgwIMpGTYpA8QZB2Xq5tJ+RE6iu3A6NhOI4VajDTwBsm8pwwrhg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.4.tgz", + "integrity": "sha512-TybiW2LA3kYVd3e+lWhINVu1o26KJbBwOpADnf0L4x/35vLVica77XVR5hvV9+kWeTGeSJ3IHTcYxbRxlbwhsg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^3.0.6", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/shared-ini-file-loader": "^3.1.7", - "@smithy/types": "^3.4.2", - "@smithy/url-parser": "^3.0.6", - "@smithy/util-middleware": "^3.0.6", + "@smithy/core": "^2.5.4", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-middleware": "^3.0.10", "tslib": "^2.6.2" }, "engines": { @@ -5821,18 +6569,19 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.18.tgz", - "integrity": "sha512-YU1o/vYob6vlqZdd97MN8cSXRToknLXhFBL3r+c9CZcnxkO/rgNZ++CfgX2vsmnEKvlqdi26+SRtSzlVp5z6Mg==", + "version": "3.0.28", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.28.tgz", + "integrity": "sha512-vK2eDfvIXG1U64FEUhYxoZ1JSj4XFbYWkK36iz02i3pFwWiDz1Q7jKhGTBCwx/7KqJNk4VS7d7cDLXFOvP7M+g==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^3.1.7", - "@smithy/protocol-http": "^4.1.3", - "@smithy/service-error-classification": "^3.0.6", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", - "@smithy/util-middleware": "^3.0.6", - "@smithy/util-retry": "^3.0.6", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/protocol-http": "^4.1.7", + "@smithy/service-error-classification": "^3.0.10", + "@smithy/smithy-client": "^3.4.5", + "@smithy/types": "^3.7.1", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", "tslib": "^2.6.2", "uuid": "^9.0.1" }, @@ -5841,12 +6590,13 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.6.tgz", - "integrity": "sha512-KKTUSl1MzOM0MAjGbudeaVNtIDo+PpekTBkCNwvfZlKndodrnvRo+00USatiyLOc0ujjO9UydMRu3O9dYML7ag==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz", + "integrity": "sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5854,12 +6604,13 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.6.tgz", - "integrity": "sha512-2c0eSYhTQ8xQqHMcRxLMpadFbTXg6Zla5l0mwNftFCZMQmuhI7EbAJMx6R5eqfuV3YbJ3QGyS3d5uSmrHV8Khg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz", + "integrity": "sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5867,14 +6618,15 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.7.tgz", - "integrity": "sha512-g3mfnC3Oo8pOI0dYuPXLtdW1WGVb3bR2tkV21GNkm0ZvQjLTtamXAwCWt/FCb0HGvKt3gHHmF1XerG0ICfalOg==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz", + "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^3.1.6", - "@smithy/shared-ini-file-loader": "^3.1.7", - "@smithy/types": "^3.4.2", + "@smithy/property-provider": "^3.1.10", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5882,15 +6634,16 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.2.2.tgz", - "integrity": "sha512-42Cy4/oT2O+00aiG1iQ7Kd7rE6q8j7vI0gFfnMlUiATvyo8vefJkhb7O10qZY0jAqo5WZdUzfl9IV6wQ3iMBCg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz", + "integrity": "sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^3.1.4", - "@smithy/protocol-http": "^4.1.3", - "@smithy/querystring-builder": "^3.0.6", - "@smithy/types": "^3.4.2", + "@smithy/abort-controller": "^3.1.8", + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5898,12 +6651,13 @@ } }, "node_modules/@smithy/property-provider": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.6.tgz", - "integrity": "sha512-NK3y/T7Q/Bw+Z8vsVs9MYIQ5v7gOX7clyrXcwhhIBQhbPgRl6JDrZbusO9qWDhcEus75Tg+VCxtIRfo3H76fpw==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz", + "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5911,12 +6665,13 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.3.tgz", - "integrity": "sha512-GcbMmOYpH9iRqtC05RbRnc/0FssxSTHlmaNhYBTgSgNCYpdR3Kt88u5GAZTBmouzv+Zlj/VRv92J9ruuDeJuEw==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.7.tgz", + "integrity": "sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5924,12 +6679,13 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.6.tgz", - "integrity": "sha512-sQe08RunoObe+Usujn9+R2zrLuQERi3CWvRO3BvnoWSYUaIrLKuAIeY7cMeDax6xGyfIP3x/yFWbEKSXvOnvVg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz", + "integrity": "sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" }, @@ -5938,12 +6694,13 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.6.tgz", - "integrity": "sha512-UJKw4LlEkytzz2Wq+uIdHf6qOtFfee/o7ruH0jF5I6UAuU+19r9QV7nU3P/uI0l6+oElRHmG/5cBBcGJrD7Ozg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz", + "integrity": "sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5951,24 +6708,26 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.6.tgz", - "integrity": "sha512-53SpchU3+DUZrN7J6sBx9tBiCVGzsib2e4sc512Q7K9fpC5zkJKs6Z9s+qbMxSYrkEkle6hnMtrts7XNkMJJMg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz", + "integrity": "sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2" + "@smithy/types": "^3.7.1" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.7.tgz", - "integrity": "sha512-IA4K2qTJYXkF5OfVN4vsY1hfnUZjaslEE8Fsr/gGFza4TAC2A9NfnZuSY2srQIbt9bwtjHiAayrRVgKse4Q7fA==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz", + "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -5976,16 +6735,17 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.3.tgz", - "integrity": "sha512-YD2KYSCEEeFHcWZ1E3mLdAaHl8T/TANh6XwmocQ6nPcTdBfh4N5fusgnblnWDlnlU1/cUqEq3PiGi22GmT2Lkg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.3.tgz", + "integrity": "sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.3", - "@smithy/types": "^3.4.2", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.6", + "@smithy/util-middleware": "^3.0.10", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -5995,16 +6755,18 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.3.2.tgz", - "integrity": "sha512-RKDfhF2MTwXl7jan5d7QfS9eCC6XJbO3H+EZAvLQN8A5in4ib2Ml4zoeLo57w9QrqFekBPcsoC2hW3Ekw4vQ9Q==", + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.5.tgz", + "integrity": "sha512-k0sybYT9zlP79sIKd1XGm4TmK0AS1nA2bzDHXx7m0nGi3RQ8dxxQUs4CPkSmQTKAo+KF9aINU3KzpGIpV7UoMw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-endpoint": "^3.1.3", - "@smithy/middleware-stack": "^3.0.6", - "@smithy/protocol-http": "^4.1.3", - "@smithy/types": "^3.4.2", - "@smithy/util-stream": "^3.1.6", + "@smithy/core": "^2.5.4", + "@smithy/middleware-endpoint": "^3.2.4", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "@smithy/util-stream": "^3.3.1", "tslib": "^2.6.2" }, "engines": { @@ -6012,10 +6774,11 @@ } }, "node_modules/@smithy/types": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.4.2.tgz", - "integrity": "sha512-tHiFcfcVedVBHpmHUEUHOCCih8iZbIAYn9NvPsNzaPm/237I3imdDdZoOC8c87H5HBAVEa06tTgb+OcSWV9g5w==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz", + "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -6024,13 +6787,14 @@ } }, "node_modules/@smithy/url-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.6.tgz", - "integrity": "sha512-47Op/NU8Opt49KyGpHtVdnmmJMsp2hEwBdyjuFB9M2V5QVOwA7pBhhxKN5z6ztKGrMw76gd8MlbPuzzvaAncuQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.10.tgz", + "integrity": "sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^3.0.6", - "@smithy/types": "^3.4.2", + "@smithy/querystring-parser": "^3.0.10", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" } }, @@ -6100,14 +6864,15 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.18.tgz", - "integrity": "sha512-/eveCzU6Z6Yw8dlYQLA4rcK30XY0E4L3lD3QFHm59mzDaWYelrXE1rlynuT3J6qxv+5yNy3a1JuzhG5hk5hcmw==", + "version": "3.0.28", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.28.tgz", + "integrity": "sha512-6bzwAbZpHRFVJsOztmov5PGDmJYsbNSoIEfHSJJyFLzfBGCCChiO3od9k7E/TLgrCsIifdAbB9nqbVbyE7wRUw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^3.1.6", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", + "@smithy/property-provider": "^3.1.10", + "@smithy/smithy-client": "^3.4.5", + "@smithy/types": "^3.7.1", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -6116,17 +6881,18 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.18.tgz", - "integrity": "sha512-9cfzRjArtOFPlTYRREJk00suUxVXTgbrzVncOyMRTUeMKnecG/YentLF3cORa+R6mUOMSrMSnT18jos1PKqK6Q==", + "version": "3.0.28", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.28.tgz", + "integrity": "sha512-78ENJDorV1CjOQselGmm3+z7Yqjj5HWCbjzh0Ixuq736dh1oEnD9sAttSBNSLlpZsX8VQnmERqA2fEFlmqWn8w==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^3.0.8", - "@smithy/credential-provider-imds": "^3.2.3", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/property-provider": "^3.1.6", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", + "@smithy/config-resolver": "^3.0.12", + "@smithy/credential-provider-imds": "^3.2.7", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.10", + "@smithy/smithy-client": "^3.4.5", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -6134,13 +6900,14 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.2.tgz", - "integrity": "sha512-FEISzffb4H8DLzGq1g4MuDpcv6CIG15fXoQzDH9SjpRJv6h7J++1STFWWinilG0tQh9H1v2UKWG19Jjr2B16zQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz", + "integrity": "sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^3.1.7", - "@smithy/types": "^3.4.2", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -6161,12 +6928,13 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.6.tgz", - "integrity": "sha512-BxbX4aBhI1O9p87/xM+zWy0GzT3CEVcXFPBRDoHAM+pV0eSW156pR+PSYEz0DQHDMYDsYAflC2bQNz2uaDBUZQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz", + "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -6174,13 +6942,14 @@ } }, "node_modules/@smithy/util-retry": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.6.tgz", - "integrity": "sha512-BRZiuF7IwDntAbevqMco67an0Sr9oLQJqqRCsSPZZHYRnehS0LHDAkJk/pSmI7Z8c/1Vet294H7fY2fWUgB+Rg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.10.tgz", + "integrity": "sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^3.0.6", - "@smithy/types": "^3.4.2", + "@smithy/service-error-classification": "^3.0.10", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -6188,14 +6957,15 @@ } }, "node_modules/@smithy/util-stream": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.6.tgz", - "integrity": "sha512-lQEUfTx1ht5CRdvIjdAN/gUL6vQt2wSARGGLaBHNe+iJSkRHlWzY+DOn0mFTmTgyU3jcI5n9DkT5gTzYuSOo6A==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.1.tgz", + "integrity": "sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^3.2.7", - "@smithy/node-http-handler": "^3.2.2", - "@smithy/types": "^3.4.2", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/types": "^3.7.1", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", @@ -6206,6 +6976,20 @@ "node": ">=16.0.0" } }, + "node_modules/@smithy/util-stream/node_modules/@smithy/fetch-http-handler": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz", + "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, "node_modules/@smithy/util-uri-escape": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", @@ -6234,14 +7018,14 @@ } }, "node_modules/@smithy/util-waiter": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.5.tgz", - "integrity": "sha512-jYOSvM3H6sZe3CHjzD2VQNCjWBJs+4DbtwBMvUp9y5EnnwNa7NQxTeYeQw0CKCAdGGZ3QvVkyJmvbvs5M/B10A==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.9.tgz", + "integrity": "sha512-/aMXPANhMOlMPjfPtSrDfPeVP8l56SJlz93xeiLmhLe5xvlXA5T3abZ2ilEsDEPeY9T/wnN/vNGn9wa1SbufWA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^3.1.4", - "@smithy/types": "^3.4.2", + "@smithy/abort-controller": "^3.1.8", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": {