From 2eb03c557959e599d98f2357244bc4aa207ab632 Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:13:08 +0000 Subject: [PATCH 1/2] Sort Notifications recipients (#1665) https://eaflood.atlassian.net/browse/WATER-4775 This change introduces a sort on the recipients array in the presenter. It sorts by the contacts name. We need to work out the name before we can sort. So we first map the recipients and then sort. This will result in all the recipients being mapped and sorted, with only 25 (the current default pagination per page) of the results being used. We have deemed this acceptable for the sake of simplicity and have accounted for performance concerns. --- .../notifications/setup/review.presenter.js | 75 +++++++++---- test/fixtures/recipients.fixtures.js | 10 +- .../setup/review.presenter.test.js | 106 +++++++++++++----- .../determine-recipients.service.test.js | 4 +- 4 files changed, 139 insertions(+), 56 deletions(-) diff --git a/app/presenters/notifications/setup/review.presenter.js b/app/presenters/notifications/setup/review.presenter.js index aeb83724e2..7d96a58373 100644 --- a/app/presenters/notifications/setup/review.presenter.js +++ b/app/presenters/notifications/setup/review.presenter.js @@ -13,7 +13,7 @@ const { defaultPageSize } = require('../../../../config/database.config.js') * * @param {object[]} recipients - List of recipient objects, each containing recipient details like email or name. * @param {number|string} page - The currently selected page - * @param {object} pagination - + * @param {object} pagination - The result from `PaginatorPresenter` * * @returns {object} - The data formatted for the view template */ @@ -29,13 +29,10 @@ function go(recipients, page, pagination) { /** * Contact can be an email or an address (letter) * - * If it is an address then we convert the contact CSV string to an array + * If it is an address then we convert the contact CSV string to an array. If it is an email we return the email in + * array for the UI to have consistent formatting. * - * If it is an email we return the email in array for the UI to have consistent formatting - * - * @param {object} recipient - * - * @returns {string[]} + * @private */ function _contact(recipient) { if (recipient.email) { @@ -44,17 +41,18 @@ function _contact(recipient) { const name = contactName(recipient.contact) const address = contactAddress(recipient.contact) + return [name, ...address] } -/** - * Convert the licence CSV string to an array - * - * @param {string} licences - * @returns {string[]} - */ -function _licences(licences) { - return licences.split(',') +function _formatRecipients(recipients) { + return recipients.map((recipient) => { + return { + contact: _contact(recipient), + licences: recipient.licence_refs.split(','), + method: `${recipient.message_type} - ${recipient.contact_type}` + } + }) } function _pageTitle(page, pagination) { @@ -66,24 +64,55 @@ function _pageTitle(page, pagination) { } /** - * Due to the complexity of the query to get the recipients data, we handle pagination in the presenter. + * Due to the complexity of the query we had to use a raw query to get the recipients data. This means we need to handle + * pagination (which recipients to display based on selected page and page size) in here. * * @private */ -function _pagination(recipients, page) { +function _paginateRecipients(recipients, page) { const pageNumber = Number(page) * defaultPageSize + return recipients.slice(pageNumber - defaultPageSize, pageNumber) } +/** + * Sorts, maps, and paginates the recipients list. + * + * This function first maps over the recipients to transform each recipient object into a new format, then sorts the + * resulting array of transformed recipients alphabetically by their contact's name. After sorting, it uses pagination + * to return only the relevant subset of recipients for the given page. + * + * The map and sort are performed before pagination, as it is necessary to have the recipients in a defined order before + * determining which recipients should appear on the page. + * + * @private + */ function _recipients(recipients, page) { - const paginatedRecipients = _pagination(recipients, page) + const formattedRecipients = _formatRecipients(recipients) + const sortedRecipients = _sortRecipients(formattedRecipients) - return paginatedRecipients.map((recipient) => { - return { - contact: _contact(recipient), - licences: _licences(recipient.licence_refs), - method: `${recipient.message_type} - ${recipient.contact_type}` + return _paginateRecipients(sortedRecipients, page) +} + +/** + * Sorts the recipients alphabetically by their 'contact name'. + * + * The contact name is the first element in the recipient's `contact` array. For letter-based recipients this will + * be either the person or organisation name, and for email recipients this will be the email address. + * + * @private + */ +function _sortRecipients(recipients) { + return recipients.sort((a, b) => { + if (a.contact[0] < b.contact[0]) { + return -1 + } + + if (a.contact[0] > b.contact[0]) { + return 1 } + + return 0 }) } diff --git a/test/fixtures/recipients.fixtures.js b/test/fixtures/recipients.fixtures.js index a5936515da..4382f1f475 100644 --- a/test/fixtures/recipients.fixtures.js +++ b/test/fixtures/recipients.fixtures.js @@ -25,9 +25,11 @@ function recipients() { */ function duplicateRecipients() { const duplicateLicenceRef = generateLicenceRef() + const licenceDuplicateLicenceRef = generateLicenceRef() + return { - duplicateLicenceHolder: _addDuplicateLicenceHolder(duplicateLicenceRef), - duplicateReturnsTo: _addDuplicateReturnsTo(duplicateLicenceRef), + duplicateLicenceHolder: _addDuplicateLicenceHolder(licenceDuplicateLicenceRef), + duplicateReturnsTo: _addDuplicateReturnsTo(licenceDuplicateLicenceRef), duplicatePrimaryUser: _addDuplicatePrimaryUser(duplicateLicenceRef), duplicateReturnsAgent: _addDuplicateReturnsAgent(duplicateLicenceRef) } @@ -45,7 +47,7 @@ function _addDuplicateLicenceHolder(licenceRef) { function _addDuplicateReturnsTo(licenceRef) { return { licence_refs: licenceRef, - contact_type: 'Returns To', + contact_type: 'Returns to', contact: _contact('4', 'Duplicate Returns to', 'Returns to'), contact_hash_id: 'b1b355491c7d42778890c545e08797ea' } @@ -96,7 +98,7 @@ function _addDuplicateReturnsAgent(licenceRef) { contact: null, contact_hash_id: '2e6918568dfbc1d78e2fbe279fftt990', contact_type: 'Returns agent', - recipient: 'returns.agent@important.com' + email: 'returns.agent@important.com' } } diff --git a/test/presenters/notifications/setup/review.presenter.test.js b/test/presenters/notifications/setup/review.presenter.test.js index 89c3c0346e..dd689ddd19 100644 --- a/test/presenters/notifications/setup/review.presenter.test.js +++ b/test/presenters/notifications/setup/review.presenter.test.js @@ -18,6 +18,7 @@ describe('Notifications Setup - Review presenter', () => { let pagination let testInput let testRecipients + let testDuplicateRecipients beforeEach(() => { page = 1 @@ -26,8 +27,12 @@ describe('Notifications Setup - Review presenter', () => { } testRecipients = RecipientsFixture.recipients() + // This data is used to ensure the recipients are grouped when they have the same licence ref / name. + // Ignore the fact that these would be considered duplicates elsewhere in the code + // (e.g. contact hash / address being identical) + testDuplicateRecipients = RecipientsFixture.duplicateRecipients() - testInput = Object.values(testRecipients).map((recipient) => { + testInput = [...Object.values(testRecipients), ...Object.values(testDuplicateRecipients)].map((recipient) => { return { ...recipient, // The determine recipients service will add the message_type relevant to the recipient @@ -39,7 +44,7 @@ describe('Notifications Setup - Review presenter', () => { }) describe('when provided with "recipients"', () => { - it('correctly presents the data', () => { + it('correctly presents the data (in alphabetical order)', () => { const result = ReviewPresenter.go(testInput, page, pagination) expect(result).to.equal({ @@ -47,25 +52,20 @@ describe('Notifications Setup - Review presenter', () => { pageTitle: 'Send returns invitations', recipients: [ { - contact: ['primary.user@important.com'], - licences: [testRecipients.primaryUser.licence_refs], - method: 'Letter or email - Primary user' + contact: ['Mr H J Duplicate Licence holder', '4', 'Privet Drive', 'Little Whinging', 'Surrey', 'WD25 7LR'], + licences: [testDuplicateRecipients.duplicateLicenceHolder.licence_refs], + method: 'Letter or email - Licence holder' }, { - contact: ['returns.agent@important.com'], - licences: [testRecipients.returnsAgent.licence_refs], - method: 'Letter or email - Returns agent' + contact: ['Mr H J Duplicate Returns to', '4', 'Privet Drive', 'Little Whinging', 'Surrey', 'WD25 7LR'], + licences: [testDuplicateRecipients.duplicateReturnsTo.licence_refs], + method: 'Letter or email - Returns to' }, { contact: ['Mr H J Licence holder', '1', 'Privet Drive', 'Little Whinging', 'Surrey', 'WD25 7LR'], licences: [testRecipients.licenceHolder.licence_refs], method: 'Letter or email - Licence holder' }, - { - contact: ['Mr H J Returns to', '2', 'Privet Drive', 'Little Whinging', 'Surrey', 'WD25 7LR'], - licences: [testRecipients.returnsTo.licence_refs], - method: 'Letter or email - Returns to' - }, { contact: [ 'Mr H J Licence holder with multiple licences', @@ -77,9 +77,34 @@ describe('Notifications Setup - Review presenter', () => { ], licences: testRecipients.licenceHolderWithMultipleLicences.licence_refs.split(','), method: 'Letter or email - Licence holder' + }, + { + contact: ['Mr H J Returns to', '2', 'Privet Drive', 'Little Whinging', 'Surrey', 'WD25 7LR'], + licences: [testRecipients.returnsTo.licence_refs], + method: 'Letter or email - Returns to' + }, + { + contact: ['primary.user@important.com'], + licences: [testRecipients.primaryUser.licence_refs], + method: 'Letter or email - Primary user' + }, + { + contact: ['primary.user@important.com'], + licences: [testDuplicateRecipients.duplicatePrimaryUser.licence_refs], + method: 'Letter or email - Primary user' + }, + { + contact: ['returns.agent@important.com'], + licences: [testRecipients.returnsAgent.licence_refs], + method: 'Letter or email - Returns agent' + }, + { + contact: ['returns.agent@important.com'], + licences: [testDuplicateRecipients.duplicateReturnsAgent.licence_refs], + method: 'Letter or email - Returns agent' } ], - recipientsAmount: 5 + recipientsAmount: 9 }) }) @@ -90,25 +115,27 @@ describe('Notifications Setup - Review presenter', () => { expect(result.recipients).to.equal([ { - contact: ['primary.user@important.com'], - licences: [testRecipients.primaryUser.licence_refs], - method: 'Letter or email - Primary user' + contact: [ + 'Mr H J Duplicate Licence holder', + '4', + 'Privet Drive', + 'Little Whinging', + 'Surrey', + 'WD25 7LR' + ], + licences: [testDuplicateRecipients.duplicateLicenceHolder.licence_refs], + method: 'Letter or email - Licence holder' }, { - contact: ['returns.agent@important.com'], - licences: [testRecipients.returnsAgent.licence_refs], - method: 'Letter or email - Returns agent' + contact: ['Mr H J Duplicate Returns to', '4', 'Privet Drive', 'Little Whinging', 'Surrey', 'WD25 7LR'], + licences: [testDuplicateRecipients.duplicateReturnsTo.licence_refs], + method: 'Letter or email - Returns to' }, { contact: ['Mr H J Licence holder', '1', 'Privet Drive', 'Little Whinging', 'Surrey', 'WD25 7LR'], licences: [testRecipients.licenceHolder.licence_refs], method: 'Letter or email - Licence holder' }, - { - contact: ['Mr H J Returns to', '2', 'Privet Drive', 'Little Whinging', 'Surrey', 'WD25 7LR'], - licences: [testRecipients.returnsTo.licence_refs], - method: 'Letter or email - Returns to' - }, { contact: [ 'Mr H J Licence holder with multiple licences', @@ -120,6 +147,31 @@ describe('Notifications Setup - Review presenter', () => { ], licences: testRecipients.licenceHolderWithMultipleLicences.licence_refs.split(','), method: 'Letter or email - Licence holder' + }, + { + contact: ['Mr H J Returns to', '2', 'Privet Drive', 'Little Whinging', 'Surrey', 'WD25 7LR'], + licences: [testRecipients.returnsTo.licence_refs], + method: 'Letter or email - Returns to' + }, + { + contact: ['primary.user@important.com'], + licences: [testRecipients.primaryUser.licence_refs], + method: 'Letter or email - Primary user' + }, + { + contact: ['primary.user@important.com'], + licences: [testDuplicateRecipients.duplicatePrimaryUser.licence_refs], + method: 'Letter or email - Primary user' + }, + { + contact: ['returns.agent@important.com'], + licences: [testRecipients.returnsAgent.licence_refs], + method: 'Letter or email - Returns agent' + }, + { + contact: ['returns.agent@important.com'], + licences: [testDuplicateRecipients.duplicateReturnsAgent.licence_refs], + method: 'Letter or email - Returns agent' } ]) }) @@ -199,7 +251,7 @@ describe('Notifications Setup - Review presenter', () => { describe('and there are >= 25 recipients', () => { beforeEach(() => { - testInput = [...testInput, ...testInput, ...testInput, ...testInput, ...testInput, ...testInput] + testInput = [...testInput, ...testInput, ...testInput] pagination = { numberOfPages: 2 @@ -228,7 +280,7 @@ describe('Notifications Setup - Review presenter', () => { it('returns the remaining recipients', () => { const result = ReviewPresenter.go(testInput, page, pagination) - expect(result.recipients.length).to.equal(5) + expect(result.recipients.length).to.equal(2) }) it('returns the updated "pageTitle"', () => { diff --git a/test/services/notifications/setup/determine-recipients.service.test.js b/test/services/notifications/setup/determine-recipients.service.test.js index 382828f523..46955367d9 100644 --- a/test/services/notifications/setup/determine-recipients.service.test.js +++ b/test/services/notifications/setup/determine-recipients.service.test.js @@ -132,7 +132,7 @@ describe('Notifications Setup - Determine Recipients service', () => { type: 'Person' }, contact_hash_id: 'b1b355491c7d42778890c545e08797ea', - contact_type: 'Licence holder', + contact_type: 'both', email: null, licence_refs: testDuplicateRecipients.duplicateLicenceHolder.licence_refs, message_type: 'Letter' @@ -194,7 +194,7 @@ describe('Notifications Setup - Determine Recipients service', () => { type: 'Person' }, contact_hash_id: 'b1b355491c7d42778890c545e08797ea', - contact_type: 'Licence holder', + contact_type: 'both', email: null, licence_refs: testDuplicateRecipients.duplicateLicenceHolder.licence_refs, message_type: 'Letter' From c40da27e4fb07484ed6584d3154006442cd07d71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Jan 2025 08:31:51 +0000 Subject: [PATCH 2/2] Bump @aws-sdk/client-s3 from 3.735.0 to 3.738.0 (#1668) --- package-lock.json | 144 +++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/package-lock.json b/package-lock.json index 61e1611df3..d100076f74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -313,16 +313,16 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.735.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.735.0.tgz", - "integrity": "sha512-6NcxX06c4tnnu6FTFiyS8shoYLy+8TvIDkYjJ5r9tvbaysOptUKQdolOuh7+Lz95QyaqiznpCsNTxsfywLXcqw==", + "version": "3.738.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.738.0.tgz", + "integrity": "sha512-1Im/p5yfoV15ydVY+QlffsWQkQm7iGVI+3V9tCHEUT6SdmukYEpN3G8Y+lWofRBidxzUE2Xd+MbChCXfzLAoAg==", "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/core": "3.734.0", - "@aws-sdk/credential-provider-node": "3.734.0", + "@aws-sdk/credential-provider-node": "3.738.0", "@aws-sdk/middleware-bucket-endpoint": "3.734.0", "@aws-sdk/middleware-expect-continue": "3.734.0", "@aws-sdk/middleware-flexible-checksums": "3.735.0", @@ -801,9 +801,9 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.734.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.734.0.tgz", - "integrity": "sha512-9NOSNbkPVb91JwaXOhyfahkzAwWdMsbWHL6fh5/PHlXYpsDjfIfT23I++toepNF2nODAJNLnOEHGYIxgNgf6jQ==", + "version": "3.738.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.738.0.tgz", + "integrity": "sha512-3MuREsazwBxghKb2sQQHvie+uuK4dX4/ckFYiSoffzJQd0YHxaGxf8cr4NOSCQCUesWu8D3Y0SzlnHGboVSkpA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/credential-provider-env": "3.734.0", @@ -3586,12 +3586,12 @@ } }, "node_modules/@smithy/core": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.1.tgz", - "integrity": "sha512-hhUZlBWYuh9t6ycAcN90XOyG76C1AzwxZZgaCVPMYpWqqk9uMFo7HGG5Zu2cEhCJn7DdOi5krBmlibWWWPgdsw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.2.tgz", + "integrity": "sha512-htwQXkbdF13uwwDevz9BEzL5ABK+1sJpVQXywwGSH973AVOvisHNfpcB8A8761G6XgHoS2kHPqc9DqHJ2gp+/Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.0.1", + "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", @@ -4037,13 +4037,13 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.2.tgz", - "integrity": "sha512-Z9m67CXizGpj8CF/AW/7uHqYNh1VXXOn9Ap54fenWsCa0HnT4cJuE61zqG3cBkTZJDCy0wHJphilI41co/PE5g==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.3.tgz", + "integrity": "sha512-YdbmWhQF5kIxZjWqPIgboVfi8i5XgiYMM7GGKFMTvBei4XjNQfNv8sukT50ITvgnWKKKpOtp0C0h7qixLgb77Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.1.1", - "@smithy/middleware-serde": "^4.0.1", + "@smithy/core": "^3.1.2", + "@smithy/middleware-serde": "^4.0.2", "@smithy/node-config-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", @@ -4068,15 +4068,15 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.3.tgz", - "integrity": "sha512-TiKwwQTwUDeDtwWW8UWURTqu7s6F3wN2pmziLU215u7bqpVT9Mk2oEvURjpRLA+5XeQhM68R5BpAGzVtomsqgA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.4.tgz", + "integrity": "sha512-wmxyUBGHaYUqul0wZiset4M39SMtDBOtUr2KpDuftKNN74Do9Y36Go6Eqzj9tL0mIPpr31ulB5UUtxcsCeGXsQ==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/service-error-classification": "^4.0.1", - "@smithy/smithy-client": "^4.1.2", + "@smithy/smithy-client": "^4.1.3", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", @@ -4113,9 +4113,9 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.1.tgz", - "integrity": "sha512-Fh0E2SOF+S+P1+CsgKyiBInAt3o2b6Qk7YOp2W0Qx2XnfTdfMuSDKUEcnrtpxCzgKJnqXeLUZYqtThaP0VGqtA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.2.tgz", + "integrity": "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.1.0", @@ -4385,13 +4385,13 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.2.tgz", - "integrity": "sha512-0yApeHWBqocelHGK22UivZyShNxFbDNrgREBllGh5Ws0D0rg/yId/CJfeoKKpjbfY2ju8j6WgDUGZHYQmINZ5w==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.3.tgz", + "integrity": "sha512-A2Hz85pu8BJJaYFdX8yb1yocqigyqBzn+OVaVgm+Kwi/DkN8vhN2kbDVEfADo6jXf5hPKquMLGA3UINA64UZ7A==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.1.1", - "@smithy/middleware-endpoint": "^4.0.2", + "@smithy/core": "^3.1.2", + "@smithy/middleware-endpoint": "^4.0.3", "@smithy/middleware-stack": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", @@ -4528,13 +4528,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.3.tgz", - "integrity": "sha512-7c5SF1fVK0EOs+2EOf72/qF199zwJflU1d02AevwKbAUPUZyE9RUZiyJxeUmhVxfKDWdUKaaVojNiaDQgnHL9g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.4.tgz", + "integrity": "sha512-Ej1bV5sbrIfH++KnWxjjzFNq9nyP3RIUq2c9Iqq7SmMO/idUR24sqvKH2LUQFTSPy/K7G4sB2m8n7YYlEAfZaw==", "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^4.0.1", - "@smithy/smithy-client": "^4.1.2", + "@smithy/smithy-client": "^4.1.3", "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" @@ -4556,16 +4556,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.3.tgz", - "integrity": "sha512-CVnD42qYD3JKgDlImZ9+On+MqJHzq9uJgPbMdeBE8c2x8VJ2kf2R3XO/yVFx+30ts5lD/GlL0eFIShY3x9ROgQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.4.tgz", + "integrity": "sha512-HE1I7gxa6yP7ZgXPCFfZSDmVmMtY7SHqzFF55gM/GPegzZKaQWZZ+nYn9C2Cc3JltCMyWe63VPR3tSFDEvuGjw==", "license": "Apache-2.0", "dependencies": { "@smithy/config-resolver": "^4.0.1", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", - "@smithy/smithy-client": "^4.1.2", + "@smithy/smithy-client": "^4.1.3", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, @@ -11731,15 +11731,15 @@ } }, "@aws-sdk/client-s3": { - "version": "3.735.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.735.0.tgz", - "integrity": "sha512-6NcxX06c4tnnu6FTFiyS8shoYLy+8TvIDkYjJ5r9tvbaysOptUKQdolOuh7+Lz95QyaqiznpCsNTxsfywLXcqw==", + "version": "3.738.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.738.0.tgz", + "integrity": "sha512-1Im/p5yfoV15ydVY+QlffsWQkQm7iGVI+3V9tCHEUT6SdmukYEpN3G8Y+lWofRBidxzUE2Xd+MbChCXfzLAoAg==", "requires": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.734.0", - "@aws-sdk/credential-provider-node": "3.734.0", + "@aws-sdk/credential-provider-node": "3.738.0", "@aws-sdk/middleware-bucket-endpoint": "3.734.0", "@aws-sdk/middleware-expect-continue": "3.734.0", "@aws-sdk/middleware-flexible-checksums": "3.735.0", @@ -12119,9 +12119,9 @@ } }, "@aws-sdk/credential-provider-node": { - "version": "3.734.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.734.0.tgz", - "integrity": "sha512-9NOSNbkPVb91JwaXOhyfahkzAwWdMsbWHL6fh5/PHlXYpsDjfIfT23I++toepNF2nODAJNLnOEHGYIxgNgf6jQ==", + "version": "3.738.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.738.0.tgz", + "integrity": "sha512-3MuREsazwBxghKb2sQQHvie+uuK4dX4/ckFYiSoffzJQd0YHxaGxf8cr4NOSCQCUesWu8D3Y0SzlnHGboVSkpA==", "requires": { "@aws-sdk/credential-provider-env": "3.734.0", "@aws-sdk/credential-provider-http": "3.734.0", @@ -14186,11 +14186,11 @@ } }, "@smithy/core": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.1.tgz", - "integrity": "sha512-hhUZlBWYuh9t6ycAcN90XOyG76C1AzwxZZgaCVPMYpWqqk9uMFo7HGG5Zu2cEhCJn7DdOi5krBmlibWWWPgdsw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.2.tgz", + "integrity": "sha512-htwQXkbdF13uwwDevz9BEzL5ABK+1sJpVQXywwGSH973AVOvisHNfpcB8A8761G6XgHoS2kHPqc9DqHJ2gp+/Q==", "requires": { - "@smithy/middleware-serde": "^4.0.1", + "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", @@ -14529,12 +14529,12 @@ } }, "@smithy/middleware-endpoint": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.2.tgz", - "integrity": "sha512-Z9m67CXizGpj8CF/AW/7uHqYNh1VXXOn9Ap54fenWsCa0HnT4cJuE61zqG3cBkTZJDCy0wHJphilI41co/PE5g==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.3.tgz", + "integrity": "sha512-YdbmWhQF5kIxZjWqPIgboVfi8i5XgiYMM7GGKFMTvBei4XjNQfNv8sukT50ITvgnWKKKpOtp0C0h7qixLgb77Q==", "requires": { - "@smithy/core": "^3.1.1", - "@smithy/middleware-serde": "^4.0.1", + "@smithy/core": "^3.1.2", + "@smithy/middleware-serde": "^4.0.2", "@smithy/node-config-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", @@ -14554,14 +14554,14 @@ } }, "@smithy/middleware-retry": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.3.tgz", - "integrity": "sha512-TiKwwQTwUDeDtwWW8UWURTqu7s6F3wN2pmziLU215u7bqpVT9Mk2oEvURjpRLA+5XeQhM68R5BpAGzVtomsqgA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.4.tgz", + "integrity": "sha512-wmxyUBGHaYUqul0wZiset4M39SMtDBOtUr2KpDuftKNN74Do9Y36Go6Eqzj9tL0mIPpr31ulB5UUtxcsCeGXsQ==", "requires": { "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/service-error-classification": "^4.0.1", - "@smithy/smithy-client": "^4.1.2", + "@smithy/smithy-client": "^4.1.3", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", @@ -14589,9 +14589,9 @@ } }, "@smithy/middleware-serde": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.1.tgz", - "integrity": "sha512-Fh0E2SOF+S+P1+CsgKyiBInAt3o2b6Qk7YOp2W0Qx2XnfTdfMuSDKUEcnrtpxCzgKJnqXeLUZYqtThaP0VGqtA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.2.tgz", + "integrity": "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ==", "requires": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" @@ -14796,12 +14796,12 @@ } }, "@smithy/smithy-client": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.2.tgz", - "integrity": "sha512-0yApeHWBqocelHGK22UivZyShNxFbDNrgREBllGh5Ws0D0rg/yId/CJfeoKKpjbfY2ju8j6WgDUGZHYQmINZ5w==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.3.tgz", + "integrity": "sha512-A2Hz85pu8BJJaYFdX8yb1yocqigyqBzn+OVaVgm+Kwi/DkN8vhN2kbDVEfADo6jXf5hPKquMLGA3UINA64UZ7A==", "requires": { - "@smithy/core": "^3.1.1", - "@smithy/middleware-endpoint": "^4.0.2", + "@smithy/core": "^3.1.2", + "@smithy/middleware-endpoint": "^4.0.3", "@smithy/middleware-stack": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", @@ -14900,12 +14900,12 @@ } }, "@smithy/util-defaults-mode-browser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.3.tgz", - "integrity": "sha512-7c5SF1fVK0EOs+2EOf72/qF199zwJflU1d02AevwKbAUPUZyE9RUZiyJxeUmhVxfKDWdUKaaVojNiaDQgnHL9g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.4.tgz", + "integrity": "sha512-Ej1bV5sbrIfH++KnWxjjzFNq9nyP3RIUq2c9Iqq7SmMO/idUR24sqvKH2LUQFTSPy/K7G4sB2m8n7YYlEAfZaw==", "requires": { "@smithy/property-provider": "^4.0.1", - "@smithy/smithy-client": "^4.1.2", + "@smithy/smithy-client": "^4.1.3", "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" @@ -14922,15 +14922,15 @@ } }, "@smithy/util-defaults-mode-node": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.3.tgz", - "integrity": "sha512-CVnD42qYD3JKgDlImZ9+On+MqJHzq9uJgPbMdeBE8c2x8VJ2kf2R3XO/yVFx+30ts5lD/GlL0eFIShY3x9ROgQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.4.tgz", + "integrity": "sha512-HE1I7gxa6yP7ZgXPCFfZSDmVmMtY7SHqzFF55gM/GPegzZKaQWZZ+nYn9C2Cc3JltCMyWe63VPR3tSFDEvuGjw==", "requires": { "@smithy/config-resolver": "^4.0.1", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", - "@smithy/smithy-client": "^4.1.2", + "@smithy/smithy-client": "^4.1.3", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" },