diff --git a/lib/api/apiUtils/object/createAndStoreObject.js b/lib/api/apiUtils/object/createAndStoreObject.js index fcf3ce4c0e..dc9b322f8d 100644 --- a/lib/api/apiUtils/object/createAndStoreObject.js +++ b/lib/api/apiUtils/object/createAndStoreObject.js @@ -218,6 +218,7 @@ function createAndStoreObject(bucketName, bucketMD, objectKey, objMD, authInfo, metadataStoreParams.contentMD5 = constants.emptyFileMd5; return next(null, null, null); } + // Handle mdOnlyHeader as a metadata only operation. If // the object in question is actually 0 byte or has a body size // then handle normally. @@ -244,6 +245,7 @@ function createAndStoreObject(bucketName, bucketMD, objectKey, objMD, authInfo, return next(null, dataGetInfo, _md5); } } + return dataStore(objectKeyContext, cipherBundle, request, size, streamingV4Params, backendInfo, log, next); }, @@ -280,10 +282,12 @@ function createAndStoreObject(bucketName, bucketMD, objectKey, objMD, authInfo, const options = overwritingVersioning(objMD, metadataStoreParams); return process.nextTick(() => next(null, options, infoArr)); } + if (!bucketMD.isVersioningEnabled() && objMD?.archive?.archiveInfo) { // Ensure we trigger a "delete" event in the oplog for the previously archived object metadataStoreParams.needOplogUpdate = 's3:ReplaceArchivedObject'; } + return versioningPreprocessing(bucketName, bucketMD, metadataStoreParams.objectKey, objMD, log, (err, options) => { if (err) { @@ -316,9 +320,11 @@ function createAndStoreObject(bucketName, bucketMD, objectKey, objMD, authInfo, metadataStoreParams.versioning = options.versioning; metadataStoreParams.isNull = options.isNull; metadataStoreParams.deleteNullKey = options.deleteNullKey; + if (options.extraMD) { Object.assign(metadataStoreParams, options.extraMD); } + return _storeInMDandDeleteData(bucketName, infoArr, cipherBundle, metadataStoreParams, options.dataToDelete, log, requestMethod, next); diff --git a/lib/api/apiUtils/object/versioning.js b/lib/api/apiUtils/object/versioning.js index 9747f7f015..9b02782689 100644 --- a/lib/api/apiUtils/object/versioning.js +++ b/lib/api/apiUtils/object/versioning.js @@ -103,6 +103,7 @@ function _storeNullVersionMD(bucketName, objKey, nullVersionId, objMD, log, cb) log.debug('error from metadata storing null version as new version', { error: err }); } + cb(err); }); } @@ -252,6 +253,7 @@ function processVersioningState(mst, vstat, nullVersionCompatMode) { } return { options, nullVersionId }; } + if (mst.isNull && !mst.isNull2) { // if master null version was put with an older // Cloudserver (or in compat mode), there is a @@ -265,6 +267,7 @@ function processVersioningState(mst, vstat, nullVersionCompatMode) { } return { options, nullVersionId }; } + // backward-compat: keep a reference to the existing null // versioned key if (mst.nullVersionId) { @@ -295,6 +298,7 @@ function getMasterState(objMD) { if (!objMD) { return {}; } + const mst = { exists: true, versionId: objMD.versionId, @@ -304,10 +308,12 @@ function getMasterState(objMD) { nullVersionId: objMD.nullVersionId, nullUploadId: objMD.nullUploadId, }; + if (objMD.location) { mst.objLocation = Array.isArray(objMD.location) ? objMD.location : [objMD.location]; } + return mst; } /** versioningPreprocessing - return versioning information for S3 to handle @@ -329,19 +335,22 @@ function versioningPreprocessing(bucketName, bucketMD, objectKey, objMD, log, callback) { const mst = getMasterState(objMD); const vCfg = bucketMD.getVersioningConfiguration(); - // bucket is not versioning configured + if (!vCfg) { const options = { dataToDelete: mst.objLocation }; return process.nextTick(callback, null, options); } - // bucket is versioning configured + const { options, nullVersionId, delOptions } = processVersioningState(mst, vCfg.Status, config.nullVersionCompatMode); + return async.series([ function storeNullVersionMD(next) { if (!nullVersionId) { return process.nextTick(next); } + + options.nullVersionId = nullVersionId; return _storeNullVersionMD(bucketName, objectKey, nullVersionId, objMD, log, next); }, function prepareNullVersionDeletion(next) { diff --git a/lib/routes/routeBackbeat.js b/lib/routes/routeBackbeat.js index fcd4c6a7c1..c310f3161c 100644 --- a/lib/routes/routeBackbeat.js +++ b/lib/routes/routeBackbeat.js @@ -40,6 +40,13 @@ const { listLifecycleOrphanDeleteMarkers } = require('../api/backbeat/listLifecy const { objectDeleteInternal } = require('../api/objectDelete'); const quotaUtils = require('../api/apiUtils/quotas/quotaUtils'); const { handleAuthorizationResults } = require('../api/api'); +const { versioningPreprocessing } + = require('../api/apiUtils/object/versioning'); +const {promisify} = require('util'); + +const versioningPreprocessingPromised = promisify(versioningPreprocessing); +metadata.getObjectMDPromised = promisify(metadata.getObjectMD); +metadata.getBucketAndObjectMDPromised = promisify(metadata.getBucketAndObjectMD); const { CURRENT_TYPE, NON_CURRENT_TYPE, ORPHAN_DM_TYPE } = constants.lifecycleListing; @@ -508,23 +515,22 @@ function putMetadata(request, response, bucketInfo, objMd, log, callback) { if (err) { return callback(err); } + let omVal; + try { omVal = JSON.parse(payload); } catch { - // FIXME: add error type MalformedJSON return callback(errors.MalformedPOSTRequest); } + const { headers, bucketName, objectKey } = request; - // check if it's metadata only operation + if (headers['x-scal-replication-content'] === 'METADATA') { if (!objMd) { - // if the target does not exist, return an error to - // backbeat, who will have to retry the operation as a - // complete replication return callback(errors.ObjNotFound); } - // use original data locations and encryption info + [ 'location', 'x-amz-server-side-encryption', @@ -611,6 +617,12 @@ function putMetadata(request, response, bucketInfo, objMd, log, callback) { // To prevent this, the versionId field is only included in options when it is defined. if (versionId !== undefined) { options.versionId = versionId; + omVal.versionId = versionId; + + if (isNull) { + omVal.isNull = isNull; + } + // In the MongoDB metadata backend, setting the versionId option leads to the creation // or update of the version object, the master object is only updated if its versionId // is the same as the version. This can lead to inconsistencies when replicating objects @@ -641,6 +653,7 @@ function putMetadata(request, response, bucketInfo, objMd, log, callback) { if (!request.query?.accountId) { return next(); } + return getCanonicalIdsByAccountId(request.query.accountId, log, (err, res) => { if (err) { return next(err); @@ -650,6 +663,36 @@ function putMetadata(request, response, bucketInfo, objMd, log, callback) { return next(); }); }, + async () => { + if (versioning) { + let masterMD; + + try { + masterMD = await metadata.getObjectMDPromised(bucketName, objectKey, {}, log); + } catch (err) { + if (err.is?.NoSuchKey) { + log.debug('no master found for versioned object', { + method: 'putMetadata', + bucketName, + objectKey, + }); + } else { + throw err; + } + } + + if (!masterMD) { + return; + } + + const versioningPreprocessingResult = + await versioningPreprocessingPromised(bucketName, bucketInfo, objectKey, masterMD, log); + + if (versioningPreprocessingResult?.nullVersionId) { + omVal.nullVersionId = versioningPreprocessingResult.nullVersionId; + } + } + }, next => { log.trace('putting object version', { objectKey: request.objectKey, omVal, options }); diff --git a/tests/functional/aws-node-sdk/lib/utility/bucket-util.js b/tests/functional/aws-node-sdk/lib/utility/bucket-util.js index 7f5b6410e0..2a0b5b7a97 100644 --- a/tests/functional/aws-node-sdk/lib/utility/bucket-util.js +++ b/tests/functional/aws-node-sdk/lib/utility/bucket-util.js @@ -17,7 +17,8 @@ class BucketUtility { bucketExists(bucketName) { return this.s3 - .headBucket({ Bucket: bucketName }).promise() + .headBucket({ Bucket: bucketName }) + .promise() .then(() => true) .catch(err => { if (err.code === 'NotFound') { @@ -29,21 +30,24 @@ class BucketUtility { createOne(bucketName) { return this.s3 - .createBucket({ Bucket: bucketName }).promise() + .createBucket({ Bucket: bucketName }) + .promise() .then(() => bucketName); } createOneWithLock(bucketName) { - return this.s3.createBucket({ - Bucket: bucketName, - ObjectLockEnabledForBucket: true, - }).promise() - .then(() => bucketName); + return this.s3 + .createBucket({ + Bucket: bucketName, + ObjectLockEnabledForBucket: true, + }) + .promise() + .then(() => bucketName); } createMany(bucketNames) { - const promises = bucketNames.map( - bucketName => this.createOne(bucketName) + const promises = bucketNames.map(bucketName => + this.createOne(bucketName), ); return Promise.all(promises); @@ -64,13 +68,12 @@ class BucketUtility { } deleteOne(bucketName) { - return this.s3 - .deleteBucket({ Bucket: bucketName }).promise(); + return this.s3.deleteBucket({ Bucket: bucketName }).promise(); } deleteMany(bucketNames) { - const promises = bucketNames.map( - bucketName => this.deleteOne(bucketName) + const promises = bucketNames.map(bucketName => + this.deleteOne(bucketName), ); return Promise.all(promises); @@ -82,74 +85,79 @@ class BucketUtility { * @returns {Promise.} */ - empty(bucketName, BypassGovernanceRetention = false) { + async empty(bucketName, BypassGovernanceRetention = false) { const param = { Bucket: bucketName, }; - return this.s3 - .listObjectVersions(param).promise() - .then(data => - Promise.all( - data.Versions - .filter(object => !object.Key.endsWith('/')) - // remove all objects - .map(object => - this.s3.deleteObject({ - Bucket: bucketName, - Key: object.Key, - VersionId: object.VersionId, - ...(BypassGovernanceRetention && { BypassGovernanceRetention }), - }).promise() - .then(() => object) - ) - .concat(data.Versions - .filter(object => object.Key.endsWith('/')) - // remove all directories - .map(object => - this.s3.deleteObject({ - Bucket: bucketName, - Key: object.Key, - VersionId: object.VersionId, - ...(BypassGovernanceRetention && { BypassGovernanceRetention }), - }).promise() - .then(() => object) - ) - ) - .concat(data.DeleteMarkers - .map(object => - this.s3.deleteObject({ - Bucket: bucketName, - Key: object.Key, - VersionId: object.VersionId, - ...(BypassGovernanceRetention && { BypassGovernanceRetention }), - }).promise() - .then(() => object))) - ) - ); + const listedObjects = await this.s3.listObjectVersions(param).promise(); + + for (const version of listedObjects.Versions) { + if (version.Key.endsWith('/')) { + continue; + } + + await this.s3 + .deleteObject({ + Bucket: bucketName, + Key: version.Key, + VersionId: version.VersionId, + ...(BypassGovernanceRetention && { + BypassGovernanceRetention, + }), + }) + .promise(); + } + + for (const version of listedObjects.Versions) { + if (!version.Key.endsWith('/')) { + continue; + } + + await this.s3 + .deleteObject({ + Bucket: bucketName, + Key: version.Key, + VersionId: version.VersionId, + ...(BypassGovernanceRetention && { + BypassGovernanceRetention, + }), + }) + .promise(); + } + + for (const marker of listedObjects.DeleteMarkers) { + await this.s3 + .deleteObject({ + Bucket: bucketName, + Key: marker.Key, + VersionId: marker.VersionId, + ...(BypassGovernanceRetention && { + BypassGovernanceRetention, + }), + }) + .promise(); + } } emptyMany(bucketNames) { - const promises = bucketNames.map( - bucketName => this.empty(bucketName) - ); + const promises = bucketNames.map(bucketName => this.empty(bucketName)); return Promise.all(promises); } emptyIfExists(bucketName) { - return this.bucketExists(bucketName) - .then(exists => { - if (exists) { - return this.empty(bucketName); - } - return undefined; - }); + return this.bucketExists(bucketName).then(exists => { + if (exists) { + return this.empty(bucketName); + } + return undefined; + }); } emptyManyIfExists(bucketNames) { - const promises = bucketNames.map( - bucketName => this.emptyIfExists(bucketName) + const promises = bucketNames.map(bucketName => + this.emptyIfExists(bucketName), ); return Promise.all(promises); @@ -157,7 +165,8 @@ class BucketUtility { getOwner() { return this.s3 - .listBuckets().promise() + .listBuckets() + .promise() .then(data => data.Owner); } } diff --git a/tests/multipleBackend/routes/routeBackbeat.js b/tests/multipleBackend/routes/routeBackbeat.js index d6e8f4af1a..1a6d5f14ec 100644 --- a/tests/multipleBackend/routes/routeBackbeat.js +++ b/tests/multipleBackend/routes/routeBackbeat.js @@ -2466,6 +2466,7 @@ describe('backbeat routes', () => { }), ], done); }); + it('should put tags if the source is Azure and tags are provided ' + 'when completing the multipart upload', done => { const containerName = getAzureContainerName(azureLocation); diff --git a/tests/multipleBackend/routes/routeBackbeatForReplication.js b/tests/multipleBackend/routes/routeBackbeatForReplication.js index be92f69282..b70be387f4 100644 --- a/tests/multipleBackend/routes/routeBackbeatForReplication.js +++ b/tests/multipleBackend/routes/routeBackbeatForReplication.js @@ -941,9 +941,7 @@ describe(`backbeat routes for replication (${name})`, () => { }); }); - // TODO fix and unskip by CLDSRV-632 - const itSkipNotS3C = process.env.S3_END_TO_END ? it : it.skip; - itSkipNotS3C('should replicate/put metadata to a destination that has a null version', done => { + it('should replicate/put metadata to a destination that has a null version', done => { let objMD; let versionId; @@ -959,6 +957,7 @@ describe(`backbeat routes for replication (${name})`, () => { if (err) { return next(err); } + versionId = data.VersionId; return next(); }), @@ -975,6 +974,7 @@ describe(`backbeat routes for replication (${name})`, () => { if (err) { return next(err); } + objMD = objectMDWithUpdatedAccountInfo(data, src === dst ? null : dstAccountInfo); return next(); }), @@ -1017,7 +1017,7 @@ describe(`backbeat routes for replication (${name})`, () => { }); }); - itSkipNotS3C('should replicate/put metadata to a destination that has a suspended null version', done => { + it('should replicate/put metadata to a destination that has a suspended null version', done => { let objMD; let versionId; @@ -1092,7 +1092,7 @@ describe(`backbeat routes for replication (${name})`, () => { }); }); - itSkipNotS3C('should replicate/put metadata to a destination that has a previously updated null version', done => { + it('should replicate/put metadata to a destination that has a previously updated null version', done => { let objMD; let objMDNull; let versionId; @@ -1193,7 +1193,7 @@ describe(`backbeat routes for replication (${name})`, () => { }); }); - itSkipNotS3C( + it( 'should replicate/put metadata to a destination that has a suspended null version with internal version', done => { const tagSet = [ @@ -1283,7 +1283,7 @@ describe(`backbeat routes for replication (${name})`, () => { }); }); - itSkipNotS3C('should mimic null version replication by crrExistingObjects, then replicate version', done => { + it('should mimic null version replication by crrExistingObjects, then replicate version', done => { let objMDNull; let objMDNullReplicated; let objMDVersion; diff --git a/tests/unit/api/apiUtils/objectLockHelpers.js b/tests/unit/api/apiUtils/objectLockHelpers.js index 912e42f171..c0c445cef6 100644 --- a/tests/unit/api/apiUtils/objectLockHelpers.js +++ b/tests/unit/api/apiUtils/objectLockHelpers.js @@ -159,7 +159,7 @@ describe('objectLockHelpers: calculateRetainUntilDate', () => { }; const date = moment(); const expectedRetainUntilDate - = date.add(mockConfigWithDays.days, 'days'); + = date.add(mockConfigWithDays.days * 86400000, 'ms'); const retainUntilDate = calculateRetainUntilDate(mockConfigWithDays); assert.strictEqual(retainUntilDate.slice(0, 16), expectedRetainUntilDate.toISOString().slice(0, 16)); diff --git a/tests/unit/routes/routeBackbeat.js b/tests/unit/routes/routeBackbeat.js index 5dc3e8576e..6875a16291 100644 --- a/tests/unit/routes/routeBackbeat.js +++ b/tests/unit/routes/routeBackbeat.js @@ -229,8 +229,11 @@ describe('routeBackbeat', () => { it('should put metadata after updating account info', async () => { mockRequest.url = '/_/backbeat/metadata/bucket0/key0?accountId=123456789012'; - - sandbox.stub(metadata, 'putObjectMD').callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { + const putObjectMDStub = sandbox.stub(metadata, 'putObjectMD'); + putObjectMDStub.onCall(0).callsFake( + (_bucketName, _objectKey, _omVal, _options, _logParam, cb) => cb(null, {}) + ); + putObjectMDStub.onCall(1).callsFake((_bucketName, _objectKey, omVal, _options, _logParam, cb) => { assert.strictEqual(omVal['owner-display-name'], 'Bart'); assert.strictEqual(omVal['owner-id'], '79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be'); @@ -258,14 +261,18 @@ describe('routeBackbeat', () => { mockRequest.url = '/_/backbeat/metadata/bucket0/key0' + '?accountId=123456789012&versionId=aIXVkw5Tw2Pd00000000001I4j3QKsvf'; - sandbox.stub(metadata, 'putObjectMD').callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { + const putObjectMDStub = sandbox.stub(metadata, 'putObjectMD'); + putObjectMDStub.onCall(0).callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { + assert.strictEqual(options.repairMaster, undefined); + cb(null, {}); + }); + putObjectMDStub.onCall(1).callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { assert.strictEqual(options.repairMaster, true); cb(null, {}); }); - // Override default callback to return undefined for objMd to simulate new version - metadataUtils.standardMetadataValidateBucketAndObj.callsFake((params, denies, log, callback) => { - callback(null, bucketInfo, undefined); + metadataUtils.standardMetadataValidateBucketAndObj.onCall(1).callsFake((params, denies, log, callback) => { + callback(null, bucketInfo, {}); }); routeBackbeat('127.0.0.1', mockRequest, mockResponse, log); @@ -291,7 +298,8 @@ describe('routeBackbeat', () => { }); it('should handle error when putting metadata', async () => { - sandbox.stub(metadata, 'putObjectMD').callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { + const putObjectMDStub = sandbox.stub(metadata, 'putObjectMD'); + putObjectMDStub.onCall(0).callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { cb(new Error('error')); }); @@ -321,7 +329,11 @@ describe('routeBackbeat', () => { callback(null, bucketInfo, existingMd); }); - sandbox.stub(metadata, 'putObjectMD').callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { + const putObjectMDStub = sandbox.stub(metadata, 'putObjectMD'); + putObjectMDStub.onCall(0).callsFake( + (_bucketName, _objectKey, _omVal, _options, _logParam, cb) => cb(null, {}) + ); + putObjectMDStub.onCall(1).callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { assert.deepStrictEqual(omVal.location, undefined); cb(null, {}); }); @@ -390,7 +402,11 @@ describe('routeBackbeat', () => { callback(null, bucketInfo, existingMd); }); - sandbox.stub(metadata, 'putObjectMD').callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { + const putObjectMDStub = sandbox.stub(metadata, 'putObjectMD'); + putObjectMDStub.onCall(0).callsFake( + (_bucketName, _objectKey, _omVal, _options, _logParam, cb) => cb(null, {}) + ); + putObjectMDStub.onCall(1).callsFake((_bucketName, _objectKey, omVal, _options, _logParam, cb) => { // Verify that the location array is empty, indicating data deletion assert.deepStrictEqual(omVal.location, []); cb(null, {}); @@ -433,7 +449,11 @@ describe('routeBackbeat', () => { mockRequest = preparePutMetadataRequest(reqBody); mockRequest.url += '?versionId=aIXVkw5Tw2Pd00000000001I4j3QKsvf'; - sandbox.stub(metadata, 'putObjectMD').callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { + const putObjectMDStub = sandbox.stub(metadata, 'putObjectMD'); + putObjectMDStub.onCall(0).callsFake( + (_bucketName, _objectKey, _omVal, _options, _logParam, cb) => cb(null, {}) + ); + putObjectMDStub.onCall(1).callsFake((_bucketName, __objectKey, omVal, _options, _logParam, cb) => { // Verify that the location array contains the new location assert.deepStrictEqual(omVal.location, reqBody.location); cb(null, {}); @@ -481,7 +501,11 @@ describe('routeBackbeat', () => { mockRequest = preparePutMetadataRequest(reqBody); mockRequest.url += '?versionId=aIXVkw5Tw2Pd00000000001I4j3QKsvf'; - sandbox.stub(metadata, 'putObjectMD').callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { + const putObjectMDStub = sandbox.stub(metadata, 'putObjectMD'); + putObjectMDStub.onCall(0).callsFake( + (_bucketName, _objectKey, _omVal, _options, _logParam, cb) => cb(null, {}) + ); + putObjectMDStub.onCall(1).callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { // Verify that the location array contains the new location assert.deepStrictEqual(omVal.location, reqBody.location); cb(null, {}); @@ -516,7 +540,11 @@ describe('routeBackbeat', () => { })); mockRequest.url += '?versionId=aIXVkw5Tw2Pd00000000001I4j3QKsvf'; - sandbox.stub(metadata, 'putObjectMD').callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { + const putObjectMDStub = sandbox.stub(metadata, 'putObjectMD'); + putObjectMDStub.onCall(0).callsFake( + (_bucketName, _objectKey, _omVal, _options, _logParam, cb) => cb(null, {}) + ); + putObjectMDStub.onCall(1).callsFake((bucketName, objectKey, omVal, options, logParam, cb) => { // Verify that the location array is empty assert.deepStrictEqual(omVal.location, undefined); // Content length should be preserved diff --git a/yarn.lock b/yarn.lock index 44695c2f2b..ef244ccdce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -97,7 +97,7 @@ "@azure/core-util" "^1.13.0" tslib "^2.6.2" -"@azure/core-client@^1.10.0", "@azure/core-client@^1.9.2", "@azure/core-client@^1.9.3": +"@azure/core-client@^1.3.0", "@azure/core-client@^1.9.2", "@azure/core-client@^1.9.3": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-client/-/core-client-1.10.1.tgz#83d78f97d647ab22e6811a7a68bb4223e7a1d019" integrity sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w== @@ -111,13 +111,13 @@ tslib "^2.6.2" "@azure/core-http-compat@^2.2.0": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@azure/core-http-compat/-/core-http-compat-2.3.1.tgz#2182e39a31c062800d4e3ad69bcf0109d87713dc" - integrity sha512-az9BkXND3/d5VgdRRQVkiJb2gOmDU8Qcq4GvjtBmDICNiQ9udFmDk4ZpSB5Qq1OmtDJGlQAfBaS4palFsazQ5g== + version "2.3.0" + resolved "https://registry.yarnpkg.com/@azure/core-http-compat/-/core-http-compat-2.3.0.tgz#e9d396299211e742308827674082c13bd638c6bf" + integrity sha512-qLQujmUypBBG0gxHd0j6/Jdmul6ttl24c8WGiLXIk7IHXdBlfoBqW27hyz3Xn6xbfdyVSarl1Ttbk0AwnZBYCw== dependencies: - "@azure/abort-controller" "^2.1.2" - "@azure/core-client" "^1.10.0" - "@azure/core-rest-pipeline" "^1.22.0" + "@azure/abort-controller" "^2.0.0" + "@azure/core-client" "^1.3.0" + "@azure/core-rest-pipeline" "^1.20.0" "@azure/core-lro@^2.2.0": version "2.7.2" @@ -150,7 +150,20 @@ https-proxy-agent "^7.0.0" tslib "^2.6.2" -"@azure/core-rest-pipeline@^1.19.1", "@azure/core-rest-pipeline@^1.22.0": +"@azure/core-rest-pipeline@^1.19.1", "@azure/core-rest-pipeline@^1.20.0": + version "1.22.0" + resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.22.0.tgz#76e44a75093a2f477fc54b84f46049dc2ce65800" + integrity sha512-OKHmb3/Kpm06HypvB3g6Q3zJuvyXcpxDpCS1PnU8OV6AJgSFaee/covXBcPbWc6XDDxtEPlbi3EMQ6nUiPaQtw== + dependencies: + "@azure/abort-controller" "^2.0.0" + "@azure/core-auth" "^1.8.0" + "@azure/core-tracing" "^1.0.1" + "@azure/core-util" "^1.11.0" + "@azure/logger" "^1.0.0" + "@typespec/ts-http-runtime" "^0.3.0" + tslib "^2.6.2" + +"@azure/core-rest-pipeline@^1.22.0": version "1.22.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.22.1.tgz#f47bc02ff9a79f62e6a32aa375420b1b86dcbccd" integrity sha512-UVZlVLfLyz6g3Hy7GNDpooMQonUygH7ghdiSASOOHy97fKj/mPLqgDX7aidOijn+sCMU+WU8NjlPlNTgnvbcGA== @@ -170,7 +183,14 @@ dependencies: tslib "^2.6.2" -"@azure/core-tracing@^1.2.0", "@azure/core-tracing@^1.3.0": +"@azure/core-tracing@^1.2.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.3.0.tgz#341153f5b2927539eb898577651ee48ce98dda25" + integrity sha512-+XvmZLLWPe67WXNZo9Oc9CrPj/Tm8QnHR92fFAFdnbzwNdCH1h+7UdpaQgRSBsMY+oW1kHXNUZQLdZ1gHX3ROw== + dependencies: + tslib "^2.6.2" + +"@azure/core-tracing@^1.3.0": version "1.3.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.3.1.tgz#e971045c901ea9c110616b0e1db272507781d5f6" integrity sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ== @@ -617,9 +637,9 @@ integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== "@ioredis/commands@^1.3.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.4.0.tgz#9f657d51cdd5d2fdb8889592aa4a355546151f25" - integrity sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ== + version "1.3.1" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.3.1.tgz#b6ecce79a6c464b5e926e92baaef71f47496f627" + integrity sha512-bYtU8avhGIcje3IhvF9aSjsa5URMZBHnwKtOvXsT4sfYy9gppW11gLPT/9oNqlJZD47yPKveQFTAFWpHjKvUoQ== "@isaacs/cliui@^8.0.2": version "8.0.2" @@ -700,13 +720,6 @@ dependencies: sparse-bitfield "^3.0.3" -"@mongodb-js/saslprep@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.3.0.tgz#75bb770b4b0908047b6c6ac2ec841047660e1c82" - integrity sha512-zlayKCsIjYb7/IdfqxorK5+xUMyi4vOKcFy10wKJYc63NSdKI8mNME+uJqfatkPmOSMMUiojrL58IePKBm3gvQ== - dependencies: - sparse-bitfield "^3.0.3" - "@npmcli/agent@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-3.0.0.tgz#1685b1fbd4a1b7bb4f930cbb68ce801edfe7aa44" @@ -1074,9 +1087,9 @@ "@types/webidl-conversions" "*" "@typespec/ts-http-runtime@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.1.tgz#2fa94050f25b4d85d0bc8b9d97874b8d347a9173" - integrity sha512-SnbaqayTVFEA6/tYumdF0UmybY0KHyKwGPBXnyckFlrrKdhWFrL3a2HIPXHjht5ZOElKGcXfD2D63P36btb+ww== + version "0.3.0" + resolved "https://registry.yarnpkg.com/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.0.tgz#f506ff2170e594a257f8e78aa196088f3a46a22d" + integrity sha512-sOx1PKSuFwnIl7z4RN0Ls7N9AQawmR9r66eI5rFCzLDIs8HTIYrIpH9QjYWoX0lkgGrkLxXhi4QnK7MizPRrIg== dependencies: http-proxy-agent "^7.0.0" https-proxy-agent "^7.0.0" @@ -5029,7 +5042,7 @@ moment@^2.30.1: resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== -mongodb-connection-string-url@^3.0.0, mongodb-connection-string-url@^3.0.2: +mongodb-connection-string-url@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz#e223089dfa0a5fa9bf505f8aedcbc67b077b33e7" integrity sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA== @@ -5046,16 +5059,7 @@ mongodb@^6.11.0: bson "^6.10.3" mongodb-connection-string-url "^3.0.0" -mongodb@^6.17.0: - version "6.20.0" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.20.0.tgz#5212dcf512719385287aa4574265352eefb01d8e" - integrity sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ== - dependencies: - "@mongodb-js/saslprep" "^1.3.0" - bson "^6.10.4" - mongodb-connection-string-url "^3.0.2" - -mongodb@^6.19.0: +mongodb@^6.17.0, mongodb@^6.19.0: version "6.19.0" resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.19.0.tgz#d28df0ae4cb3bea4381206e2d9efc3c7b77531fe" integrity sha512-H3GtYujOJdeKIMLKBT9PwlDhGrQfplABNF1G904w6r5ZXKWyv77aB0X9B+rhmaAwjtllHzaEkvi9mkGVZxs2Bw==