feat(events/sqs): add a new AWS SQS event publisher

This change introduces a new plugin `@backstage/plugin-events-backend-module-aws-sqs`.

This plugin provides an event publisher which receives events from
(an) AWS SQS queue(s) and publishes them to the event broker.

The plugin supports the new backend-plugin-api and connects with the other plugins.

Signed-off-by: Patrick Jungermann <Patrick.Jungermann@gmail.com>
This commit is contained in:
Patrick Jungermann
2022-10-04 16:50:24 +02:00
parent 53bfad8576
commit d3ecb2382d
16 changed files with 2041 additions and 3 deletions
+12
View File
@@ -0,0 +1,12 @@
---
'@backstage/plugin-events-backend-module-aws-sqs': minor
---
Adds a new module `aws-sqs` for plugin-events-backend.
The module provides an event publisher `AwsSqsConsumingEventPublisher`
which will allow you to receive events from
an AWS SQS queue and will publish these to the used event broker.
Please find more information at
https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md.
+1
View File
@@ -37,6 +37,7 @@ yarn.lock @backstage/reviewers @backst
/plugins/cost-insights @backstage/reviewers @backstage/silver-lining
/plugins/cost-insights-* @backstage/reviewers @backstage/silver-lining
/plugins/events-backend @backstage/reviewers @pjungermann
/plugins/events-backend-module-aws-sqs @backstage/reviewers @pjungermann
/plugins/events-backend-test-utils @backstage/reviewers @pjungermann
/plugins/events-node @backstage/reviewers @pjungermann
/plugins/explore @backstage/reviewers @backstage/sda-se-reviewers
@@ -0,0 +1 @@
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
@@ -0,0 +1,42 @@
# events-backend-module-aws-sqs
Welcome to the `events-backend-module-aws-sqs` backend plugin!
This plugin is a module for the `events-backend` backend plugin
and extends it with an `AwsSqsConsumingEventPublisher`.
This event publisher will allow you to receive events from
an AWS SQS queue and will publish these to the used event broker.
## Configuration
The polled AWS SQS queues depend on your configuration:
```yaml
events:
modules:
awsSqs:
awsSqsConsumingEventPublisher:
topics:
topicName1: # replace with actual topic name as expected by subscribers
queue:
url: 'https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue'
region: us-east-2
# visibilityTimeout - as HumanDuration; defaults to queue-based config
# waitTime - as HumanDuration; defaults to max of 20 seconds (long polling)
# timeout - as HumanDuration; timeout for the task execution
# waitTimeAfterEmptyReceive - as HumanDuration; time to wait before a retry when there was no message.
topicName2:
# [...]
```
## Installation
1. Install the [`events-backend` plugin](../events-backend/README.md).
2. Install this module
3. Add your configuration.
```bash
# From your Backstage root directory
yarn add --cwd packages/backend @backstage/plugin-events-backend-module-aws-sqs
```
@@ -0,0 +1,29 @@
## API Report File for "@backstage/plugin-events-backend-module-aws-sqs"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { BackendFeature } from '@backstage/backend-plugin-api';
import { Config } from '@backstage/config';
import { EventBroker } from '@backstage/plugin-events-node';
import { EventPublisher } from '@backstage/plugin-events-node';
import { Logger } from 'winston';
import { PluginTaskScheduler } from '@backstage/backend-tasks';
// @public
export class AwsSqsConsumingEventPublisher implements EventPublisher {
// (undocumented)
static fromConfig(env: {
config: Config;
logger: Logger;
scheduler: PluginTaskScheduler;
}): AwsSqsConsumingEventPublisher[];
// (undocumented)
setEventBroker(eventBroker: EventBroker): Promise<void>;
}
// @alpha
export const awsSqsConsumingEventPublisherEventsModule: (
options?: undefined,
) => BackendFeature;
```
+78
View File
@@ -0,0 +1,78 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { HumanDuration } from '@backstage/types';
export interface Config {
events?: {
modules?: {
/**
* events-backend-module-aws-sqs plugin configuration.
*/
awsSqs?: {
/**
* Configuration for AwsSqsConsumingEventPublisher.
*/
awsSqsConsumingEventPublisher?: {
/**
* Contains a record per topic for which an AWS SQS queue
* should be used as source of events.
*/
topics: Record<
string,
{
/**
* (Required) Queue-related configuration.
*/
queue: {
/**
* (Required) The region of the AWS SQS queue.
*/
region: string;
/**
* (Required) The absolute URL for the AWS SQS queue to be used.
*/
url: string;
/**
* (Optional) Visibility timeout for messages in flight.
*/
visibilityTimeout: HumanDuration;
/**
* (Optional) Wait time when polling for available messages.
* Default: 20 seconds.
*/
waitTime: HumanDuration;
};
/**
* (Optional) Timeout for the task execution which includes polling for messages
* and publishing the events to the event broker
* and the wait time after empty receives.
*
* Must be greater than `queue.waitTime` + `waitTimeAfterEmptyReceive`.
*/
timeout: HumanDuration;
/**
* (Optional) Wait time before polling again if no message was received.
* Default: 1 minute.
*/
waitTimeAfterEmptyReceive: HumanDuration;
}
>;
};
};
};
};
}
@@ -0,0 +1,48 @@
{
"name": "@backstage/plugin-events-backend-module-aws-sqs",
"version": "0.0.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"publishConfig": {
"access": "public",
"alphaTypes": "dist/index.alpha.d.ts",
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts"
},
"backstage": {
"role": "backend-plugin-module"
},
"scripts": {
"start": "backstage-cli package start",
"build": "backstage-cli package build --experimental-type-build",
"lint": "backstage-cli package lint",
"test": "backstage-cli package test",
"clean": "backstage-cli package clean",
"prepack": "backstage-cli package prepack",
"postpack": "backstage-cli package postpack"
},
"dependencies": {
"@aws-sdk/client-sqs": "^3.0.0",
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/backend-tasks": "workspace:^",
"@backstage/config": "workspace:^",
"@backstage/plugin-events-node": "workspace:^",
"@backstage/types": "workspace:^",
"luxon": "^3.0.0",
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/backend-common": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-events-backend-test-utils": "workspace:^",
"aws-sdk-client-mock": "^2.0.0"
},
"files": [
"alpha",
"config.d.ts",
"dist"
],
"configSchema": "config.d.ts"
}
@@ -0,0 +1,27 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* The module "sqs" for the Backstage backend plugin "events"
* adding an AWS SQS-based publisher,
* receiving events from an AWS SQS queue and passing it to the
* internal event broker.
*
* @packageDocumentation
*/
export { AwsSqsConsumingEventPublisher } from './publisher/AwsSqsConsumingEventPublisher';
export { awsSqsConsumingEventPublisherEventsModule } from './service/AwsSqsConsumingEventPublisherEventsModule';
@@ -0,0 +1,227 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
DeleteMessageBatchCommand,
ReceiveMessageCommand,
SQSClient,
} from '@aws-sdk/client-sqs';
import { getVoidLogger } from '@backstage/backend-common';
import { PluginTaskScheduler } from '@backstage/backend-tasks';
import { ConfigReader } from '@backstage/config';
import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils';
import { mockClient } from 'aws-sdk-client-mock';
import { AwsSqsConsumingEventPublisher } from './AwsSqsConsumingEventPublisher';
describe('AwsSqsConsumingEventPublisher', () => {
it('creates one publisher instance per configured topic', async () => {
const config = new ConfigReader({
events: {
modules: {
awsSqs: {
awsSqsConsumingEventPublisher: {
topics: {
fake1: {
queue: {
region: 'eu-west-1',
url: 'https://fake1.queue.url',
},
},
fake2: {
queue: {
region: 'us-east-1',
url: 'https://fake2.queue.url',
},
},
},
},
},
},
},
});
const logger = getVoidLogger();
const scheduler = {
scheduleTask: jest.fn(),
} as unknown as PluginTaskScheduler;
const publishers = AwsSqsConsumingEventPublisher.fromConfig({
config,
logger,
scheduler,
});
expect(publishers.length).toEqual(2);
});
it('polling will be scheduled after connecting to the EventBroker', async () => {
const config = new ConfigReader({
events: {
modules: {
awsSqs: {
awsSqsConsumingEventPublisher: {
topics: {
fake1: {
queue: {
region: 'eu-west-1',
url: 'https://fake1.queue.url',
},
},
},
},
},
},
},
});
const logger = getVoidLogger();
const scheduler = {
scheduleTask: jest.fn(),
} as unknown as PluginTaskScheduler;
const publishers = AwsSqsConsumingEventPublisher.fromConfig({
config,
logger,
scheduler,
});
expect(publishers.length).toEqual(1);
const publisher = publishers[0];
const eventBroker = new TestEventBroker();
await publisher.setEventBroker(eventBroker);
// publisher.connect(..) was causing the polling for events to be scheduled
expect(scheduler.scheduleTask).toHaveBeenCalledWith(
expect.objectContaining({
id: 'events.awsSqs.publisher:fake1',
frequency: { seconds: 0 },
timeout: { seconds: 260 },
scope: 'local',
}),
);
});
it('publishes events for received messages and deletes them in bulk', async () => {
const config = new ConfigReader({
events: {
modules: {
awsSqs: {
awsSqsConsumingEventPublisher: {
topics: {
fake1: {
queue: {
region: 'eu-west-1',
url: 'https://fake1.queue.url',
},
waitTimeAfterEmptyReceive: { seconds: 1 },
},
},
},
},
},
},
});
const logger = getVoidLogger();
let taskFn: (() => Promise<void>) | undefined = undefined;
const scheduler = {
scheduleTask: (spec: { fn: () => Promise<void> }) => {
taskFn = spec.fn;
},
} as unknown as PluginTaskScheduler;
// on the first attempt, we will return 1 message and 0 messages afterwards
const sqsMock = mockClient(SQSClient);
sqsMock
.on(ReceiveMessageCommand, {
MaxNumberOfMessages: 10,
QueueUrl: 'https://fake1.queue.url',
WaitTimeSeconds: 20,
})
.resolvesOnce({
Messages: [],
})
.resolvesOnce({
Messages: [
{
Body: '{"event":"payload1"}',
ReceiptHandle: 'fake-handle1',
MessageAttributes: {
'X-Custom-Attr': {
DataType: 'String',
StringValue: 'value',
},
},
},
{
Body: '{"event":"payload2"}',
ReceiptHandle: 'fake-handle2',
},
],
})
.on(DeleteMessageBatchCommand, {
Entries: [
{
Id: 'message-0',
ReceiptHandle: 'fake-handle1',
},
{
Id: 'message-1',
ReceiptHandle: 'fake-handle2',
},
],
QueueUrl: 'https://fake1.queue.url',
})
.resolvesOnce({
Failed: [
{
Id: 'message-1',
Message: 'test failure',
SenderFault: true,
Code: '400',
},
],
Successful: [{ Id: 'message-0' }],
});
const publishers = AwsSqsConsumingEventPublisher.fromConfig({
config,
logger,
scheduler,
});
expect(publishers.length).toEqual(1);
const publisher = publishers[0];
const eventBroker = new TestEventBroker();
await publisher.setEventBroker(eventBroker);
await taskFn!();
await taskFn!();
await taskFn!();
expect(eventBroker.published.length).toEqual(2);
expect(eventBroker.published[0].topic).toEqual('fake1');
expect(eventBroker.published[0].eventPayload).toEqual({
event: 'payload1',
});
expect(eventBroker.published[0].metadata).toEqual({
'X-Custom-Attr': 'value',
});
expect(eventBroker.published[1].topic).toEqual('fake1');
expect(eventBroker.published[1].eventPayload).toEqual({
event: 'payload2',
});
expect(eventBroker.published[1].metadata).toEqual({});
});
});
@@ -0,0 +1,191 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
DeleteMessageBatchCommand,
Message,
ReceiveMessageCommand,
ReceiveMessageCommandInput,
SQSClient,
} from '@aws-sdk/client-sqs';
import { PluginTaskScheduler } from '@backstage/backend-tasks';
import { Config } from '@backstage/config';
import { EventBroker, EventPublisher } from '@backstage/plugin-events-node';
import { Logger } from 'winston';
import { AwsSqsEventSourceConfig, readConfig } from './config';
/**
* Publishes events received from an AWS SQS queue.
* The message payload will be used as event payload and passed to registered subscribers.
*
* @public
*/
// TODO(pjungermann): add prom metrics? (see plugins/catalog-backend/src/util/metrics.ts, etc.)
export class AwsSqsConsumingEventPublisher implements EventPublisher {
private readonly topic: string;
private readonly receiveParams: ReceiveMessageCommandInput;
private readonly sqs: SQSClient;
private readonly queueUrl: string;
private readonly taskTimeoutSeconds: number;
private readonly waitTimeAfterEmptyReceiveMs;
private eventBroker?: EventBroker;
static fromConfig(env: {
config: Config;
logger: Logger;
scheduler: PluginTaskScheduler;
}): AwsSqsConsumingEventPublisher[] {
return readConfig(env.config).map(
config =>
new AwsSqsConsumingEventPublisher(env.logger, env.scheduler, config),
);
}
private constructor(
private readonly logger: Logger,
private readonly scheduler: PluginTaskScheduler,
config: AwsSqsEventSourceConfig,
) {
this.topic = config.topic;
this.receiveParams = {
MaxNumberOfMessages: 10,
MessageAttributeNames: ['All'],
QueueUrl: config.queueUrl,
VisibilityTimeout: config.visibilityTimeout?.as('seconds'),
WaitTimeSeconds: config.pollingWaitTime.as('seconds'),
};
this.sqs = new SQSClient({ region: config.region });
this.queueUrl = config.queueUrl;
this.taskTimeoutSeconds = config.timeout.as('seconds');
this.waitTimeAfterEmptyReceiveMs =
config.waitTimeAfterEmptyReceive.as('milliseconds');
}
async setEventBroker(eventBroker: EventBroker): Promise<void> {
this.eventBroker = eventBroker;
return this.start();
}
private async start(): Promise<void> {
const id = `events.awsSqs.publisher:${this.topic}`;
const logger = this.logger.child({
class: AwsSqsConsumingEventPublisher.prototype.constructor.name,
taskId: id,
});
await this.scheduler.scheduleTask({
id: id,
frequency: { seconds: 0 },
timeout: { seconds: this.taskTimeoutSeconds },
scope: 'local',
fn: async () => {
try {
const numMessages = await this.consumeMessages();
if (numMessages === 0) {
await this.sleep(this.waitTimeAfterEmptyReceiveMs);
}
} catch (error) {
logger.error(error);
}
},
});
}
private async deleteMessages(messages?: Message[]): Promise<void> {
if (!messages) {
return;
}
const deleteParams = {
QueueUrl: this.queueUrl,
Entries: messages.map((message, index) => {
return {
Id: message.MessageId ?? `message-${index}`,
ReceiptHandle: message.ReceiptHandle,
};
}),
};
try {
const result = await this.sqs.send(
new DeleteMessageBatchCommand(deleteParams),
);
if (result.Failed) {
this.logger.error(
`Failed to delete ${result.Failed!.length} of ${
messages.length
} messages from AWS SQS ${this.queueUrl}. First: ${
result.Failed[0].Message
}`,
);
}
} catch (error) {
this.logger.error(
`Failed to delete message from AWS SQS ${this.queueUrl}`,
error,
);
}
}
private async consumeMessages(): Promise<number> {
try {
const data = await this.sqs.send(
new ReceiveMessageCommand(this.receiveParams),
);
data.Messages?.forEach(message => {
const eventPayload = JSON.parse(message.Body!);
const metadata: Record<string, string | string[]> = {};
Object.keys(message.MessageAttributes ?? {}).forEach(key => {
const attrValue = message.MessageAttributes![key];
if (
!attrValue ||
!attrValue.DataType ||
!['String', 'Number'].includes(attrValue.DataType)
) {
return;
}
const value = attrValue.StringListValues ?? attrValue.StringValue;
if (value !== undefined) {
metadata[key] = value;
}
});
this.eventBroker!.publish({
topic: this.topic,
eventPayload,
metadata,
});
});
await this.deleteMessages(data.Messages);
return data.Messages?.length ?? 0;
} catch (error) {
this.logger.error(
`Failed to receive events from AWS SQS ${this.queueUrl}`,
error,
);
return 0;
}
}
private sleep(ms: number): Promise<void> {
return new Promise<void>(resolve => setTimeout(resolve, ms));
}
}
@@ -0,0 +1,222 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ConfigReader } from '@backstage/config';
import { readConfig } from './config';
describe('readConfig', () => {
it('not configured', () => {
const config = new ConfigReader({});
const publisherConfigs = readConfig(config);
expect(publisherConfigs.length).toBe(0);
});
it('only required fields configured', () => {
const config = new ConfigReader({
events: {
modules: {
awsSqs: {
awsSqsConsumingEventPublisher: {
topics: {
fake1: {
queue: {
region: 'eu-west-1',
url: 'https://fake1.queue.url',
},
},
fake2: {
queue: {
region: 'us-east-1',
url: 'https://fake2.queue.url',
},
},
},
},
},
},
},
});
const publisherConfigs = readConfig(config);
expect(publisherConfigs.length).toBe(2);
expect(publisherConfigs[0].topic).toEqual('fake1');
expect(publisherConfigs[0].region).toEqual('eu-west-1');
expect(publisherConfigs[0].queueUrl).toEqual('https://fake1.queue.url');
expect(publisherConfigs[0].pollingWaitTime.as('seconds')).toBe(20);
expect(publisherConfigs[0].timeout.as('seconds')).toBe(260);
expect(publisherConfigs[0].waitTimeAfterEmptyReceive.as('seconds')).toBe(
60,
);
});
it('all fields configured', () => {
const config = new ConfigReader({
events: {
modules: {
awsSqs: {
awsSqsConsumingEventPublisher: {
topics: {
fake1: {
queue: {
region: 'eu-west-1',
url: 'https://fake1.queue.url',
visibilityTimeout: { minutes: 5 },
waitTime: { seconds: 10 },
},
timeout: { minutes: 5 },
waitTimeAfterEmptyReceive: { seconds: 30 },
},
},
},
},
},
},
});
const publisherConfigs = readConfig(config);
expect(publisherConfigs.length).toBe(1);
expect(publisherConfigs[0].topic).toEqual('fake1');
expect(publisherConfigs[0].region).toEqual('eu-west-1');
expect(publisherConfigs[0].queueUrl).toEqual('https://fake1.queue.url');
expect(publisherConfigs[0].pollingWaitTime.as('seconds')).toBe(10);
expect(publisherConfigs[0].timeout.as('seconds')).toBe(300);
expect(publisherConfigs[0].waitTimeAfterEmptyReceive.as('seconds')).toBe(
30,
);
});
it('fail on negative queue.waitTime', () => {
const config = new ConfigReader({
events: {
modules: {
awsSqs: {
awsSqsConsumingEventPublisher: {
topics: {
fake1: {
queue: {
region: 'eu-west-1',
url: 'https://fake1.queue.url',
visibilityTimeout: { minutes: 5 },
waitTime: { seconds: -10 },
},
timeout: { minutes: 5 },
waitTimeAfterEmptyReceive: { seconds: 30 },
},
},
},
},
},
},
});
expect(() => readConfig(config)).toThrow(
'events.modules.awsSqs.awsSqsConsumingEventPublisher.topics.fake1.queue.waitTime must be within 0..20 seconds',
);
});
it('fail on too high queue.waitTime', () => {
const config = new ConfigReader({
events: {
modules: {
awsSqs: {
awsSqsConsumingEventPublisher: {
topics: {
fake1: {
queue: {
region: 'eu-west-1',
url: 'https://fake1.queue.url',
visibilityTimeout: { minutes: 5 },
waitTime: { seconds: 30 },
},
timeout: { minutes: 5 },
waitTimeAfterEmptyReceive: { seconds: 30 },
},
},
},
},
},
},
});
expect(() => readConfig(config)).toThrow(
'events.modules.awsSqs.awsSqsConsumingEventPublisher.topics.fake1.queue.waitTime must be within 0..20 seconds',
);
});
it('fail on too low timeout', () => {
const config = new ConfigReader({
events: {
modules: {
awsSqs: {
awsSqsConsumingEventPublisher: {
topics: {
fake1: {
queue: {
region: 'eu-west-1',
url: 'https://fake1.queue.url',
visibilityTimeout: { minutes: 5 },
waitTime: { seconds: 10 },
},
timeout: { seconds: 10 },
waitTimeAfterEmptyReceive: { seconds: 30 },
},
},
},
},
},
},
});
expect(() => readConfig(config)).toThrow(
'The events.modules.awsSqs.awsSqsConsumingEventPublisher.topics.fake1.timeout must be greater than events.modules.awsSqs.awsSqsConsumingEventPublisher.topics.fake1.queue.waitTime',
);
});
it('fail on negative waitTimeAfterEmptyReceive', () => {
const config = new ConfigReader({
events: {
modules: {
awsSqs: {
awsSqsConsumingEventPublisher: {
topics: {
fake1: {
queue: {
region: 'eu-west-1',
url: 'https://fake1.queue.url',
visibilityTimeout: { minutes: 5 },
waitTime: { seconds: 10 },
},
timeout: { minutes: 5 },
waitTimeAfterEmptyReceive: { seconds: -30 },
},
},
},
},
},
},
});
expect(() => readConfig(config)).toThrow(
'The events.modules.awsSqs.awsSqsConsumingEventPublisher.topics.fake1.waitTimeAfterEmptyReceive must not be negative',
);
});
});
@@ -0,0 +1,117 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Config } from '@backstage/config';
import { HumanDuration, JsonObject } from '@backstage/types';
import { Duration } from 'luxon';
const CONFIG_PREFIX_MODULE = 'events.modules.awsSqs.';
const CONFIG_PREFIX_PUBLISHER = `${CONFIG_PREFIX_MODULE}awsSqsConsumingEventPublisher.`;
const DEFAULT_WAIT_TIME_AFTER_EMPTY_RECEIVE = { minutes: 1 };
const MAX_WAIT_SECONDS = 20;
export interface AwsSqsEventSourceConfig {
pollingWaitTime: Duration;
queueUrl: string;
region: string;
timeout: Duration;
topic: string;
visibilityTimeout?: Duration;
waitTimeAfterEmptyReceive: Duration;
}
// TODO(pjungermann): validation could be improved similar to `convertToHumanDuration` at @backstage/backend-tasks
function readOptionalHumanDuration(
config: Config,
key: string,
): HumanDuration | undefined {
return config.getOptional<JsonObject>(key) as HumanDuration;
}
function readOptionalDuration(
config: Config,
key: string,
): Duration | undefined {
const duration = readOptionalHumanDuration(config, key);
return duration ? Duration.fromObject(duration) : undefined;
}
export function readConfig(config: Config): AwsSqsEventSourceConfig[] {
const key = `${CONFIG_PREFIX_PUBLISHER}topics`;
const topics = config.getOptionalConfig(key);
return (
topics?.keys()?.map(topic => {
const topicConfig = topics.getConfig(topic);
const keyPrefix = `${key}.${topic}.`;
// queue config:
const pollingWaitTime = Duration.fromObject(
readOptionalHumanDuration(topicConfig, 'queue.waitTime') ?? {
seconds: MAX_WAIT_SECONDS,
},
);
if (
pollingWaitTime.valueOf() < 0 ||
pollingWaitTime.as('seconds') > MAX_WAIT_SECONDS
) {
throw new Error(
`${keyPrefix}queue.waitTime must be within 0..${MAX_WAIT_SECONDS} seconds.`,
);
}
const queueUrl = topicConfig.getString('queue.url');
const region = topicConfig.getString('queue.region');
const visibilityTimeout = readOptionalDuration(
topicConfig,
'queue.visibilityTimeout',
);
// task:
const waitTimeAfterEmptyReceive = Duration.fromObject(
readOptionalHumanDuration(topicConfig, 'waitTimeAfterEmptyReceive') ??
DEFAULT_WAIT_TIME_AFTER_EMPTY_RECEIVE,
);
if (waitTimeAfterEmptyReceive.valueOf() < 0) {
throw new Error(
`The ${keyPrefix}waitTimeAfterEmptyReceive must not be negative.`,
);
}
const timeout =
readOptionalDuration(topicConfig, 'timeout') ??
pollingWaitTime
.plus(waitTimeAfterEmptyReceive)
.plus(Duration.fromObject({ seconds: 180 }));
if (
timeout.valueOf() <=
pollingWaitTime.valueOf() + waitTimeAfterEmptyReceive.valueOf()
) {
throw new Error(
`The ${keyPrefix}timeout must be greater than ${keyPrefix}queue.waitTime + ${keyPrefix}waitTimeAfterEmptyReceive.`,
);
}
return {
pollingWaitTime,
queueUrl,
region,
timeout,
topic,
visibilityTimeout,
waitTimeAfterEmptyReceive,
};
}) ?? []
);
}
@@ -0,0 +1,94 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import {
configServiceRef,
loggerServiceRef,
schedulerServiceRef,
} from '@backstage/backend-plugin-api';
import { startTestBackend } from '@backstage/backend-test-utils';
import { ConfigReader } from '@backstage/config';
import { eventsExtensionPoint } from '@backstage/plugin-events-node';
import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils';
import { awsSqsConsumingEventPublisherEventsModule } from './AwsSqsConsumingEventPublisherEventsModule';
import { AwsSqsConsumingEventPublisher } from '../publisher/AwsSqsConsumingEventPublisher';
describe('awsSqsEventsModule', () => {
it('should be correctly wired and set up', async () => {
const config = new ConfigReader({
events: {
modules: {
awsSqs: {
awsSqsConsumingEventPublisher: {
topics: {
fake1: {
queue: {
region: 'eu-west-1',
url: 'https://fake1.queue.url',
},
},
fake2: {
queue: {
region: 'us-east-1',
url: 'https://fake2.queue.url',
},
},
},
},
},
},
},
});
let addedPublishers: AwsSqsConsumingEventPublisher[] | undefined;
const extensionPoint = {
addPublishers: (publishers: any) => {
addedPublishers = publishers;
},
};
const scheduler = {
scheduleTask: jest.fn(),
};
await startTestBackend({
extensionPoints: [[eventsExtensionPoint, extensionPoint]],
services: [
[configServiceRef, config],
[loggerServiceRef, getVoidLogger()],
[schedulerServiceRef, scheduler],
],
features: [awsSqsConsumingEventPublisherEventsModule()],
});
expect(addedPublishers).not.toBeUndefined();
expect(addedPublishers!.length).toEqual(2);
const eventBroker = new TestEventBroker();
await Promise.all(
addedPublishers!.map(publisher => publisher.setEventBroker(eventBroker)),
);
// publisher.connect(..) was causing the polling for events to be scheduled
expect(scheduler.scheduleTask).toHaveBeenCalledWith(
expect.objectContaining({ id: 'events.awsSqs.publisher:fake1' }),
);
expect(scheduler.scheduleTask).toHaveBeenCalledWith(
expect.objectContaining({ id: 'events.awsSqs.publisher:fake2' }),
);
});
});
@@ -0,0 +1,55 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
configServiceRef,
createBackendModule,
loggerServiceRef,
loggerToWinstonLogger,
schedulerServiceRef,
} from '@backstage/backend-plugin-api';
import { eventsExtensionPoint } from '@backstage/plugin-events-node';
import { AwsSqsConsumingEventPublisher } from '../publisher/AwsSqsConsumingEventPublisher';
/**
* AWS SQS module for the Events plugin.
*
* @alpha
*/
export const awsSqsConsumingEventPublisherEventsModule = createBackendModule({
pluginId: 'events',
moduleId: 'awsSqsConsumingEventPublisherEventsModule',
register(env) {
env.registerInit({
deps: {
config: configServiceRef,
events: eventsExtensionPoint,
logger: loggerServiceRef,
scheduler: schedulerServiceRef,
},
async init({ config, events, logger, scheduler }) {
const winstonLogger = loggerToWinstonLogger(logger);
const sqs = AwsSqsConsumingEventPublisher.fromConfig({
config: config,
logger: winstonLogger,
scheduler: scheduler,
});
events.addPublishers(sqs);
},
});
},
});
@@ -0,0 +1,17 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {};
+880 -3
View File
@@ -330,6 +330,790 @@ __metadata:
languageName: node
linkType: hard
"@aws-crypto/ie11-detection@npm:^2.0.0":
version: 2.0.2
resolution: "@aws-crypto/ie11-detection@npm:2.0.2"
dependencies:
tslib: ^1.11.1
checksum: 713293deea8eefd3ab43dc05e62228571d27754e7293f8ec2fd8a0c693fbbfc55213e6599387776e3cdbc951965dc62e24e92b9c4a853e4a50d00ae6a9f6b2bd
languageName: node
linkType: hard
"@aws-crypto/sha256-browser@npm:2.0.0":
version: 2.0.0
resolution: "@aws-crypto/sha256-browser@npm:2.0.0"
dependencies:
"@aws-crypto/ie11-detection": ^2.0.0
"@aws-crypto/sha256-js": ^2.0.0
"@aws-crypto/supports-web-crypto": ^2.0.0
"@aws-crypto/util": ^2.0.0
"@aws-sdk/types": ^3.1.0
"@aws-sdk/util-locate-window": ^3.0.0
"@aws-sdk/util-utf8-browser": ^3.0.0
tslib: ^1.11.1
checksum: 7bc1ff042d0c53a46c0fc3824bd97fb3ed1df7dc030b8a995889471052860b8c8ade469c97866fafd8249a3144d0f48b0f1054f357e2b403606009381c4b8f0e
languageName: node
linkType: hard
"@aws-crypto/sha256-js@npm:2.0.0":
version: 2.0.0
resolution: "@aws-crypto/sha256-js@npm:2.0.0"
dependencies:
"@aws-crypto/util": ^2.0.0
"@aws-sdk/types": ^3.1.0
tslib: ^1.11.1
checksum: e4abf9baec6bed19d380f92a999a41ac5bdd8890dfd45971d29054c298854c5b7087e7de633413f2e64618ef8238ccf4c0b75797c73063c74bbba3cb5d8b2581
languageName: node
linkType: hard
"@aws-crypto/sha256-js@npm:^2.0.0":
version: 2.0.2
resolution: "@aws-crypto/sha256-js@npm:2.0.2"
dependencies:
"@aws-crypto/util": ^2.0.2
"@aws-sdk/types": ^3.110.0
tslib: ^1.11.1
checksum: 9125ec65a2b05fce908ac2289ba97b995a299f2d717684804211df8e8bcffd8cd9b8861582240655b88f2255c46fcee34026f75c057ffb22f44b6a76cd43f65a
languageName: node
linkType: hard
"@aws-crypto/supports-web-crypto@npm:^2.0.0":
version: 2.0.2
resolution: "@aws-crypto/supports-web-crypto@npm:2.0.2"
dependencies:
tslib: ^1.11.1
checksum: 03d04d29292dc1b76db9bc6becd05f52fa79adee0ec084f971b0767f7e73250dd0422bea57636015f8c27f38aefcd1d9c58800a4749cf35339296c8d670f3ccb
languageName: node
linkType: hard
"@aws-crypto/util@npm:^2.0.0, @aws-crypto/util@npm:^2.0.2":
version: 2.0.2
resolution: "@aws-crypto/util@npm:2.0.2"
dependencies:
"@aws-sdk/types": ^3.110.0
"@aws-sdk/util-utf8-browser": ^3.0.0
tslib: ^1.11.1
checksum: 13cb33a39005b09c062398d361043c2224bc8ba42b1432bad52e15bc4bf9ffad4facdddc394b3cc71b3fb8d86a7ec325fd1afa107b5fde0dab84a7e32d311d7f
languageName: node
linkType: hard
"@aws-sdk/abort-controller@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/abort-controller@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 28f5bc16b5aba414e354df603bc8becd010aa8c9b3c79e527130723a39f21d5a3df98c3bafb3cea733d415a5b042af90098ffa9dfa29d400114c2f6f5292524e
languageName: node
linkType: hard
"@aws-sdk/client-sqs@npm:^3.0.0":
version: 3.183.0
resolution: "@aws-sdk/client-sqs@npm:3.183.0"
dependencies:
"@aws-crypto/sha256-browser": 2.0.0
"@aws-crypto/sha256-js": 2.0.0
"@aws-sdk/client-sts": 3.183.0
"@aws-sdk/config-resolver": 3.183.0
"@aws-sdk/credential-provider-node": 3.183.0
"@aws-sdk/fetch-http-handler": 3.183.0
"@aws-sdk/hash-node": 3.183.0
"@aws-sdk/invalid-dependency": 3.183.0
"@aws-sdk/md5-js": 3.183.0
"@aws-sdk/middleware-content-length": 3.183.0
"@aws-sdk/middleware-host-header": 3.183.0
"@aws-sdk/middleware-logger": 3.183.0
"@aws-sdk/middleware-recursion-detection": 3.183.0
"@aws-sdk/middleware-retry": 3.183.0
"@aws-sdk/middleware-sdk-sqs": 3.183.0
"@aws-sdk/middleware-serde": 3.183.0
"@aws-sdk/middleware-signing": 3.183.0
"@aws-sdk/middleware-stack": 3.183.0
"@aws-sdk/middleware-user-agent": 3.183.0
"@aws-sdk/node-config-provider": 3.183.0
"@aws-sdk/node-http-handler": 3.183.0
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/smithy-client": 3.183.0
"@aws-sdk/types": 3.183.0
"@aws-sdk/url-parser": 3.183.0
"@aws-sdk/util-base64-browser": 3.183.0
"@aws-sdk/util-base64-node": 3.183.0
"@aws-sdk/util-body-length-browser": 3.183.0
"@aws-sdk/util-body-length-node": 3.183.0
"@aws-sdk/util-defaults-mode-browser": 3.183.0
"@aws-sdk/util-defaults-mode-node": 3.183.0
"@aws-sdk/util-user-agent-browser": 3.183.0
"@aws-sdk/util-user-agent-node": 3.183.0
"@aws-sdk/util-utf8-browser": 3.183.0
"@aws-sdk/util-utf8-node": 3.183.0
entities: 2.2.0
fast-xml-parser: 3.19.0
tslib: ^2.3.1
checksum: fe0a7ba53cac4d52c25a4a4f1a1bb16438d5011347fcfec037df1d73379d750cd47b437f7a45aea2d4e29bc92587b51dd7631a06f5d6881e3b67b2d4c0dd2633
languageName: node
linkType: hard
"@aws-sdk/client-sso@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/client-sso@npm:3.183.0"
dependencies:
"@aws-crypto/sha256-browser": 2.0.0
"@aws-crypto/sha256-js": 2.0.0
"@aws-sdk/config-resolver": 3.183.0
"@aws-sdk/fetch-http-handler": 3.183.0
"@aws-sdk/hash-node": 3.183.0
"@aws-sdk/invalid-dependency": 3.183.0
"@aws-sdk/middleware-content-length": 3.183.0
"@aws-sdk/middleware-host-header": 3.183.0
"@aws-sdk/middleware-logger": 3.183.0
"@aws-sdk/middleware-recursion-detection": 3.183.0
"@aws-sdk/middleware-retry": 3.183.0
"@aws-sdk/middleware-serde": 3.183.0
"@aws-sdk/middleware-stack": 3.183.0
"@aws-sdk/middleware-user-agent": 3.183.0
"@aws-sdk/node-config-provider": 3.183.0
"@aws-sdk/node-http-handler": 3.183.0
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/smithy-client": 3.183.0
"@aws-sdk/types": 3.183.0
"@aws-sdk/url-parser": 3.183.0
"@aws-sdk/util-base64-browser": 3.183.0
"@aws-sdk/util-base64-node": 3.183.0
"@aws-sdk/util-body-length-browser": 3.183.0
"@aws-sdk/util-body-length-node": 3.183.0
"@aws-sdk/util-defaults-mode-browser": 3.183.0
"@aws-sdk/util-defaults-mode-node": 3.183.0
"@aws-sdk/util-user-agent-browser": 3.183.0
"@aws-sdk/util-user-agent-node": 3.183.0
"@aws-sdk/util-utf8-browser": 3.183.0
"@aws-sdk/util-utf8-node": 3.183.0
tslib: ^2.3.1
checksum: 6909329cf87c1a0c830fa9657e04c7e1ae496d7d79cc0a6813999503ae809f245f0b879af1d5564a5d97c2c69583c8a4df702d29ec7dc75934d98a0cdf017ad3
languageName: node
linkType: hard
"@aws-sdk/client-sts@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/client-sts@npm:3.183.0"
dependencies:
"@aws-crypto/sha256-browser": 2.0.0
"@aws-crypto/sha256-js": 2.0.0
"@aws-sdk/config-resolver": 3.183.0
"@aws-sdk/credential-provider-node": 3.183.0
"@aws-sdk/fetch-http-handler": 3.183.0
"@aws-sdk/hash-node": 3.183.0
"@aws-sdk/invalid-dependency": 3.183.0
"@aws-sdk/middleware-content-length": 3.183.0
"@aws-sdk/middleware-host-header": 3.183.0
"@aws-sdk/middleware-logger": 3.183.0
"@aws-sdk/middleware-recursion-detection": 3.183.0
"@aws-sdk/middleware-retry": 3.183.0
"@aws-sdk/middleware-sdk-sts": 3.183.0
"@aws-sdk/middleware-serde": 3.183.0
"@aws-sdk/middleware-signing": 3.183.0
"@aws-sdk/middleware-stack": 3.183.0
"@aws-sdk/middleware-user-agent": 3.183.0
"@aws-sdk/node-config-provider": 3.183.0
"@aws-sdk/node-http-handler": 3.183.0
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/smithy-client": 3.183.0
"@aws-sdk/types": 3.183.0
"@aws-sdk/url-parser": 3.183.0
"@aws-sdk/util-base64-browser": 3.183.0
"@aws-sdk/util-base64-node": 3.183.0
"@aws-sdk/util-body-length-browser": 3.183.0
"@aws-sdk/util-body-length-node": 3.183.0
"@aws-sdk/util-defaults-mode-browser": 3.183.0
"@aws-sdk/util-defaults-mode-node": 3.183.0
"@aws-sdk/util-user-agent-browser": 3.183.0
"@aws-sdk/util-user-agent-node": 3.183.0
"@aws-sdk/util-utf8-browser": 3.183.0
"@aws-sdk/util-utf8-node": 3.183.0
entities: 2.2.0
fast-xml-parser: 3.19.0
tslib: ^2.3.1
checksum: d4492e537803d64e5fc0c5db8ac3a3788204aadc14b21e4fb407188feb58b35689c4a6878b4f13123a5f35f7e9fa01d95d427be168aeec9072aea881f2a92fb7
languageName: node
linkType: hard
"@aws-sdk/config-resolver@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/config-resolver@npm:3.183.0"
dependencies:
"@aws-sdk/signature-v4": 3.183.0
"@aws-sdk/types": 3.183.0
"@aws-sdk/util-config-provider": 3.183.0
"@aws-sdk/util-middleware": 3.183.0
tslib: ^2.3.1
checksum: 1be0ab79d5019f7502a7aee8c740f4e381ab7501ed639569526a4a7e1c70ad6bb36d642a8a2b18afe58c34497c6f2f8244dbf05211a0f6bc9a57e5e379c70b2b
languageName: node
linkType: hard
"@aws-sdk/credential-provider-env@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/credential-provider-env@npm:3.183.0"
dependencies:
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 4281e14c286cc5c57c69ba88c49fe1c1ff61f27923db5e8f852a84cce02b40fdc938f876ad08e72005deae9a28fab7400f747f63ca50f9c4d60e04e6c2705205
languageName: node
linkType: hard
"@aws-sdk/credential-provider-imds@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/credential-provider-imds@npm:3.183.0"
dependencies:
"@aws-sdk/node-config-provider": 3.183.0
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/types": 3.183.0
"@aws-sdk/url-parser": 3.183.0
tslib: ^2.3.1
checksum: e9fe1007b22825dc0c033beb2057b9f759d8cafec6e65d08ba4915bccb9b7d737eeccb3d06e9768a084b6726d9ea10778172b1bec695353c60276c1a5c21370e
languageName: node
linkType: hard
"@aws-sdk/credential-provider-ini@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/credential-provider-ini@npm:3.183.0"
dependencies:
"@aws-sdk/credential-provider-env": 3.183.0
"@aws-sdk/credential-provider-imds": 3.183.0
"@aws-sdk/credential-provider-sso": 3.183.0
"@aws-sdk/credential-provider-web-identity": 3.183.0
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/shared-ini-file-loader": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: c7784a3674c863dacc1305a08dd63cb16d1e7374250b0ceafa9feee8344de4228d7c32e84fbaa9d963adab69eb3938cd75b99554756da120cd9beae4693eded9
languageName: node
linkType: hard
"@aws-sdk/credential-provider-node@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/credential-provider-node@npm:3.183.0"
dependencies:
"@aws-sdk/credential-provider-env": 3.183.0
"@aws-sdk/credential-provider-imds": 3.183.0
"@aws-sdk/credential-provider-ini": 3.183.0
"@aws-sdk/credential-provider-process": 3.183.0
"@aws-sdk/credential-provider-sso": 3.183.0
"@aws-sdk/credential-provider-web-identity": 3.183.0
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/shared-ini-file-loader": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: f23e1148054a96d68632284501ba01c4285cce1a2f4562817ec4b7fa315ff56e2f6b97fae0d2ae26fd52fca8c9f000be5d72a3582cff6c32ba10010f02a30977
languageName: node
linkType: hard
"@aws-sdk/credential-provider-process@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/credential-provider-process@npm:3.183.0"
dependencies:
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/shared-ini-file-loader": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 3109e79ec2b4647f5e7f78c6dc2e10cd8a34a70147e7e90549153b7ff3ff12eda3499b3189d6fc1f3b99f461d5445e8017b44cd50029d30b0fc7437ad88a5f38
languageName: node
linkType: hard
"@aws-sdk/credential-provider-sso@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/credential-provider-sso@npm:3.183.0"
dependencies:
"@aws-sdk/client-sso": 3.183.0
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/shared-ini-file-loader": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 8775894ef50499361a4b49d846417c2c1e1ea90383730a32428154628358e7847f6f29dddd3cd04d3a4e15c1343fe10b051a92863055989ac3c4cb241e68f63a
languageName: node
linkType: hard
"@aws-sdk/credential-provider-web-identity@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/credential-provider-web-identity@npm:3.183.0"
dependencies:
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: c39576c8f35137284fc69db8d94adcf07fa89d51153ee9710481262e205d485ff089a796e8a253aa14a0434dde91eadb65602fc614167a4f14301201ee840c08
languageName: node
linkType: hard
"@aws-sdk/fetch-http-handler@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/fetch-http-handler@npm:3.183.0"
dependencies:
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/querystring-builder": 3.183.0
"@aws-sdk/types": 3.183.0
"@aws-sdk/util-base64-browser": 3.183.0
tslib: ^2.3.1
checksum: 87c51d1dad8c469e32b99f6ed3729e753097cd4a9f8f417ec8681cf01e18b9a5dc6571f3cd1220293216bd4527b8499bb2ea1f821a240fde6d9560817c120066
languageName: node
linkType: hard
"@aws-sdk/hash-node@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/hash-node@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
"@aws-sdk/util-buffer-from": 3.183.0
tslib: ^2.3.1
checksum: fbed8757df633620807594535e3bb7d387576e0c2f89ad16dc7c98405a9d1d9743bea50148186de2f19cac67144b30f7f89e6c15317ddd7b8c0c8f61ca9556ef
languageName: node
linkType: hard
"@aws-sdk/invalid-dependency@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/invalid-dependency@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: d928ca26d4390ad4f5e2c8198d16e14b675face6ad8c4a4eef699b54ce3f6cba584456659287b0e57e9f9019bc456b51dfa474671e11bf555fe04ed16174c10c
languageName: node
linkType: hard
"@aws-sdk/is-array-buffer@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/is-array-buffer@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: 717e508989821434a2ace4f690fc599f67b3f28ee9de5f06fce65a296fe11a68a5b97f30d66bfbf490d4a83259e4ffa1f0321231e4a54ce2440a9c6fdbacde24
languageName: node
linkType: hard
"@aws-sdk/md5-js@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/md5-js@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
"@aws-sdk/util-utf8-browser": 3.183.0
"@aws-sdk/util-utf8-node": 3.183.0
tslib: ^2.3.1
checksum: 5bd92465940ace6b3ca13342bd60eab42ffd5d74dfa65655c28e10bbf4aa0c32b2f9b4deb2050f3d092b8586e558bf248559af9c3cffb37810961169ad0797af
languageName: node
linkType: hard
"@aws-sdk/middleware-content-length@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-content-length@npm:3.183.0"
dependencies:
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: bf3ec6872a925dbafd91e57334b6264e8446ca59eba598ee4bc7b37113c466300ac6b77ab314c4aa2859221f1f4e98beabbd365346e0815d591f276e642d1849
languageName: node
linkType: hard
"@aws-sdk/middleware-host-header@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-host-header@npm:3.183.0"
dependencies:
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: b4c4886976cffec614ff368daa995a69c765e737c8d366daa0033d781cf8e7483565bb3627ecd752698edc23dcf578de6657c9e8cb41c0fcd92631d17b7749b8
languageName: node
linkType: hard
"@aws-sdk/middleware-logger@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-logger@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 10ffb6af0f81b0144fef91af2bbeaeb680df2beff838f2a6ebcc260971fd6252a166e3bf3501c1fc00f6f8f203117ff6e2b4baebb7a6d8cd8504b7e1f392bd6d
languageName: node
linkType: hard
"@aws-sdk/middleware-recursion-detection@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-recursion-detection@npm:3.183.0"
dependencies:
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 461117e0dc8c38750942035a07163817bc8e89f377211f5fb52d4314acae4e7e6cb49be04193c508112833535b33814c1609196cb65e38cff1122043398ad89e
languageName: node
linkType: hard
"@aws-sdk/middleware-retry@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-retry@npm:3.183.0"
dependencies:
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/service-error-classification": 3.183.0
"@aws-sdk/types": 3.183.0
"@aws-sdk/util-middleware": 3.183.0
tslib: ^2.3.1
uuid: ^8.3.2
checksum: 76fa3f9fe5f1c67bbfa792611289edf0afa2d0271073039931ac9ea46b3f432d74692d2db55443f40b7e97014898454f6d4bd8d2f2f5714a4281428b7464efac
languageName: node
linkType: hard
"@aws-sdk/middleware-sdk-sqs@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
"@aws-sdk/util-hex-encoding": 3.183.0
tslib: ^2.3.1
checksum: 0bb914b2e7a5391f5b22a5262a5c299fa7e3eb22076d00c4cfffb449e97404b4830a77bb742e8f3110d66f15ae9aad81ea740238799cc35bb8d328eaf13f3fe2
languageName: node
linkType: hard
"@aws-sdk/middleware-sdk-sts@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-sdk-sts@npm:3.183.0"
dependencies:
"@aws-sdk/middleware-signing": 3.183.0
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/signature-v4": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 1969d6128d24cc7d8ff199c2900d805281928668f4dc3ffd128065ccfe515f9f7467a265af276592009bd285847cb9298f8ba4b1dfbe33971c3e7de80986b422
languageName: node
linkType: hard
"@aws-sdk/middleware-serde@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-serde@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 7495bb2adceab2c686588697fd9dd50a859706a8d33d98d9907ffc8f9ef78af141f2654cdac8d7b28b1f0544dcf2e52f25d109f5da1348102234ab5b4e79b256
languageName: node
linkType: hard
"@aws-sdk/middleware-signing@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-signing@npm:3.183.0"
dependencies:
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/signature-v4": 3.183.0
"@aws-sdk/types": 3.183.0
"@aws-sdk/util-middleware": 3.183.0
tslib: ^2.3.1
checksum: 8025499acfefc072511adbc5084a1ed3cfe9cd9e514c58045425c87538af72ad3adfc134f7d0a059ff52832da392b4679b62d4ad28e477b866a20e78370f0758
languageName: node
linkType: hard
"@aws-sdk/middleware-stack@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-stack@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: 03136847b96b0e4baba9b64f53a6c6b5738b1fa2c645edb3f47c1f85082791549b423ea791af33e9da3507cd56fbcbd052f1ba773a9f45ea42a3647277e85264
languageName: node
linkType: hard
"@aws-sdk/middleware-user-agent@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/middleware-user-agent@npm:3.183.0"
dependencies:
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 8d1001d6d30f0f56aa440c541f6dcee9aad9190837e7a9653aef35448ff13e644cb7a441373192134ac86b5741fa64a120add07202cb97674018bd44612acdf7
languageName: node
linkType: hard
"@aws-sdk/node-config-provider@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/node-config-provider@npm:3.183.0"
dependencies:
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/shared-ini-file-loader": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 673fb105de8d11ddd1c3e636c7ed01ef4fbe412a7d96543d9db69149dfad64d33adf5b96b106763c058190841ea497f220e1b75ca438dbda7b34729f00b9e823
languageName: node
linkType: hard
"@aws-sdk/node-http-handler@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/node-http-handler@npm:3.183.0"
dependencies:
"@aws-sdk/abort-controller": 3.183.0
"@aws-sdk/protocol-http": 3.183.0
"@aws-sdk/querystring-builder": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: a24ee8cc4e3b63fdec0ebb671caa1e634af488befa7c93a28bb733bb532934c221f6c47707db20264af91ca84336a50b98427b425329b89aeac2a6d2be9537ff
languageName: node
linkType: hard
"@aws-sdk/property-provider@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/property-provider@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 6e8616e5f7efa9f46bdf62118dfc586e61dcdf0bc99f82305759020ce3d25fc1d2db71c62cfd4417a757a138b1a539cf305b584e6e7ade9bce9975fbe66fd326
languageName: node
linkType: hard
"@aws-sdk/protocol-http@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/protocol-http@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 13b255bcb37b70853d93374f972d743c80f33ac16188c41b512536c2dbec4d7beb55226bfac6d809981d63bbc87f6bf345334238f187da2faa9feaef5001e0a7
languageName: node
linkType: hard
"@aws-sdk/querystring-builder@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/querystring-builder@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
"@aws-sdk/util-uri-escape": 3.183.0
tslib: ^2.3.1
checksum: a3de19863ccee4e8c9d5bbd719688ee1ffea02c3d90aad5e9c3eb04bed942ff8e5be0bfbc21ed03a968481abe2a2b1093e93b986b4111c468a9f3d3466b61f83
languageName: node
linkType: hard
"@aws-sdk/querystring-parser@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/querystring-parser@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: f05a03c46317c97f1b775f7c5be19365cf464396edc6b23c93efd5289ff1a8658883f7c9dde2cc7b74bb42b57f257bc212abae5d62100d23cdec5409fbffe468
languageName: node
linkType: hard
"@aws-sdk/service-error-classification@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/service-error-classification@npm:3.183.0"
checksum: 8c015163aee9ec4d789daa8605e5b9424dfda81d3f609a2c34d800cb36ee78f4a3af02d1738c7e75f9a62cd1ef8ec4307f77457eecba3de4c6565a981484bca4
languageName: node
linkType: hard
"@aws-sdk/shared-ini-file-loader@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/shared-ini-file-loader@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 317fd0d8012559754f82b88fb386d2a01c19be1d3a0b6da3a6436f71701ed8cd8fbe3f5aa869fd7bbfb8dfb148cd9de02aa68e93001200c76ba9e0691e135773
languageName: node
linkType: hard
"@aws-sdk/signature-v4@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/signature-v4@npm:3.183.0"
dependencies:
"@aws-sdk/is-array-buffer": 3.183.0
"@aws-sdk/types": 3.183.0
"@aws-sdk/util-hex-encoding": 3.183.0
"@aws-sdk/util-middleware": 3.183.0
"@aws-sdk/util-uri-escape": 3.183.0
tslib: ^2.3.1
checksum: 6639a4925b194171907fc1cf61101470836f5a8fa363f3fcd7b70bbaa4c756f43e13ad93b575885218a68192c375295d359a7e91db370816bd8f39f9c158ba36
languageName: node
linkType: hard
"@aws-sdk/smithy-client@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/smithy-client@npm:3.183.0"
dependencies:
"@aws-sdk/middleware-stack": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 70866adfd91fb35721bcd8667d9a4638e306de6ddc22be37a5b3ea19dfc2a1404a7325992f7f56d635a3bfd3b0ffa159d32f17df35c47ada4724ad8d5bb8d1ce
languageName: node
linkType: hard
"@aws-sdk/types@npm:3.183.0, @aws-sdk/types@npm:^3.1.0, @aws-sdk/types@npm:^3.110.0":
version: 3.183.0
resolution: "@aws-sdk/types@npm:3.183.0"
checksum: ab6e888ef8f6d5f5c047dbe0899ac94ad4aa83b9ae1b1fd7a3b88eacec61ab912f215fda65c71f783418d569d1088641806f6b98c9a28ddae04cc70d0eeccea7
languageName: node
linkType: hard
"@aws-sdk/url-parser@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/url-parser@npm:3.183.0"
dependencies:
"@aws-sdk/querystring-parser": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 54c99d47e927368db12b6aa1fe4331a27461502355e0c18e99d8e05d9a114529d0b15965ff885cae8e19e49692ad44bf3c323ffdc535d7129deac900f286d1d5
languageName: node
linkType: hard
"@aws-sdk/util-base64-browser@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-base64-browser@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: 2c3a4dc7e285b146285ac23de155de5e885d96aa46b29f9c830b6f12541032c6a42be7fd412ec019ddb83e6f155f561d04065b99159515d26d28c0968965dcf2
languageName: node
linkType: hard
"@aws-sdk/util-base64-node@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-base64-node@npm:3.183.0"
dependencies:
"@aws-sdk/util-buffer-from": 3.183.0
tslib: ^2.3.1
checksum: d8d0330aa768f816411a7b2343c500728501775d2f8d7c121d52d8484cbdd938102f3049e69e28574c838416ead0cb742494140609287b8d462bfb041218600d
languageName: node
linkType: hard
"@aws-sdk/util-body-length-browser@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-body-length-browser@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: 294074e20e4eb46ea992fc9d50fac0b97875d1d09efa706d5298e34f4200226c90bb33bbe96c41c7e91a43fbe44e6cfc0654d09fcdb823fe579545ada65701d9
languageName: node
linkType: hard
"@aws-sdk/util-body-length-node@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-body-length-node@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: 60697959c63731d6b4b334bed91d08c4e38e09c0ad95000509641370249c76c5df1ffa0a7cab7418d250a526f49e660f0c67cea28547e442ac47feb7623413b8
languageName: node
linkType: hard
"@aws-sdk/util-buffer-from@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-buffer-from@npm:3.183.0"
dependencies:
"@aws-sdk/is-array-buffer": 3.183.0
tslib: ^2.3.1
checksum: 5f16145cf68b0756f0930990cfba57ac343c83c6e9dc48bc8d4f488cd66548a9e186e702fa94ba33b69d852c2d019eedf4116ac676cf0dfb701081e39e0776dd
languageName: node
linkType: hard
"@aws-sdk/util-config-provider@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-config-provider@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: 8af6bf5ba31ec0a2fcf994f0a13bde5ff948bcdba02d153cdeea2105ea5eaf934368456bc92f35bfa42a7475cd4d2d2b9a644dfb8b4c2670ae2f103c045dc8b4
languageName: node
linkType: hard
"@aws-sdk/util-defaults-mode-browser@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-defaults-mode-browser@npm:3.183.0"
dependencies:
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/types": 3.183.0
bowser: ^2.11.0
tslib: ^2.3.1
checksum: 8ff54acf1684dd9d82ca13a522c5d2d7ee305511a2748f6e8ef7dc43e668798269e51455ac81b905a5b000a704fd5536f178c84425b8c431500e6a8dc1418135
languageName: node
linkType: hard
"@aws-sdk/util-defaults-mode-node@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-defaults-mode-node@npm:3.183.0"
dependencies:
"@aws-sdk/config-resolver": 3.183.0
"@aws-sdk/credential-provider-imds": 3.183.0
"@aws-sdk/node-config-provider": 3.183.0
"@aws-sdk/property-provider": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
checksum: 40665d251844c4add23e358d9171add7180e0f1fcd4bd99601f4bdd03daa2259fed2567fa200152e14c4d7b1acc1126997f5b4e74c569ee1032f9fee16e6b582
languageName: node
linkType: hard
"@aws-sdk/util-hex-encoding@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-hex-encoding@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: 1bf9577d96d01c13a3118e5d767c1e16b1f4f1c574168d78e128e0342edac30c87776340e9e14deb1e9adf539a6b2f953338adabc097fb143e870889698a6308
languageName: node
linkType: hard
"@aws-sdk/util-locate-window@npm:^3.0.0":
version: 3.183.0
resolution: "@aws-sdk/util-locate-window@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: c29899b440c148aa44a5d9322e06e4cf21644e47bee10555cf8db104d9d76b3985fa4da6e8ca92c137b0b739f7504a7d106e9da49e1d189b84f51f45c21b2204
languageName: node
linkType: hard
"@aws-sdk/util-middleware@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-middleware@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: e1a433aebae5e74b365ecb4a57e3c583e7b89697f24b0c9edde93b8ba358e92256550329efb7c6924c0a5037e1bad2b7a1c8ed1b6d02e1aaaa35bca502923752
languageName: node
linkType: hard
"@aws-sdk/util-uri-escape@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-uri-escape@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: 9d5f30821cdad15ed6912f7406f83b5b5a45358b208a9374ea944313d9853da8f4ec9881aefa5d6fe78caeaefbb0d103c8485a32f7c25e8b2cae193ea2233bb8
languageName: node
linkType: hard
"@aws-sdk/util-user-agent-browser@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-user-agent-browser@npm:3.183.0"
dependencies:
"@aws-sdk/types": 3.183.0
bowser: ^2.11.0
tslib: ^2.3.1
checksum: 21349881a4069a09fb0f8c0f5a6d69e6659255008861817c5d9dada61bf032f0bd7d5735f01dbddbc310d228ea843fbec6ada9f83a4197909efd6ebadb364f6b
languageName: node
linkType: hard
"@aws-sdk/util-user-agent-node@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-user-agent-node@npm:3.183.0"
dependencies:
"@aws-sdk/node-config-provider": 3.183.0
"@aws-sdk/types": 3.183.0
tslib: ^2.3.1
peerDependencies:
aws-crt: ">=1.0.0"
peerDependenciesMeta:
aws-crt:
optional: true
checksum: 727d46842053f8f19789fee1550e235adff399559ef6c9b8dd0fe9edd7ac629a9b5c5849377553bfff37deba1ba9889d0c313f059f27cfc40a33895990c1f894
languageName: node
linkType: hard
"@aws-sdk/util-utf8-browser@npm:3.183.0, @aws-sdk/util-utf8-browser@npm:^3.0.0":
version: 3.183.0
resolution: "@aws-sdk/util-utf8-browser@npm:3.183.0"
dependencies:
tslib: ^2.3.1
checksum: f1c9cbafc3dcf5b04264c3708509117d5e6f6b373fb30712a0cd9d09966a2cdead0a91067a8e9513abac9b082971fd40519e421a2e046b3653ce1ede136197c2
languageName: node
linkType: hard
"@aws-sdk/util-utf8-node@npm:3.183.0":
version: 3.183.0
resolution: "@aws-sdk/util-utf8-node@npm:3.183.0"
dependencies:
"@aws-sdk/util-buffer-from": 3.183.0
tslib: ^2.3.1
checksum: c37f2bd388783c33c981afcd5a6a80481cc4e019f42bc5ab10ba2dfb039a4684acb4fa30df579cb3a5b509f61b1261870b30cd966c179029adb2a42672c0a871
languageName: node
linkType: hard
"@azure/abort-controller@npm:^1.0.0":
version: 1.0.2
resolution: "@azure/abort-controller@npm:1.0.2"
@@ -5532,6 +6316,26 @@ __metadata:
languageName: unknown
linkType: soft
"@backstage/plugin-events-backend-module-aws-sqs@workspace:plugins/events-backend-module-aws-sqs":
version: 0.0.0-use.local
resolution: "@backstage/plugin-events-backend-module-aws-sqs@workspace:plugins/events-backend-module-aws-sqs"
dependencies:
"@aws-sdk/client-sqs": ^3.0.0
"@backstage/backend-common": "workspace:^"
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/backend-tasks": "workspace:^"
"@backstage/backend-test-utils": "workspace:^"
"@backstage/cli": "workspace:^"
"@backstage/config": "workspace:^"
"@backstage/plugin-events-backend-test-utils": "workspace:^"
"@backstage/plugin-events-node": "workspace:^"
"@backstage/types": "workspace:^"
aws-sdk-client-mock: ^2.0.0
luxon: ^3.0.0
winston: ^3.2.1
languageName: unknown
linkType: soft
"@backstage/plugin-events-backend-test-utils@workspace:^, @backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils":
version: 0.0.0-use.local
resolution: "@backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils"
@@ -12705,7 +13509,16 @@ __metadata:
languageName: node
linkType: hard
"@sinonjs/samsam@npm:^6.1.1":
"@sinonjs/fake-timers@npm:^7.1.2":
version: 7.1.2
resolution: "@sinonjs/fake-timers@npm:7.1.2"
dependencies:
"@sinonjs/commons": ^1.7.0
checksum: c84773d7973edad5511a31d2cc75023447b5cf714a84de9bb50eda45dda88a0d3bd2c30bf6e6e936da50a048d5352e2151c694e13e59b97d187ba1f329e9a00c
languageName: node
linkType: hard
"@sinonjs/samsam@npm:^6.0.2, @sinonjs/samsam@npm:^6.1.1":
version: 6.1.1
resolution: "@sinonjs/samsam@npm:6.1.1"
dependencies:
@@ -14916,6 +15729,22 @@ __metadata:
languageName: node
linkType: hard
"@types/sinon@npm:^10.0.10":
version: 10.0.13
resolution: "@types/sinon@npm:10.0.13"
dependencies:
"@types/sinonjs__fake-timers": "*"
checksum: 46a14c888db50f0098ec53d451877e0111d878ec4a653b9e9ed7f8e54de386d6beb0e528ddc3e95cd3361a8ab9ad54e4cca33cd88d45b9227b83e9fc8fb6688a
languageName: node
linkType: hard
"@types/sinonjs__fake-timers@npm:*":
version: 8.1.2
resolution: "@types/sinonjs__fake-timers@npm:8.1.2"
checksum: bbc73a5ab6c0ec974929392f3d6e1e8db4ebad97ec506d785301e1c3d8a4f98a35b1aa95b97035daef02886fd8efd7788a2fa3ced2ec7105988bfd8dce61eedd
languageName: node
linkType: hard
"@types/sinonjs__fake-timers@npm:8.1.1":
version: 8.1.1
resolution: "@types/sinonjs__fake-timers@npm:8.1.1"
@@ -16755,6 +17584,17 @@ __metadata:
languageName: node
linkType: hard
"aws-sdk-client-mock@npm:^2.0.0":
version: 2.0.0
resolution: "aws-sdk-client-mock@npm:2.0.0"
dependencies:
"@types/sinon": ^10.0.10
sinon: ^11.1.1
tslib: ^2.1.0
checksum: e6081ca6bb72f5c082dfcd93155bbb7e1c9e8d3d346914ed05d736c495a5ef99ab3d0253507aff2e07b5b995fae63671e53e094437ddfaf8649d69725628ff8f
languageName: node
linkType: hard
"aws-sdk-mock@npm:^5.2.1":
version: 5.7.0
resolution: "aws-sdk-mock@npm:5.7.0"
@@ -17411,6 +18251,13 @@ __metadata:
languageName: node
linkType: hard
"bowser@npm:^2.11.0":
version: 2.11.0
resolution: "bowser@npm:2.11.0"
checksum: 29c3f01f22e703fa6644fc3b684307442df4240b6e10f6cfe1b61c6ca5721073189ca97cdeedb376081148c8518e33b1d818a57f781d70b0b70e1f31fb48814f
languageName: node
linkType: hard
"brace-expansion@npm:^1.1.7":
version: 1.1.11
resolution: "brace-expansion@npm:1.1.11"
@@ -21021,6 +21868,13 @@ __metadata:
languageName: node
linkType: hard
"entities@npm:2.2.0":
version: 2.2.0
resolution: "entities@npm:2.2.0"
checksum: 19010dacaf0912c895ea262b4f6128574f9ccf8d4b3b65c7e8334ad0079b3706376360e28d8843ff50a78aabcb8f08f0a32dbfacdc77e47ed77ca08b713669b3
languageName: node
linkType: hard
"entities@npm:^2.0.0, entities@npm:~2.1.0":
version: 2.1.0
resolution: "entities@npm:2.1.0"
@@ -22767,6 +23621,15 @@ __metadata:
languageName: node
linkType: hard
"fast-xml-parser@npm:3.19.0":
version: 3.19.0
resolution: "fast-xml-parser@npm:3.19.0"
bin:
xml2js: cli.js
checksum: d9da9145f73d90c05ee2746d80c78eca4da0249dea8c81ea8f1a6e1245e62988ed4a040dbd1c7229b1e0bdcbf69d33c882e0ac337d10c7eedb159a4dc9779327
languageName: node
linkType: hard
"fastest-stable-stringify@npm:^2.0.2":
version: 2.0.2
resolution: "fastest-stable-stringify@npm:2.0.2"
@@ -30077,7 +30940,7 @@ __metadata:
languageName: node
linkType: hard
"nise@npm:^5.1.1":
"nise@npm:^5.1.0, nise@npm:^5.1.1":
version: 5.1.1
resolution: "nise@npm:5.1.1"
dependencies:
@@ -35666,6 +36529,20 @@ __metadata:
languageName: node
linkType: hard
"sinon@npm:^11.1.1":
version: 11.1.2
resolution: "sinon@npm:11.1.2"
dependencies:
"@sinonjs/commons": ^1.8.3
"@sinonjs/fake-timers": ^7.1.2
"@sinonjs/samsam": ^6.0.2
diff: ^5.0.0
nise: ^5.1.0
supports-color: ^7.2.0
checksum: 1d01377e230c9ba976bf33f28b588bae7901b0b5a503d2f6b2a7914b0dbaa9f09823481926c6f2abed820123c7fa865519695af3ae2e9ba18d8b025616163501
languageName: node
linkType: hard
"sinon@npm:^13.0.2":
version: 13.0.2
resolution: "sinon@npm:13.0.2"
@@ -37713,7 +38590,7 @@ __metadata:
languageName: node
linkType: hard
"tslib@npm:^1.10.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0, tslib@npm:^1.9.3":
"tslib@npm:^1.10.0, tslib@npm:^1.11.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0, tslib@npm:^1.9.3":
version: 1.14.1
resolution: "tslib@npm:1.14.1"
checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd