@message-queue-toolkit/sqs
Version:
SQS adapter for message-queue-toolkit
179 lines • 7.07 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getQueueUrl = getQueueUrl;
exports.getQueueAttributes = getQueueAttributes;
exports.assertQueue = assertQueue;
exports.deleteQueue = deleteQueue;
exports.calculateOutgoingMessageSize = calculateOutgoingMessageSize;
exports.calculateSqsMessageBodySize = calculateSqsMessageBodySize;
const client_sqs_1 = require("@aws-sdk/client-sqs");
const node_core_1 = require("@lokalise/node-core");
const core_1 = require("@message-queue-toolkit/core");
const sqsAttributeUtils_1 = require("./sqsAttributeUtils");
const sqsInitter_1 = require("./sqsInitter");
const AWS_QUEUE_DOES_NOT_EXIST_ERROR_NAME = 'QueueDoesNotExist';
async function getQueueUrl(sqsClient, queueName) {
try {
const result = await sqsClient.send(new client_sqs_1.GetQueueUrlCommand({
QueueName: queueName,
}));
if (result.QueueUrl) {
return {
result: result.QueueUrl,
};
}
return {
error: 'not_found',
};
}
catch (err) {
// @ts-ignore
if (err.Code === 'AWS.SimpleQueueService.NonExistentQueue') {
return {
error: 'not_found',
};
}
throw err;
}
}
async function getQueueAttributes(sqsClient, queueUrl, attributeNames = ['All']) {
const command = new client_sqs_1.GetQueueAttributesCommand({
QueueUrl: queueUrl,
AttributeNames: attributeNames,
});
try {
const response = await sqsClient.send(command);
return {
result: {
attributes: response.Attributes,
},
};
}
catch (err) {
// @ts-ignore
if (err.Code === 'AWS.SimpleQueueService.NonExistentQueue') {
return {
// @ts-ignore
error: 'not_found',
};
}
throw err;
}
}
async function updateExistingQueue(sqsClient, queueUrl, queueConfig, extraParams) {
const existingAttributes = await getQueueAttributes(sqsClient, queueUrl);
if (!existingAttributes.result?.attributes) {
throw new Error('Attributes are not set');
}
const queueArn = existingAttributes.result?.attributes.QueueArn;
if (!queueArn) {
throw new Error('Queue ARN was not set');
}
// we will try to update existing queue if exists
if (extraParams?.updateAttributesIfExists) {
const updatedAttributes = {
...queueConfig.Attributes,
};
if (extraParams?.topicArnsWithPublishPermissionsPrefix) {
updatedAttributes.Policy = (0, sqsAttributeUtils_1.generateQueuePublishForTopicPolicy)(queueArn, extraParams.topicArnsWithPublishPermissionsPrefix);
}
// Only perform update if there are new or changed values in the queue config
if (!(0, core_1.isShallowSubset)(updatedAttributes, existingAttributes.result.attributes)) {
await (0, sqsInitter_1.updateQueueAttributes)(sqsClient, queueUrl, updatedAttributes);
}
}
if (extraParams?.forceTagUpdate) {
await (0, sqsInitter_1.updateQueueTags)(sqsClient, queueUrl, queueConfig.tags);
}
return {
queueUrl,
queueArn,
queueName: queueConfig.QueueName,
};
}
async function assertQueue(sqsClient, queueConfig, extraParams) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const queueUrlResult = await getQueueUrl(sqsClient, queueConfig.QueueName);
const queueExists = !!queueUrlResult.result;
if (queueExists) {
return updateExistingQueue(sqsClient, queueUrlResult.result, queueConfig, extraParams);
}
// create new queue
const command = new client_sqs_1.CreateQueueCommand(queueConfig);
await sqsClient.send(command);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const newQueueUrlResult = await getQueueUrl(sqsClient, queueConfig.QueueName);
const newQueueExists = !!newQueueUrlResult.result;
if (!newQueueExists) {
throw new Error(`Queue ${queueConfig.QueueName ?? ''} was not created`);
}
const getQueueAttributesCommand = new client_sqs_1.GetQueueAttributesCommand({
QueueUrl: newQueueUrlResult.result,
AttributeNames: ['QueueArn'],
});
const queueAttributesResponse = await sqsClient.send(getQueueAttributesCommand);
const queueArn = queueAttributesResponse.Attributes?.QueueArn;
if (!queueArn) {
throw new Error('Queue ARN was not set');
}
if (extraParams?.topicArnsWithPublishPermissionsPrefix) {
const setTopicAttributesCommand = new client_sqs_1.SetQueueAttributesCommand({
QueueUrl: newQueueUrlResult.result,
Attributes: {
Policy: (0, sqsAttributeUtils_1.generateQueuePublishForTopicPolicy)(queueArn, extraParams.topicArnsWithPublishPermissionsPrefix),
},
});
await sqsClient.send(setTopicAttributesCommand);
}
return {
queueArn,
queueUrl: newQueueUrlResult.result,
queueName: queueConfig.QueueName,
};
}
async function deleteQueue(client, queueName, waitForConfirmation = true) {
try {
const queueUrlCommand = new client_sqs_1.GetQueueUrlCommand({
QueueName: queueName,
});
const response = await client.send(queueUrlCommand);
const command = new client_sqs_1.DeleteQueueCommand({
QueueUrl: response.QueueUrl,
});
await client.send(command);
if (waitForConfirmation) {
await (0, core_1.waitAndRetry)(async () => {
const queueList = await client.send(new client_sqs_1.ListQueuesCommand({
QueueNamePrefix: queueName,
}));
return !queueList.QueueUrls || queueList.QueueUrls.length === 0;
});
}
}
catch (err) {
// This is fine
// @ts-ignore
if (err.name === AWS_QUEUE_DOES_NOT_EXIST_ERROR_NAME) {
return;
}
// @ts-ignore
node_core_1.globalLogger.error(`Failed to delete: ${err.message}`);
}
}
/**
* Calculates the size of an outgoing SQS message.
*
* SQS imposes a 256 KB limit on the total size of a message, which includes both the message body and any metadata (attributes).
* This function currently computes the size based solely on the message body, as no attributes are included at this time.
* For future updates, if message attributes are added, their sizes should also be considered.
*
* Reference: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-metadata.html#sqs-message-attributes
*/
function calculateOutgoingMessageSize(message) {
const messageBody = JSON.stringify(message);
return calculateSqsMessageBodySize(messageBody);
}
function calculateSqsMessageBodySize(messageBody) {
return messageBody ? Buffer.byteLength(messageBody, 'utf8') : 0;
}
//# sourceMappingURL=sqsUtils.js.map
;