From 4460d3da30a6e604d5186f0bfbbc6fdbc405e3a4 Mon Sep 17 00:00:00 2001 From: Jack Burgess Date: Fri, 27 Sep 2024 20:21:59 +0100 Subject: [PATCH] feat: refactor to upgrade to mongodb driver 6.9 --- CHANGELOG.md | 22 +++++ lib/backends/MongoBackend.js | 146 +++++++++++++-------------- package.json | 3 +- support/migration/fs-to-s3.js | 4 +- support/migration/mongodb-to-s3.js | 18 ++-- test/lib/backends/mongo.test.js | 8 +- yarn.lock | 154 +++++++++++++---------------- 7 files changed, 182 insertions(+), 173 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe16b2d..9db6140 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # CHANGELOG +## Version 14.0.0 + +A major upgrade to the MongoDB driver from 3.7.3 to 6.9.0. + +This means MongoDB server versions below 3.6 are **no longer supported**. +(3.6 support is _deprecated_ in this version). + +Additionally, the native GridFS driver removes the `md5` and `contentType` attributes from records. +These are now stored under `metadata.{md5,contentType}`. No consumer application changes are required - only if other +supporting applications are interacting directly with the Darkroom database. + +This means a database update is required for migrations from v13.0.0 to v14.0.0. + +To do this, run the following mongo shell commands in order: + +```js + +db['fs.files'].updateMany({ md5: { $exists: true } }, { $rename: { 'md5': 'metadata.md5' } }) +db['fs.files'].updateMany({ contentType: { $exists: true } }, { $rename: { 'contentType': 'metadata.contentType' } }) +db['fs.files'].updateMany({ filename: '' }, [{ $set: { 'filename': '$metadata.md5' }] }) +``` + ## Version 13.0.0 Updates response code on restricted uploads file types from 403 to 415. diff --git a/lib/backends/MongoBackend.js b/lib/backends/MongoBackend.js index 0717a7c..6606594 100644 --- a/lib/backends/MongoBackend.js +++ b/lib/backends/MongoBackend.js @@ -1,5 +1,4 @@ const mongo = require('mongodb') -const GridStream = require('@appveen/gridfs-stream') const tmp = require('tmp') const { PassThrough } = require('stream') const crypto = require('crypto') @@ -11,24 +10,26 @@ const Backend = require('./Backend') class MongoBackend extends Backend { setup(cb) { const client = new mongo.MongoClient(this.config.databaseUri) - client.connect((error) => { - if (error) return cb(error) + client + .connect() + .then(() => { + const db = client.db(this.config.databaseName) - const db = client.db(this.config.databaseName) + const gfs = new mongo.GridFSBucket(db) - const gfsStream = new GridStream(db, mongo) - const gfs = new mongo.GridFSBucket(db) + this._db = db + this._gfs = gfs - this._db = db - this._gfsStream = gfsStream - this._gfs = gfs - - cb() - }) + cb() + }) + .catch(cb) } clean(cb) { - this._db.dropDatabase(cb) + this._db + .dropDatabase() + .then(() => cb()) + .catch(cb) } isHealthy(cb) { @@ -37,42 +38,44 @@ class MongoBackend extends Backend { this._db .collection('users') .find({}) - .toArray((error) => { - if (error) { - return cb(error, false) - } - cb(null, true) - }) + .toArray() + .then(() => cb(null, true)) + .catch((error) => cb(error, false)) } _getReadStream(query, id) { const stream = new PassThrough() - this._gfsStream.findOne(query, (error, file) => { - if (file === null) return stream.emit('notFound', id) - if (error) return stream.emit('error', error) - const readStream = this._gfsStream.createReadStream({ _id: file._id }) - readStream.pipe(stream) - stream.emit('meta', { - type: file.contentType, - size: file.length, - lastModified: file.uploadDate, - originalId: file.metadata.originalId - }) + this._gfs + .find(query) + .limit(1) + .toArray() + .then((files) => files[0]) + .then((file) => { + if (!file) return stream.emit('notFound', id) + const readStream = this._gfs.openDownloadStream(file._id) + readStream.pipe(stream) + stream.emit('meta', { + type: file.metadata.contentType, + size: file.length, + lastModified: file.uploadDate, + originalId: file.metadata.originalId + }) - readStream.on('error', (error) => { - if (error.code === 'ENOENT') { - stream.emit('notFound', id) - } else { - stream.emit('error', error) - } + readStream.on('error', (error) => { + if (error.code === 'ENOENT') { + stream.emit('notFound', id) + } else { + stream.emit('error', error) + } + }) }) - }) + .catch((error) => stream.emit('error', error)) return stream } createDataReadStream(id) { - return this._getReadStream({ md5: id }, id) + return this._getReadStream({ 'metadata.md5': id }, id) } createCacheReadStream(id) { @@ -111,34 +114,36 @@ class MongoBackend extends Backend { return passThrough.emit('error', error) } - this._gfsStream.files.countDocuments({ md5: md5 }, (error, count) => { - if (error) { - tmpFile.removeCallback() - return passThrough.emit('error', error) - } - if (count > 0) { - tmpFile.removeCallback() - passThrough.emit('done', { id: md5, type: uploadType, size: size }) - } else { - const mongoWriteStream = this._gfsStream.createWriteStream({ - _id: '', - mode: 'w', - content_type: uploadType, - metadata: { type: 'data' } - }) - - mongoWriteStream.on('close', () => { + this._gfs + .find({ 'metadata.md5': md5 }) + .limit(1) + .toArray() + .then((files) => files.length) + .then((count) => { + if (count > 0) { tmpFile.removeCallback() - passThrough.emit('done', { - id: md5, - type: uploadType, - size: size + passThrough.emit('done', { id: md5, type: uploadType, size: size }) + } else { + const mongoWriteStream = this._gfs.openUploadStream(md5, { + metadata: { type: 'data', contentType: uploadType, md5 } }) - }) - fs.createReadStream(tmpFile.name).pipe(mongoWriteStream) - } - }) + mongoWriteStream.on('close', () => { + tmpFile.removeCallback() + passThrough.emit('done', { + id: md5, + type: uploadType, + size: size + }) + }) + + fs.createReadStream(tmpFile.name).pipe(mongoWriteStream) + } + }) + .catch((error) => { + tmpFile.removeCallback() + return passThrough.emit('error', error) + }) }) passThrough.pipe(typeDetectorStream) @@ -158,8 +163,8 @@ class MongoBackend extends Backend { async deleteData(id) { const deletes = [] const cursor = this._gfs.find({ - md5: id, - 'metadata.type': 'data' + 'metadata.type': 'data', + 'metadata.md5': id }) while (await cursor.hasNext()) { @@ -199,14 +204,11 @@ class MongoBackend extends Backend { }) typeDetectorStream.on('detect', (type) => { - const mongoWriteStream = this._gfsStream.createWriteStream({ - filename: id, - mode: 'w', - content_type: type, - metadata: { type: 'cache', originalId: originalId } + const mongoWriteStream = this._gfs.openUploadStream(id, { + metadata: { type: 'cache', originalId: originalId, contentType: type } }) - mongoWriteStream.on('close', (file) => { + mongoWriteStream.on('finish', () => { if (size === 0) { const error = new Error('Zero size') error.name = 'SizeError' @@ -215,7 +217,7 @@ class MongoBackend extends Backend { passThrough.emit('done', { id: id, - size: file.length, + size: mongoWriteStream.gridFSFile.length, type: type }) }) diff --git a/package.json b/package.json index 6ee61e4..7331c37 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,6 @@ "description": "Darkroom API for image manipulation", "main": "app.js", "dependencies": { - "@appveen/gridfs-stream": "^1.0.0", "@clocklimited/darkroom": "^8.1.1", "@serby/logger": "^3.1.0", "async": "^3.2.0", @@ -21,7 +20,7 @@ "lodash.clone": "^4.0.1", "mkdirp": "^1.0.4", "mmmagic": "^0.5.3", - "mongodb": "3.7.3", + "mongodb": "6.9.0", "morgan": "^1.10.0", "mv": "^2.0.3", "response-time": "^2.3.2", diff --git a/support/migration/fs-to-s3.js b/support/migration/fs-to-s3.js index f3d3a2b..f5939e6 100644 --- a/support/migration/fs-to-s3.js +++ b/support/migration/fs-to-s3.js @@ -161,7 +161,7 @@ async function migrateImages() { const params = { Bucket: config.bucket, Key: `${file.type}/${file.id}`, - ContentType: file.contentType, + ContentType: file.metadata.contentType, ContentLength: file.size, Metadata: { type: file.type }, Body: readStream @@ -180,7 +180,7 @@ async function migrateImages() { retries: 5, onFailedAttempt: (error) => { console.log( - `File #${i} ${file.md5} failed attempt #${error.attemptNumber}. ${error.retriesLeft} retries left.` + `File #${i} ${file.metadata.md5} failed attempt #${error.attemptNumber}. ${error.retriesLeft} retries left.` ) } }) diff --git a/support/migration/mongodb-to-s3.js b/support/migration/mongodb-to-s3.js index 08f4a67..e22d9d5 100644 --- a/support/migration/mongodb-to-s3.js +++ b/support/migration/mongodb-to-s3.js @@ -1,6 +1,5 @@ /* eslint-disable no-console */ const mongo = require('mongodb') -const GridStream = require('@appveen/gridfs-stream') const AWS = require('aws-sdk') const pLimit = require('p-limit') const pRetry = require('p-retry') @@ -16,7 +15,6 @@ async function migrateImages() { await client.connect() const db = client.db(config.databaseName) - const gfsStream = new GridStream(db, mongo) const gfs = new mongo.GridFSBucket(db) AWS.config.update({ @@ -46,7 +44,7 @@ async function migrateImages() { const s3Object = await s3 .headObject({ Bucket: config.bucket, - Key: `${file.metadata.type}/${file.md5}` + Key: `${file.metadata.type}/${file.metadata.md5}` }) .promise() return s3Object !== null @@ -83,8 +81,8 @@ async function migrateImages() { const [nextGridFsFile] = await getFileAtIndex(mid + 1) console.log({ - gridFsFile: gridFsFile && gridFsFile.md5, - nextGridFsFile: nextGridFsFile && nextGridFsFile.md5 + gridFsFile: gridFsFile && gridFsFile.metadata.md5, + nextGridFsFile: nextGridFsFile && nextGridFsFile.metadata.md5 }) const fileInS3 = await hasFileInS3(gridFsFile) const nextFileInS3 = nextGridFsFile @@ -120,13 +118,13 @@ async function migrateImages() { const migrateFile = (file, i) => new Promise((resolve, reject) => { - console.log(`Migrating #${i} ${file.md5}...`) - const readStream = gfsStream.createReadStream({ _id: file._id }) + console.log(`Migrating #${i} ${file.metadata.md5}...`) + const readStream = gfs.openDownloadStream(file._id) const params = { Bucket: config.bucket, - Key: `${file.metadata.type}/${file.md5}`, - ContentType: file.contentType, + Key: `${file.metadata.type}/${file.metadata.md5}`, + ContentType: file.metadata.contentType, ContentLength: file.length, Metadata: { type: file.metadata.type }, Body: readStream @@ -145,7 +143,7 @@ async function migrateImages() { retries: 5, onFailedAttempt: (error) => { console.log( - `File #${i} ${file.md5} failed attempt #${error.attemptNumber}. ${error.retriesLeft} retries left.` + `File #${i} ${file.metadata.md5} failed attempt #${error.attemptNumber}. ${error.retriesLeft} retries left.` ) } }) diff --git a/test/lib/backends/mongo.test.js b/test/lib/backends/mongo.test.js index d7cb4f6..a88fb24 100644 --- a/test/lib/backends/mongo.test.js +++ b/test/lib/backends/mongo.test.js @@ -31,10 +31,12 @@ describe('Mongo Backend using: ' + getConfig().databaseUri, function () { writeStream.on('done', function (file) { backend._db .collection('fs.files') - .findOne({ md5: file.id }, function (err, data) { + .findOne({ 'metadata.md5': file.id }) + .then((data) => { assert.strictEqual(data.metadata.type, 'data') done() }) + .catch(done) }) writeStream.write('hello') writeStream.end() @@ -45,10 +47,12 @@ describe('Mongo Backend using: ' + getConfig().databaseUri, function () { writeStream.on('done', function (file) { backend._db .collection('fs.files') - .findOne({ filename: file.id }, function (err, data) { + .findOne({ filename: file.id }) + .then((data) => { assert.strictEqual(data.metadata.type, 'cache') done() }) + .catch(done) }) writeStream.write('hello') writeStream.end() diff --git a/yarn.lock b/yarn.lock index ef0499e..ee80220 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,13 +2,6 @@ # yarn lockfile v1 -"@appveen/gridfs-stream@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@appveen/gridfs-stream/-/gridfs-stream-1.0.0.tgz#58eb9711784b05bbe8efc770161ad2095b95efe1" - integrity sha512-HK39PN5SyJT95o9Cw8f5smkfCWnnWUyBIIHsdcoeCP9vOc3/uKn1fSIZv/W8dIhKB+S0bdlRg/g3bAYUFL1JzQ== - dependencies: - flushwritable "^1.0.0" - "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -265,6 +258,13 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== +"@mongodb-js/saslprep@^1.1.5": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz#e974bab8eca9faa88677d4ea4da8d09a52069004" + integrity sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw== + dependencies: + sparse-bitfield "^3.0.3" + "@netflix/nerror@^1.0.0": version "1.1.3" resolved "https://registry.yarnpkg.com/@netflix/nerror/-/nerror-1.1.3.tgz#9d88eccca442f1d544f2761d15ea557dc0a44ed2" @@ -336,6 +336,18 @@ resolved "https://registry.yarnpkg.com/@types/url-regex/-/url-regex-4.1.0.tgz#12908eeec04e8e95d40f5c2e28af0ba64a5e62fe" integrity sha512-+a+ePEm9DZ0FIW7kZVGW3S2qpnVh02IOLuvJct0qdIN7VvQBTLo0kTltSlnVdVw/WVTBEh2rzTaUkC81CVENXA== +"@types/webidl-conversions@*": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz#1306dbfa53768bcbcfc95a1c8cde367975581859" + integrity sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA== + +"@types/whatwg-url@^11.0.2": + version "11.0.5" + resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-11.0.5.tgz#aaa2546e60f0c99209ca13360c32c78caf2c409f" + integrity sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ== + dependencies: + "@types/webidl-conversions" "*" + "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" @@ -594,14 +606,6 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bl@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5" - integrity sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g== - dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" - bl@^4.0.3: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" @@ -672,10 +676,10 @@ browserslist@^4.14.5: escalade "^3.1.1" node-releases "^1.1.71" -bson@^1.1.4: - version "1.1.6" - resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.6.tgz#fb819be9a60cd677e0853aee4ca712a785d6618a" - integrity sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg== +bson@^6.7.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/bson/-/bson-6.8.0.tgz#5063c41ba2437c2b8ff851b50d9e36cb7aaa7525" + integrity sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ== buffer@4.9.2: version "4.9.2" @@ -981,7 +985,7 @@ cookiejar@^2.1.2: resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= @@ -1092,11 +1096,6 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -denque@^1.4.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf" - integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw== - depd@~1.1.0, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -1992,7 +1991,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2162,7 +2161,7 @@ is-yarn-global@^0.3.0: resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== -isarray@^1.0.0, isarray@~1.0.0: +isarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -2634,18 +2633,22 @@ mocha@^8.3.2: yargs-parser "20.2.4" yargs-unparser "2.0.0" -mongodb@3.7.3: - version "3.7.3" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.7.3.tgz#b7949cfd0adc4cc7d32d3f2034214d4475f175a5" - integrity sha512-Psm+g3/wHXhjBEktkxXsFMZvd3nemI0r3IPsE0bU+4//PnvNWKkzhZcEsbPcYiWqe8XqXJJEg4Tgtr7Raw67Yw== +mongodb-connection-string-url@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz#c13e6ac284ae401752ebafdb8cd7f16c6723b141" + integrity sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg== + dependencies: + "@types/whatwg-url" "^11.0.2" + whatwg-url "^13.0.0" + +mongodb@6.9.0: + version "6.9.0" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.9.0.tgz#743ebfff6b3c14b04ac6e00a55e30d4127d3016d" + integrity sha512-UMopBVx1LmEUbW/QE0Hw18u583PEDVQmUmVzzBRH0o/xtE9DBRA5ZYLOjpLIa03i8FXjzvQECJcqoMvCXftTUA== dependencies: - bl "^2.2.1" - bson "^1.1.4" - denque "^1.4.1" - optional-require "^1.1.8" - safe-buffer "^5.1.2" - optionalDependencies: - saslprep "^1.0.0" + "@mongodb-js/saslprep" "^1.1.5" + bson "^6.7.0" + mongodb-connection-string-url "^3.0.0" morgan@^1.10.0: version "1.10.0" @@ -2839,13 +2842,6 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -optional-require@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/optional-require/-/optional-require-1.1.8.tgz#16364d76261b75d964c482b2406cb824d8ec44b7" - integrity sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA== - dependencies: - require-at "^1.0.6" - optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -3020,11 +3016,6 @@ prettier@^2.2.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - process-on-spawn@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/process-on-spawn/-/process-on-spawn-1.0.0.tgz#95b05a23073d30a17acfdc92a440efd2baefdc93" @@ -3088,6 +3079,11 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +punycode@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + pupa@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" @@ -3153,19 +3149,6 @@ rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -readable-stream@^2.3.5: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" @@ -3260,11 +3243,6 @@ request@^2.87.0: tunnel-agent "^0.6.0" uuid "^3.3.2" -require-at@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/require-at/-/require-at-1.0.6.tgz#9eb7e3c5e00727f5a4744070a7f560d4de4f6e6a" - integrity sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g== - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -3348,12 +3326,12 @@ rimraf@~2.6.2: dependencies: glob "^7.1.3" -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -3366,13 +3344,6 @@ safe-json-stringify@^1.0.4: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" -saslprep@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226" - integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag== - dependencies: - sparse-bitfield "^3.0.3" - sax@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" @@ -3644,13 +3615,6 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -3875,6 +3839,13 @@ tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +tr46@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-4.1.1.tgz#281a758dcc82aeb4fe38c7dfe4d11a395aac8469" + integrity sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw== + dependencies: + punycode "^2.3.0" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -3987,7 +3958,7 @@ url@0.10.3: punycode "1.3.2" querystring "0.2.0" -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -4037,6 +4008,11 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + webpinfo@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/webpinfo/-/webpinfo-1.3.0.tgz#eeae683a28679a988b38e228d5947ee329e8393c" @@ -4052,6 +4028,14 @@ webpinfo@^1.3.0: thunks "^4.9.2" url-regex "^4.1.1" +whatwg-url@^13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-13.0.0.tgz#b7b536aca48306394a34e44bda8e99f332410f8f" + integrity sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig== + dependencies: + tr46 "^4.1.1" + webidl-conversions "^7.0.0" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"